Esempio n. 1
0
public class ExampleLoader {

  private static final Logger LOGGER = LoggerFactory.getLogger(ExampleLoader.class);
  private static final String STAGE_SKILL_SPEC_PATH =
      "src/main/resources/ProjectStageSkillSpecification.txt";
  private static final String TEAMS_EMPLOYEES_SPEC_PATH =
      "src/main/resources/TeamPersonalSpecification.txt";
  private static final int NAME_COL_INDEX = 1;
  private static final int HOURS_COL_INDEX = 2;
  private static final int FIRST_SKILL_COL_INDEX = 6;
  private static final String EPICS_SPEC_PATH = "src/main/resources/EpicsSpecification.txt";
  private static final int EPIC_ID_COL_INDEX = 0;
  private static final int EPIC_TITLE_COL_INDEX = 1;
  private static final int STORY_ID_COL_INDEX = 3;
  private static final int STORY_TITLE_COL_INDEX = 4;
  private static final PeriodType DEFAULT_WORKLOAD_TIMEUNIT = PeriodType.days();
  private static final int STORY_PREDS_COL_INDEX = 5;

  public static void main(String[] args) throws IOException {
    FileInputStream inputStream = new FileInputStream(STAGE_SKILL_SPEC_PATH);
    try {
      List<String> projectStageAndSkillsString = IOUtils.readLines(inputStream);
      String skillString = projectStageAndSkillsString.get(1);
      List<IProjectStageSkill> skills =
          Collections.unmodifiableList(extractProjectStageSkills(skillString));
      //			System.out.println(Joiner.on(",").join(skills));

      String stageString = projectStageAndSkillsString.get(0);
      List<IProjectStage> stages = extractProjectStages(stageString, skills);
      //			System.out.println(Joiner.on(",").join(stages));

      List<String> teamsEmployeesStrings =
          IOUtils.readLines(new FileInputStream(TEAMS_EMPLOYEES_SPEC_PATH));
      List<ITeam> teams = extractTeamsList(teamsEmployeesStrings, skills);
      //	    	System.out.println(Joiner.on(",").join(teams));

      List<String> epicsStrings = IOUtils.readLines(new FileInputStream(EPICS_SPEC_PATH));
      Map<IEpic, Map<IStory, Set<String>>> epicsToStoryPredsMap =
          extractEpicsToStoryPredsMap(epicsStrings, stages, skills);
      Set<IEpic> epics = epicsToStoryPredsMap.keySet();
      //			System.out.println(Joiner.on(",").join(epics));

      Set<IStoryRelation> storyRelations =
          extractStoryRelations(epicsToStoryPredsMap.values(), epics);
      BusinessDomainModel domainModel =
          new BusinessDomainModel(Sets.newHashSet(teams), stages, epics, storyRelations);

      IRoadmapProblem problem = BusinessModelToRmppTransformer.createRoadmapProblem(domainModel);
      RmppConstructionAlgorithm algo = new RmppConstructionAlgorithm();
      IRoadmapSchedule construct = algo.construct(problem);
      System.out.println(construct);
      System.out.println("makespan: " + construct.getMakeSpan());
    } finally {
      inputStream.close();
    }
  }

  private static Set<IStoryRelation> extractStoryRelations(
      Collection<Map<IStory, Set<String>>> values, Set<IEpic> epics) {
    Set<IStoryRelation> storyRelations = Sets.newHashSet();
    Map<IStory, Set<String>> storyToPredStringMap = mergeMaps(values);
    for (Entry<IStory, Set<String>> predecessorEntry : storyToPredStringMap.entrySet()) {
      IStory story = predecessorEntry.getKey();
      for (String predCode : predecessorEntry.getValue()) {
        if (predCode.isEmpty()) {
          continue;
        }
        Set<IStory> predecessors =
            getPredecessorsForId(predCode, storyToPredStringMap.keySet(), epics);
        for (IStory predecessor : predecessors) {
          IStoryRelation relation = new PredecessorRelation(predecessor, story);
          storyRelations.add(relation);
        }
      }
    }
    return storyRelations;
  }

  private static Set<IStory> getPredecessorsForId(
      String predCode, Set<IStory> stories, Set<IEpic> epics) {
    for (IEpic epic : epics) {
      if (epic.getId().equals(predCode)) {
        return epic.getStories();
      }
    }
    for (IStory story : stories) {
      if (story.getId().equals(predCode)) {
        return Sets.newHashSet(story);
      }
    }
    throw new RuntimeException();
  }

  private static <K, V> Map<K, V> mergeMaps(Collection<Map<K, V>> maps) {
    Map<K, V> merged = Maps.newHashMap();
    for (Map<K, V> map : maps) {
      merged.putAll(map);
    }
    return merged;
  }

  private static Map<IEpic, Map<IStory, Set<String>>> extractEpicsToStoryPredsMap(
      List<String> epicsStrings, List<IProjectStage> stages, List<IProjectStageSkill> skillList) {
    Map<IEpic, Map<IStory, Set<String>>> epicsToStoryMap = Maps.newHashMap();
    Map<IStory, Set<String>> storyToPredIdMap = Maps.newHashMap();
    String epicTitle = null;
    String epicId = null;
    for (String storyString : epicsStrings) {
      if (Strings.isNullOrEmpty(storyString.trim())) {
        continue;
      }
      LOGGER.debug("create story for string: {}", storyString);
      Iterable<String> strings = Splitter.on('\t').split(storyString);
      List<String> words = Lists.newArrayList(strings);
      if (!words.get(0).isEmpty()) {
        if (epicTitle != null) {
          IEpic epic = new Epic(epicId, epicTitle, storyToPredIdMap.keySet());
          epicsToStoryMap.put(epic, storyToPredIdMap);
        }
        storyToPredIdMap = Maps.newHashMap();
        epicId = words.get(EPIC_ID_COL_INDEX);
        epicTitle = words.get(EPIC_TITLE_COL_INDEX);
      }
      Entry<IStory, Set<String>> storyToPredIdsEntry =
          extractStoryAndPredecessorIds(words, stages, skillList);
      storyToPredIdMap.put(storyToPredIdsEntry.getKey(), storyToPredIdsEntry.getValue());
    }
    // TODO last epic is missing
    return epicsToStoryMap;
  }

  private static Entry<IStory, Set<String>> extractStoryAndPredecessorIds(
      List<String> words, List<IProjectStage> stages, List<IProjectStageSkill> skills) {
    String id = words.get(STORY_ID_COL_INDEX);
    String title = words.get(STORY_TITLE_COL_INDEX);
    CharSequence predString = words.get(STORY_PREDS_COL_INDEX);
    Iterable<String> predecessors = Splitter.on(", ").split(predString);
    Set<String> predecessorCodes = Sets.newHashSet(predecessors);
    LinkedHashMap<IProjectStage, Map<IProjectStageSkill, IWorkLoad>> stageToWorkLoadMap =
        extractSkillToWorkLoadMapList(words, stages, skills);
    IStory story = new Story(id, title, stageToWorkLoadMap);
    LOGGER.debug(
        "created story {} with predecessor strings {}",
        story,
        Joiner.on(",").join(predecessorCodes));
    return new AbstractMap.SimpleEntry<IStory, Set<String>>(story, predecessorCodes);
  }

  private static LinkedHashMap<IProjectStage, Map<IProjectStageSkill, IWorkLoad>>
      extractSkillToWorkLoadMapList(
          List<String> words, List<IProjectStage> stages, List<IProjectStageSkill> skillsList) {
    LinkedHashMap<IProjectStage, Map<IProjectStageSkill, IWorkLoad>> stageToWorkLoadMap =
        Maps.newLinkedHashMap();
    LinkedHashMap<IProjectStage, List<String>> estimationStringMap =
        extractEstimationStringMap(words, stages);
    Map<IProjectStage, List<IProjectStageSkill>> stageToSkillMap =
        extractStageToSkillMap(stages, skillsList);
    for (Entry<IProjectStage, List<String>> estimationStringEntry :
        estimationStringMap.entrySet()) {
      Map<IProjectStageSkill, IWorkLoad> workLoadMap = Maps.newHashMap();
      IProjectStage stage = estimationStringEntry.getKey();
      List<String> estimationStrings = estimationStringEntry.getValue();
      List<IProjectStageSkill> stageSkillList = stageToSkillMap.get(stage);
      for (int i = 0; i < stageSkillList.size(); i++) {
        String estimationString = estimationStrings.get(i);
        IProjectStageSkill skill = stageSkillList.get(i);
        if (estimationString == null || estimationString.trim().isEmpty()) {
          continue;
        }
        Float estimation = Float.parseFloat(estimationString.replace(',', '.'));
        IWorkLoad load = new WorkLoad(estimation, DEFAULT_WORKLOAD_TIMEUNIT);
        workLoadMap.put(skill, load);
      }
      stageToWorkLoadMap.put(stage, workLoadMap);
    }
    return stageToWorkLoadMap;
  }

  private static Map<IProjectStage, List<IProjectStageSkill>> extractStageToSkillMap(
      List<IProjectStage> stages, List<IProjectStageSkill> skillsList) {
    Map<IProjectStage, List<IProjectStageSkill>> stageToSkillListMap = Maps.newHashMap();
    LinkedList<IProjectStageSkill> skillListCopy = Lists.newLinkedList(skillsList);
    for (IProjectStage stage : stages) {
      Set<IProjectStageSkill> skillSet = stage.getProjectStageSkills();
      List<IProjectStageSkill> entryList = Lists.newLinkedList();
      while (skillSet.contains(skillListCopy.peekFirst())) {
        entryList.add(skillListCopy.pollFirst());
      }
      stageToSkillListMap.put(stage, entryList);
    }
    return stageToSkillListMap;
  }

  private static LinkedHashMap<IProjectStage, List<String>> extractEstimationStringMap(
      List<String> words, List<IProjectStage> stages) {
    LinkedHashMap<IProjectStage, List<String>> estimationStringMap = Maps.newLinkedHashMap();
    LinkedList<String> wordsCopy = Lists.newLinkedList(words);
    for (int i = 1; i <= stages.size(); i++) {
      IProjectStage stage = stages.get(stages.size() - i);
      int stageSkillCount = stage.getProjectStageSkills().size();
      int estimationCount = stageSkillCount + 1;
      LinkedList<String> entryList = Lists.newLinkedList();
      for (int j = 0; j < estimationCount; j++) {
        String word = wordsCopy.pollLast();
        entryList.addFirst(word);
      }
      estimationStringMap.put(stage, entryList);
      wordsCopy.pollLast();
    }
    return estimationStringMap;
  }

  private static List<ITeam> extractTeamsList(
      List<String> teamsEmployeesStrings, List<IProjectStageSkill> skills) {
    List<ITeam> teams = Lists.newArrayList();
    Set<IEmployee> employees = Sets.newHashSet();
    String teamName = null;
    for (String employeeString : teamsEmployeesStrings) {
      if (Strings.isNullOrEmpty(employeeString.trim())) {
        continue;
      }
      LOGGER.debug("create employee for string: {}", employeeString);
      Iterable<String> strings = Splitter.on('\t').split(employeeString);
      List<String> words = Lists.newArrayList(strings);
      if (!words.get(0).isEmpty()) {
        if (teamName != null) {
          ITeam team = new Team(teamName, employees);
          teams.add(team);
        }
        employees = Sets.newHashSet();
        teamName = words.get(0);
      }
      IEmployee employee = extractEmployee(words, skills);
      employees.add(employee);
    }
    return teams;
  }

  private static IEmployee extractEmployee(List<String> words, List<IProjectStageSkill> skills) {
    String name = words.get(NAME_COL_INDEX);
    int hoursPerWeek = Integer.parseInt(words.get(HOURS_COL_INDEX));
    Map<IProjectStageSkill, SkillLevel> skillMap = extractSkillMap(words, skills);
    IEmployee employee = new Employee(name, hoursPerWeek, skillMap);
    LOGGER.debug("created employee: {}", employee);
    return employee;
  }

  private static Map<IProjectStageSkill, SkillLevel> extractSkillMap(
      List<String> words, List<IProjectStageSkill> skills) {
    Map<IProjectStageSkill, SkillLevel> skillsMap = Maps.newHashMap();
    List<String> skillEvaluations = words.subList(FIRST_SKILL_COL_INDEX, words.size());
    for (int i = 0; i < skills.size(); i++) {
      String evaluation = skillEvaluations.get(i);
      if (Strings.isNullOrEmpty(evaluation)) {
        continue;
      }
      IProjectStageSkill skill = skills.get(i);
      SkillLevel level = SkillLevel.parse(evaluation);
      skillsMap.put(skill, level);
    }
    return skillsMap;
  }

  private static List<IProjectStage> extractProjectStages(
      String stageString, List<IProjectStageSkill> skills) {
    LinkedHashMap<String, Integer> stageNameToSkillCountMap =
        createStageNameToSkillCountMap(stageString);
    List<IProjectStage> stages = createStages(stageNameToSkillCountMap, skills);
    return stages;
  }

  private static List<IProjectStage> createStages(
      LinkedHashMap<String, Integer> stageNameToSkillCountMap, List<IProjectStageSkill> skills) {
    LOGGER.debug(
        "create project stages for stageNameToSkillCountMap {} and skill list {}",
        Joiner.on(",").join(stageNameToSkillCountMap.entrySet()),
        Joiner.on(",").join(skills));
    List<IProjectStage> stages = Lists.newArrayList();

    List<IProjectStageSkill> copy = Lists.newArrayList(skills);
    for (Entry<String, Integer> entry : stageNameToSkillCountMap.entrySet()) {
      String name = entry.getKey();
      int skillCount = entry.getValue();
      Set<IProjectStageSkill> stageSkills = getAndRemoveNextSkills(copy, skillCount);
      IProjectStage stage = new ProjectStage(stageSkills, name);
      stages.add(stage);
    }
    LOGGER.debug("created project stages: {}", Joiner.on(",").join(stages));
    return stages;
  }

  private static Set<IProjectStageSkill> getAndRemoveNextSkills(
      List<IProjectStageSkill> skills, int skillCount) {
    Set<IProjectStageSkill> nextSkills = Sets.newHashSet();
    for (int i = 0; i < skillCount; i++) {
      IProjectStageSkill skill = skills.remove(0);
      nextSkills.add(skill);
    }
    return nextSkills;
  }

  private static LinkedHashMap<String, Integer> createStageNameToSkillCountMap(String stageString) {
    LOGGER.debug("create stage to skill count map for string {}", stageString);
    List<String> stageNames = extractStageNames(stageString);
    List<String> stageNamesAndTabs = extractStageNamesWithTabs(stageNames, stageString);
    LinkedHashMap<String, Integer> nameToCountMap = Maps.newLinkedHashMap();
    for (int i = 0; i < stageNames.size(); i++) {
      String stageName = stageNames.get(i);
      String stageAndTabs = stageNamesAndTabs.get(i);
      int count = CharMatcher.is('\t').countIn(stageAndTabs) - 1;
      nameToCountMap.put(stageName, count);
    }
    return nameToCountMap;
  }

  private static List<String> extractStageNamesWithTabs(
      List<String> stageNames, String stageString) {
    List<String> namesWithTabs = Lists.newArrayList();
    for (int i = 0; i < stageNames.size() - 1; i++) {
      String thisStage = stageNames.get(i);
      String nextStage = stageNames.get(i + 1);
      int indexThisStage = stageString.indexOf(thisStage);
      int indexNextStage = stageString.indexOf(nextStage);
      String string = stageString.substring(indexThisStage, indexNextStage);
      namesWithTabs.add(string);
    }
    int lastStageIndex = stageString.indexOf(stageNames.get(stageNames.size() - 1));
    String last = stageString.substring(lastStageIndex);
    namesWithTabs.add(last);
    return namesWithTabs;
  }

  private static List<String> extractStageNames(String stageString) {
    List<String> stageNames = Lists.newArrayList();
    StringTokenizer tokenizer = new StringTokenizer(stageString, "\t");
    while (tokenizer.hasMoreElements()) {
      String next = tokenizer.nextToken();
      stageNames.add(next);
    }
    return stageNames;
  }

  private static List<IProjectStageSkill> extractProjectStageSkills(String skillString) {
    StringTokenizer tokenizer = new StringTokenizer(skillString, "\t");
    List<IProjectStageSkill> skills = Lists.newArrayList();
    while (tokenizer.hasMoreElements()) {
      String name = tokenizer.nextToken();
      IProjectStageSkill skill = new ProjectStageSkill(name);
      skills.add(skill);
    }
    return skills;
  }
}