Changeset 1982 for trunk/autoquest-core-tasktrees/src
- Timestamp:
- 06/30/15 10:26:24 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java
r1976 r1982 28 28 import de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTraversal; 29 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 30 31 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 31 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; … … 45 46 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 46 47 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskPath; 48 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeUtils; 47 49 import de.ugoe.cs.util.console.Console; 48 50 import difflib.Chunk; … … 194 196 195 197 /*mergecount++; 196 if ((mergecount > 140) && ((mergecount % 20) == 0)) { 198 System.out.println(mergecount); 199 if ((mergecount % 20) == 0) { 197 200 System.out.println("performing validation " + mergecount); 198 new TaskTreeValidator().validate(appData.getTaskModel().getUserSessions(), true); 201 new de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTreeValidator() 202 .validate(appData.getTaskModel().getUserSessions(), true); 199 203 }*/ 200 201 204 202 205 appData.setMostSimilarTasks(null); … … 235 238 } 236 239 237 harmonizeM arkingTemporalRelationships(sessions);240 harmonizeModel(sessions, appData.getTaskModel()); 238 241 } 239 242 while (appData.getMostSimilarTasks() != null); … … 284 287 * 285 288 */ 286 private void harmonizeMarkingTemporalRelationships(List<IUserSession> sessions) { 287 final Map<ITask, IIteration> harmonizedIterations = new HashMap<>(); 288 final Map<ITask, IOptional> harmonizedOptionals = new HashMap<>(); 289 290 for (IUserSession session : sessions) { 291 for (ITaskInstance instance : session) { 292 instance.accept(new DefaultTaskInstanceTraversingVisitor() { 293 294 @Override 295 public void visit(IIterationInstance iterationInstance) { 296 // visit the children 297 super.visit(iterationInstance); 298 299 // there may have been a model update at the children. If so, set the 300 // new marked task 301 IIteration iteration = iterationInstance.getIteration(); 302 ITask newChildTask = iterationInstance.get(0).getTask(); 303 304 if (newChildTask != iteration.getMarkedTask()) { 305 taskBuilder.setMarkedTask(iteration, newChildTask); 306 } 307 308 // check, if there is a harmonized iteration 309 IIteration harmonizedIteration = 310 harmonizedIterations.get(iteration.getMarkedTask()); 311 312 if ((harmonizedIteration != null) && (iteration != harmonizedIteration)) { 313 // there is a harmonized iteration --> set it as new task 314 /*System.out.println("harmonizing iteration of " + 315 iteration.getMarkedTask() + " from " + iteration + 316 " to " + harmonizedIteration);*/ 317 taskBuilder.setTask(iterationInstance, harmonizedIteration); 318 } 319 else if (harmonizedIteration == null) { 320 // remember this iteration as the harmonized one 321 harmonizedIterations.put(iteration.getMarkedTask(), iteration); 322 } 323 } 324 325 @Override 326 public void visit(IOptionalInstance optionalInstance) { 327 // visit the children 328 super.visit(optionalInstance); 329 330 IOptional optional = optionalInstance.getOptional(); 331 332 if (optionalInstance.getChild() != null) { 333 // there may have been a model update at the child. If so, set the 334 // new marked task 335 ITask newChildTask = optionalInstance.getChild().getTask(); 336 337 if (newChildTask != optional.getMarkedTask()) { 338 taskBuilder.setMarkedTask(optional, newChildTask); 339 } 340 } 341 342 // check, if there is a harmonized optional 343 IOptional harmonizedOptional = 344 harmonizedOptionals.get(optional.getMarkedTask()); 345 346 if ((harmonizedOptional != null) && (optional != harmonizedOptional)) { 347 // there is a harmonized optional --> set it as new task 348 /*System.out.println("harmonizing optional of " + 349 optional.getMarkedTask() + " from " + optional + 350 " to " + harmonizedOptional);*/ 351 taskBuilder.setTask(optionalInstance, harmonizedOptional); 352 } 353 else if (harmonizedOptional == null) { 354 // remember this optional as the harmonized one 355 harmonizedOptionals.put(optional.getMarkedTask(), optional); 356 } 357 } 358 359 @Override 360 public void visit(ISelectionInstance selectionInstance) { 361 ITask childTaskBeforeUpdate = selectionInstance.getChild().getTask(); 362 363 super.visit(selectionInstance); 364 365 ITask childTaskAfterUpdate = selectionInstance.getChild().getTask(); 366 367 if (childTaskBeforeUpdate != childTaskAfterUpdate) { 368 // update the selection model if required. 369 ISelection selection = selectionInstance.getSelection(); 370 371 boolean foundOtherInstanceWithOldChild = false; 372 373 for (ITaskInstance instance : selection.getInstances()) { 374 ITask child = ((ISelectionInstance) instance).getChild().getTask(); 375 376 if (child == childTaskBeforeUpdate) { 377 foundOtherInstanceWithOldChild = true; 378 break; 379 } 380 } 381 382 if (!foundOtherInstanceWithOldChild) { 383 taskBuilder.removeChild(selection, childTaskBeforeUpdate); 384 } 385 386 // remove and add the child to ensure to have it only once 387 taskBuilder.removeChild(selection, childTaskAfterUpdate); 388 taskBuilder.addChild(selection, childTaskAfterUpdate); 389 } 390 } 391 392 @Override 393 public void visit(ISequenceInstance sequenceInstance) { 394 ISequence sequence = sequenceInstance.getSequence(); 395 int childIndex = 0; 396 397 for (ITaskInstance child : sequenceInstance) { 398 child.accept(this); 399 400 ITask newChildTask = child.getTask(); 401 402 if (sequence.getChildren().get(childIndex) != newChildTask) { 403 taskBuilder.setChild(sequenceInstance.getSequence(), childIndex, 404 newChildTask); 405 } 406 407 childIndex++; 408 } 409 } 410 411 }); 412 413 } 414 415 // several subsequent instances, which had formerly different tasks, may now have 416 // the same. Hence, they need to be merged. But as everything else would be way too 417 // complex, we only perform the merge, if they occur next to each other on the 418 // same level 419 mergeSubsequentIdenticalMarkingTemporalRelationships(session); 420 } 289 private void harmonizeModel(List<IUserSession> sessions, ITaskModel model) { 290 boolean somethingChanged; 291 292 do { 293 // harmonize marking temporal relationships 294 MarkingTemporalRelationshipHarmonizer harmonizer = 295 new MarkingTemporalRelationshipHarmonizer(); 296 297 for (IUserSession session : sessions) { 298 for (ITaskInstance instance : session) { 299 instance.accept(harmonizer); 300 } 301 } 302 303 // integrate iterations performed once for children that were somewhere iterated more 304 // than once 305 SingleIterationExecutionsIntegrator integrator = 306 new SingleIterationExecutionsIntegrator(harmonizer.harmonizedIterations); 307 308 for (IUserSession session : sessions) { 309 for (ITaskInstance instance : session) { 310 instance.accept(integrator); 311 } 312 } 313 314 // search for sequences having subsequent identical children (may be the result 315 // of merging two subsequent children) 316 SubsequentIdenticalChildrenMerger merger = new SubsequentIdenticalChildrenMerger(); 317 for (ITask task : model.getTasks()) { 318 merger.mergeSubsequentIdenticalTasks(task); 319 } 320 321 for (IUserSession session : sessions) { 322 merger.mergeSubsequentIdenticalInstances(session); 323 } 324 325 somethingChanged = harmonizer.somethingChanged || integrator.somethingChanged || 326 merger.somethingChanged; 327 328 } 329 while(somethingChanged); 421 330 } 422 331 … … 477 386 (similarTasks, identTaskHandlStrat.getTaskComparator()); 478 387 479 if ( similarTasks == null) {388 if ((similarTasks == null) || (similarTasks.getDiffLevel() == 100)) { 480 389 // this may happen, if no mergable level of similarity can be found 481 390 return; … … 486 395 List<FlattenInstruction> flattenInstructions = 487 396 getFlattenInstructions(similarTasks, appData); 397 398 if (flattenInstructions == null) { 399 // we cannot merge this 400 return; 401 } 488 402 489 403 // for (FlattenInstruction instruction : flattenInstructions) { … … 572 486 } 573 487 574 /*if (replacement s.size() > 0) {488 /*if (replacementTask != null) { 575 489 System.out.println("replacement task is calculated to be: "); 576 new TaskTreeEncoder().encode(replacements.values().iterator().next().getTask(),577 490 new de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTreeEncoder().encode 491 (replacementTask, System.out); 578 492 }*/ 579 493 … … 581 495 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 582 496 497 ITask uniqueReplacement = appData.ensureUnique(replacementTask); 498 499 if (uniqueReplacement != replacementTask) { 500 System.out.println("updating task instances with a unified replacement task"); 501 for (ITaskInstance replacement : replacements.values()) { 502 taskBuilder.setTask(replacement, uniqueReplacement); 503 } 504 } 583 505 584 506 for (IUserSession session : appData.getSessions()) { … … 760 682 else if (selection.getChildren().contains(child2)) { 761 683 existingChildTask = child2; 762 }684 } 763 685 764 686 if (existingChildTask != null) { … … 812 734 } 813 735 } 814 736 737 // tasks that refer to themselves are not valid. But due to the creation of 738 // selections, this may happen. This must be prevented 739 /*final Set<ITask> tasks = new HashSet<ITask>(); 740 741 try { 742 selection.accept(new DefaultTaskTraversingVisitor() { 743 @Override 744 public void visit(ITask task) { 745 if (!tasks.contains(task)) { 746 tasks.add(task); 747 super.visit(task); 748 } 749 else { 750 throw new RuntimeException("tasks refers to itself"); 751 } 752 } 753 }); 754 } 755 catch (RuntimeException e) { 756 // a task refers to itself 757 return null; 758 }*/ 759 760 // the new selection does not refer to itself, no apply it 815 761 selection = (ISelection) appData.ensureUnique(selection); 816 762 817 763 createReplacementInstructions 818 764 (delta.getOriginal(), selection, expectedChild1, result); … … 907 853 */ 908 854 private void addSelectionChildIfRequired(ISelection selection, ITask child) { 855 if (TaskTreeUtils.isChild(selection, child)) { 856 System.out.println(selection); 857 System.out.println(child); 858 throw new RuntimeException("child of selection has selection itself as child"); 859 } 909 860 for (ITask candidate : selection.getChildren()) { 910 861 if (identTaskHandlStrat.getTaskComparator().equals(candidate, child)) { … … 1098 1049 // first check, if the instance was already created, if not create it 1099 1050 ISequenceInstance sequenceInstance = ensureSequenceChildInstanceFor 1100 (selection, (ISequence) instruction.getSelectedChild(), 1051 (selection, (ISequence) instruction.getSelectedChild(), session); 1101 1052 1102 1053 taskBuilder.addChild(sequenceInstance, instance); … … 1469 1420 } 1470 1421 } 1471 1472 /** 1473 * 1474 */ 1475 private void mergeSubsequentIdenticalMarkingTemporalRelationships(ITaskInstanceList list) { 1476 int index = 0; 1477 TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 1478 1479 while (index < (list.size() - 1)) { 1480 ITaskInstance instance1 = list.get(index); 1481 ITaskInstance instance2 = list.get(index + 1); 1482 1483 if (comparator.equals(instance1.getTask(), instance2.getTask())) { 1484 if (instance1 instanceof IIterationInstance) { 1485 // add the children of the second to the first iteration instance and discard 1486 // the second 1487 for (ITaskInstance child : (IIterationInstance) instance2) { 1488 taskBuilder.addChild((IIterationInstance) instance1, child); 1489 } 1490 1491 taskBuilder.removeTaskInstance(list, index + 1); 1492 taskBuilder.discardTaskInstance(instance2); 1493 } 1494 else if (instance1 instanceof IOptionalInstance) { 1495 ITaskInstance optionalChildInstance1 = 1496 ((IOptionalInstance) instance1).getChild(); 1497 ITaskInstance optionalChildInstance2 = 1498 ((IOptionalInstance) instance2).getChild(); 1499 1500 if (optionalChildInstance1 == null) { 1501 // independent of the second, just remove the first. The second will be the 1502 // unique representation 1503 taskBuilder.removeTaskInstance(list, index); 1504 } 1505 else if (optionalChildInstance2 == null) { 1506 // remove the second. The first will be the unique representation 1507 taskBuilder.removeTaskInstance(list, index + 1); 1508 } 1509 else if (optionalChildInstance1 instanceof IIterationInstance) { 1510 // add all children of the second optional iteration instance to the 1511 // first and discard the second 1512 for (ITaskInstance child : (IIterationInstance) optionalChildInstance2) { 1513 taskBuilder.addChild 1514 ((IIterationInstance) optionalChildInstance1, child); 1515 } 1516 1517 taskBuilder.removeTaskInstance(list, index + 1); 1518 taskBuilder.discardTaskInstance(instance2); 1519 } 1520 else { 1521 // both optional children are no iterations --> create an iteration 1522 // for them and add them both as children. 1523 throw new java.lang.UnsupportedOperationException("not implemented yet"); 1524 } 1525 } 1526 else { 1527 index++; 1528 } 1529 } 1530 else { 1531 index++; 1532 } 1533 } 1534 1535 for (ITaskInstance child : list) { 1536 if (child instanceof ITaskInstanceList) { 1537 mergeSubsequentIdenticalMarkingTemporalRelationships((ITaskInstanceList) child); 1538 } 1539 } 1540 } 1541 1422 1542 1423 /** 1543 1424 * … … 1559 1440 } 1560 1441 } 1561 1562 /** 1563 * 1564 */ 1565 /*private boolean containsNewTask(ITask task, RuleApplicationData appData) {1566 if (appData.isSelfCreatedTask(task)) {1567 return true;1568 }1569 else if (task instanceof IStructuringTemporalRelationship) {1570 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) {1571 if (containsNewTask(child, appData)) {1572 returntrue;1573 }1574 } 1575 } 1576 else if (task instanceof IMarkingTemporalRelationship) {1577 return containsNewTask(((IMarkingTemporalRelationship) task).getMarkedTask(), appData);1578 }1579 1580 return false; 1581 } */1442 1443 /** 1444 * 1445 */ 1446 private void removeSelectionChildIfNotUsedAnymoreInInstances(ISelection selection, ITask child) { 1447 boolean foundOtherInstanceWithChild = false; 1448 1449 for (ITaskInstance instance : selection.getInstances()) { 1450 ITask candidate = ((ISelectionInstance) instance).getChild().getTask(); 1451 1452 if (candidate == child) { 1453 foundOtherInstanceWithChild = true; 1454 break; 1455 } 1456 } 1457 1458 if (!foundOtherInstanceWithChild) { 1459 taskBuilder.removeChild(selection, child); 1460 } 1461 1462 } 1582 1463 1583 1464 /** … … 1983 1864 } 1984 1865 1866 /** 1867 * 1868 */ 1869 private class MarkingTemporalRelationshipHarmonizer 1870 extends DefaultTaskInstanceTraversingVisitor 1871 { 1872 /** */ 1873 final Map<ITask, IIteration> harmonizedIterations = new HashMap<>(); 1874 1875 /** */ 1876 final Map<ITask, IOptional> harmonizedOptionals = new HashMap<>(); 1877 1878 /** */ 1879 private boolean somethingChanged = false; 1880 1881 /** 1882 * 1883 */ 1884 @Override 1885 public void visit(IIterationInstance iterationInstance) { 1886 // visit the children 1887 super.visit(iterationInstance); 1888 1889 // there may have been a model update at the children. If so, set the 1890 // new marked task 1891 IIteration iteration = iterationInstance.getIteration(); 1892 ITask newChildTask = iterationInstance.get(0).getTask(); 1893 1894 if (newChildTask != iteration.getMarkedTask()) { 1895 taskBuilder.setMarkedTask(iteration, newChildTask); 1896 } 1897 1898 // check, if there is a harmonized iteration 1899 IIteration harmonizedIteration = 1900 harmonizedIterations.get(iteration.getMarkedTask()); 1901 1902 if ((harmonizedIteration != null) && (iteration != harmonizedIteration)) { 1903 // there is a harmonized iteration --> set it as new task 1904 /*System.out.println("harmonizing iteration of " + 1905 iteration.getMarkedTask() + " from " + iteration + 1906 " to " + harmonizedIteration);*/ 1907 taskBuilder.setTask(iterationInstance, harmonizedIteration); 1908 somethingChanged = true; 1909 } 1910 else if (harmonizedIteration == null) { 1911 // remember this iteration as the harmonized one 1912 harmonizedIterations.put(iteration.getMarkedTask(), iteration); 1913 } 1914 } 1915 1916 /** 1917 * 1918 */ 1919 @Override 1920 public void visit(IOptionalInstance optionalInstance) { 1921 // visit the children 1922 super.visit(optionalInstance); 1923 1924 IOptional optional = optionalInstance.getOptional(); 1925 1926 if (optionalInstance.getChild() != null) { 1927 // there may have been a model update at the child. If so, set the 1928 // new marked task 1929 ITask newChildTask = optionalInstance.getChild().getTask(); 1930 1931 if (newChildTask != optional.getMarkedTask()) { 1932 taskBuilder.setMarkedTask(optional, newChildTask); 1933 } 1934 } 1935 1936 // check, if there is a harmonized optional 1937 IOptional harmonizedOptional = 1938 harmonizedOptionals.get(optional.getMarkedTask()); 1939 1940 if ((harmonizedOptional != null) && (optional != harmonizedOptional)) { 1941 // there is a harmonized optional --> set it as new task 1942 /*System.out.println("harmonizing optional of " + 1943 optional.getMarkedTask() + " from " + optional + 1944 " to " + harmonizedOptional);*/ 1945 taskBuilder.setTask(optionalInstance, harmonizedOptional); 1946 somethingChanged = true; 1947 } 1948 else if (harmonizedOptional == null) { 1949 // remember this optional as the harmonized one 1950 harmonizedOptionals.put(optional.getMarkedTask(), optional); 1951 } 1952 } 1953 1954 /** 1955 * 1956 */ 1957 @Override 1958 public void visit(ISelectionInstance selectionInstance) { 1959 ITask childTaskBeforeUpdate = selectionInstance.getChild().getTask(); 1960 1961 super.visit(selectionInstance); 1962 1963 ITask childTaskAfterUpdate = selectionInstance.getChild().getTask(); 1964 1965 if (childTaskBeforeUpdate != childTaskAfterUpdate) { 1966 // update the selection model if required. 1967 ISelection selection = selectionInstance.getSelection(); 1968 removeSelectionChildIfNotUsedAnymoreInInstances(selection, childTaskBeforeUpdate); 1969 1970 // remove and add the child to ensure to have it only once 1971 taskBuilder.removeChild(selection, childTaskAfterUpdate); 1972 taskBuilder.addChild(selection, childTaskAfterUpdate); 1973 somethingChanged = true; 1974 } 1975 } 1976 1977 /** 1978 * 1979 */ 1980 @Override 1981 public void visit(ISequenceInstance sequenceInstance) { 1982 ISequence sequence = sequenceInstance.getSequence(); 1983 int childIndex = 0; 1984 1985 for (ITaskInstance child : sequenceInstance) { 1986 child.accept(this); 1987 1988 ITask newChildTask = child.getTask(); 1989 1990 if (sequence.getChildren().get(childIndex) != newChildTask) { 1991 taskBuilder.setChild(sequenceInstance.getSequence(), childIndex, 1992 newChildTask); 1993 somethingChanged = true; 1994 } 1995 1996 childIndex++; 1997 } 1998 } 1999 2000 } 2001 2002 2003 /** 2004 * 2005 */ 2006 private class SingleIterationExecutionsIntegrator 2007 extends DefaultTaskInstanceTraversingVisitor 2008 { 2009 2010 /** */ 2011 private Map<ITask, IIteration> iterations; 2012 2013 /** */ 2014 private boolean somethingChanged = false; 2015 2016 /** 2017 * 2018 */ 2019 public SingleIterationExecutionsIntegrator(Map<ITask, IIteration> iterations) { 2020 this.iterations = iterations; 2021 } 2022 2023 /* (non-Javadoc) 2024 * @see DefaultTaskInstanceTraversingVisitor#visit(IOptionalInstance) 2025 */ 2026 @Override 2027 public void visit(IOptionalInstance optionalInstance) { 2028 super.visit(optionalInstance); 2029 2030 if (optionalInstance.getChild() != null) { 2031 IIteration iteration = iterations.get(optionalInstance.getChild().getTask()); 2032 2033 if (iteration != null) { 2034 taskBuilder.setMarkedTask(optionalInstance.getOptional(), iteration); 2035 IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 2036 taskBuilder.addChild(replacement, optionalInstance.getChild()); 2037 taskBuilder.setChild(optionalInstance, replacement); 2038 somethingChanged = true; 2039 } 2040 } 2041 } 2042 2043 /* (non-Javadoc) 2044 * @see DefaultTaskInstanceTraversingVisitor#visit(ISelectionInstance) 2045 */ 2046 @Override 2047 public void visit(ISelectionInstance selectionInstance) { 2048 super.visit(selectionInstance); 2049 2050 ITask usedChildTask = selectionInstance.getChild().getTask(); 2051 IIteration iteration = iterations.get(usedChildTask); 2052 2053 if (iteration != null) { 2054 // extend the selection model 2055 // remove and add the child to ensure to have it only once 2056 ISelection selection = selectionInstance.getSelection(); 2057 taskBuilder.removeChild(selection, iteration); 2058 taskBuilder.addChild(selection, iteration); 2059 2060 // update the instance 2061 IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 2062 taskBuilder.addChild(replacement, selectionInstance.getChild()); 2063 taskBuilder.setChild(selectionInstance, replacement); 2064 2065 // update the selection model if required. 2066 removeSelectionChildIfNotUsedAnymoreInInstances(selection, usedChildTask); 2067 2068 somethingChanged = true; 2069 } 2070 2071 } 2072 2073 /* (non-Javadoc) 2074 * @see DefaultTaskInstanceTraversingVisitor#visit(ISequenceInstance) 2075 */ 2076 @Override 2077 public void visit(ISequenceInstance sequenceInstance) { 2078 int index = 0; 2079 while (index < sequenceInstance.size()) { 2080 ITaskInstance child = sequenceInstance.get(index); 2081 child.accept(this); 2082 2083 IIteration iteration = iterations.get(child.getTask()); 2084 2085 if (iteration != null) { 2086 taskBuilder.setChild(sequenceInstance.getSequence(), index, iteration); 2087 IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 2088 taskBuilder.addChild(replacement, child); 2089 taskBuilder.setTaskInstance(sequenceInstance, index, replacement); 2090 somethingChanged = true; 2091 } 2092 2093 index++; 2094 } 2095 } 2096 2097 } 2098 2099 /** 2100 * 2101 */ 2102 private class SubsequentIdenticalChildrenMerger { 2103 2104 /** */ 2105 private boolean somethingChanged = false; 2106 2107 /** 2108 * 2109 */ 2110 private void mergeSubsequentIdenticalTasks(ITask task) { 2111 TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 2112 2113 if (task instanceof ISequence) { 2114 // merge the children 2115 mergeSubsequentIdenticalTasks((ISequence) task); 2116 2117 int index = 0; 2118 2119 while (index < ((ISequence) task).getChildren().size()) { 2120 ITask child = ((ISequence) task).getChildren().get(index); 2121 2122 List<ITaskInstance> childInstances = new LinkedList<>(); 2123 2124 for (ITaskInstance instance : task.getInstances()) { 2125 ITaskInstance childInstance = ((ISequenceInstance) instance).get(index); 2126 if (comparator.equals(childInstance.getTask(), child)) { 2127 childInstances.add(childInstance); 2128 } 2129 } 2130 2131 Map<ITaskInstance, ITaskInstance> childInstanceReplacements = new HashMap<>(); 2132 2133 ITask replacementTask = 2134 getReplacements(child, childInstances, childInstanceReplacements); 2135 2136 if (replacementTask != null) { 2137 taskBuilder.setChild((ISequence) task, index, replacementTask); 2138 2139 for (ITaskInstance instance : task.getInstances()) { 2140 ITaskInstance childInstance = ((ISequenceInstance) instance).get(index); 2141 ITaskInstance replacement = childInstanceReplacements.get(childInstance); 2142 2143 if (replacement != null) { 2144 taskBuilder.setTaskInstance 2145 ((ISequenceInstance) instance, index, replacement); 2146 } 2147 } 2148 2149 somethingChanged = true; 2150 } 2151 2152 index++; 2153 } 2154 } 2155 else if (task instanceof ISelection) { 2156 // it could have children being marking temporal relationship of a sequence of 2157 // interest. If so, adapt the model and the instances 2158 int index = 0; 2159 2160 while (index < ((ISelection) task).getChildren().size()) { 2161 ITask child = ((ISelection) task).getChildren().get(index); 2162 List<ITaskInstance> childInstances = new LinkedList<>(); 2163 2164 for (ITaskInstance instance : task.getInstances()) { 2165 ITaskInstance childInstance = ((ISelectionInstance) instance).getChild(); 2166 if (comparator.equals(childInstance.getTask(), child)) { 2167 childInstances.add(childInstance); 2168 } 2169 } 2170 2171 Map<ITaskInstance, ITaskInstance> childInstanceReplacements = new HashMap<>(); 2172 2173 ITask replacementTask = 2174 getReplacements(child, childInstances, childInstanceReplacements); 2175 2176 if (replacementTask != null) { 2177 taskBuilder.removeChild((ISelection) task, child); 2178 taskBuilder.addChild((ISelection) task, replacementTask); 2179 2180 for (ITaskInstance instance : task.getInstances()) { 2181 ITaskInstance childInstance = ((ISelectionInstance) instance).getChild(); 2182 ITaskInstance replacement = childInstanceReplacements.get(childInstance); 2183 2184 if (replacement != null) { 2185 taskBuilder.setChild(((ISelectionInstance) instance), replacement); 2186 } 2187 } 2188 2189 // start from the beginning as the children order may have changed 2190 index = 0; 2191 somethingChanged = true; 2192 } 2193 else { 2194 index++; 2195 } 2196 } 2197 } 2198 } 2199 2200 /** 2201 * 2202 */ 2203 private ITask getReplacements(ITask child, 2204 List<ITaskInstance> childInstances, 2205 Map<ITaskInstance, ITaskInstance> childInstanceReplacements) 2206 { 2207 final TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 2208 ITask candidate = child; 2209 boolean isOptional = false; 2210 2211 while (candidate instanceof IMarkingTemporalRelationship) { 2212 if (candidate instanceof IOptional) { 2213 isOptional = true; 2214 } 2215 candidate = ((IMarkingTemporalRelationship) candidate).getMarkedTask(); 2216 } 2217 2218 if ((candidate instanceof IEventTask) || (candidate instanceof ISelection) || 2219 (((ISequence) candidate).getChildren().size() != 1)) 2220 { 2221 // no sequence of interest as it has more than one children 2222 return null; 2223 } 2224 2225 // found a sequence to be handled. The sequence has a single child and this will 2226 // be either an optional of an iteration of the single child, or an iteration of 2227 // the single child. 2228 final ISequence sequenceWithSingleChild = (ISequence) candidate; 2229 2230 // determine all instances of the sequence rooted by the provided parent instance 2231 ITask singleChild = sequenceWithSingleChild.getChildren().get(0); 2232 IOptional optional = null; 2233 2234 if (singleChild instanceof IOptional) { 2235 isOptional = true; 2236 optional = (IOptional) singleChild; 2237 singleChild = optional.getMarkedTask(); 2238 } 2239 2240 IIteration iteration = (IIteration) singleChild; 2241 2242 if (isOptional && (optional == null)) { 2243 optional = taskFactory.createNewOptional(); 2244 taskBuilder.setMarkedTask(optional, iteration); 2245 } 2246 2247 for (ITaskInstance childInstance : childInstances) { 2248 // get all instances of the single child of the sequence of interest which belong to 2249 // the a child instance to be replaced and calculate a replacement 2250 final List<ITaskInstance> singleChildInstances = new LinkedList<>(); 2251 final ITask taskToSearchFor = singleChild; 2252 2253 childInstance.accept(new DefaultTaskInstanceTraversingVisitor() { 2254 @Override 2255 public void visit(ISelectionInstance selectionInstance) { 2256 if (comparator.equals(selectionInstance.getTask(), taskToSearchFor)) { 2257 singleChildInstances.add(selectionInstance); 2258 } 2259 } 2260 2261 @Override 2262 public void visit(ISequenceInstance sequenceInstance) { 2263 if (comparator.equals(sequenceInstance.getTask(), taskToSearchFor)) { 2264 singleChildInstances.add(sequenceInstance); 2265 } 2266 else if (comparator.equals(sequenceInstance.getTask(), 2267 sequenceWithSingleChild)) 2268 { 2269 super.visit(sequenceInstance); 2270 } 2271 } 2272 2273 }); 2274 2275 IIterationInstance iterationInstance = taskFactory.createNewTaskInstance(iteration); 2276 for (ITaskInstance singleChildInstance : singleChildInstances) { 2277 taskBuilder.addTaskInstance(iterationInstance, singleChildInstance); 2278 } 2279 2280 ITaskInstance replacement = iterationInstance; 2281 2282 if (isOptional) { 2283 IOptionalInstance optionalInstance = taskFactory.createNewTaskInstance(optional); 2284 taskBuilder.setChild(optionalInstance, replacement); 2285 replacement = optionalInstance; 2286 } 2287 2288 childInstanceReplacements.put(childInstance, replacement); 2289 } 2290 2291 if (isOptional) { 2292 return optional; 2293 } 2294 else { 2295 return iteration; 2296 } 2297 } 2298 2299 /** 2300 * 2301 */ 2302 private void mergeSubsequentIdenticalTasks(ISequence sequence) { 2303 int index = 0; 2304 TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 2305 2306 while (index < (sequence.getChildren().size() - 1)) { 2307 ITask child1 = sequence.getChildren().get(index); 2308 ITask child2 = sequence.getChildren().get(index + 1); 2309 2310 // get the actual first task 2311 ITask task1 = child1; 2312 2313 while (task1 instanceof IMarkingTemporalRelationship) { 2314 task1 = ((IMarkingTemporalRelationship) task1).getMarkedTask(); 2315 } 2316 2317 // get the actual second task 2318 ITask task2 = child2; 2319 2320 while (task2 instanceof IMarkingTemporalRelationship) { 2321 task2 = ((IMarkingTemporalRelationship) task2).getMarkedTask(); 2322 } 2323 2324 if (comparator.equals(task1, task2)) { 2325 // determine if the task is optional 2326 boolean isOptional = false; 2327 2328 if (child1 instanceof IOptional) { 2329 child1 = ((IOptional) child1).getMarkedTask(); 2330 isOptional = true; 2331 } 2332 2333 if (child2 instanceof IOptional) { 2334 child2 = ((IOptional) child2).getMarkedTask(); 2335 isOptional = true; 2336 } 2337 2338 if (child1 instanceof IIteration) { 2339 child1 = ((IIteration) child1).getMarkedTask(); 2340 } 2341 2342 if (child2 instanceof IIteration) { 2343 child2 = ((IIteration) child2).getMarkedTask(); 2344 } 2345 2346 IIteration iteration = taskFactory.createNewIteration(); 2347 taskBuilder.setMarkedTask(iteration, task1); 2348 2349 IOptional optional = null; 2350 2351 if (isOptional) { 2352 optional = taskFactory.createNewOptional(); 2353 taskBuilder.setMarkedTask(optional, iteration); 2354 taskBuilder.setChild(sequence, index, optional); 2355 } 2356 else { 2357 taskBuilder.setChild(sequence, index, iteration); 2358 } 2359 2360 taskBuilder.removeChild(sequence, index + 1); 2361 2362 for (ITaskInstance instance : sequence.getInstances()) { 2363 mergeSubsequentIdenticalInstances((ISequenceInstance) instance, index, 2364 iteration, optional); 2365 } 2366 2367 somethingChanged = true; 2368 } 2369 else { 2370 index++; 2371 } 2372 } 2373 } 2374 2375 /** 2376 * 2377 */ 2378 private void mergeSubsequentIdenticalInstances(ITaskInstanceList list) { 2379 int index = 0; 2380 TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 2381 2382 while (index < (list.size() - 1)) { 2383 boolean isOptional = false; 2384 ITaskInstance instance1 = list.get(index); 2385 ITaskInstance instance2 = list.get(index + 1); 2386 2387 // get the actual first task 2388 ITask task1 = instance1.getTask(); 2389 2390 while (task1 instanceof IMarkingTemporalRelationship) { 2391 if (task1 instanceof IOptional) { 2392 isOptional = true; 2393 } 2394 2395 task1 = ((IMarkingTemporalRelationship) task1).getMarkedTask(); 2396 } 2397 2398 // get the actual second task 2399 ITask task2 = instance2.getTask(); 2400 2401 while (task2 instanceof IMarkingTemporalRelationship) { 2402 if (task2 instanceof IOptional) { 2403 isOptional = true; 2404 } 2405 2406 task2 = ((IMarkingTemporalRelationship) task2).getMarkedTask(); 2407 } 2408 2409 if (comparator.equals(task1, task2)) { 2410 IIteration iteration = taskFactory.createNewIteration(); 2411 IOptional optional = null; 2412 2413 if (isOptional) { 2414 optional = taskFactory.createNewOptional(); 2415 taskBuilder.setMarkedTask(optional, iteration); 2416 } 2417 2418 mergeSubsequentIdenticalInstances(list, index, iteration, optional); 2419 } 2420 2421 index++; 2422 } 2423 } 2424 2425 /** 2426 * 2427 */ 2428 private void mergeSubsequentIdenticalInstances(ITaskInstanceList list, 2429 int index, 2430 IIteration iteration, 2431 IOptional optional) 2432 { 2433 ITaskInstance instance1 = list.get(index); 2434 ITaskInstance instance2 = list.get(index + 1); 2435 List<ITaskInstance> equalInstances = new LinkedList<>(); 2436 2437 if (instance1 instanceof IOptionalInstance) { 2438 taskBuilder.discardTaskInstance(instance1); 2439 instance1 = ((IOptionalInstance) instance1).getChild(); 2440 } 2441 2442 if (instance2 instanceof IOptionalInstance) { 2443 taskBuilder.discardTaskInstance(instance2); 2444 instance2 = ((IOptionalInstance) instance2).getChild(); 2445 } 2446 2447 if (instance1 instanceof IIterationInstance) { 2448 for (ITaskInstance child : (IIterationInstance) instance1) { 2449 equalInstances.add(child); 2450 } 2451 2452 taskBuilder.discardTaskInstance(instance1); 2453 } 2454 else if (instance1 != null) { 2455 equalInstances.add(instance1); 2456 } 2457 2458 if (instance2 instanceof IIterationInstance) { 2459 for (ITaskInstance child : (IIterationInstance) instance2) { 2460 equalInstances.add(child); 2461 } 2462 2463 taskBuilder.discardTaskInstance(instance2); 2464 } 2465 else if (instance2 != null) { 2466 equalInstances.add(instance2); 2467 } 2468 2469 ITaskInstance replacement = taskFactory.createNewTaskInstance(iteration); 2470 2471 for (ITaskInstance equalInstance : equalInstances) { 2472 taskBuilder.addChild((IIterationInstance) replacement, equalInstance); 2473 } 2474 2475 if (optional != null) { 2476 IOptionalInstance optionalInstance = taskFactory.createNewTaskInstance(optional); 2477 2478 taskBuilder.setChild(optionalInstance, replacement); 2479 replacement = optionalInstance; 2480 } 2481 2482 taskBuilder.setTaskInstance(list, index, replacement); 2483 taskBuilder.removeTaskInstance(list, index + 1); 2484 } 2485 } 1985 2486 }
Note: See TracChangeset
for help on using the changeset viewer.