Changeset 1733


Ignore:
Timestamp:
09/05/14 19:33:12 (10 years ago)
Author:
rkrimmel
Message:

Used Eclipse code cleanup

Location:
branches/autoquest-core-tasktrees-alignment
Files:
1 added
95 edited

Legend:

Unmodified
Added
Removed
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Alignment.java

    r1593 r1733  
    55public class Alignment { 
    66        ArrayList<NumberSequence> alingment; 
    7          
    8          
     7 
    98} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/AlignmentAlgorithm.java

    r1649 r1733  
    66 
    77public interface AlignmentAlgorithm { 
    8          
     8 
     9        void align(NumberSequence input1, NumberSequence input2, 
     10                        SubstitutionMatrix submat, float threshold); 
     11 
     12        public abstract ArrayList<NumberSequence> getAlignment(); 
     13 
    914        /** 
    1015         * Get the alignment score between the two input strings. 
     
    1217        public abstract double getAlignmentScore(); 
    1318 
    14         public abstract ArrayList<NumberSequence> getAlignment(); 
     19        public abstract ArrayList<Match> getMatches(); 
     20 
     21        public double getMaxScore(); 
     22 
     23        public abstract void printAlignment(); 
    1524 
    1625        public abstract void printDPMatrix(); 
    1726 
    18         public abstract void printAlignment(); 
    19  
    20         public abstract ArrayList<Match> getMatches(); 
    21          
    22         public double getMaxScore(); 
    23  
    24         void align(NumberSequence input1, NumberSequence input2, 
    25                         SubstitutionMatrix submat, float threshold); 
    26  
    2727} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/AlignmentAlgorithmFactory.java

    r1616 r1733  
    11package de.ugoe.cs.autoquest.tasktrees.alignment.algorithms; 
    22 
     3public class AlignmentAlgorithmFactory { 
    34 
    4 public class AlignmentAlgorithmFactory { 
    5          
    6         public static void setDefaultAlgorithm(String algorithmname) { 
    7                 //TODO: check for valid algorihm class names here 
    8                 algorithmclass = algorithmname; 
    9         } 
    10          
    11         private static String algorithmclass = "de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.SmithWatermanRepeated"; 
    12          
    13          
    14          
    155        public static AlignmentAlgorithm create() { 
    166                Class<?> newclass; 
    177                Object object = null; 
    188                try { 
    19                          newclass = Class.forName(algorithmclass); 
    20                          object = newclass.newInstance(); 
    21                          
    22                 } catch (ClassNotFoundException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException e) { 
     9                        newclass = Class.forName(algorithmclass); 
     10                        object = newclass.newInstance(); 
     11 
     12                } catch (ClassNotFoundException | SecurityException 
     13                                | InstantiationException | IllegalAccessException 
     14                                | IllegalArgumentException e) { 
    2315                        e.printStackTrace(); 
    2416                } 
    2517                return (AlignmentAlgorithm) object; 
    2618        } 
     19 
     20        public static void setDefaultAlgorithm(String algorithmname) { 
     21                // TODO: check for valid algorihm class names here 
     22                algorithmclass = algorithmname; 
     23        } 
     24 
     25        private static String algorithmclass = "de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.SmithWatermanRepeated"; 
    2726} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/AlignmentHelpers.java

    r1553 r1733  
    77import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    88 
     9public class AlignmentHelpers extends GUIModel { 
    910 
    10 public class AlignmentHelpers extends GUIModel { 
    11          
     11        public static int distanceBetween(IGUIElement first, IGUIElement second) { 
    1212 
    13          
    14         /** 
    15          *  
    16          */ 
    17         private static final long serialVersionUID = -2593092958275693133L; 
     13                int hopcount1 = 0; 
     14                int hopcount2 = 0; 
     15                final List<IGUIElement> tmp = new ArrayList<IGUIElement>(); 
     16                tmp.add(first); 
     17                tmp.add(second); 
     18                final IGUIElement commonDenominator = getCommonDenominator(tmp); 
     19 
     20                while (!(first.equals(commonDenominator))) { 
     21                        first = first.getParent(); 
     22                        hopcount1++; 
     23                } 
     24 
     25                while (!(second.equals(commonDenominator))) { 
     26                        second = second.getParent(); 
     27                        hopcount2++; 
     28                } 
     29 
     30                return hopcount1 + hopcount2; 
     31        } 
    1832 
    1933        /** 
     
    2438         * </p> 
    2539         */ 
    26         private static IGUIElement getCommonDenominator(List<IGUIElement> guiElements) { 
     40        private static IGUIElement getCommonDenominator( 
     41                        List<IGUIElement> guiElements) { 
    2742                IGUIElement commonDenominator = null; 
    2843 
    2944                if (guiElements.size() > 0) { 
    30                         List<IGUIElement> commonDenominatorPath = new ArrayList<IGUIElement>(); 
     45                        final List<IGUIElement> commonDenominatorPath = new ArrayList<IGUIElement>(); 
    3146 
    3247                        // create a reference list using the first GUI element 
     
    4964                        // well as it subsequent 
    5065                        // siblings 
    51                         List<IGUIElement> currentPath = new ArrayList<IGUIElement>(); 
     66                        final List<IGUIElement> currentPath = new ArrayList<IGUIElement>(); 
    5267                        for (int i = 1; i < guiElements.size(); i++) { 
    5368                                currentPath.clear(); 
     
    5570                                while (guiElement != null) { 
    5671                                        // if (guiElementMatchesConsideredTypes(guiElement)) { 
    57                                     currentPath.add(0, guiElement); 
     72                                        currentPath.add(0, guiElement); 
    5873                                        // } 
    5974                                        guiElement = guiElement.getParent(); 
     
    8499        } 
    85100 
    86         public static int distanceBetween(IGUIElement first, IGUIElement second) { 
    87  
    88                 int hopcount1 = 0; 
    89                 int hopcount2 = 0; 
    90                 List<IGUIElement> tmp = new ArrayList<IGUIElement>(); 
    91                 tmp.add(first); 
    92                 tmp.add(second); 
    93                 IGUIElement commonDenominator = getCommonDenominator(tmp); 
    94                  
    95                 while(!(first.equals(commonDenominator))) { 
    96                         first = first.getParent(); 
    97                         hopcount1++; 
    98                 } 
    99                  
    100                 while(!(second.equals(commonDenominator))) { 
    101                         second = second.getParent(); 
    102                         hopcount2++; 
    103                 } 
    104  
    105                 return hopcount1 + hopcount2; 
    106         } 
     101        /** 
     102         *  
     103         */ 
     104        private static final long serialVersionUID = -2593092958275693133L; 
    107105 
    108106} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Constants.java

    r1578 r1733  
    22 
    33public class Constants { 
    4          
     4 
    55        public static final int GAP_SYMBOL = -1; 
    66        public static final int UNMATCHED_SYMBOL = -2; 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Match.java

    r1717 r1733  
    55import java.util.LinkedList; 
    66 
    7  
    8  
    9 public class Match implements Serializable{ 
     7public class Match implements Serializable { 
    108        /** 
    119         *  
     
    1311        private static final long serialVersionUID = -3206992723755714741L; 
    1412 
    15         private ArrayList<NumberSequence> matchseqs; 
     13        private final ArrayList<NumberSequence> matchseqs; 
    1614 
    1715        private LinkedList<MatchOccurence> occurences; 
     
    2422        } 
    2523 
    26         public NumberSequence getFirstSequence() { 
    27                 return matchseqs.get(0); 
    28         } 
    29  
    30         public NumberSequence getSecondSequence() { 
    31                 return matchseqs.get(1); 
    32         } 
    33  
    34         public void setFirstSequence(NumberSequence seq) { 
    35                 matchseqs.set(0, seq); 
    36         } 
    37  
    38         public void setSecondSequence(NumberSequence seq) { 
    39                 matchseqs.set(1, seq); 
    40         } 
    41  
    4224        public void addOccurence(MatchOccurence occurence) { 
    4325                occurences.add(occurence); 
    4426        } 
    4527 
    46         public int occurenceCount() { 
    47                 return occurences.size(); 
    48         } 
    49          
    50         public int size() { 
    51                 //Both sequences should be equally long 
    52                 return matchseqs.get(0).size(); 
     28        public void addOccurencesOf(Match m) { 
     29                occurences.addAll(m.getOccurences()); 
    5330        } 
    5431 
     
    6340        } 
    6441 
     42        public NumberSequence getFirstSequence() { 
     43                return matchseqs.get(0); 
     44        } 
     45 
    6546        public LinkedList<MatchOccurence> getOccurences() { 
    6647                return occurences; 
     48        } 
     49 
     50        public NumberSequence getSecondSequence() { 
     51                return matchseqs.get(1); 
     52        } 
     53 
     54        public int occurenceCount() { 
     55                return occurences.size(); 
     56        } 
     57 
     58        public void setFirstSequence(NumberSequence seq) { 
     59                matchseqs.set(0, seq); 
    6760        } 
    6861 
     
    7164        } 
    7265 
    73          
    74         public void addOccurencesOf(Match m) { 
    75                 occurences.addAll(m.getOccurences()); 
     66        public void setSecondSequence(NumberSequence seq) { 
     67                matchseqs.set(1, seq); 
    7668        } 
    77          
    78          
    79     
     69 
     70        public int size() { 
     71                // Both sequences should be equally long 
     72                return matchseqs.get(0).size(); 
     73        } 
    8074 
    8175} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurence.java

    r1717 r1733  
    33import java.io.Serializable; 
    44 
    5 public class MatchOccurence implements Serializable{ 
     5public class MatchOccurence implements Serializable { 
    66        /** 
    77         *  
     
    1111        private int endindex; 
    1212        private int sequenceId; 
    13          
     13 
    1414        public MatchOccurence(int startindex, int endindex, int sequenceId) { 
    1515                this.startindex = startindex; 
     
    1717                this.sequenceId = sequenceId; 
    1818        } 
    19          
     19 
    2020        public int getEndindex() { 
    2121                return endindex; 
     22        } 
     23 
     24        public int getSequenceId() { 
     25                return sequenceId; 
     26        } 
     27 
     28        public int getStartindex() { 
     29                return startindex; 
    2230        } 
    2331 
     
    2634        } 
    2735 
    28         public int getStartindex() { 
    29                 return startindex; 
     36        public void setSequenceId(int sequenceId) { 
     37                this.sequenceId = sequenceId; 
    3038        } 
     39 
    3140        public void setStartindex(int startindex) { 
    3241                this.startindex = startindex; 
    3342        } 
    34         public int getSequenceId() { 
    35                 return sequenceId; 
    36         } 
    37  
    38         public void setSequenceId(int sequenceId) { 
    39                 this.sequenceId = sequenceId; 
    40         } 
    4143} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatrixEntry.java

    r1568 r1733  
    66        private int xvalue; 
    77        private int yvalue; 
    8          
    9         public MatrixEntry(float score, MatrixEntry previous)   { 
     8 
     9        public MatrixEntry() { 
     10        } 
     11 
     12        public MatrixEntry(float score, MatrixEntry previous) { 
    1013                this.score = score; 
    1114                this.previous = previous; 
    1215        } 
    13          
    14         public MatrixEntry() { 
     16 
     17        public MatrixEntry getPrevious() { 
     18                return previous; 
    1519        } 
    1620 
    1721        public double getScore() { 
    1822                return score; 
    19         } 
    20         public void setScore(double score) { 
    21                 this.score = score; 
    22         } 
    23         public MatrixEntry getPrevious() { 
    24                 return previous; 
    25         } 
    26         public void setPrevious(MatrixEntry previous) { 
    27                 this.previous = previous; 
    2823        } 
    2924 
     
    3227        } 
    3328 
     29        public int getYvalue() { 
     30                return yvalue; 
     31        } 
     32 
     33        public void setPrevious(MatrixEntry previous) { 
     34                this.previous = previous; 
     35        } 
     36 
     37        public void setScore(double score) { 
     38                this.score = score; 
     39        } 
     40 
    3441        public void setXvalue(int xvalue) { 
    3542                this.xvalue = xvalue; 
    36         } 
    37  
    38         public int getYvalue() { 
    39                 return yvalue; 
    4043        } 
    4144 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/NeedlemanWunsch.java

    r1620 r1733  
    88import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Constants; 
    99 
    10  
    1110public class NeedlemanWunsch implements AlignmentAlgorithm { 
    1211 
     
    3938        private SubstitutionMatrix submat; 
    4039 
     40        @Override 
     41        public void align(NumberSequence input1, NumberSequence input2, 
     42                        SubstitutionMatrix submat, float threshold) { 
     43                this.input1 = input1.getSequence(); 
     44                this.input2 = input2.getSequence(); 
     45                length1 = input1.size(); 
     46                length2 = input2.size(); 
     47                this.submat = submat; 
     48 
     49                // System.out.println("Starting SmithWaterman algorithm with a " 
     50                // + submat.getClass() + " Substitution Matrix: " + 
     51                // submat.getClass().getCanonicalName()); 
     52 
     53                matrix = new MatrixEntry[length1 + 1][length2 + 1]; 
     54                alignment = new ArrayList<NumberSequence>(); 
     55 
     56                for (int i = 0; i < (length1 + 1); i++) { 
     57                        for (int j = 0; j < (length2 + 1); j++) { 
     58                                matrix[i][j] = new MatrixEntry(); 
     59                        } 
     60                } 
     61 
     62                buildMatrix(); 
     63                traceback(); 
     64 
     65        } 
     66 
     67        /** 
     68         * Build the score matrix using dynamic programming. 
     69         */ 
     70        private void buildMatrix() { 
     71                if (submat.getGapPenalty() >= 0) { 
     72                        throw new Error("Indel score must be negative"); 
     73                } 
     74 
     75                // it's a gap 
     76                matrix[0][0].setScore(0); 
     77                matrix[0][0].setPrevious(null); // starting point 
     78 
     79                // the first column 
     80                for (int j = 1; j <= length2; j++) { 
     81                        matrix[0][j].setScore(j * submat.getGapPenalty()); 
     82                        matrix[0][j].setPrevious(matrix[0][j - 1]); 
     83                        matrix[0][j].setYvalue(input2[j - 1]); 
     84                        matrix[0][j].setXvalue(Constants.GAP_SYMBOL); 
     85                } 
     86                // the first row 
     87 
     88                for (int j = 1; j <= length1; j++) { 
     89                        matrix[j][0].setScore(j * submat.getGapPenalty()); 
     90                        matrix[j][0].setPrevious(matrix[j - 1][0]); 
     91                        matrix[j][0].setXvalue(input1[j - 1]); 
     92                        matrix[j][0].setYvalue(Constants.GAP_SYMBOL); 
     93                } 
     94 
     95                for (int i = 1; i <= length1; i++) { 
     96 
     97                        for (int j = 1; j <= length2; j++) { 
     98                                final double diagScore = matrix[i - 1][j - 1].getScore() 
     99                                                + similarity(i, j); 
     100                                final double upScore = matrix[i][j - 1].getScore() 
     101                                                + submat.getGapPenalty(); 
     102                                final double leftScore = matrix[i - 1][j].getScore() 
     103                                                + submat.getGapPenalty(); 
     104 
     105                                matrix[i][j].setScore(Math.max(diagScore, 
     106                                                Math.max(upScore, leftScore))); 
     107 
     108                                // find the directions that give the maximum scores. 
     109                                // TODO: Multiple directions are ignored, we choose the first 
     110                                // maximum score 
     111                                // True if we had a match 
     112                                if (diagScore == matrix[i][j].getScore()) { 
     113                                        matrix[i][j].setPrevious(matrix[i - 1][j - 1]); 
     114                                        matrix[i][j].setXvalue(input1[i - 1]); 
     115                                        matrix[i][j].setYvalue(input2[j - 1]); 
     116                                } 
     117                                // true if we took an event from sequence x and not from y 
     118                                if (leftScore == matrix[i][j].getScore()) { 
     119                                        matrix[i][j].setXvalue(input1[i - 1]); 
     120                                        matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
     121                                        matrix[i][j].setPrevious(matrix[i - 1][j]); 
     122                                } 
     123                                // true if we took an event from sequence y and not from x 
     124                                if (upScore == matrix[i][j].getScore()) { 
     125                                        matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
     126                                        matrix[i][j].setYvalue(input2[j - 1]); 
     127                                        matrix[i][j].setPrevious(matrix[i][j - 1]); 
     128                                } 
     129                        } 
     130                } 
     131        } 
     132 
     133        /* 
     134         * (non-Javadoc) 
     135         *  
     136         * @see 
     137         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     138         * #getAlignment() 
     139         */ 
     140        @Override 
     141        public ArrayList<NumberSequence> getAlignment() { 
     142                return alignment; 
     143        } 
     144 
     145        /* 
     146         * (non-Javadoc) 
     147         *  
     148         * @see 
     149         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     150         * #getAlignmentScore() 
     151         */ 
     152        @Override 
     153        public double getAlignmentScore() { 
     154                return getMaxScore(); 
     155        } 
     156 
     157        @Override 
     158        public ArrayList<Match> getMatches() { 
     159                // TODO Auto-generated method stub 
     160                return null; 
     161        } 
     162 
     163        /** 
     164         * Get the maximum value in the score matrix. 
     165         */ 
     166        @Override 
     167        public double getMaxScore() { 
     168                double maxScore = 0; 
     169 
     170                // skip the first row and column 
     171                for (int i = 1; i <= length1; i++) { 
     172                        for (int j = 1; j <= length2; j++) { 
     173                                if (matrix[i][j].getScore() > maxScore) { 
     174                                        maxScore = matrix[i][j].getScore(); 
     175                                } 
     176                        } 
     177                } 
     178 
     179                return maxScore; 
     180        } 
     181 
     182        @Override 
     183        public void printAlignment() { 
     184                final int[] tmp1 = alignment.get(0).getSequence(); 
     185                final int[] tmp2 = alignment.get(1).getSequence(); 
     186                for (int i = 0; i < tmp1.length; i++) { 
     187                        if (tmp1[i] == Constants.GAP_SYMBOL) { 
     188                                System.out.print("  ___"); 
     189                        } else if (tmp1[i] == Constants.UNMATCHED_SYMBOL) { 
     190                                System.out.print("  ..."); 
     191                        } else { 
     192                                System.out.format("%5d", tmp1[i]); 
     193                        } 
     194 
     195                } 
     196                System.out.println(); 
     197                for (int i = 0; i < tmp2.length; i++) { 
     198                        if (tmp2[i] == Constants.GAP_SYMBOL) { 
     199                                System.out.print("  ___"); 
     200                        } else if (tmp2[i] == Constants.UNMATCHED_SYMBOL) { 
     201                                System.out.print("  ..."); 
     202                        } else { 
     203                                System.out.format("%5d", tmp2[i]); 
     204                        } 
     205 
     206                } 
     207                System.out.println(); 
     208 
     209        } 
     210 
     211        /** 
     212         * print the dynmaic programming matrix 
     213         */ 
     214        @Override 
     215        public void printDPMatrix() { 
     216                System.out.print("          "); 
     217                for (int i = 1; i <= length1; i++) { 
     218                        System.out.format("%5d", input1[i - 1]); 
     219                } 
     220                System.out.println(); 
     221                for (int j = 0; j <= length2; j++) { 
     222                        if (j > 0) { 
     223                                System.out.format("%5d ", input2[j - 1]); 
     224                        } else { 
     225                                System.out.print("      "); 
     226                        } 
     227                        for (int i = 0; i <= length1; i++) { 
     228                                System.out.format("%4.1f ", matrix[i][j].getScore()); 
     229                        } 
     230                        System.out.println(); 
     231                } 
     232        } 
     233 
     234        public void setAlignment(ArrayList<NumberSequence> alignment) { 
     235                this.alignment = alignment; 
     236        } 
    41237 
    42238        /** 
     
    54250        } 
    55251 
    56         /** 
    57          * Build the score matrix using dynamic programming. 
    58          */ 
    59         private void buildMatrix() { 
    60                 if (submat.getGapPenalty() >= 0) { 
    61                         throw new Error("Indel score must be negative"); 
    62                 } 
    63  
    64                 // it's a gap 
    65                 matrix[0][0].setScore(0); 
    66                 matrix[0][0].setPrevious(null); // starting point 
    67  
    68                 // the first column 
    69                 for (int j = 1; j <= length2; j++) { 
    70                         matrix[0][j].setScore(j*submat.getGapPenalty()); 
    71                         matrix[0][j].setPrevious(matrix[0][j - 1]); 
    72                         matrix[0][j].setYvalue(input2[j-1]); 
    73                         matrix[0][j].setXvalue(Constants.GAP_SYMBOL); 
    74                 } 
    75                 // the first row 
    76  
    77                 for (int j = 1; j <= length1; j++) { 
    78                         matrix[j][0].setScore(j*submat.getGapPenalty()); 
    79                         matrix[j][0].setPrevious(matrix[j - 1][0]); 
    80                         matrix[j][0].setXvalue(input1[j-1]); 
    81                         matrix[j][0].setYvalue(Constants.GAP_SYMBOL); 
    82                 } 
    83  
    84                 for (int i = 1; i <= length1; i++) { 
    85  
    86                         for (int j = 1; j <= length2; j++) { 
    87                                 double diagScore = matrix[i - 1][j - 1].getScore() 
    88                                                 + similarity(i, j); 
    89                                 double upScore = matrix[i][j - 1].getScore() 
    90                                                 + submat.getGapPenalty(); 
    91                                 double leftScore = matrix[i - 1][j].getScore() 
    92                                                 + submat.getGapPenalty(); 
    93  
    94                                 matrix[i][j].setScore(Math.max(diagScore, 
    95                                                 Math.max(upScore, leftScore))); 
    96  
    97                                 // find the directions that give the maximum scores. 
    98                                 // TODO: Multiple directions are ignored, we choose the first 
    99                                 // maximum score 
    100                                 // True if we had a match 
    101                                 if (diagScore == matrix[i][j].getScore()) { 
    102                                         matrix[i][j].setPrevious(matrix[i - 1][j - 1]); 
    103                                         matrix[i][j].setXvalue(input1[i - 1]); 
    104                                         matrix[i][j].setYvalue(input2[j - 1]); 
    105                                 } 
    106                                 // true if we took an event from sequence x and not from y 
    107                                 if (leftScore == matrix[i][j].getScore()) { 
    108                                         matrix[i][j].setXvalue(input1[i - 1]); 
    109                                         matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
    110                                         matrix[i][j].setPrevious(matrix[i - 1][j]); 
    111                                 } 
    112                                 // true if we took an event from sequence y and not from x 
    113                                 if (upScore == matrix[i][j].getScore()) { 
    114                                         matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
    115                                         matrix[i][j].setYvalue(input2[j - 1]); 
    116                                         matrix[i][j].setPrevious(matrix[i][j - 1]); 
    117                                 } 
    118                         } 
    119                 } 
    120         } 
    121  
    122         /** 
    123          * Get the maximum value in the score matrix. 
    124          */ 
    125         public double getMaxScore() { 
    126                 double maxScore = 0; 
    127  
    128                 // skip the first row and column 
    129                 for (int i = 1; i <= length1; i++) { 
    130                         for (int j = 1; j <= length2; j++) { 
    131                                 if (matrix[i][j].getScore() > maxScore) { 
    132                                         maxScore = matrix[i][j].getScore(); 
    133                                 } 
    134                         } 
    135                 } 
    136  
    137                 return maxScore; 
    138         } 
    139  
    140         /* 
    141          * (non-Javadoc) 
    142          *  
    143          * @see 
    144          * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
    145          * #getAlignmentScore() 
    146          */ 
    147         @Override 
    148         public double getAlignmentScore() { 
    149                 return getMaxScore(); 
    150         } 
    151  
    152252        public void traceback() { 
    153253                MatrixEntry tmp = matrix[length1][length2]; 
    154                 LinkedList<Integer> aligned1 = new LinkedList<Integer>(); 
    155                 LinkedList<Integer> aligned2 = new LinkedList<Integer>(); 
     254                final LinkedList<Integer> aligned1 = new LinkedList<Integer>(); 
     255                final LinkedList<Integer> aligned2 = new LinkedList<Integer>(); 
    156256                while (tmp.getPrevious() != null) { 
    157                          
     257 
    158258                        aligned1.add(new Integer(tmp.getXvalue())); 
    159259                        aligned2.add(new Integer(tmp.getYvalue())); 
    160260 
    161261                        tmp = tmp.getPrevious(); 
    162                 }  
    163                  
     262                } 
     263 
    164264                // reverse order of the alignment 
    165                 int reversed1[] = new int[aligned1.size()]; 
    166                 int reversed2[] = new int[aligned2.size()]; 
     265                final int reversed1[] = new int[aligned1.size()]; 
     266                final int reversed2[] = new int[aligned2.size()]; 
    167267 
    168268                int count = 0; 
    169                 for (Iterator<Integer> it = aligned1.iterator(); it.hasNext();) { 
     269                for (final Iterator<Integer> it = aligned1.iterator(); it.hasNext();) { 
    170270                        count++; 
    171271                        reversed1[reversed1.length - count] = it.next(); 
    172                          
     272 
    173273                } 
    174274                count = 0; 
    175                 for (Iterator<Integer> it = aligned2.iterator(); it.hasNext();) { 
     275                for (final Iterator<Integer> it = aligned2.iterator(); it.hasNext();) { 
    176276                        count++; 
    177277                        reversed2[reversed2.length - count] = it.next(); 
    178278                } 
    179279 
    180                 NumberSequence ns1 = new NumberSequence(reversed1.length); 
    181                 NumberSequence ns2 = new NumberSequence(reversed2.length); 
     280                final NumberSequence ns1 = new NumberSequence(reversed1.length); 
     281                final NumberSequence ns2 = new NumberSequence(reversed2.length); 
    182282                ns1.setSequence(reversed1); 
    183283                ns2.setSequence(reversed2); 
     
    187287        } 
    188288 
    189          
    190         /** 
    191          * print the dynmaic programming matrix 
    192          */ 
    193         public void printDPMatrix() { 
    194                 System.out.print("          "); 
    195                 for (int i = 1; i <= length1; i++) 
    196                         System.out.format("%5d", input1[i - 1]); 
    197                 System.out.println(); 
    198                 for (int j = 0; j <= length2; j++) { 
    199                         if (j > 0) 
    200                                 System.out.format("%5d ", input2[j - 1]); 
    201                         else { 
    202                                 System.out.print("      "); 
    203                         } 
    204                         for (int i = 0; i <= length1; i++) { 
    205                                         System.out.format("%4.1f ", matrix[i][j].getScore()); 
    206                         } 
    207                         System.out.println(); 
    208                 } 
    209         } 
    210          
    211         public void printAlignment() { 
    212                 int[] tmp1 = alignment.get(0).getSequence(); 
    213                 int[] tmp2 = alignment.get(1).getSequence(); 
    214                 for (int i=0; i< tmp1.length;i++) { 
    215                         if(tmp1[i] == Constants.GAP_SYMBOL) { 
    216                                 System.out.print("  ___"); 
    217                         } 
    218                         else if(tmp1[i] == Constants.UNMATCHED_SYMBOL) { 
    219                                 System.out.print("  ..."); 
    220                         } 
    221                         else { 
    222                                 System.out.format("%5d", tmp1[i]); 
    223                         } 
    224                          
    225                 } 
    226                 System.out.println(); 
    227                 for (int i=0; i< tmp2.length;i++) { 
    228                         if(tmp2[i] == Constants.GAP_SYMBOL) { 
    229                                 System.out.print("  ___"); 
    230                         } 
    231                         else if(tmp2[i] == Constants.UNMATCHED_SYMBOL) { 
    232                                 System.out.print("  ..."); 
    233                         } 
    234                         else { 
    235                                 System.out.format("%5d", tmp2[i]); 
    236                         } 
    237                          
    238                 } 
    239                 System.out.println(); 
    240                  
    241                  
    242          
    243         } 
    244  
    245         /* 
    246          * (non-Javadoc) 
    247          *  
    248          * @see 
    249          * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
    250          * #getAlignment() 
    251          */ 
    252         @Override 
    253         public ArrayList<NumberSequence> getAlignment() { 
    254                 return alignment; 
    255         } 
    256  
    257         public void setAlignment(ArrayList<NumberSequence> alignment) { 
    258                 this.alignment = alignment; 
    259         } 
    260  
    261         @Override 
    262         public ArrayList<Match> getMatches() { 
    263                 // TODO Auto-generated method stub 
    264                 return null; 
    265         } 
    266  
    267         @Override 
    268         public void align(NumberSequence input1, NumberSequence input2, SubstitutionMatrix submat, 
    269                         float threshold) { 
    270                 this.input1 = input1.getSequence(); 
    271                 this.input2 = input2.getSequence(); 
    272                 length1 = input1.size(); 
    273                 length2 = input2.size(); 
    274                 this.submat = submat; 
    275  
    276                 // System.out.println("Starting SmithWaterman algorithm with a " 
    277                 // + submat.getClass() + " Substitution Matrix: " + 
    278                 // submat.getClass().getCanonicalName()); 
    279  
    280                 matrix = new MatrixEntry[length1 + 1][length2 + 1]; 
    281                 alignment = new ArrayList<NumberSequence>(); 
    282  
    283                 for (int i = 0; i < length1+1; i++) { 
    284                         for (int j = 0; j < length2+1; j++) { 
    285                                 matrix[i][j] = new MatrixEntry(); 
    286                         } 
    287                 } 
    288  
    289                 buildMatrix(); 
    290                 traceback(); 
    291                  
    292         } 
    293  
    294  
    295  
    296289} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/NumberSequence.java

    r1717 r1733  
    55import java.util.Random; 
    66 
    7 public class NumberSequence implements Serializable{ 
     7public class NumberSequence implements Serializable { 
    88        /** 
    99         *  
     
    1818        } 
    1919 
    20         public int[] getSequence() { 
    21                 return sequence; 
    22         } 
     20        // Searching occurrences of pattern 
     21        public LinkedList<Integer> containsPattern(Match pattern) { 
     22                final LinkedList<Integer> result = new LinkedList<Integer>(); 
     23                int i = 0; 
     24                final int[] pat1 = pattern.getFirstSequence().getSequence(); 
     25                final int[] pat2 = pattern.getSecondSequence().getSequence(); 
    2326 
    24         public void setSequence(int[] sequence) { 
    25                 this.sequence = sequence; 
    26         } 
    27  
    28         public void printSequence() { 
    29                 for (int i = 0; i < sequence.length; i++) { 
    30                         System.out.format("%5d", sequence[i]); 
    31                 } 
    32                 System.out.println(); 
    33         } 
    34  
    35         public NumberSequence shuffle() { 
    36                 NumberSequence result = new NumberSequence(sequence.length); 
    37                 result.setId(getId()); 
    38                 result.setSequence(this.sequence); 
    39                 Random rgen = new Random(); 
    40  
    41                 for (int i = 0; i < result.sequence.length; i++) { 
    42                         int randomPosition = rgen.nextInt(result.sequence.length); 
    43                         int temp = result.sequence[i]; 
    44                         result.sequence[i] = result.sequence[randomPosition]; 
    45                         result.sequence[randomPosition] = temp; 
    46                 } 
    47                 return result; 
    48  
    49         } 
    50  
    51         //Recursive check if sequence contains pattern at position i 
    52         private boolean matches(int i,  
    53                                 int[] p1,  
    54                                 int[] p2 , 
    55                                 int ip1, 
    56                                 int ip2, 
    57                                 boolean jumped1, //True if there was a gap in Sequence 1 of the pattern 
    58                                 boolean jumped2, //True if there was a gap in Sequence 2 of the pattern 
    59                                 boolean hadSelection, //True if the last match was a selection  
    60                                 boolean matchseq1, 
    61                                 boolean matchseq2) { 
    62                  
    63                 if(p1.length==ip1) { 
    64                         return true; 
    65                 } 
    66                 if(p2.length==ip2) { 
    67                         return true; 
    68                 } 
    69                 if(i==sequence.length) { 
    70                         return false; 
    71                 } 
    72  
    73                 boolean foundselection=(!(p1[ip1] == p2[ip2])&&!(p1[ip1]==-1||p2[ip2]==-1)); 
    74                 boolean matchInFirstPattern = (p1[ip1]==sequence[i]); 
    75                 boolean matchInSecondPattern = (p2[ip2]==sequence[i]); 
    76                  
    77                 if(foundselection && hadSelection) { 
    78                         if((matchInFirstPattern && matchseq1) || (matchInSecondPattern && matchseq2)){ 
    79                                 if(jumped1) { 
    80                                         return matches(i+1,p1,p2,ip1+1,ip2+2,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    81                                 } 
    82                                 if(jumped2) { 
    83                                         return matches(i+1,p1,p2,ip1+2,ip2+1,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    84                                 } 
    85                                 return matches(i+1,p1,p2,ip1+1,ip2+1,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    86                         }        
    87                         else { 
    88                                 return false; 
    89                         } 
    90                 } 
    91  
    92                 if((matchInFirstPattern||matchInSecondPattern) && jumped1) { 
    93                         return matches(i+1,p1,p2,ip1+1,ip2+2,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    94                 } 
    95                 if((matchInFirstPattern||matchInSecondPattern) && jumped2) { 
    96                         return matches(i+1,p1,p2,ip1+2,ip2+1,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    97                 } 
    98                 if(matchInFirstPattern||matchInSecondPattern) { 
    99                         return matches(i+1,p1,p2,ip1+1,ip2+1,false,false,foundselection,matchInFirstPattern,matchInSecondPattern); 
    100                 } 
    101                 if(p1[ip1]==-1) { 
    102                         return matches(i,p1,p2,ip1+1,ip2,true,false,false,false,false); 
    103                 } 
    104                 if(p2[ip2]==-1) { 
    105                         return matches(i,p1,p2,ip1,ip2+1,false,true,false,false,false); 
    106                 } 
    107          
    108                 return false; 
    109         } 
    110          
    111         //Searching occurrences of pattern 
    112         public LinkedList<Integer> containsPattern(Match pattern) { 
    113                 LinkedList<Integer> result = new LinkedList<Integer>(); 
    114                 int i = 0; 
    115                 int[] pat1 = pattern.getFirstSequence().getSequence(); 
    116                 int[] pat2 = pattern.getSecondSequence().getSequence(); 
    117  
    118                 while (i < sequence.length ) { 
    119                         if(matches(i,pat1,pat2,0,0,false,false,false,false,false)) { 
     27                while (i < sequence.length) { 
     28                        if (matches(i, pat1, pat2, 0, 0, false, false, false, false, false)) { 
    12029                                result.add(i); 
    12130                        } 
     
    12332                } 
    12433                return result; 
     34        } 
     35 
     36        public boolean equals(NumberSequence n) { 
     37                final int[] seq = n.getSequence(); 
     38                if (n.size() != this.size()) { 
     39                        return false; 
     40                } 
     41                for (int i = 0; i < n.size(); i++) { 
     42                        if (seq[i] != this.sequence[i]) { 
     43                                return false; 
     44                        } 
     45                } 
     46                return true; 
    12547        } 
    12648 
     
    13658        } 
    13759 
    138         public int size() { 
    139                 return sequence.length; 
     60        public int getId() { 
     61                return id; 
    14062        } 
    14163 
    142         public int getId() { 
    143                 return id; 
     64        public int[] getSequence() { 
     65                return sequence; 
     66        } 
     67 
     68        // Recursive check if sequence contains pattern at position i 
     69        private boolean matches(int i, int[] p1, int[] p2, int ip1, int ip2, 
     70                        boolean jumped1, // True if there was a gap in Sequence 1 of the 
     71                                                                // pattern 
     72                        boolean jumped2, // True if there was a gap in Sequence 2 of the 
     73                                                                // pattern 
     74                        boolean hadSelection, // True if the last match was a selection 
     75                        boolean matchseq1, boolean matchseq2) { 
     76 
     77                if (p1.length == ip1) { 
     78                        return true; 
     79                } 
     80                if (p2.length == ip2) { 
     81                        return true; 
     82                } 
     83                if (i == sequence.length) { 
     84                        return false; 
     85                } 
     86 
     87                final boolean foundselection = (!(p1[ip1] == p2[ip2]) && !((p1[ip1] == -1) || (p2[ip2] == -1))); 
     88                final boolean matchInFirstPattern = (p1[ip1] == sequence[i]); 
     89                final boolean matchInSecondPattern = (p2[ip2] == sequence[i]); 
     90 
     91                if (foundselection && hadSelection) { 
     92                        if ((matchInFirstPattern && matchseq1) 
     93                                        || (matchInSecondPattern && matchseq2)) { 
     94                                if (jumped1) { 
     95                                        return matches(i + 1, p1, p2, ip1 + 1, ip2 + 2, false, 
     96                                                        false, foundselection, matchInFirstPattern, 
     97                                                        matchInSecondPattern); 
     98                                } 
     99                                if (jumped2) { 
     100                                        return matches(i + 1, p1, p2, ip1 + 2, ip2 + 1, false, 
     101                                                        false, foundselection, matchInFirstPattern, 
     102                                                        matchInSecondPattern); 
     103                                } 
     104                                return matches(i + 1, p1, p2, ip1 + 1, ip2 + 1, false, false, 
     105                                                foundselection, matchInFirstPattern, 
     106                                                matchInSecondPattern); 
     107                        } else { 
     108                                return false; 
     109                        } 
     110                } 
     111 
     112                if ((matchInFirstPattern || matchInSecondPattern) && jumped1) { 
     113                        return matches(i + 1, p1, p2, ip1 + 1, ip2 + 2, false, false, 
     114                                        foundselection, matchInFirstPattern, matchInSecondPattern); 
     115                } 
     116                if ((matchInFirstPattern || matchInSecondPattern) && jumped2) { 
     117                        return matches(i + 1, p1, p2, ip1 + 2, ip2 + 1, false, false, 
     118                                        foundselection, matchInFirstPattern, matchInSecondPattern); 
     119                } 
     120                if (matchInFirstPattern || matchInSecondPattern) { 
     121                        return matches(i + 1, p1, p2, ip1 + 1, ip2 + 1, false, false, 
     122                                        foundselection, matchInFirstPattern, matchInSecondPattern); 
     123                } 
     124                if (p1[ip1] == -1) { 
     125                        return matches(i, p1, p2, ip1 + 1, ip2, true, false, false, false, 
     126                                        false); 
     127                } 
     128                if (p2[ip2] == -1) { 
     129                        return matches(i, p1, p2, ip1, ip2 + 1, false, true, false, false, 
     130                                        false); 
     131                } 
     132 
     133                return false; 
     134        } 
     135 
     136        public void printSequence() { 
     137                for (int i = 0; i < sequence.length; i++) { 
     138                        System.out.format("%5d", sequence[i]); 
     139                } 
     140                System.out.println(); 
    144141        } 
    145142 
     
    148145        } 
    149146 
    150         public boolean equals(NumberSequence n) { 
    151                 int[] seq = n.getSequence(); 
    152                 if (n.size() != this.size()) { 
    153                         return false; 
     147        public void setSequence(int[] sequence) { 
     148                this.sequence = sequence; 
     149        } 
     150 
     151        public NumberSequence shuffle() { 
     152                final NumberSequence result = new NumberSequence(sequence.length); 
     153                result.setId(getId()); 
     154                result.setSequence(this.sequence); 
     155                final Random rgen = new Random(); 
     156 
     157                for (int i = 0; i < result.sequence.length; i++) { 
     158                        final int randomPosition = rgen.nextInt(result.sequence.length); 
     159                        final int temp = result.sequence[i]; 
     160                        result.sequence[i] = result.sequence[randomPosition]; 
     161                        result.sequence[randomPosition] = temp; 
    154162                } 
    155                 for (int i = 0; i < n.size(); i++) { 
    156                         if (seq[i] != this.sequence[i]) { 
    157                                 return false; 
    158                         } 
    159                 } 
    160                 return true; 
     163                return result; 
     164 
     165        } 
     166 
     167        public int size() { 
     168                return sequence.length; 
    161169        } 
    162170 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWaterman.java

    r1620 r1733  
    3838        private SubstitutionMatrix submat; 
    3939 
     40        @Override 
     41        public void align(NumberSequence input1, NumberSequence input2, 
     42                        SubstitutionMatrix submat, float threshold) { 
     43                this.input1 = input1.getSequence(); 
     44                this.input2 = input2.getSequence(); 
     45                length1 = input1.size(); 
     46                length2 = input2.size(); 
     47                this.submat = submat; 
     48 
     49                // System.out.println("Starting SmithWaterman algorithm with a " 
     50                // + submat.getClass() + " Substitution Matrix: " + 
     51                // submat.getClass().getCanonicalName()); 
     52 
     53                matrix = new MatrixEntry[length1 + 1][length2 + 1]; 
     54                alignment = new ArrayList<NumberSequence>(); 
     55 
     56                for (int i = 0; i < (length1 + 1); i++) { 
     57                        for (int j = 0; j < (length2 + 1); j++) { 
     58                                matrix[i][j] = new MatrixEntry(); 
     59                        } 
     60                } 
     61 
     62                buildMatrix(); 
     63                traceback(); 
     64 
     65        } 
     66 
     67        /** 
     68         * Build the score matrix using dynamic programming. 
     69         */ 
     70        private void buildMatrix() { 
     71                if (submat.getGapPenalty() >= 0) { 
     72                        throw new Error("Indel score must be negative"); 
     73                } 
     74 
     75                // it's a gap 
     76                matrix[0][0].setScore(0); 
     77                matrix[0][0].setPrevious(null); // starting point 
     78 
     79                // the first column 
     80                for (int j = 1; j < length2; j++) { 
     81                        matrix[0][j].setScore(0); 
     82                        matrix[0][j].setPrevious(matrix[0][j - 1]); 
     83                        matrix[0][j].setYvalue(input2[j]); 
     84                        matrix[0][j].setXvalue(Constants.GAP_SYMBOL); 
     85                } 
     86                // the first row 
     87 
     88                for (int j = 1; j < length1; j++) { 
     89                        matrix[j][0].setScore(0); 
     90                        matrix[j][0].setPrevious(matrix[j - 1][0]); 
     91                        matrix[j][0].setXvalue(input1[j]); 
     92                        matrix[j][0].setYvalue(Constants.GAP_SYMBOL); 
     93                } 
     94 
     95                for (int i = 1; i < length1; i++) { 
     96 
     97                        for (int j = 1; j < length2; j++) { 
     98                                final double diagScore = matrix[i - 1][j - 1].getScore() 
     99                                                + similarity(i, j); 
     100                                final double upScore = matrix[i][j - 1].getScore() 
     101                                                + submat.getGapPenalty(); 
     102                                final double leftScore = matrix[i - 1][j].getScore() 
     103                                                + submat.getGapPenalty(); 
     104 
     105                                matrix[i][j].setScore(Math.max(diagScore, 
     106                                                Math.max(upScore, Math.max(leftScore, 0)))); 
     107 
     108                                // find the directions that give the maximum scores. 
     109                                // TODO: Multiple directions are ignored, we choose the first 
     110                                // maximum score 
     111                                // True if we had a match 
     112                                if (diagScore == matrix[i][j].getScore()) { 
     113                                        matrix[i][j].setPrevious(matrix[i - 1][j - 1]); 
     114                                        matrix[i][j].setXvalue(input1[i - 1]); 
     115                                        matrix[i][j].setYvalue(input2[j - 1]); 
     116                                } 
     117                                // true if we took an event from sequence x and not from y 
     118                                if (leftScore == matrix[i][j].getScore()) { 
     119                                        matrix[i][j].setXvalue(input1[i - 1]); 
     120                                        matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
     121                                        matrix[i][j].setPrevious(matrix[i - 1][j]); 
     122                                } 
     123                                // true if we took an event from sequence y and not from x 
     124                                if (upScore == matrix[i][j].getScore()) { 
     125                                        matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
     126                                        matrix[i][j].setYvalue(input2[j - 1]); 
     127                                        matrix[i][j].setPrevious(matrix[i][j - 1]); 
     128                                } 
     129                                if (0 == matrix[i][j].getScore()) { 
     130                                        matrix[i][j].setPrevious(matrix[0][0]); 
     131                                        matrix[i][j].setXvalue(-2); 
     132                                        matrix[i][j].setYvalue(-2); 
     133                                } 
     134                        } 
     135 
     136                        // Set the complete score cell 
     137 
     138                } 
     139        } 
     140 
     141        /* 
     142         * (non-Javadoc) 
     143         *  
     144         * @see 
     145         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     146         * #getAlignment() 
     147         */ 
     148        @Override 
     149        public ArrayList<NumberSequence> getAlignment() { 
     150                return alignment; 
     151        } 
     152 
     153        /* 
     154         * (non-Javadoc) 
     155         *  
     156         * @see 
     157         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     158         * #getAlignmentScore() 
     159         */ 
     160        @Override 
     161        public double getAlignmentScore() { 
     162                return getMaxScore(); 
     163        } 
     164 
     165        @Override 
     166        public ArrayList<Match> getMatches() { 
     167                // TODO Auto-generated method stub 
     168                return null; 
     169        } 
     170 
     171        /** 
     172         * Get the maximum value in the score matrix. 
     173         */ 
     174        @Override 
     175        public double getMaxScore() { 
     176                double maxScore = 0; 
     177 
     178                // skip the first row and column 
     179                for (int i = 1; i <= length1; i++) { 
     180                        for (int j = 1; j < length2; j++) { 
     181                                if (matrix[i][j].getScore() > maxScore) { 
     182                                        maxScore = matrix[i][j].getScore(); 
     183                                } 
     184                        } 
     185                } 
     186 
     187                return maxScore; 
     188        } 
     189 
     190        @Override 
     191        public void printAlignment() { 
     192                MatrixEntry tmp = matrix[length1 + 1][0]; 
     193                String aligned1 = ""; 
     194                String aligned2 = ""; 
     195                int count = 0; 
     196                do { 
     197                        String append1 = ""; 
     198                        String append2 = ""; 
     199 
     200                        if (tmp.getXvalue() == Constants.GAP_SYMBOL) { 
     201                                append1 = "  ___"; 
     202                        } else { 
     203                                append1 = String.format("%5d", tmp.getXvalue()); 
     204                        } 
     205 
     206                        if (tmp.getYvalue() == Constants.GAP_SYMBOL) { 
     207                                append2 = "  ___"; 
     208                        } else { 
     209                                append2 = String.format("%5d", tmp.getYvalue()); 
     210                        } 
     211                        if (count != 0) { 
     212                                aligned1 = append1 + aligned1; 
     213                                aligned2 = append2 + aligned2; 
     214                        } 
     215 
     216                        tmp = tmp.getPrevious(); 
     217                        count++; 
     218 
     219                } while (tmp != null); 
     220                System.out.println(aligned1); 
     221                System.out.println(aligned2); 
     222        } 
     223 
     224        /** 
     225         * print the dynmaic programming matrix 
     226         */ 
     227        @Override 
     228        public void printDPMatrix() { 
     229                System.out.print("          "); 
     230                for (int i = 1; i <= length1; i++) { 
     231                        System.out.format("%5d", input1[i - 1]); 
     232                } 
     233                System.out.println(); 
     234                for (int j = 0; j <= length2; j++) { 
     235                        if (j > 0) { 
     236                                System.out.format("%5d ", input2[j - 1]); 
     237                        } else { 
     238                                System.out.print("      "); 
     239                        } 
     240                        for (int i = 0; i <= length1; i++) { 
     241                                System.out.format("%4.1f ", matrix[i][j].getScore()); 
     242                        } 
     243                        System.out.println(); 
     244                } 
     245        } 
     246 
     247        public void setAlignment(ArrayList<NumberSequence> alignment) { 
     248                this.alignment = alignment; 
     249        } 
    40250 
    41251        /** 
     
    53263        } 
    54264 
    55         /** 
    56          * Build the score matrix using dynamic programming. 
    57          */ 
    58         private void buildMatrix() { 
    59                 if (submat.getGapPenalty() >= 0) { 
    60                         throw new Error("Indel score must be negative"); 
    61                 } 
    62  
    63                 // it's a gap 
    64                 matrix[0][0].setScore(0); 
    65                 matrix[0][0].setPrevious(null); // starting point 
    66  
    67                 // the first column 
    68                 for (int j = 1; j < length2; j++) { 
    69                         matrix[0][j].setScore(0); 
    70                         matrix[0][j].setPrevious(matrix[0][j - 1]); 
    71                         matrix[0][j].setYvalue(input2[j]); 
    72                         matrix[0][j].setXvalue(Constants.GAP_SYMBOL); 
    73                 } 
    74                 // the first row 
    75  
    76                 for (int j = 1; j < length1; j++) { 
    77                         matrix[j][0].setScore(0); 
    78                         matrix[j][0].setPrevious(matrix[j - 1][0]); 
    79                         matrix[j][0].setXvalue(input1[j]); 
    80                         matrix[j][0].setYvalue(Constants.GAP_SYMBOL); 
    81                 } 
    82  
    83                 for (int i = 1; i < length1; i++) { 
    84  
    85                         for (int j = 1; j < length2; j++) { 
    86                                 double diagScore = matrix[i - 1][j - 1].getScore() 
    87                                                 + similarity(i, j); 
    88                                 double upScore = matrix[i][j - 1].getScore() 
    89                                                 + submat.getGapPenalty(); 
    90                                 double leftScore = matrix[i - 1][j].getScore() 
    91                                                 + submat.getGapPenalty(); 
    92  
    93                                 matrix[i][j].setScore(Math.max(diagScore, 
    94                                                 Math.max(upScore, Math.max(leftScore, 0)))); 
    95  
    96                                 // find the directions that give the maximum scores. 
    97                                 // TODO: Multiple directions are ignored, we choose the first 
    98                                 // maximum score 
    99                                 // True if we had a match 
    100                                 if (diagScore == matrix[i][j].getScore()) { 
    101                                         matrix[i][j].setPrevious(matrix[i - 1][j - 1]); 
    102                                         matrix[i][j].setXvalue(input1[i - 1]); 
    103                                         matrix[i][j].setYvalue(input2[j - 1]); 
    104                                 } 
    105                                 // true if we took an event from sequence x and not from y 
    106                                 if (leftScore == matrix[i][j].getScore()) { 
    107                                         matrix[i][j].setXvalue(input1[i - 1]); 
    108                                         matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
    109                                         matrix[i][j].setPrevious(matrix[i - 1][j]); 
    110                                 } 
    111                                 // true if we took an event from sequence y and not from x 
    112                                 if (upScore == matrix[i][j].getScore()) { 
    113                                         matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
    114                                         matrix[i][j].setYvalue(input2[j - 1]); 
    115                                         matrix[i][j].setPrevious(matrix[i][j - 1]); 
    116                                 } 
    117                                 if (0 == matrix[i][j].getScore()) { 
    118                                         matrix[i][j].setPrevious(matrix[0][0]); 
    119                                         matrix[i][j].setXvalue(-2); 
    120                                         matrix[i][j].setYvalue(-2); 
    121                                 } 
    122                         } 
    123  
    124                         // Set the complete score cell 
    125  
    126                 } 
    127         } 
    128  
    129         /** 
    130          * Get the maximum value in the score matrix. 
    131          */ 
    132         public double getMaxScore() { 
    133                 double maxScore = 0; 
    134  
    135                 // skip the first row and column 
    136                 for (int i = 1; i <= length1; i++) { 
    137                         for (int j = 1; j < length2; j++) { 
    138                                 if (matrix[i][j].getScore() > maxScore) { 
    139                                         maxScore = matrix[i][j].getScore(); 
    140                                 } 
    141                         } 
    142                 } 
    143  
    144                 return maxScore; 
    145         } 
    146  
    147         /* 
    148          * (non-Javadoc) 
    149          *  
    150          * @see 
    151          * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
    152          * #getAlignmentScore() 
    153          */ 
    154         @Override 
    155         public double getAlignmentScore() { 
    156                 return getMaxScore(); 
    157         } 
    158  
    159265        public void traceback() { 
    160266                MatrixEntry tmp = matrix[length1][length2]; 
    161                 int aligned1[] = new int[length1 + length2 + 2]; 
    162                 int aligned2[] = new int[length1 + length2 + 2]; 
     267                final int aligned1[] = new int[length1 + length2 + 2]; 
     268                final int aligned2[] = new int[length1 + length2 + 2]; 
    163269                int count = 0; 
    164270                do { 
    165                         if (length1 + length2 + 2 == count) { 
     271                        if ((length1 + length2 + 2) == count) { 
    166272                                Console.traceln(Level.WARNING, 
    167273                                                "Traceback longer than both sequences summed up!"); 
     
    177283                count--; 
    178284                // reverse order of the alignment 
    179                 int reversed1[] = new int[count]; 
    180                 int reversed2[] = new int[count]; 
     285                final int reversed1[] = new int[count]; 
     286                final int reversed2[] = new int[count]; 
    181287 
    182288                for (int i = count - 1; i > 0; i--) { 
     
    185291                } 
    186292 
    187                 NumberSequence ns1 = new NumberSequence(reversed1.length); 
    188                 NumberSequence ns2 = new NumberSequence(reversed2.length); 
     293                final NumberSequence ns1 = new NumberSequence(reversed1.length); 
     294                final NumberSequence ns2 = new NumberSequence(reversed2.length); 
    189295                ns1.setSequence(reversed1); 
    190296                ns2.setSequence(reversed2); 
     
    194300        } 
    195301 
    196         public void printAlignment() { 
    197                 MatrixEntry tmp = matrix[length1 + 1][0]; 
    198                 String aligned1 = ""; 
    199                 String aligned2 = ""; 
    200                 int count = 0; 
    201                 do { 
    202                         String append1 = ""; 
    203                         String append2 = ""; 
    204  
    205                         if (tmp.getXvalue() == Constants.GAP_SYMBOL) { 
    206                                 append1 = "  ___"; 
    207                         } else { 
    208                                 append1 = String.format("%5d", tmp.getXvalue()); 
    209                         } 
    210  
    211                         if (tmp.getYvalue() == Constants.GAP_SYMBOL) { 
    212                                 append2 = "  ___"; 
    213                         } else { 
    214                                 append2 = String.format("%5d", tmp.getYvalue()); 
    215                         } 
    216                         if (count != 0) { 
    217                                 aligned1 = append1 + aligned1; 
    218                                 aligned2 = append2 + aligned2; 
    219                         } 
    220  
    221                         tmp = tmp.getPrevious(); 
    222                         count++; 
    223  
    224                 } while (tmp != null); 
    225                 System.out.println(aligned1); 
    226                 System.out.println(aligned2); 
    227         } 
    228  
    229         /** 
    230          * print the dynmaic programming matrix 
    231          */ 
    232         public void printDPMatrix() { 
    233                 System.out.print("          "); 
    234                 for (int i = 1; i <= length1; i++) 
    235                         System.out.format("%5d", input1[i - 1]); 
    236                 System.out.println(); 
    237                 for (int j = 0; j <= length2; j++) { 
    238                         if (j > 0) 
    239                                 System.out.format("%5d ", input2[j - 1]); 
    240                         else { 
    241                                 System.out.print("      "); 
    242                         } 
    243                         for (int i = 0; i <= length1; i++) { 
    244                                         System.out.format("%4.1f ", matrix[i][j].getScore()); 
    245                         } 
    246                         System.out.println(); 
    247                 } 
    248         } 
    249  
    250         /* 
    251          * (non-Javadoc) 
    252          *  
    253          * @see 
    254          * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
    255          * #getAlignment() 
    256          */ 
    257         @Override 
    258         public ArrayList<NumberSequence> getAlignment() { 
    259                 return alignment; 
    260         } 
    261  
    262         public void setAlignment(ArrayList<NumberSequence> alignment) { 
    263                 this.alignment = alignment; 
    264         } 
    265  
    266         @Override 
    267         public ArrayList<Match> getMatches() { 
    268                 // TODO Auto-generated method stub 
    269                 return null; 
    270         } 
    271  
    272         @Override 
    273         public void align(NumberSequence input1, NumberSequence input2, SubstitutionMatrix submat, 
    274                         float threshold) { 
    275                 this.input1 = input1.getSequence(); 
    276                 this.input2 = input2.getSequence(); 
    277                 length1 = input1.size(); 
    278                 length2 = input2.size(); 
    279                 this.submat = submat; 
    280  
    281                 // System.out.println("Starting SmithWaterman algorithm with a " 
    282                 // + submat.getClass() + " Substitution Matrix: " + 
    283                 // submat.getClass().getCanonicalName()); 
    284  
    285                 matrix = new MatrixEntry[length1 + 1][length2 + 1]; 
    286                 alignment = new ArrayList<NumberSequence>(); 
    287  
    288                 for (int i = 0; i < length1+1; i++) { 
    289                         for (int j = 0; j < length2+1; j++) { 
    290                                 matrix[i][j] = new MatrixEntry(); 
    291                         } 
    292                 } 
    293  
    294                 buildMatrix(); 
    295                 traceback(); 
    296                  
    297         } 
    298  
    299302} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWatermanRepeated.java

    r1654 r1733  
    55import java.util.LinkedList; 
    66 
    7  
    87import de.ugoe.cs.autoquest.tasktrees.alignment.matrix.SubstitutionMatrix; 
    98import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Constants; 
    109 
    11  
    1210public class SmithWatermanRepeated implements AlignmentAlgorithm { 
    1311 
     
    3331        private MatrixEntry[][] matrix; 
    3432 
    35  
    3633        private ArrayList<NumberSequence> alignment; 
    37          
     34 
    3835        private float scoreThreshold; 
    3936 
     
    4441 
    4542        public SmithWatermanRepeated() { 
    46          
     43 
     44        } 
     45 
     46        @Override 
     47        public void align(NumberSequence input1, NumberSequence input2, 
     48                        SubstitutionMatrix submat, float threshold) { 
     49 
     50                alignment = new ArrayList<NumberSequence>(); 
     51                alignment.add(input1); 
     52                alignment.add(input2); 
     53 
     54                this.input1 = input1.getSequence(); 
     55                this.input2 = input2.getSequence(); 
     56 
     57                length1 = input1.size(); 
     58                length2 = input2.size(); 
     59                this.submat = submat; 
     60 
     61                // System.out.println("Starting SmithWaterman algorithm with a " 
     62                // + submat.getClass() + " Substitution Matrix: " + 
     63                // submat.getClass().getCanonicalName()); 
     64                this.scoreThreshold = threshold; 
     65 
     66                matrix = new MatrixEntry[length1 + 2][length2 + 1]; 
     67 
     68                for (int i = 0; i <= (length1 + 1); i++) { 
     69                        for (int j = 0; j <= length2; j++) { 
     70                                matrix[i][j] = new MatrixEntry(); 
     71                        } 
     72                } 
     73 
     74                // Console.traceln(Level.INFO,"Generating DP Matrix"); 
     75                buildMatrix(); 
     76                // Console.traceln(Level.INFO,"Doing traceback"); 
     77                traceback(); 
     78        } 
     79 
     80        /** 
     81         * Build the score matrix using dynamic programming. 
     82         */ 
     83        private void buildMatrix() { 
     84                if (submat.getGapPenalty() >= 0) { 
     85                        throw new Error("Indel score must be negative"); 
     86                } 
     87 
     88                // it's a gap 
     89                matrix[0][0].setScore(0); 
     90                matrix[0][0].setPrevious(null); // starting point 
     91                matrix[0][0].setXvalue(Constants.UNMATCHED_SYMBOL); 
     92                matrix[0][0].setYvalue(Constants.UNMATCHED_SYMBOL); 
     93 
     94                // the first column 
     95                for (int j = 1; j < length2; j++) { 
     96                        matrix[0][j].setScore(0); 
     97                        // We don't need to go back to [0][0] if we reached matrix[0][x], so 
     98                        // just end here 
     99                        // matrix[0][j].setPrevious(matrix[0][j-1]); 
     100                        matrix[0][j].setPrevious(null); 
     101                } 
     102 
     103                for (int i = 1; i < (length1 + 2); i++) { 
     104 
     105                        // Formula for first row: 
     106                        // F(i,0) = max { F(i-1,0), F(i-1,j)-T j=1,...,m 
     107 
     108                        final double firstRowLeftScore = matrix[i - 1][0].getScore(); 
     109                        // for sequences of length 1 
     110                        double tempMax; 
     111                        int maxRowIndex; 
     112                        if (length2 == 1) { 
     113                                tempMax = matrix[i - 1][0].getScore(); 
     114                                maxRowIndex = 0; 
     115                        } else { 
     116                                tempMax = matrix[i - 1][1].getScore(); 
     117                                maxRowIndex = 1; 
     118                                // position of the maximal score of the previous row 
     119 
     120                                for (int j = 2; j <= length2; j++) { 
     121                                        if (matrix[i - 1][j].getScore() > tempMax) { 
     122                                                tempMax = matrix[i - 1][j].getScore(); 
     123                                                maxRowIndex = j; 
     124                                        } 
     125                                } 
     126 
     127                        } 
     128 
     129                        tempMax -= scoreThreshold; 
     130                        matrix[i][0].setScore(Math.max(firstRowLeftScore, tempMax)); 
     131                        if (tempMax == matrix[i][0].getScore()) { 
     132                                matrix[i][0].setPrevious(matrix[i - 1][maxRowIndex]); 
     133                        } 
     134 
     135                        if (firstRowLeftScore == matrix[i][0].getScore()) { 
     136                                matrix[i][0].setPrevious(matrix[i - 1][0]); 
     137                        } 
     138 
     139                        // The last additional score is not related to a character in the 
     140                        // input sequence, it's the total score. Therefore we don't need to 
     141                        // save something for it 
     142                        // and can end here 
     143                        if (i < (length1 + 1)) { 
     144                                matrix[i][0].setXvalue(input1[i - 1]); 
     145                                matrix[i][0].setYvalue(Constants.UNMATCHED_SYMBOL); 
     146                        } else { 
     147                                return; 
     148                        } 
     149 
     150                        for (int j = 1; j <= length2; j++) { 
     151                                final double diagScore = matrix[i - 1][j - 1].getScore() 
     152                                                + similarity(i, j); 
     153                                final double upScore = matrix[i][j - 1].getScore() 
     154                                                + submat.getGapPenalty(); 
     155                                final double leftScore = matrix[i - 1][j].getScore() 
     156                                                + submat.getGapPenalty(); 
     157 
     158                                matrix[i][j].setScore(Math.max( 
     159                                                diagScore, 
     160                                                Math.max(upScore, 
     161                                                                Math.max(leftScore, matrix[i][0].getScore())))); 
     162 
     163                                // find the directions that give the maximum scores. 
     164                                // TODO: Multiple directions are ignored, we choose the first 
     165                                // maximum score 
     166                                // True if we had a match 
     167                                if (diagScore == matrix[i][j].getScore()) { 
     168                                        matrix[i][j].setPrevious(matrix[i - 1][j - 1]); 
     169                                        matrix[i][j].setXvalue(input1[i - 1]); 
     170                                        matrix[i][j].setYvalue(input2[j - 1]); 
     171                                } 
     172                                // true if we took an event from sequence x and not from y 
     173                                if (leftScore == matrix[i][j].getScore()) { 
     174                                        matrix[i][j].setXvalue(input1[i - 1]); 
     175                                        matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
     176                                        matrix[i][j].setPrevious(matrix[i - 1][j]); 
     177                                } 
     178                                // true if we took an event from sequence y and not from x 
     179                                if (upScore == matrix[i][j].getScore()) { 
     180                                        matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
     181                                        matrix[i][j].setYvalue(input2[j - 1]); 
     182                                        matrix[i][j].setPrevious(matrix[i][j - 1]); 
     183                                } 
     184                                // true if we ended a matching region 
     185                                if (matrix[i][0].getScore() == matrix[i][j].getScore()) { 
     186                                        matrix[i][j].setPrevious(matrix[i][0]); 
     187                                        matrix[i][j].setXvalue(input1[i - 1]); 
     188                                        matrix[i][j].setYvalue(Constants.UNMATCHED_SYMBOL); 
     189                                } 
     190                        } 
     191 
     192                        // Set the complete score cell 
     193 
     194                } 
     195        } 
     196 
     197        /* 
     198         * (non-Javadoc) 
     199         *  
     200         * @see 
     201         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     202         * #getAlignment() 
     203         */ 
     204        @Override 
     205        public ArrayList<NumberSequence> getAlignment() { 
     206                return alignment; 
     207        } 
     208 
     209        /* 
     210         * (non-Javadoc) 
     211         *  
     212         * @see 
     213         * de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm 
     214         * #getAlignmentScore() 
     215         */ 
     216        @Override 
     217        public double getAlignmentScore() { 
     218                return matrix[length1 + 1][0].getScore(); 
     219        } 
     220 
     221        @Override 
     222        public ArrayList<Match> getMatches() { 
     223                final ArrayList<Match> result = new ArrayList<Match>(); 
     224 
     225                // both alignment sequences should be equally long 
     226                int i = 0; 
     227                final int[] seq1 = alignment.get(0).getSequence(); 
     228                final int[] seq2 = alignment.get(1).getSequence(); 
     229                int start = 0; 
     230                while (i < seq1.length) { 
     231                        if (seq2[i] != Constants.UNMATCHED_SYMBOL) { 
     232                                start = i; 
     233                                int count = 0; 
     234                                while ((i < seq2.length) 
     235                                                && (seq2[i] != Constants.UNMATCHED_SYMBOL)) { 
     236                                        i++; 
     237                                        count++; 
     238                                } 
     239                                // I am really missing memcpy here? How does one do this better 
     240                                // in java? 
     241                                final int[] tmp1 = new int[count]; 
     242                                final int[] tmp2 = new int[count]; 
     243                                for (int j = 0; j < count; j++) { 
     244                                        tmp1[j] = seq1[start + j]; 
     245                                        tmp2[j] = seq2[start + j]; 
     246                                } 
     247                                final NumberSequence tmpns1 = new NumberSequence(count); 
     248                                final NumberSequence tmpns2 = new NumberSequence(count); 
     249                                tmpns1.setSequence(tmp1); 
     250                                tmpns2.setSequence(tmp2); 
     251                                final Match tmpal = new Match(); 
     252                                tmpal.setFirstSequence(tmpns1); 
     253                                tmpal.setSecondSequence(tmpns2); 
     254                                // tmpal.addOccurence(new 
     255                                // MatchOccurence(start,alignment.get(0).getId())); 
     256                                // tmpal.addOccurence(new 
     257                                // MatchOccurence(start,alignment.get(1).getId())); 
     258                                result.add(tmpal); 
     259                        } 
     260                        i++; 
     261                } 
     262                return result; 
     263        } 
     264 
     265        /** 
     266         * Get the maximum value in the score matrix. 
     267         */ 
     268        @Override 
     269        public double getMaxScore() { 
     270                double maxScore = 0; 
     271 
     272                // skip the first row and column 
     273                for (int i = 1; i <= length1; i++) { 
     274                        for (int j = 1; j <= length2; j++) { 
     275                                if (matrix[i][j].getScore() > maxScore) { 
     276                                        maxScore = matrix[i][j].getScore(); 
     277                                } 
     278                        } 
     279                } 
     280 
     281                return maxScore; 
     282        } 
     283 
     284        @Override 
     285        public void printAlignment() { 
     286                final int[] tmp1 = alignment.get(0).getSequence(); 
     287                final int[] tmp2 = alignment.get(1).getSequence(); 
     288                for (int i = 0; i < tmp1.length; i++) { 
     289                        if (tmp1[i] == Constants.GAP_SYMBOL) { 
     290                                System.out.print("  ___"); 
     291                        } else if (tmp1[i] == Constants.UNMATCHED_SYMBOL) { 
     292                                System.out.print("  ..."); 
     293                        } else { 
     294                                System.out.format("%5d", tmp1[i]); 
     295                        } 
     296 
     297                } 
     298                System.out.println(); 
     299                for (int i = 0; i < tmp2.length; i++) { 
     300                        if (tmp2[i] == Constants.GAP_SYMBOL) { 
     301                                System.out.print("  ___"); 
     302                        } else if (tmp2[i] == Constants.UNMATCHED_SYMBOL) { 
     303                                System.out.print("  ..."); 
     304                        } else { 
     305                                System.out.format("%5d", tmp2[i]); 
     306                        } 
     307 
     308                } 
     309                System.out.println(); 
     310 
     311        } 
     312 
     313        /** 
     314         * print the dynmaic programming matrix 
     315         */ 
     316        @Override 
     317        public void printDPMatrix() { 
     318                System.out.print("          "); 
     319                for (int i = 1; i <= length1; i++) { 
     320                        System.out.format("%5d", input1[i - 1]); 
     321                } 
     322                System.out.println(); 
     323                for (int j = 0; j <= length2; j++) { 
     324                        if (j > 0) { 
     325                                System.out.format("%5d ", input2[j - 1]); 
     326                        } else { 
     327                                System.out.print("      "); 
     328                        } 
     329                        for (int i = 0; i <= (length1 + 1); i++) { 
     330                                if ((i < (length1 + 1)) || ((i == (length1 + 1)) && (j == 0))) { 
     331                                        System.out.format("%4.1f ", matrix[i][j].getScore()); 
     332                                } 
     333 
     334                        } 
     335                        System.out.println(); 
     336                } 
     337        } 
     338 
     339        public void setAlignment(ArrayList<NumberSequence> alignment) { 
     340                this.alignment = alignment; 
    47341        } 
    48342 
     
    57351         * @return Cost of substitution of the character in str1 by the one in str2 
    58352         */ 
    59         private double similarity(int i, int j) {  
     353        private double similarity(int i, int j) { 
    60354                return submat.getScore(input1[i - 1], input2[j - 1]); 
    61355        } 
    62356 
    63         /** 
    64          * Build the score matrix using dynamic programming. 
    65          */ 
    66         private void buildMatrix() { 
    67                 if (submat.getGapPenalty() >= 0) { 
    68                         throw new Error("Indel score must be negative"); 
    69                 } 
    70                  
    71                 // it's a gap 
    72                 matrix[0][0].setScore(0); 
    73                 matrix[0][0].setPrevious(null); // starting point 
    74                 matrix[0][0].setXvalue(Constants.UNMATCHED_SYMBOL); 
    75                 matrix[0][0].setYvalue(Constants.UNMATCHED_SYMBOL); 
    76  
    77                 // the first column 
    78                 for (int j = 1; j < length2; j++) { 
    79                         matrix[0][j].setScore(0); 
    80                         //We don't need to go back to [0][0] if we reached matrix[0][x], so just end here 
    81                         //matrix[0][j].setPrevious(matrix[0][j-1]); 
    82                         matrix[0][j].setPrevious(null);  
    83                 } 
    84                  
    85                  
    86                  
    87                 for (int i = 1; i < length1 + 2; i++) { 
    88                  
    89                         // Formula for first row: 
    90                         // F(i,0) = max { F(i-1,0), F(i-1,j)-T  j=1,...,m 
    91                          
    92                         double firstRowLeftScore = matrix[i-1][0].getScore(); 
    93                         //for sequences of length 1 
    94                         double tempMax; 
    95                         int maxRowIndex; 
    96                         if(length2 == 1) { 
    97                                 tempMax = matrix[i-1][0].getScore(); 
    98                                 maxRowIndex = 0; 
    99                         } else { 
    100                                 tempMax = matrix[i-1][1].getScore(); 
    101                                 maxRowIndex = 1; 
    102                                 //position of the maximal score of the previous row 
    103                                  
    104                                 for(int j = 2; j <= length2;j++) { 
    105                                         if(matrix[i-1][j].getScore() > tempMax) { 
    106                                                 tempMax = matrix[i-1][j].getScore(); 
    107                                                 maxRowIndex = j; 
    108                                         } 
    109                                 } 
    110  
    111                         } 
    112                                          
    113                         tempMax -= scoreThreshold; 
    114                         matrix[i][0].setScore(Math.max(firstRowLeftScore, tempMax)); 
    115                         if(tempMax == matrix[i][0].getScore()){ 
    116                                 matrix[i][0].setPrevious(matrix[i-1][maxRowIndex]); 
    117                         } 
    118                          
    119                         if(firstRowLeftScore == matrix[i][0].getScore()) { 
    120                                 matrix[i][0].setPrevious(matrix[i-1][0]); 
    121                         } 
    122                          
    123                         //The last additional score is not related to a character in the input sequence, it's the total score. Therefore we don't need to save something for it 
    124                         //and can end here 
    125                         if(i<length1+1) { 
    126                                 matrix[i][0].setXvalue(input1[i-1]); 
    127                                 matrix[i][0].setYvalue(Constants.UNMATCHED_SYMBOL); 
    128                         } 
    129                         else { 
    130                                 return; 
    131                         } 
    132                   
    133                          
    134                          
    135                         for (int j = 1; j <= length2; j++) { 
    136                                 double diagScore = matrix[i - 1][j - 1].getScore() + similarity(i, j); 
    137                                 double upScore = matrix[i][j - 1].getScore() + submat.getGapPenalty(); 
    138                                 double leftScore = matrix[i - 1][j].getScore() + submat.getGapPenalty(); 
    139  
    140                                 matrix[i][j].setScore(Math.max(diagScore,Math.max(upScore, Math.max(leftScore,matrix[i][0].getScore())))); 
    141  
    142                                 // find the directions that give the maximum scores. 
    143                                 // TODO: Multiple directions are ignored, we choose the first maximum score  
    144                                 //True if we had a match 
    145                                 if (diagScore == matrix[i][j].getScore()) { 
    146                                         matrix[i][j].setPrevious(matrix[i-1][j-1]); 
    147                                         matrix[i][j].setXvalue(input1[i-1]); 
    148                                         matrix[i][j].setYvalue(input2[j-1]); 
    149                                 } 
    150                                 //true if we took an event from sequence x and not from y 
    151                                 if (leftScore == matrix[i][j].getScore()) { 
    152                                         matrix[i][j].setXvalue(input1[i-1]); 
    153                                         matrix[i][j].setYvalue(Constants.GAP_SYMBOL); 
    154                                         matrix[i][j].setPrevious(matrix[i-1][j]); 
    155                                 } 
    156                                 //true if we took an event from sequence y and not from x 
    157                                 if (upScore == matrix[i][j].getScore()) { 
    158                                         matrix[i][j].setXvalue(Constants.GAP_SYMBOL); 
    159                                         matrix[i][j].setYvalue(input2[j-1]); 
    160                                         matrix[i][j].setPrevious(matrix[i][j-1]); 
    161                                 } 
    162                                 //true if we ended a matching region  
    163                                 if (matrix[i][0].getScore() == matrix[i][j].getScore()) { 
    164                                         matrix[i][j].setPrevious(matrix[i][0]); 
    165                                         matrix[i][j].setXvalue(input1[i-1]); 
    166                                         matrix[i][j].setYvalue(Constants.UNMATCHED_SYMBOL); 
    167                                 } 
    168                         } 
    169                          
    170                         //Set the complete score cell 
    171                          
    172                 } 
    173         } 
    174  
    175         /** 
    176          * Get the maximum value in the score matrix. 
    177          */ 
    178         public double getMaxScore() { 
    179                 double maxScore = 0; 
    180  
    181                 // skip the first row and column 
    182                 for (int i = 1; i <= length1; i++) { 
    183                         for (int j = 1; j <= length2; j++) { 
    184                                 if (matrix[i][j].getScore() > maxScore) { 
    185                                         maxScore = matrix[i][j].getScore(); 
    186                                 } 
    187                         } 
    188                 } 
    189  
    190                 return maxScore; 
    191         } 
    192  
    193         /* (non-Javadoc) 
    194          * @see de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm#getAlignmentScore() 
    195          */ 
    196         @Override 
    197         public double getAlignmentScore() { 
    198                 return matrix[length1+1][0].getScore(); 
    199         } 
    200  
    201357        public void traceback() { 
    202                 MatrixEntry tmp = matrix[length1+1][0].getPrevious(); 
    203                 LinkedList<Integer> aligned1 = new LinkedList<Integer>(); 
    204                 LinkedList<Integer> aligned2 = new LinkedList<Integer>(); 
     358                MatrixEntry tmp = matrix[length1 + 1][0].getPrevious(); 
     359                final LinkedList<Integer> aligned1 = new LinkedList<Integer>(); 
     360                final LinkedList<Integer> aligned2 = new LinkedList<Integer>(); 
    205361                while (tmp.getPrevious() != null) { 
    206                          
     362 
    207363                        aligned1.add(new Integer(tmp.getXvalue())); 
    208364                        aligned2.add(new Integer(tmp.getYvalue())); 
    209365 
    210366                        tmp = tmp.getPrevious(); 
    211                 }  
    212                  
     367                } 
     368 
    213369                // reverse order of the alignment 
    214                 int reversed1[] = new int[aligned1.size()]; 
    215                 int reversed2[] = new int[aligned2.size()]; 
     370                final int reversed1[] = new int[aligned1.size()]; 
     371                final int reversed2[] = new int[aligned2.size()]; 
    216372 
    217373                int count = 0; 
    218                 for (Iterator<Integer> it = aligned1.iterator(); it.hasNext();) { 
     374                for (final Iterator<Integer> it = aligned1.iterator(); it.hasNext();) { 
    219375                        count++; 
    220376                        reversed1[reversed1.length - count] = it.next(); 
    221                          
     377 
    222378                } 
    223379                count = 0; 
    224                 for (Iterator<Integer> it = aligned2.iterator(); it.hasNext();) { 
     380                for (final Iterator<Integer> it = aligned2.iterator(); it.hasNext();) { 
    225381                        count++; 
    226382                        reversed2[reversed2.length - count] = it.next(); 
    227383                } 
    228384 
    229                  
    230                 NumberSequence ns1 = new NumberSequence(reversed1.length); 
    231                 NumberSequence ns2 = new NumberSequence(reversed2.length); 
     385                final NumberSequence ns1 = new NumberSequence(reversed1.length); 
     386                final NumberSequence ns2 = new NumberSequence(reversed2.length); 
    232387                ns1.setSequence(reversed1); 
    233388                ns2.setSequence(reversed2); 
    234389                ns1.setId(alignment.get(0).getId()); 
    235390                ns2.setId(alignment.get(1).getId()); 
    236                  
     391 
    237392                alignment.set(0, ns1); 
    238393                alignment.set(1, ns2); 
    239394        } 
    240          
    241  
    242          
    243         public void printAlignment() { 
    244                 int[] tmp1 = alignment.get(0).getSequence(); 
    245                 int[] tmp2 = alignment.get(1).getSequence(); 
    246                 for (int i=0; i< tmp1.length;i++) { 
    247                         if(tmp1[i] == Constants.GAP_SYMBOL) { 
    248                                 System.out.print("  ___"); 
    249                         } 
    250                         else if(tmp1[i] == Constants.UNMATCHED_SYMBOL) { 
    251                                 System.out.print("  ..."); 
    252                         } 
    253                         else { 
    254                                 System.out.format("%5d", tmp1[i]); 
    255                         } 
    256                          
    257                 } 
    258                 System.out.println(); 
    259                 for (int i=0; i< tmp2.length;i++) { 
    260                         if(tmp2[i] == Constants.GAP_SYMBOL) { 
    261                                 System.out.print("  ___"); 
    262                         } 
    263                         else if(tmp2[i] == Constants.UNMATCHED_SYMBOL) { 
    264                                 System.out.print("  ..."); 
    265                         } 
    266                         else { 
    267                                 System.out.format("%5d", tmp2[i]); 
    268                         } 
    269                          
    270                 } 
    271                 System.out.println(); 
    272                  
    273                  
    274          
    275         } 
    276          
    277         public ArrayList<Match> getMatches() { 
    278                 ArrayList<Match> result = new ArrayList<Match>(); 
    279                  
    280                 //both alignment sequences should be equally long 
    281                 int i = 0; 
    282                 int[] seq1 = alignment.get(0).getSequence(); 
    283                 int[] seq2 = alignment.get(1).getSequence(); 
    284                 int start = 0; 
    285                 while (i < seq1.length){ 
    286                         if(seq2[i] != Constants.UNMATCHED_SYMBOL) { 
    287                                 start = i; 
    288                                 int count = 0; 
    289                                 while(i < seq2.length && seq2[i] != Constants.UNMATCHED_SYMBOL) { 
    290                                         i++; 
    291                                         count++; 
    292                                 } 
    293                                 //I am really missing memcpy here? How does one do this better in java?  
    294                                 int[] tmp1 = new int[count]; 
    295                                 int[] tmp2 = new int[count]; 
    296                                 for (int j = 0; j<count;j++) { 
    297                                         tmp1[j] = seq1[start+j]; 
    298                                         tmp2[j] = seq2[start+j]; 
    299                                 } 
    300                                 NumberSequence tmpns1 = new NumberSequence(count); 
    301                                 NumberSequence tmpns2 = new NumberSequence(count); 
    302                                 tmpns1.setSequence(tmp1); 
    303                                 tmpns2.setSequence(tmp2); 
    304                                 Match tmpal = new Match(); 
    305                                 tmpal.setFirstSequence(tmpns1); 
    306                                 tmpal.setSecondSequence(tmpns2); 
    307                                 //tmpal.addOccurence(new MatchOccurence(start,alignment.get(0).getId())); 
    308                                 //tmpal.addOccurence(new MatchOccurence(start,alignment.get(1).getId())); 
    309                                 result.add(tmpal); 
    310                         } 
    311                         i++; 
    312                 } 
    313                 return result; 
    314         } 
    315          
    316         /** 
    317          * print the dynmaic programming matrix 
    318          */ 
    319         public void printDPMatrix() { 
    320                 System.out.print("          "); 
    321                 for (int i = 1; i <= length1; i++) 
    322                         System.out.format("%5d", input1[i - 1]); 
    323                 System.out.println(); 
    324                 for (int j = 0; j <= length2; j++) { 
    325                         if (j > 0) 
    326                                 System.out.format("%5d ",input2[j - 1]); 
    327                         else{ 
    328                                 System.out.print("      "); 
    329                         } 
    330                         for (int i = 0; i <= length1 + 1; i++) { 
    331                                 if((i<length1+1) || (i==length1+1 && j==0))     { 
    332                                         System.out.format("%4.1f ",matrix[i][j].getScore()); 
    333                                 } 
    334                                  
    335                         }                        
    336                         System.out.println(); 
    337                 } 
    338         } 
    339  
    340  
    341         /* (non-Javadoc) 
    342          * @see de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm#getAlignment() 
    343          */ 
    344         @Override 
    345         public ArrayList<NumberSequence> getAlignment() { 
    346                 return alignment; 
    347         } 
    348  
    349         public void setAlignment(ArrayList<NumberSequence> alignment) { 
    350                 this.alignment = alignment; 
    351         } 
    352  
    353         @Override 
    354         public void align(NumberSequence input1, NumberSequence input2, SubstitutionMatrix submat, 
    355                         float threshold) { 
    356                  
    357                 alignment = new ArrayList<NumberSequence>(); 
    358                 alignment.add(input1); 
    359                 alignment.add(input2); 
    360                  
    361                 this.input1=input1.getSequence(); 
    362                 this.input2=input2.getSequence(); 
    363                  
    364                 length1 = input1.size(); 
    365                 length2 = input2.size(); 
    366                 this.submat = submat; 
    367  
    368                 //System.out.println("Starting SmithWaterman algorithm with a " 
    369                 //              + submat.getClass() + " Substitution Matrix: " + submat.getClass().getCanonicalName()); 
    370                 this.scoreThreshold = threshold; 
    371                  
    372                 matrix = new MatrixEntry[length1+2][length2+1]; 
    373                  
    374                  
    375                 for (int i = 0; i <= length1+1; i++) { 
    376                         for(int j = 0; j<= length2; j++) { 
    377                                 matrix[i][j] = new MatrixEntry(); 
    378                         } 
    379                 } 
    380          
    381                 //Console.traceln(Level.INFO,"Generating DP Matrix"); 
    382                 buildMatrix(); 
    383                 //Console.traceln(Level.INFO,"Doing traceback"); 
    384                 traceback(); 
    385         } 
    386395 
    387396} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/DifferenceSubstitutionMatrix.java

    r1702 r1733  
    99import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    1010 
    11  
    1211/** 
    1312 * @author Ralph Krimmel 
     
    1615public class DifferenceSubstitutionMatrix implements SubstitutionMatrix { 
    1716 
    18         private int[] input1; 
    19         private int[] input2; 
    20         private int maxValue; 
    21          
    22         public DifferenceSubstitutionMatrix(int[] input1,int[] input2) { 
     17        private final int[] input1; 
     18        private final int[] input2; 
     19        private final int maxValue; 
     20 
     21        public DifferenceSubstitutionMatrix(int[] input1, int[] input2) { 
    2322                this.input1 = input1; 
    2423                this.input2 = input2; 
    2524                this.maxValue = getMaxValue(); 
    2625        } 
    27          
    28         /* (non-Javadoc) 
    29          * @see de.ugoe.cs.autoquest.plugin.alignment.SubstitutionMatrix#getDistance(int, int) 
    30          */ 
    31         public float getScore(int pos1, int pos2) { 
    32                 return maxValue - (input1[pos1] - input2[pos2]); 
    33         } 
    34          
    35         private int getMaxValue() { 
    36                 int max = input1[0]; 
    37                 for (int i=0; i < input1.length; i++) { 
    38                         if(input1[i] > max) { 
    39                                 max = input1[i]; 
    40                         } 
    41                 } 
    42                 for (int j=0; j < input2.length; j++) { 
    43                         if(input2[j] > max) { 
    44                                 max = input2[j]; 
    45                         } 
    46                 } 
    47                 return max; 
     26 
     27        @Override 
     28        public void generate(HashSet<ITask> uniqueTasks) { 
    4829        } 
    4930 
     
    5334        } 
    5435 
     36        private int getMaxValue() { 
     37                int max = input1[0]; 
     38                for (int i = 0; i < input1.length; i++) { 
     39                        if (input1[i] > max) { 
     40                                max = input1[i]; 
     41                        } 
     42                } 
     43                for (int j = 0; j < input2.length; j++) { 
     44                        if (input2[j] > max) { 
     45                                max = input2[j]; 
     46                        } 
     47                } 
     48                return max; 
     49        } 
    5550 
     51        /* 
     52         * (non-Javadoc) 
     53         *  
     54         * @see 
     55         * de.ugoe.cs.autoquest.plugin.alignment.SubstitutionMatrix#getDistance(int, 
     56         * int) 
     57         */ 
    5658        @Override 
    57         public void generate(HashSet<ITask> uniqueTasks) { 
     59        public float getScore(int pos1, int pos2) { 
     60                return maxValue - (input1[pos1] - input2[pos2]); 
    5861        } 
    5962 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/DummySubstitutionMatrix.java

    r1702 r1733  
    99 
    1010        @Override 
    11         public float getScore(int pos1, int pos2) { 
    12                 if(pos1==pos2) { 
    13                         return 1; 
    14                 } 
    15                 else { 
    16                         return 0; 
    17                 } 
     11        public void generate(HashSet<ITask> uniqueTasks) { 
    1812        } 
    1913 
     
    2418 
    2519        @Override 
    26         public void generate(HashSet<ITask> uniqueTasks) { 
     20        public float getScore(int pos1, int pos2) { 
     21                if (pos1 == pos2) { 
     22                        return 1; 
     23                } else { 
     24                        return 0; 
     25                } 
    2726        } 
    2827 
     
    3029        public void update(LinkedList<ITask> newlyGeneratedTasks) { 
    3130                // TODO Auto-generated method stub 
    32                  
     31 
    3332        } 
    34          
    3533 
    3634} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/DynamicTriangleMatrix.java

    r1702 r1733  
    55//Must be initialized! 
    66public class DynamicTriangleMatrix implements ITriangleMatrix { 
    7          
    8         private ArrayList<Float> matrix; 
     7 
     8        private final ArrayList<Float> matrix; 
    99        protected int size; 
    1010        private float initalizationValue; 
    11          
    12          
    13          
    14         //Increases the size 
    15         /* (non-Javadoc) 
    16          * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#increaseSize(int) 
     11 
     12        public DynamicTriangleMatrix(int size) { 
     13                this.size = size; 
     14                matrix = new ArrayList<Float>(); 
     15                matrix.ensureCapacity(size * (size + (1 / 2))); 
     16        } 
     17 
     18        /* 
     19         * (non-Javadoc) 
     20         *  
     21         * @see 
     22         * de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#get(int, 
     23         * int) 
     24         */ 
     25        @Override 
     26        public float get(int first, int second) { 
     27                final int row = Math.min(first, second); 
     28                final int col = Math.max(first, second); 
     29                return matrix.get((row * size) 
     30                                - (((row * (row + 1)) / 2) - (size - col))); 
     31 
     32        } 
     33 
     34        // Increases the size 
     35        /* 
     36         * (non-Javadoc) 
     37         *  
     38         * @see 
     39         * de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#increaseSize 
     40         * (int) 
    1741         */ 
    1842        @Override 
    1943        public void increaseSize(int count) { 
    20                 int oldsize = size; 
     44                final int oldsize = size; 
    2145                this.size += count; 
    22                 matrix.ensureCapacity(size*(size+1/2)); 
    23                 for(int i=0;i<(oldsize*count)+(count*(count+1)/2);i++) { 
     46                matrix.ensureCapacity(size * (size + (1 / 2))); 
     47                for (int i = 0; i < ((oldsize * count) + ((count * (count + 1)) / 2)); i++) { 
    2448                        matrix.add(this.initalizationValue); 
    2549                } 
    2650        } 
    2751 
    28  
    29         public DynamicTriangleMatrix(int size) { 
    30                 this.size = size; 
    31                 matrix = new ArrayList<Float>(); 
    32                 matrix.ensureCapacity(size*(size+1/2)); 
    33         } 
    34  
    35          
    36         /* (non-Javadoc) 
    37          * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#get(int, int) 
    38          */ 
    39         @Override 
    40         public float get(int first, int second) { 
    41                 int row = Math.min(first, second); 
    42                 int col = Math.max(first, second); 
    43                 return matrix.get(row*size-(row*(row+1)/2 - (size-col))); 
    44                  
    45         } 
    46          
    47         /* (non-Javadoc) 
    48          * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#set(int, int, float) 
    49          */ 
    50         @Override 
    51         public void set(int first, int second, float value) { 
    52                 int row = Math.min(first, second); 
    53                 int col = Math.max(first, second); 
    54                 matrix.set(row*size-(row*(row+1)/2 - (size-col)),value); 
    55         } 
    56  
    57         /* (non-Javadoc) 
    58          * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#initialize(float) 
     52        /* 
     53         * (non-Javadoc) 
     54         *  
     55         * @see 
     56         * de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#initialize 
     57         * (float) 
    5958         */ 
    6059        @Override 
     
    6261                this.initalizationValue = value; 
    6362                matrix.clear(); 
    64                 for (int i=0; i < this.size*(this.size+1)/2; i++) { 
     63                for (int i = 0; i < ((this.size * (this.size + 1)) / 2); i++) { 
    6564                        matrix.add(value); 
    6665                } 
    6766        } 
    68          
    69          
    70         /* (non-Javadoc) 
    71          * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#toString() 
     67 
     68        /* 
     69         * (non-Javadoc) 
     70         *  
     71         * @see 
     72         * de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#set(int, 
     73         * int, float) 
     74         */ 
     75        @Override 
     76        public void set(int first, int second, float value) { 
     77                final int row = Math.min(first, second); 
     78                final int col = Math.max(first, second); 
     79                matrix.set((row * size) - (((row * (row + 1)) / 2) - (size - col)), 
     80                                value); 
     81        } 
     82 
     83        @Override 
     84        public int size() { 
     85                return size; 
     86        } 
     87 
     88        /* 
     89         * (non-Javadoc) 
     90         *  
     91         * @see 
     92         * de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ITriangleMatrix#toString 
     93         * () 
    7294         */ 
    7395        @Override 
     
    7597                String result = ""; 
    7698                for (int i = 0; i < size; i++) { 
    77                         for(int j = 0; j< size; j++) { 
    78                                 if(i<j) { 
    79                                         if(Float.isInfinite(this.get(i,j))) { 
     99                        for (int j = 0; j < size; j++) { 
     100                                if (i < j) { 
     101                                        if (Float.isInfinite(this.get(i, j))) { 
    80102                                                result = result + " -------"; 
     103                                        } else { 
     104                                                result = result 
     105                                                                + String.format("%+8.2f", this.get(i, j)); 
    81106                                        } 
    82                                         else { 
    83                                                 result = result + String.format("%+8.2f",this.get(i,j)); 
    84                                         } 
    85                                 } 
    86                                 else { 
     107                                } else { 
    87108                                        result = result + ("        "); 
    88109                                } 
     
    92113                return result; 
    93114        } 
    94  
    95  
    96         @Override 
    97         public int size() { 
    98                 return size; 
    99         } 
    100115} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/EventTaskInstancesListGenerator.java

    r1695 r1733  
    77import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
    88 
    9 public class EventTaskInstancesListGenerator extends DefaultTaskTraversingVisitor { 
    10          
    11                 private LinkedList<IEventTaskInstance> eventlist; 
    12                  
    13                 public LinkedList<IEventTaskInstance> getEventlist() { 
    14                         return eventlist; 
     9public class EventTaskInstancesListGenerator extends 
     10                DefaultTaskTraversingVisitor { 
     11 
     12        private LinkedList<IEventTaskInstance> eventlist; 
     13 
     14        public EventTaskInstancesListGenerator() { 
     15                eventlist = new LinkedList<IEventTaskInstance>(); 
     16        } 
     17 
     18        public LinkedList<IEventTaskInstance> getEventlist() { 
     19                return eventlist; 
     20        } 
     21 
     22        public void setEventlist(LinkedList<IEventTaskInstance> eventlist) { 
     23                this.eventlist = eventlist; 
     24        } 
     25 
     26        @Override 
     27        public void visit(IEventTask eventTask) { 
     28                if (eventTask.getInstances().size() > 0) { 
     29                        final IEventTaskInstance eti = (IEventTaskInstance) eventTask 
     30                                        .getInstances().iterator().next(); 
     31                        // System.out.println("Adding eventtaskinstance to list: " + eti); 
     32                        eventlist.add(eti); 
    1533                } 
     34        } 
    1635 
    17                 public void setEventlist(LinkedList<IEventTaskInstance> eventlist) { 
    18                         this.eventlist = eventlist; 
    19                 } 
    20  
    21                 @Override 
    22             public void visit(IEventTask eventTask) { 
    23                         if(eventTask.getInstances().size() > 0) { 
    24                                 IEventTaskInstance eti = (IEventTaskInstance) eventTask.getInstances().iterator().next(); 
    25                                 //System.out.println("Adding eventtaskinstance to list: " + eti); 
    26                                 eventlist.add(eti); 
    27                         } 
    28             } 
    29           
    30                 public EventTaskInstancesListGenerator() { 
    31                         eventlist = new LinkedList<IEventTaskInstance>();        
    32                 } 
    33          
    3436} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/ITriangleMatrix.java

    r1702 r1733  
    33public interface ITriangleMatrix { 
    44 
    5         //Increases the size 
     5        public abstract float get(int first, int second); 
     6 
     7        // Increases the size 
    68        public abstract void increaseSize(int count) throws Exception; 
    79 
    8         public abstract float get(int first, int second); 
     10        public abstract void initialize(float value); 
    911 
    1012        public abstract void set(int first, int second, float value); 
    1113 
    12         public abstract void initialize(float value); 
     14        public abstract int size(); 
    1315 
     16        @Override 
    1417        public abstract String toString(); 
    1518 
    16         public abstract int size(); 
    17  
    1819} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/NearbySubstitutionMatrix.java

    r1702 r1733  
    1515public class NearbySubstitutionMatrix implements SubstitutionMatrix { 
    1616 
    17         private int[] input1; 
    18         private int[] input2; 
    19         private int range; 
    20          
    21         public NearbySubstitutionMatrix(int[] input1,int[] input2, int range) { 
     17        private final int[] input1; 
     18        private final int[] input2; 
     19        private final int range; 
     20 
     21        public NearbySubstitutionMatrix(int[] input1, int[] input2, int range) { 
    2222                this.input1 = input1; 
    2323                this.input2 = input2; 
    2424                this.range = range; 
    2525        } 
    26          
    27         /* (non-Javadoc) 
    28          * @see de.ugoe.cs.autoquest.plugin.alignment.SubstitutionMatrix#getDistance(int, int) 
    29          */ 
    30         public float getScore(int pos1, int pos2) { 
    31                 int difference = Math.abs(input1[pos1]-input2[pos2]);  
    32                 if(difference < range) { 
    33                         return range-difference; 
    34                 } 
    35                 else { 
    36                         return -range; 
    37                 } 
    38         } 
    39  
    40  
    41         @Override 
    42         public float getGapPenalty() { 
    43                 return -range-1; 
    44         } 
    45  
    46  
    4726 
    4827        @Override 
     
    5130 
    5231        @Override 
     32        public float getGapPenalty() { 
     33                return -range - 1; 
     34        } 
     35 
     36        /* 
     37         * (non-Javadoc) 
     38         *  
     39         * @see 
     40         * de.ugoe.cs.autoquest.plugin.alignment.SubstitutionMatrix#getDistance(int, 
     41         * int) 
     42         */ 
     43        @Override 
     44        public float getScore(int pos1, int pos2) { 
     45                final int difference = Math.abs(input1[pos1] - input2[pos2]); 
     46                if (difference < range) { 
     47                        return range - difference; 
     48                } else { 
     49                        return -range; 
     50                } 
     51        } 
     52 
     53        @Override 
    5354        public void update(LinkedList<ITask> newlyGeneratedTasks) { 
    5455        } 
    5556 
    56          
    57  
    5857} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/ObjectDistanceSubstitionMatrix.java

    r1711 r1733  
    1717import de.ugoe.cs.util.console.Console; 
    1818 
    19  
    20  
    21 public class ObjectDistanceSubstitionMatrix implements SubstitutionMatrix,Serializable { 
     19public class ObjectDistanceSubstitionMatrix implements SubstitutionMatrix, 
     20                Serializable { 
    2221 
    2322        /** 
     
    2524         */ 
    2625        private static final long serialVersionUID = -4253258274617754083L; 
    27         private HashMap<Integer, Integer> idmapping; 
     26        private final HashMap<Integer, Integer> idmapping; 
    2827        private ITriangleMatrix matrix; 
    2928        private HashSet<ITask> uniqueTasks; 
    3029        private float gapPenalty; 
    3130        private int index = 0; 
    32         private HashMap<Integer, LinkedList<IEventTaskInstance>> etisOfTasks; 
     31        private final HashMap<Integer, LinkedList<IEventTaskInstance>> etisOfTasks; 
    3332        private boolean calculateNonTaskInstances = true; 
    3433        private int firstRoundMaxIndex = 0; 
    3534 
    36         private double positiveThreshold; 
    37  
    38         public ObjectDistanceSubstitionMatrix( 
    39                 float positiveThreshold, int gapPenalty, 
    40                 boolean calculateNonTaskInstances) { 
     35        private final double positiveThreshold; 
     36 
     37        public ObjectDistanceSubstitionMatrix(float positiveThreshold, 
     38                        int gapPenalty, boolean calculateNonTaskInstances) { 
    4139                this.positiveThreshold = positiveThreshold; 
    4240                idmapping = new HashMap<Integer, Integer>(); 
     
    4543                this.calculateNonTaskInstances = calculateNonTaskInstances; 
    4644 
    47         } 
    48  
    49         public float getGapPenalty() { 
    50                 return gapPenalty; 
    51         } 
    52  
    53         public void setGapPenalty(float gapPenalty) { 
    54                 this.gapPenalty = gapPenalty; 
    55         } 
    56  
    57         //TODO: Merge this with updateEventTaskInstances 
    58         private void searchEventTaskInstances() { 
    59                 for (Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { 
    60                         ITask task = it.next(); 
    61                         if (!(task instanceof IEventTask)) { 
    62                                 EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); 
    63                                 task.accept(etlg); 
    64                                 LinkedList<IEventTaskInstance> eventTaskInstances = etlg 
    65                                                 .getEventlist(); 
    66                                 etisOfTasks.put(task.getId(), eventTaskInstances); 
    67                         } 
    68                 } 
    69         } 
    70          
    71         public void updateEventTaskInstances(LinkedList<ITask> newTasks){ 
    72                 for (Iterator<ITask> it = newTasks.iterator();it.hasNext();) { 
    73                         ITask task = it.next(); 
    74                         if (!(task instanceof IEventTask)) { 
    75                                 EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); 
    76                                 task.accept(etlg); 
    77                                 LinkedList<IEventTaskInstance> eventTaskInstances = etlg 
    78                                                 .getEventlist(); 
    79                                 etisOfTasks.put(task.getId(), eventTaskInstances); 
    80                         } 
    81                 } 
    82         } 
    83          
    84         //Just Calculate the distance between the new tasks and the matrix. 
    85         public void update(LinkedList<ITask> newTasks) { 
    86  
    87                 if (this.calculateNonTaskInstances) { 
    88                         try { 
    89                                 matrix.increaseSize(newTasks.size()); 
    90                                 System.out.println("Subsitution matrix size is now " + matrix.size()*(matrix.size()+1)/2); 
    91                                 Console.traceln(Level.INFO, "searching EventTasks in Tasks"); 
    92                         } catch (Exception e) { 
    93                                 Console.logException(e); 
    94                         } 
    95                         this.updateEventTaskInstances(newTasks); 
    96                         for(Iterator<ITask> it = newTasks.iterator();it.hasNext();) { 
    97                                 ITask task1 = it.next(); 
    98                                 for (Iterator<ITask> jt = uniqueTasks.iterator(); jt.hasNext();) { 
    99                                         ITask task2 = jt.next(); 
    100                                         computeDistance(task1,task2); 
    101                                 } 
    102                         } 
    103                 } 
    10445        } 
    10546 
     
    11253                // We just need to the first instance here 
    11354                if (task1.getInstances().size() > 0) { 
    114                         ti1 = (ITaskInstance) task1.getInstances().iterator() 
    115                                         .next(); 
     55                        ti1 = task1.getInstances().iterator().next(); 
    11656                } 
    11757                if (task2.getInstances().size() > 0) { 
    118                         ti2 = (ITaskInstance) task2.getInstances().iterator() 
    119                                         .next(); 
     58                        ti2 = task2.getInstances().iterator().next(); 
    12059                } 
    12160                IEventTaskInstance eti1 = null; 
    12261                IEventTaskInstance eti2 = null; 
    12362 
    124                 if (ti1 instanceof IEventTaskInstance 
    125                                 && ti2 instanceof IEventTaskInstance) { 
     63                if ((ti1 instanceof IEventTaskInstance) 
     64                                && (ti2 instanceof IEventTaskInstance)) { 
    12665                        eti1 = (IEventTaskInstance) ti1; 
    12766                        index1 = getIndex(eti1); 
     
    12968                        index2 = getIndex(eti2); 
    13069                        distance = distanceBetweenInstances(eti1, eti2); 
    131                 } else if (ti1 instanceof IEventTaskInstance 
     70                } else if ((ti1 instanceof IEventTaskInstance) 
    13271                                && !(ti2 instanceof IEventTaskInstance)) { 
    133                         task1 = ((ITaskInstance) ti1).getTask(); 
     72                        task1 = ti1.getTask(); 
    13473                        index2 = getIndex(task2); 
    13574                        eti1 = (IEventTaskInstance) ti1; 
     
    13776                        distance = distanceBetweenTaskAndInstance(task2, eti1); 
    13877                } else if (!(ti1 instanceof IEventTaskInstance) 
    139                                 && ti2 instanceof IEventTaskInstance) { 
     78                                && (ti2 instanceof IEventTaskInstance)) { 
    14079                        index1 = getIndex(task1); 
    14180                        eti2 = (IEventTaskInstance) ti2; 
     
    15291                matrix.set(index1, index2, distance); 
    15392        } 
    154          
    155          
     93 
     94        private float distanceBetweenInstances(IEventTaskInstance eti1, 
     95                        IEventTaskInstance eti2) { 
     96                final IGUIElement first = (IGUIElement) eti1.getEvent().getTarget(); 
     97                final IGUIElement second = (IGUIElement) eti2.getEvent().getTarget(); 
     98                float distance = -1 * AlignmentHelpers.distanceBetween(first, second); 
     99                distance += positiveThreshold; 
     100                return distance; 
     101        } 
     102 
     103        private float distanceBetweenTaskAndInstance(ITask task1, 
     104                        IEventTaskInstance eti1) { 
     105                if (this.calculateNonTaskInstances) { 
     106                        float tmpDistance = 0; 
     107                        // System.out.println(etisOfTasks); 
     108                        final LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks 
     109                                        .get(task1.getId()); 
     110                        for (final Iterator<IEventTaskInstance> it = eventTaskInstances 
     111                                        .iterator(); it.hasNext();) { 
     112                                final IEventTaskInstance eti2 = it.next(); 
     113                                // int taskId1 = eti1.getTask().getId(); 
     114                                // int taskId2 = eti2.getTask().getId(); 
     115                                // if (scoreExists(taskId1, taskId2)) { 
     116                                // tmpDistance += getScore(taskId1, taskId2); 
     117                                // } else { 
     118                                final float dist = distanceBetweenInstances(eti1, eti2); 
     119                                matrix.set(getIndex(eti1), getIndex(eti2), dist); 
     120                                tmpDistance += dist; 
     121                                // } 
     122                        } 
     123                        return tmpDistance / eventTaskInstances.size(); 
     124                } else { 
     125                        return 0; 
     126                } 
     127        } 
     128 
     129        private float distanceBetweenTasks(ITask task1, ITask task2) { 
     130                if (this.calculateNonTaskInstances) { 
     131                        final LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks 
     132                                        .get(task1.getId()); 
     133                        float tmpDistance = 0; 
     134                        for (final Iterator<IEventTaskInstance> it = eventTaskInstances 
     135                                        .iterator(); it.hasNext();) { 
     136                                final IEventTaskInstance eti1 = it.next(); 
     137                                tmpDistance += distanceBetweenTaskAndInstance(task2, eti1); 
     138                        } 
     139 
     140                        return tmpDistance / eventTaskInstances.size(); 
     141                } else { 
     142                        return 0; 
     143                } 
     144        } 
     145 
     146        @Override 
    156147        public void generate(HashSet<ITask> uniqueTasks) { 
    157148                this.uniqueTasks = uniqueTasks; 
     
    160151                        Console.traceln(Level.INFO, "searching EventTasks in Tasks"); 
    161152                        searchEventTaskInstances(); 
    162                 } 
    163                 else{ 
    164                         matrix = new StaticTriangleMatrix(uniqueTasks.size()+1); 
     153                } else { 
     154                        matrix = new StaticTriangleMatrix(uniqueTasks.size() + 1); 
    165155                } 
    166156                matrix.initialize(0); 
    167                        
    168                 int count=0; 
    169                 int size=uniqueTasks.size(); 
    170                 for (Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { 
    171                         ITask task1 = it.next(); 
     157 
     158                int count = 0; 
     159                final int size = uniqueTasks.size(); 
     160                for (final Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { 
     161                        final ITask task1 = it.next(); 
    172162                        count++; 
    173                         if((count%(size/100)==0)) { 
    174                                 Console.traceln(Level.INFO,(Math.round((float) count/size*100))+ "%"); 
    175                         } 
    176                         for (Iterator<ITask> jt = uniqueTasks.iterator(); jt.hasNext();) { 
    177                                 ITask task2 = jt.next(); 
    178                                 computeDistance(task1,task2); 
    179                         } 
    180                 } 
    181                 this.firstRoundMaxIndex=index; 
    182         } 
    183          
    184                  
    185  
    186          
    187          
    188  
    189         private float distanceBetweenTaskAndInstance(ITask task1, 
    190                         IEventTaskInstance eti1) { 
    191                 if (this.calculateNonTaskInstances) { 
    192                         float tmpDistance = 0; 
    193                         //System.out.println(etisOfTasks); 
    194                         LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks 
    195                                         .get(task1.getId()); 
    196                         for (Iterator<IEventTaskInstance> it = eventTaskInstances 
    197                                         .iterator(); it.hasNext();) { 
    198                                 IEventTaskInstance eti2 = it.next(); 
    199                                 //int taskId1 = eti1.getTask().getId(); 
    200                                 //int taskId2 = eti2.getTask().getId(); 
    201                                 //if (scoreExists(taskId1, taskId2)) { 
    202                                 //      tmpDistance += getScore(taskId1, taskId2); 
    203                                 //} else { 
    204                                         float dist = distanceBetweenInstances(eti1, eti2); 
    205                                         matrix.set(getIndex(eti1), getIndex(eti2), dist); 
    206                                         tmpDistance += dist; 
    207                                 //} 
    208                         } 
    209                         return tmpDistance / eventTaskInstances.size(); 
    210                 } else { 
    211                         return 0; 
    212                 } 
    213         } 
    214  
    215         //public boolean scoreExists(int id, int id2) { 
    216                 //return idmapping.containsKey(id) && idmapping.containsKey(id2); 
    217         //      return false; 
    218         //} 
    219  
    220         private float distanceBetweenTasks(ITask task1, ITask task2) { 
    221                 if (this.calculateNonTaskInstances) { 
    222                         LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks 
    223                                         .get(task1.getId()); 
    224                         float tmpDistance = 0; 
    225                         for (Iterator<IEventTaskInstance> it = eventTaskInstances 
    226                                         .iterator(); it.hasNext();) { 
    227                                 IEventTaskInstance eti1 = it.next(); 
    228                                 tmpDistance += distanceBetweenTaskAndInstance(task2, eti1); 
    229                         } 
    230  
    231                         return tmpDistance / eventTaskInstances.size(); 
    232                 } else { 
    233                         return 0; 
    234                 } 
    235         } 
    236  
    237         synchronized private int getIndex(ITask task) { 
    238                 int tempindex = -1; 
    239  
    240                 if (!idmapping.containsKey(task.getId())) { 
    241                          
    242                         idmapping.put(task.getId(), index); 
    243                         tempindex = index; 
    244                         index++; 
    245                 } else { 
    246                         tempindex = idmapping.get(task.getId()); 
    247                 } 
    248  
    249                 return tempindex; 
     163                        if (((count % (size / 100)) == 0)) { 
     164                                Console.traceln(Level.INFO, 
     165                                                (Math.round(((float) count / size) * 100)) + "%"); 
     166                        } 
     167                        for (final Iterator<ITask> jt = uniqueTasks.iterator(); jt 
     168                                        .hasNext();) { 
     169                                final ITask task2 = jt.next(); 
     170                                computeDistance(task1, task2); 
     171                        } 
     172                } 
     173                this.firstRoundMaxIndex = index; 
     174        } 
     175 
     176        @Override 
     177        public float getGapPenalty() { 
     178                return gapPenalty; 
    250179        } 
    251180 
     
    260189                } 
    261190                return tempindex; 
     191        } 
     192 
     193        synchronized private int getIndex(ITask task) { 
     194                int tempindex = -1; 
     195 
     196                if (!idmapping.containsKey(task.getId())) { 
     197 
     198                        idmapping.put(task.getId(), index); 
     199                        tempindex = index; 
     200                        index++; 
     201                } else { 
     202                        tempindex = idmapping.get(task.getId()); 
     203                } 
     204 
     205                return tempindex; 
     206        } 
     207 
     208        // public boolean scoreExists(int id, int id2) { 
     209        // return idmapping.containsKey(id) && idmapping.containsKey(id2); 
     210        // return false; 
     211        // } 
     212 
     213        @Override 
     214        public float getScore(int taskId1, int taskId2) { 
     215                if ((taskId1 == Constants.GAP_SYMBOL) 
     216                                || (taskId1 == Constants.UNMATCHED_SYMBOL) 
     217                                || (taskId2 == Constants.GAP_SYMBOL) 
     218                                || (taskId2 == Constants.UNMATCHED_SYMBOL)) { 
     219                        return 0; 
     220                } else if ((this.calculateNonTaskInstances == false) 
     221                                && ((taskId1 > this.firstRoundMaxIndex) || (taskId2 > this.firstRoundMaxIndex))) { 
     222                        return 0; 
     223                } else { 
     224                        final Integer first = idmapping.get(taskId1); 
     225                        final Integer second = idmapping.get(taskId2); 
     226                        return matrix.get(first, second); 
     227                } 
     228 
     229        } 
     230 
     231        // TODO: Merge this with updateEventTaskInstances 
     232        private void searchEventTaskInstances() { 
     233                for (final Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { 
     234                        final ITask task = it.next(); 
     235                        if (!(task instanceof IEventTask)) { 
     236                                final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); 
     237                                task.accept(etlg); 
     238                                final LinkedList<IEventTaskInstance> eventTaskInstances = etlg 
     239                                                .getEventlist(); 
     240                                etisOfTasks.put(task.getId(), eventTaskInstances); 
     241                        } 
     242                } 
     243        } 
     244 
     245        public void setGapPenalty(float gapPenalty) { 
     246                this.gapPenalty = gapPenalty; 
    262247        }; 
    263248 
    264         private float distanceBetweenInstances(IEventTaskInstance eti1, 
    265                         IEventTaskInstance eti2) { 
    266                 IGUIElement first = (IGUIElement) eti1.getEvent().getTarget(); 
    267                 IGUIElement second = (IGUIElement) eti2.getEvent().getTarget(); 
    268                 float distance = -1 * AlignmentHelpers.distanceBetween(first, second); 
    269                 distance += positiveThreshold; 
    270                 return distance; 
    271         } 
    272  
     249        @Override 
    273250        public String toString() { 
    274251                return matrix.toString(); 
    275252        } 
    276253 
    277         public float getScore(int taskId1, int taskId2) { 
    278                 if (taskId1 == Constants.GAP_SYMBOL 
    279                                 || taskId1 == Constants.UNMATCHED_SYMBOL 
    280                                 || taskId2 == Constants.GAP_SYMBOL 
    281                                 || taskId2 == Constants.UNMATCHED_SYMBOL) { 
    282                         return 0; 
    283                 } else if(this.calculateNonTaskInstances==false &&       
    284                                 (taskId1>this.firstRoundMaxIndex 
    285                                 || taskId2>this.firstRoundMaxIndex)) { 
    286                         return 0; 
    287                 } else { 
    288                         Integer first = idmapping.get(taskId1); 
    289                         Integer second = idmapping.get(taskId2); 
    290                         return matrix.get(first, second); 
    291                 } 
    292  
     254        // Just Calculate the distance between the new tasks and the matrix. 
     255        @Override 
     256        public void update(LinkedList<ITask> newTasks) { 
     257 
     258                if (this.calculateNonTaskInstances) { 
     259                        try { 
     260                                matrix.increaseSize(newTasks.size()); 
     261                                System.out.println("Subsitution matrix size is now " 
     262                                                + ((matrix.size() * (matrix.size() + 1)) / 2)); 
     263                                Console.traceln(Level.INFO, "searching EventTasks in Tasks"); 
     264                        } catch (final Exception e) { 
     265                                Console.logException(e); 
     266                        } 
     267                        this.updateEventTaskInstances(newTasks); 
     268                        for (final Iterator<ITask> it = newTasks.iterator(); it.hasNext();) { 
     269                                final ITask task1 = it.next(); 
     270                                for (final Iterator<ITask> jt = uniqueTasks.iterator(); jt 
     271                                                .hasNext();) { 
     272                                        final ITask task2 = jt.next(); 
     273                                        computeDistance(task1, task2); 
     274                                } 
     275                        } 
     276                } 
     277        } 
     278 
     279        public void updateEventTaskInstances(LinkedList<ITask> newTasks) { 
     280                for (final Iterator<ITask> it = newTasks.iterator(); it.hasNext();) { 
     281                        final ITask task = it.next(); 
     282                        if (!(task instanceof IEventTask)) { 
     283                                final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); 
     284                                task.accept(etlg); 
     285                                final LinkedList<IEventTaskInstance> eventTaskInstances = etlg 
     286                                                .getEventlist(); 
     287                                etisOfTasks.put(task.getId(), eventTaskInstances); 
     288                        } 
     289                } 
    293290        } 
    294291} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/StaticTriangleMatrix.java

    r1707 r1733  
    33import java.io.Serializable; 
    44 
    5 public class StaticTriangleMatrix implements ITriangleMatrix,Serializable { 
    6          
     5public class StaticTriangleMatrix implements ITriangleMatrix, Serializable { 
     6 
    77        /** 
    88         *  
    99         */ 
    1010        private static final long serialVersionUID = 7599542322424894866L; 
    11         private float[] matrix; 
     11        private final float[] matrix; 
    1212        protected int size; 
    13          
    14          
     13 
    1514        public StaticTriangleMatrix(int size) { 
    1615                this.size = size; 
    17                 matrix = new float [size*(size+1)/2]; 
    18         } 
    19          
    20         public float get(int first, int second) { 
    21                 int row = Math.min(first, second); 
    22                 int col = Math.max(first, second); 
    23                 return matrix[row*size-(row*(row+1)/2 - (size-col))]; 
    24                  
    25         } 
    26          
    27         public void set(int first, int second, float value) { 
    28                 int row = Math.min(first, second); 
    29                 int col = Math.max(first, second); 
    30                 matrix[row*size-(row*(row+1)/2 - (size-col))] = value; 
     16                matrix = new float[(size * (size + 1)) / 2]; 
    3117        } 
    3218 
     19        @Override 
     20        public float get(int first, int second) { 
     21                final int row = Math.min(first, second); 
     22                final int col = Math.max(first, second); 
     23                return matrix[(row * size) - (((row * (row + 1)) / 2) - (size - col))]; 
     24 
     25        } 
     26 
     27        @Override 
     28        public void increaseSize(int count) throws Exception { 
     29                throw new Exception( 
     30                                "Cannot call this function on this implementation of ITriangle Matrix"); 
     31 
     32        } 
     33 
     34        @Override 
    3335        public void initialize(float value) { 
    34                 for (int i=0; i < matrix.length; i++) { 
     36                for (int i = 0; i < matrix.length; i++) { 
    3537                        matrix[i] = value; 
    3638                } 
    3739        } 
    38          
    3940 
    40          
     41        @Override 
     42        public void set(int first, int second, float value) { 
     43                final int row = Math.min(first, second); 
     44                final int col = Math.max(first, second); 
     45                matrix[(row * size) - (((row * (row + 1)) / 2) - (size - col))] = value; 
     46        } 
     47 
     48        @Override 
     49        public int size() { 
     50                return size; 
     51        } 
     52 
     53        @Override 
    4154        public String toString() { 
    4255                String result = ""; 
    4356                for (int i = 0; i < size; i++) { 
    44                         for(int j = 0; j< size; j++) { 
    45                                 if(i<j) { 
    46                                         if(Float.isInfinite(this.get(i,j))) { 
     57                        for (int j = 0; j < size; j++) { 
     58                                if (i < j) { 
     59                                        if (Float.isInfinite(this.get(i, j))) { 
    4760                                                result = result + " -------"; 
     61                                        } else { 
     62                                                result = result 
     63                                                                + String.format("%+8.2f", this.get(i, j)); 
    4864                                        } 
    49                                         else { 
    50                                                 result = result + String.format("%+8.2f",this.get(i,j)); 
    51                                         } 
    52                                 } 
    53                                 else { 
     65                                } else { 
    5466                                        result = result + ("        "); 
    5567                                } 
     
    5971                return result; 
    6072        } 
    61  
    62         @Override 
    63         public void increaseSize(int count) throws Exception { 
    64                 throw new Exception("Cannot call this function on this implementation of ITriangle Matrix"); 
    65                  
    66         } 
    67  
    68         @Override 
    69         public int size() { 
    70                 return size; 
    71         } 
    7273} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/SubstitutionMatrix.java

    r1702 r1733  
    66import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    77 
     8public interface SubstitutionMatrix { 
    89 
     10        public void generate(HashSet<ITask> uniqueTasks); 
    911 
    10 public interface SubstitutionMatrix { 
    11          
     12        public float getGapPenalty(); 
    1213 
    1314        public float getScore(int pos1, int pos2); 
    1415 
    15         public float getGapPenalty(); 
    16  
    17         public void generate(HashSet<ITask> uniqueTasks); 
    18          
    1916        public void update(LinkedList<ITask> newlyGeneratedTasks); 
    2017 
    21          
    2218} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/UPGMAMatrix.java

    r1702 r1733  
    11package de.ugoe.cs.autoquest.tasktrees.alignment.matrix; 
    2  
    3  
    42 
    53public class UPGMAMatrix extends StaticTriangleMatrix { 
     
    97        } 
    108 
     9        @Override 
    1110        public int size() { 
    1211                return size; 
    1312        } 
    1413 
     14        @Override 
    1515        public String toString() { 
    1616                String result = ""; 
     
    1919                } 
    2020                result += "\n"; 
    21                  
     21 
    2222                for (int i = 0; i < size; i++) { 
    23                         for(int j = 0; j< size; j++) { 
    24                                 if(i<j) { 
    25                                         if(Double.isInfinite(this.get(i,j))) { 
     23                        for (int j = 0; j < size; j++) { 
     24                                if (i < j) { 
     25                                        if (Double.isInfinite(this.get(i, j))) { 
    2626                                                result = result + " -------"; 
     27                                        } else { 
     28                                                result = result 
     29                                                                + String.format("%+8.2f", this.get(i, j)); 
    2730                                        } 
    28                                         else { 
    29                                                 result = result + String.format("%+8.2f",this.get(i,j)); 
    30                                         } 
    31                                 } 
    32                                 else { 
     31                                } else { 
    3332                                        result = result + ("        "); 
    3433                                } 
     
    3938        } 
    4039 
    41          
    42  
    4340} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/ComponentManager.java

    r1189 r1733  
    2323/** 
    2424 * <p> 
    25  * The component manager is the central reference for the distinct submodules required for 
    26  * task tree generation. Such include the temporal relationship rule manager, the task equality 
    27  * rule manager, the default task builder, as well as the default task factory. 
     25 * The component manager is the central reference for the distinct submodules 
     26 * required for task tree generation. Such include the temporal relationship 
     27 * rule manager, the task equality rule manager, the default task builder, as 
     28 * well as the default task factory. 
    2829 * </p> 
    2930 *  
     
    3233 */ 
    3334public class ComponentManager { 
    34      
    35     /** 
    36      * <p> 
    37      * singleton instance of this class 
    38      * </p> 
    39      */ 
    40     private static ComponentManager instance; 
    4135 
    42     /** 
    43      * <p> 
    44      * the default temporal relationship rule manager 
    45      * </p> 
    46      */ 
    47     private TemporalRelationshipRuleManager temporalRelationshipRuleManager; 
     36        /** 
     37         * <p> 
     38         * clears the singleton instance. Needed for test purposes to ensure 
     39         * statelessness between tests. 
     40         * </p> 
     41         */ 
     42        public static synchronized void clearInstance() { 
     43                instance = null; 
     44        } 
    4845 
    49     /** 
    50      * <p> 
    51      * the default task builder 
    52      * </p> 
    53      */ 
    54     private ITaskBuilder taskBuilder; 
     46        /** 
     47         * <p> 
     48         * returns the default task builder 
     49         * </p> 
     50         *  
     51         * @return as described 
     52         */ 
     53        public static ITaskBuilder getDefaultTaskBuilder() { 
     54                return getInstance().taskBuilder; 
     55        } 
    5556 
    56     /** 
    57      * <p> 
    58      * the default task factory 
    59      * </p> 
    60      */ 
    61     private ITaskFactory taskFactory; 
     57        /** 
     58         * <p> 
     59         * returns the default task factory 
     60         * </p> 
     61         *  
     62         * @return as described 
     63         */ 
     64        public static ITaskFactory getDefaultTaskFactory() { 
     65                return getInstance().taskFactory; 
     66        } 
    6267 
    63     /** 
    64      * <p> 
    65      * returns the default temporal relationship rule manager 
    66      * </p> 
    67      *  
    68      * @return as described 
    69      */ 
    70     public static TemporalRelationshipRuleManager getTemporalRelationshipRuleManager() { 
    71         return getInstance().temporalRelationshipRuleManager; 
    72     } 
     68        /** 
     69         * <p> 
     70         * returns the singleton instance of this class 
     71         * </p> 
     72         *  
     73         * @return as described 
     74         */ 
     75        private static synchronized ComponentManager getInstance() { 
     76                if (instance == null) { 
     77                        instance = new ComponentManager(); 
     78                        instance.init(); 
     79                } 
     80                return instance; 
     81        } 
    7382 
    74     /** 
    75     * <p> 
    76      * returns the default task builder 
    77     * </p> 
    78     *  
    79     * @return as described 
    80     */ 
    81     public static ITaskBuilder getDefaultTaskBuilder() { 
    82         return getInstance().taskBuilder; 
    83     } 
     83        /** 
     84        * <p> 
     85         * returns the default temporal relationship rule manager 
     86        * </p> 
     87        *  
     88        * @return as described 
     89        */ 
     90        public static TemporalRelationshipRuleManager getTemporalRelationshipRuleManager() { 
     91                return getInstance().temporalRelationshipRuleManager; 
     92        } 
    8493 
    85     /** 
    86      * <p> 
    87      * returns the default task factory 
    88      * </p> 
    89      *  
    90      * @return as described 
    91      */ 
    92     public static ITaskFactory getDefaultTaskFactory() { 
    93         return getInstance().taskFactory; 
    94     } 
     94        /** 
     95         * <p> 
     96         * singleton instance of this class 
     97         * </p> 
     98         */ 
     99        private static ComponentManager instance; 
    95100 
    96     /** 
    97      * <p> 
    98      * clears the singleton instance. Needed for test purposes to ensure statelessness between 
    99      * tests. 
    100      * </p> 
    101      */ 
    102     public static synchronized void clearInstance() { 
    103         instance = null; 
    104     } 
     101        /** 
     102         * <p> 
     103         * the default temporal relationship rule manager 
     104         * </p> 
     105         */ 
     106        private TemporalRelationshipRuleManager temporalRelationshipRuleManager; 
    105107 
    106     /** 
    107      * <p> 
    108      * returns the singleton instance of this class 
    109      * </p> 
    110      *  
    111      * @return as described 
    112      */ 
    113     private static synchronized ComponentManager getInstance() { 
    114         if (instance == null) { 
    115             instance = new ComponentManager(); 
    116             instance.init(); 
    117         } 
    118         return instance; 
    119     } 
     108        /** 
     109         * <p> 
     110         * the default task builder 
     111         * </p> 
     112         */ 
     113        private ITaskBuilder taskBuilder; 
    120114 
    121     /** 
    122      * <p> 
    123      * initialized the component manager with all it default components which are the temporal 
    124      * relationship rule manager, the task equality rule manager, the default task builder, as 
    125      * well as the default task factory.  
    126      * </p> 
    127      */ 
    128     private void init() { 
    129         taskBuilder = new TaskBuilder(); 
    130         taskFactory = new TaskFactory(); 
     115        /** 
     116         * <p> 
     117         * the default task factory 
     118         * </p> 
     119         */ 
     120        private ITaskFactory taskFactory; 
    131121 
    132         temporalRelationshipRuleManager = 
    133             new TemporalRelationshipRuleManager(taskFactory, taskBuilder); 
    134         temporalRelationshipRuleManager.init(); 
    135     } 
     122        /** 
     123         * <p> 
     124         * initialized the component manager with all it default components which 
     125         * are the temporal relationship rule manager, the task equality rule 
     126         * manager, the default task builder, as well as the default task factory. 
     127         * </p> 
     128         */ 
     129        private void init() { 
     130                taskBuilder = new TaskBuilder(); 
     131                taskFactory = new TaskFactory(); 
     132 
     133                temporalRelationshipRuleManager = new TemporalRelationshipRuleManager( 
     134                                taskFactory, taskBuilder); 
     135                temporalRelationshipRuleManager.init(); 
     136        } 
    136137 
    137138} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/TaskTreeManager.java

    r1397 r1733  
    3030/** 
    3131 * <p> 
    32  * The task tree manager is responsible for transforming one or more user sessions into a task 
    33  * model. It can be called by providing a collection of user sessions where the result 
    34  * will be a task model. Furthermore, it can be used by providing single events in their respective 
    35  * order including notifications about where a user session ends. The result is a task model, 
    36  * as well.  
     32 * The task tree manager is responsible for transforming one or more user 
     33 * sessions into a task model. It can be called by providing a collection of 
     34 * user sessions where the result will be a task model. Furthermore, it can be 
     35 * used by providing single events in their respective order including 
     36 * notifications about where a user session ends. The result is a task model, as 
     37 * well. 
    3738 * </p> 
    3839 *  
     
    4142 */ 
    4243public class TaskTreeManager { 
    43      
    44     /** 
    45      * <p> 
    46      * the internally used task builder 
    47      * </p> 
    48      */ 
    49     private ITaskBuilder taskBuilder = ComponentManager.getDefaultTaskBuilder(); 
    5044 
    51     /** 
    52      * <p> 
    53      * the internally used task factory 
    54      * </p> 
    55      */ 
    56     private ITaskFactory taskFactory = ComponentManager.getDefaultTaskFactory(); 
     45        /** 
     46         * <p> 
     47         * the internally used task builder 
     48         * </p> 
     49         */ 
     50        private final ITaskBuilder taskBuilder = ComponentManager 
     51                        .getDefaultTaskBuilder(); 
    5752 
    58     /** 
    59      * <p> 
    60      * if single events are provided, the user sessions collected so far 
    61      * </p> 
    62      */ 
    63     private List<IUserSession> sessions = null; 
     53        /** 
     54         * <p> 
     55         * the internally used task factory 
     56         * </p> 
     57         */ 
     58        private final ITaskFactory taskFactory = ComponentManager 
     59                        .getDefaultTaskFactory(); 
    6460 
    65     /** 
    66     * <p> 
    67      * if single events are provided, the currently collected user session 
    68     * </p> 
    69     */ 
    70     private IUserSession currentSession = null; 
     61        /** 
     62        * <p> 
     63         * if single events are provided, the user sessions collected so far 
     64        * </p> 
     65        */ 
     66        private List<IUserSession> sessions = null; 
    7167 
    72     /** 
    73      * <p> 
    74      * initializes the task tree manager 
    75      * </p> 
    76      */ 
    77     public TaskTreeManager() { 
    78         sessions = new LinkedList<IUserSession>(); 
    79     } 
     68        /** 
     69         * <p> 
     70         * if single events are provided, the currently collected user session 
     71         * </p> 
     72         */ 
     73        private IUserSession currentSession = null; 
    8074 
    81     /** 
    82      * <p> 
    83      * creates a task model based on the provided user sessions. Yet, the user sessions are 
    84      * list of events. Such will be transformed in into task instances of event tasks assigned 
    85      * to {@link IUserSession}s. The {@link IUserSession}s will then be restructured using 
    86      * the temporal relationship rule manager to detect tasks and respective instances. The 
    87      * results of this transformation is stored in a task model which is the return value of 
    88      * this method. 
    89      * </p> 
    90      *  
    91      * @param newSessions the user sessions of which the task model shall be created 
    92      *  
    93      * @return the task model created from the user sessions 
    94      *  
    95      * @throws IllegalStateException if the task manager is already used by providing it with 
    96      *                               single events 
    97      */ 
    98     public synchronized ITaskModel createTaskModel(Collection<List<Event>> newSessions) { 
    99         if ((currentSession != null) || (sessions.size() > 0)) { 
    100             throw new IllegalStateException("do not mix calls to this method with calls to the " + 
    101                                             "other methods for handling tasks. Use only one " + 
    102                                             "variant instead."); 
    103         } 
    104          
    105         for (List<Event> newSession : newSessions) { 
    106             if (newSession.size() > 0) { 
    107                 for (Event event : newSession) { 
    108                     handleNewEvent(event); 
    109                 } 
    110                 finishSession(); 
    111             } 
    112         } 
    113          
    114         return getTaskModel(); 
    115     } 
     75        /** 
     76         * <p> 
     77         * initializes the task tree manager 
     78         * </p> 
     79         */ 
     80        public TaskTreeManager() { 
     81                sessions = new LinkedList<IUserSession>(); 
     82        } 
    11683 
    117     /** 
    118      * <p> 
    119      * handles a single event that occurred in a user session. 
    120      * </p> 
    121      *  
    122      * @param event the event to handle 
    123      */ 
    124     public void handleNewEvent(Event event) { 
    125         assertSessionSequence(); 
    126         String description = event.getType().getName() + " \u21D2 " + event.getTarget(); 
    127         IEventTask eventTask = taskFactory.createNewEventTask(description); 
    128         taskBuilder.addExecutedTask 
    129             (currentSession, taskFactory.createNewTaskInstance(eventTask, event)); 
    130     } 
     84        /** 
     85         * <p> 
     86         * internally asserts that there is a current session to add new events to 
     87         * </p> 
     88         */ 
     89        private void assertSessionSequence() { 
     90                if (currentSession == null) { 
     91                        currentSession = taskFactory.createUserSession(); 
     92                } 
     93        } 
    13194 
    132     /** 
    133      * <p> 
    134      * used to denote, that all previously added events using {@link #handleNewEvent(Event)} 
    135      * belong to the same session and that this session is now complete. All further events 
    136      * will be added to a new session which may be ended using this method, as well. 
    137      * </p> 
    138      */ 
    139     public void finishSession() { 
    140         if ((currentSession != null) && (currentSession.size() > 0)) { 
    141             sessions.add(currentSession); 
    142             currentSession = null; 
    143         } 
    144     } 
     95        /** 
     96         * <p> 
     97         * creates a task model based on the provided user sessions. Yet, the user 
     98         * sessions are list of events. Such will be transformed in into task 
     99         * instances of event tasks assigned to {@link IUserSession}s. The 
     100         * {@link IUserSession}s will then be restructured using the temporal 
     101         * relationship rule manager to detect tasks and respective instances. The 
     102         * results of this transformation is stored in a task model which is the 
     103         * return value of this method. 
     104         * </p> 
     105         *  
     106         * @param newSessions 
     107         *            the user sessions of which the task model shall be created 
     108         *  
     109         * @return the task model created from the user sessions 
     110         *  
     111         * @throws IllegalStateException 
     112         *             if the task manager is already used by providing it with 
     113         *             single events 
     114         */ 
     115        public synchronized ITaskModel createTaskModel( 
     116                        Collection<List<Event>> newSessions) { 
     117                if ((currentSession != null) || (sessions.size() > 0)) { 
     118                        throw new IllegalStateException( 
     119                                        "do not mix calls to this method with calls to the " 
     120                                                        + "other methods for handling tasks. Use only one " 
     121                                                        + "variant instead."); 
     122                } 
    145123 
    146     /** 
    147      * <p> 
    148      * returns the task model, that belongs to the events in the user sessions collected so far. 
    149      * </p> 
    150      *  
    151      * @return the task model 
    152      */ 
    153     public synchronized ITaskModel getTaskModel() { 
    154         finishSession(); 
    155          
    156         Console.traceln(Level.INFO, "applying temporal relationship generation rules"); 
    157          
    158         ComponentManager.getTemporalRelationshipRuleManager().applyRules(sessions); 
     124                for (final List<Event> newSession : newSessions) { 
     125                        if (newSession.size() > 0) { 
     126                                for (final Event event : newSession) { 
     127                                        handleNewEvent(event); 
     128                                } 
     129                                finishSession(); 
     130                        } 
     131                } 
    159132 
    160         return taskFactory.createTaskModel(sessions); 
    161     } 
     133                return getTaskModel(); 
     134        } 
    162135 
    163     /** 
    164      * <p> 
    165      * internally asserts that there is a current session to add new events to 
    166      * </p> 
    167      */ 
    168     private void assertSessionSequence() { 
    169         if (currentSession == null) { 
    170             currentSession = taskFactory.createUserSession(); 
    171         } 
    172     } 
     136        /** 
     137         * <p> 
     138         * used to denote, that all previously added events using 
     139         * {@link #handleNewEvent(Event)} belong to the same session and that this 
     140         * session is now complete. All further events will be added to a new 
     141         * session which may be ended using this method, as well. 
     142         * </p> 
     143         */ 
     144        public void finishSession() { 
     145                if ((currentSession != null) && (currentSession.size() > 0)) { 
     146                        sessions.add(currentSession); 
     147                        currentSession = null; 
     148                } 
     149        } 
     150 
     151        /** 
     152         * <p> 
     153         * returns the task model, that belongs to the events in the user sessions 
     154         * collected so far. 
     155         * </p> 
     156         *  
     157         * @return the task model 
     158         */ 
     159        public synchronized ITaskModel getTaskModel() { 
     160                finishSession(); 
     161 
     162                Console.traceln(Level.INFO, 
     163                                "applying temporal relationship generation rules"); 
     164 
     165                ComponentManager.getTemporalRelationshipRuleManager().applyRules( 
     166                                sessions); 
     167 
     168                return taskFactory.createTaskModel(sessions); 
     169        } 
     170 
     171        /** 
     172         * <p> 
     173         * handles a single event that occurred in a user session. 
     174         * </p> 
     175         *  
     176         * @param event 
     177         *            the event to handle 
     178         */ 
     179        public void handleNewEvent(Event event) { 
     180                assertSessionSequence(); 
     181                final String description = event.getType().getName() + " \u21D2 " 
     182                                + event.getTarget(); 
     183                final IEventTask eventTask = taskFactory 
     184                                .createNewEventTask(description); 
     185                taskBuilder.addExecutedTask(currentSession, 
     186                                taskFactory.createNewTaskInstance(eventTask, event)); 
     187        } 
    173188 
    174189} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java

    r1294 r1733  
    2424/** 
    2525 * <p> 
    26  * This rule identifies two tasks as lexically equal, if they are both event tasks and 
    27  * if their respective event types and targets equal.  
     26 * This rule identifies two tasks as lexically equal, if they are both event 
     27 * tasks and if their respective event types and targets equal. 
    2828 * </p> 
    2929 *  
     
    3131 */ 
    3232public class EventTaskComparisonRule implements TaskComparisonRule { 
    33      
    34     /* (non-Javadoc) 
    35      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    36      */ 
    37     @Override 
    38     public boolean isApplicable(ITask task1, ITask task2) { 
    39         return (task1 instanceof IEventTask) && (task2 instanceof IEventTask); 
    40     } 
    4133 
    42     /* (non-Javadoc) 
    43      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    44      */ 
    45     @Override 
    46     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    47         Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 
    48         Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 
    49          
    50         for (ITaskInstance instance1 : taskInstances1) { 
    51             boolean found = false; 
    52              
    53             for (ITaskInstance instance2 : taskInstances2) { 
    54                 if (areLexicallyEqual(instance1, instance2)) { 
    55                     found = true; 
    56                     break; 
    57                 } 
    58             } 
    59              
    60             if (!found) { 
    61                 return false; 
    62             } 
    63         } 
    64          
    65         return true; 
    66     } 
     34        /* 
     35         * (non-Javadoc) 
     36         *  
     37         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     38         */ 
     39        @Override 
     40        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     41                final Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 
     42                final Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 
    6743 
    68     /* (non-Javadoc) 
    69      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    70      */ 
    71     @Override 
    72     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    73         return areLexicallyEqual(task1, task2); 
    74     } 
     44                for (final ITaskInstance instance1 : taskInstances1) { 
     45                        boolean found = false; 
    7546 
    76     /* (non-Javadoc) 
    77      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    78      */ 
    79     @Override 
    80     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    81         return areLexicallyEqual(task1, task2); 
    82     } 
     47                        for (final ITaskInstance instance2 : taskInstances2) { 
     48                                if (areLexicallyEqual(instance1, instance2)) { 
     49                                        found = true; 
     50                                        break; 
     51                                } 
     52                        } 
    8353 
    84     /* (non-Javadoc) 
    85      * @see TaskComparisonRule#compare(ITask, ITask) 
    86      */ 
    87     @Override 
    88     public TaskEquality compare(ITask task1, ITask task2) { 
    89         if (areLexicallyEqual(task1, task2)) { 
    90             return TaskEquality.LEXICALLY_EQUAL; 
    91         } 
    92         else { 
    93             return TaskEquality.UNEQUAL; 
    94         } 
    95     } 
     54                        if (!found) { 
     55                                return false; 
     56                        } 
     57                } 
    9658 
    97      
    98     /* (non-Javadoc) 
    99      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    100      */ 
    101     @Override 
    102     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    103         return 
    104             (instance1 instanceof IEventTaskInstance) && (instance2 instanceof IEventTaskInstance); 
    105     } 
     59                return true; 
     60        } 
    10661 
    107     /* (non-Javadoc) 
    108      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    109      */ 
    110     @Override 
    111     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    112         IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 
    113         IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 
    114          
    115         return (eventTask1.getEvent().getType().equals(eventTask2.getEvent().getType()) && 
    116                 eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget())); 
    117     } 
     62        /* 
     63         * (non-Javadoc) 
     64         *  
     65         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     66         */ 
     67        @Override 
     68        public boolean areLexicallyEqual(ITaskInstance instance1, 
     69                        ITaskInstance instance2) { 
     70                final IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 
     71                final IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 
    11872 
    119     /* (non-Javadoc) 
    120      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    121      */ 
    122     @Override 
    123     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    124         return areLexicallyEqual(instance1, instance2); 
    125     } 
     73                return (eventTask1.getEvent().getType() 
     74                                .equals(eventTask2.getEvent().getType()) && eventTask1 
     75                                .getEvent().getTarget() 
     76                                .equals(eventTask2.getEvent().getTarget())); 
     77        } 
    12678 
    127     /* (non-Javadoc) 
    128      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    129      */ 
    130     @Override 
    131     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    132         return areLexicallyEqual(instance1, instance2); 
    133     } 
     79        /* 
     80         * (non-Javadoc) 
     81         *  
     82         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     83         */ 
     84        @Override 
     85        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     86                return areLexicallyEqual(task1, task2); 
     87        } 
    13488 
    135     /* (non-Javadoc) 
    136      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    137      */ 
    138     @Override 
    139     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    140         if (areLexicallyEqual(instance1, instance2)) { 
    141             return TaskEquality.LEXICALLY_EQUAL; 
    142         } 
    143         else { 
    144             return TaskEquality.UNEQUAL; 
    145         } 
    146     } 
     89        /* 
     90         * (non-Javadoc) 
     91         *  
     92         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     93         * ITaskInstance) 
     94         */ 
     95        @Override 
     96        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     97                        ITaskInstance instance2) { 
     98                return areLexicallyEqual(instance1, instance2); 
     99        } 
     100 
     101        /* 
     102         * (non-Javadoc) 
     103         *  
     104         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     105         */ 
     106        @Override 
     107        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     108                return areLexicallyEqual(task1, task2); 
     109        } 
     110 
     111        /* 
     112         * (non-Javadoc) 
     113         *  
     114         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     115         * ITaskInstance) 
     116         */ 
     117        @Override 
     118        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     119                        ITaskInstance instance2) { 
     120                return areLexicallyEqual(instance1, instance2); 
     121        } 
     122 
     123        /* 
     124         * (non-Javadoc) 
     125         *  
     126         * @see TaskComparisonRule#compare(ITask, ITask) 
     127         */ 
     128        @Override 
     129        public TaskEquality compare(ITask task1, ITask task2) { 
     130                if (areLexicallyEqual(task1, task2)) { 
     131                        return TaskEquality.LEXICALLY_EQUAL; 
     132                } else { 
     133                        return TaskEquality.UNEQUAL; 
     134                } 
     135        } 
     136 
     137        /* 
     138         * (non-Javadoc) 
     139         *  
     140         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     141         */ 
     142        @Override 
     143        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     144                if (areLexicallyEqual(instance1, instance2)) { 
     145                        return TaskEquality.LEXICALLY_EQUAL; 
     146                } else { 
     147                        return TaskEquality.UNEQUAL; 
     148                } 
     149        } 
     150 
     151        /* 
     152         * (non-Javadoc) 
     153         *  
     154         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     155         */ 
     156        @Override 
     157        public boolean isApplicable(ITask task1, ITask task2) { 
     158                return (task1 instanceof IEventTask) && (task2 instanceof IEventTask); 
     159        } 
     160 
     161        /* 
     162         * (non-Javadoc) 
     163         *  
     164         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     165         */ 
     166        @Override 
     167        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     168                return (instance1 instanceof IEventTaskInstance) 
     169                                && (instance2 instanceof IEventTaskInstance); 
     170        } 
    147171 
    148172} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java

    r1294 r1733  
    5050 * <p> 
    5151 * This rule compares GUI event tasks (i.e. it is more concrete, than the 
    52  * {@link EventTaskComparisonRule}). Two GUI event tasks are only equal if their event type and 
    53  * target are equal. The returned equality is even more fine-grained for events whose type is 
    54  * {@link TextInput} and {@link ValueSelection}. For text inputs, lexical equality is returned if 
    55  * the same text is entered using the same key interactions. Syntactical equality is returned if 
    56  * the same text is entered using different key interactions. Semantical equality is returned if 
    57  * different text is entered, but into the same event target. Value selections are syntactically 
    58  * equal, if the same value is selected. Otherwise they are semantically equal. 
     52 * {@link EventTaskComparisonRule}). Two GUI event tasks are only equal if their 
     53 * event type and target are equal. The returned equality is even more 
     54 * fine-grained for events whose type is {@link TextInput} and 
     55 * {@link ValueSelection}. For text inputs, lexical equality is returned if the 
     56 * same text is entered using the same key interactions. Syntactical equality is 
     57 * returned if the same text is entered using different key interactions. 
     58 * Semantical equality is returned if different text is entered, but into the 
     59 * same event target. Value selections are syntactically equal, if the same 
     60 * value is selected. Otherwise they are semantically equal. 
    5961 * </p> 
    6062 *  
     
    6264 */ 
    6365public class GUIEventTaskComparisonRule implements TaskComparisonRule { 
    64      
    65     /* (non-Javadoc) 
    66      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    67      */ 
    68     @Override 
    69     public boolean isApplicable(ITask task1, ITask task2) { 
    70         for (ITaskInstance instance : task1.getInstances()) { 
    71             if ((!(instance instanceof IEventTaskInstance)) || 
    72                 (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) 
    73             { 
    74                 return false; 
    75             } 
    76         } 
    77          
    78         for (ITaskInstance instance : task2.getInstances()) { 
    79             if ((!(instance instanceof IEventTaskInstance)) || 
    80                 (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) 
    81             { 
    82                 return false; 
    83             } 
    84         } 
    85          
    86         return true; 
    87     } 
    88  
    89     /* (non-Javadoc) 
    90      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    91      */ 
    92     @Override 
    93     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    94         TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 
    95         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    96     } 
    97  
    98     /* (non-Javadoc) 
    99      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    100      */ 
    101     @Override 
    102     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    103         TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 
    104         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    105     } 
    106  
    107     /* (non-Javadoc) 
    108      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    109      */ 
    110     @Override 
    111     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    112         TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 
    113         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    114     } 
    115  
    116     /* (non-Javadoc) 
    117      * @see TaskComparisonRule#compare(ITask, ITask) 
    118      */ 
    119     @Override 
    120     public TaskEquality compare(ITask task1, ITask task2) { 
    121         return getEquality(task1, task2, null); 
    122     } 
    123  
    124     /* (non-Javadoc) 
    125      * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#isApplicable(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
    126      */ 
    127     @Override 
    128     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    129         return 
    130             (instance1 instanceof IEventTaskInstance) && 
    131             (instance2 instanceof IEventTaskInstance) && 
    132             (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction) && 
    133             (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction); 
    134     } 
    135  
    136     /* (non-Javadoc) 
    137      * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areLexicallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
    138      */ 
    139     @Override 
    140     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    141         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 
    142         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    143     } 
    144  
    145     /* (non-Javadoc) 
    146      * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSyntacticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
    147      */ 
    148     @Override 
    149     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    150         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 
    151         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    152     } 
    153  
    154     /* (non-Javadoc) 
    155      * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSemanticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
    156      */ 
    157     @Override 
    158     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    159         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 
    160         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    161     } 
    162  
    163     /* (non-Javadoc) 
    164      * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#compare(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
    165      */ 
    166     @Override 
    167     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    168         return getEquality(instance1, instance2, null); 
    169     } 
    170  
    171     /** 
    172      *  
    173      */ 
    174     private TaskEquality getEquality(ITask         task1, 
    175                                      ITask         task2, 
    176                                      TaskEquality  requiredEqualityLevel) 
    177     { 
    178         Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 
    179         Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 
    180          
    181         TaskEquality checkedEquality = 
    182             requiredEqualityLevel != null ? requiredEqualityLevel : TaskEquality.SEMANTICALLY_EQUAL; 
    183          
    184         TaskEquality commonDenominator = TaskEquality.LEXICALLY_EQUAL; 
    185          
    186         for (ITaskInstance instance1 : taskInstances1) { 
    187             TaskEquality mostConcreteEquality = null; 
    188              
    189             for (ITaskInstance instance2 : taskInstances2) { 
    190                 TaskEquality equality = getEquality(instance1, instance2, requiredEqualityLevel); 
    191                  
    192                 if ((equality != null) && ((mostConcreteEquality == null) || 
    193                                            (equality.isAtLeast(mostConcreteEquality)))) 
    194                 { 
    195                     mostConcreteEquality = equality; 
    196                      
    197                     if (((requiredEqualityLevel != null) && 
    198                          (mostConcreteEquality.isAtLeast(requiredEqualityLevel))) || 
    199                         (mostConcreteEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL))) 
    200                     { 
    201                         break; 
    202                     } 
    203                 } 
    204             } 
    205              
    206             commonDenominator = commonDenominator.getCommonDenominator(mostConcreteEquality); 
    207              
    208             if (!commonDenominator.isAtLeast(checkedEquality)) { 
    209                 return TaskEquality.UNEQUAL; 
    210             } 
    211         } 
    212          
    213         return commonDenominator; 
    214     } 
    215  
    216     /** 
    217      *  
    218      */ 
    219     private TaskEquality getEquality(ITaskInstance instance1, 
    220                                      ITaskInstance instance2, 
    221                                      TaskEquality  requiredEqualityLevel) 
    222     { 
    223         IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 
    224         IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 
    225          
    226         if (!eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget())) { 
    227             return TaskEquality.UNEQUAL; 
    228         } 
    229          
    230         IInteraction interaction1 = (IInteraction) eventTask1.getEvent().getType(); 
    231         IInteraction interaction2 = (IInteraction) eventTask2.getEvent().getType(); 
    232          
    233         return compareInteractions 
    234             (interaction1, interaction2, eventTask1.getEvent().getTarget(), requiredEqualityLevel); 
    235     } 
    236  
    237     /** 
    238      * <p> 
    239      * compares two interactions. The method delegates to other, more specific compare method, e.g., 
    240      * {@link #compareTextInputs(TextInput, TextInput)} and 
    241      * {@link #compareValueSelections(ValueSelection, ValueSelection)}, if any exist for the 
    242      * concrete interaction types. Otherwise it uses the equals method of the interactions for 
    243      * comparison. In this case, if the interactions equals method returns true, this method 
    244      * returns lexical equality. 
    245      * </p> 
    246      * <p> 
    247      * The provided equality level can be used to restrict the quality check to the given level. 
    248      * This is done for optimization purposes. The returned equality level can be at most as 
    249      * concrete as the provided one. If the provided one is null, it is expected to be lexical 
    250      * equality. 
    251      * </p> 
    252      * 
    253      * @param interaction1  the first interaction to compare 
    254      * @param interaction2  the second interaction to compare 
    255      * @param eventTarget   the event target on which the interactions happened (used within 
    256      *                      special comparisons like mouse clicks on buttons, where the coordinates 
    257      *                      can be ignored) 
    258      * @param equalityLevel the equality level to be checked for 
    259      *  
    260      * @return as described 
    261      */ 
    262     private TaskEquality compareInteractions(IInteraction interaction1, 
    263                                              IInteraction interaction2, 
    264                                              IEventTarget eventTarget, 
    265                                              TaskEquality equalityLevel) 
    266     { 
    267         TaskEquality level = equalityLevel; 
    268          
    269         if (level == null) { 
    270             level = TaskEquality.LEXICALLY_EQUAL; 
    271         } 
    272          
    273         if (interaction1 == interaction2) { 
    274             return TaskEquality.LEXICALLY_EQUAL; 
    275         } 
    276         else if ((interaction1 instanceof KeyInteraction) && 
    277                  (interaction2 instanceof KeyInteraction)) 
    278         { 
    279             return compareKeyInteractions 
    280                 ((KeyInteraction) interaction1, (KeyInteraction) interaction2, level); 
    281         } 
    282         else if ((interaction1 instanceof MouseButtonInteraction) && 
    283                  (interaction2 instanceof MouseButtonInteraction)) 
    284         { 
    285             return compareMouseButtonInteractions 
    286                 ((MouseButtonInteraction) interaction1, (MouseButtonInteraction) interaction2, 
    287                  eventTarget, level); 
    288         } 
    289         else if ((interaction1 instanceof Scroll) && (interaction2 instanceof Scroll)) { 
    290             return compareScrolls((Scroll) interaction1, (Scroll) interaction2, level); 
    291         } 
    292         else if ((interaction1 instanceof TextInput) && (interaction2 instanceof TextInput)) { 
    293             return compareTextInputs 
    294                 ((TextInput) interaction1, (TextInput) interaction2, level); 
    295         } 
    296         else if ((interaction1 instanceof ValueSelection) && 
    297                  (interaction2 instanceof ValueSelection)) 
    298         { 
    299             return compareValueSelections 
    300                 ((ValueSelection<?>) interaction1, (ValueSelection<?>) interaction2, level); 
    301         } 
    302         else if (interaction1.equals(interaction2)) { 
    303             return TaskEquality.LEXICALLY_EQUAL; 
    304         } 
    305         else { 
    306             return TaskEquality.UNEQUAL; 
    307         } 
    308     } 
    309  
    310     /** 
    311      * <p> 
    312      * compares two key interactions. If both are of the same type and if both have the 
    313      * same key, they are lexically equal. If both are only of the same type, they are 
    314      * semantically equal. Otherwise, they are unequal. 
    315      * </p> 
    316      * <p> 
    317      * The provided equality level can be used to restrict the quality check to the given level. 
    318      * This is done for optimization purposes. The returned equality level is as concrete as 
    319      * the provided one. It may be more concrete if there is no difference regarding the 
    320      * comparison on the levels. 
    321      * </p> 
    322      * 
    323      * @param interaction1  the first key interaction 
    324      * @param interaction2  the second key interaction 
    325      * @param equalityLevel the equality level to be checked for 
    326      *  
    327      * @return as described 
    328      */ 
    329     private TaskEquality compareKeyInteractions(KeyInteraction interaction1, 
    330                                                 KeyInteraction interaction2, 
    331                                                 TaskEquality   equalityLevel) 
    332     { 
    333         if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) || 
    334             ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) || 
    335             ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped))) 
    336         { 
    337             if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) && 
    338                 (interaction1.getKey() == interaction2.getKey())) 
    339             { 
    340                 return TaskEquality.LEXICALLY_EQUAL; 
    341             } 
    342             else { 
    343                 return TaskEquality.SEMANTICALLY_EQUAL; 
    344             } 
    345         } 
    346          
    347         return TaskEquality.UNEQUAL; 
    348     } 
    349      
    350     /** 
    351      * <p> 
    352      * compares two mouse drag and drops. If both drag and drops have the same start and end 
    353      * coordinates, they are lexically equal. Otherwise, they are semantically equal. 
    354      * </p> 
    355      * <p> 
    356      * The provided equality level can be used to restrict the quality check to the given level. 
    357      * This is done for optimization purposes. The returned equality level is as concrete as 
    358      * the provided one. It may be more concrete if there is no difference regarding the 
    359      * comparison on the levels. 
    360      * </p> 
    361      * 
    362      * @param interaction1  the first mouse drag and drop to compare 
    363      * @param interaction2  the second mouse drag and drop to compare 
    364      * @param equalityLevel the equality level to be checked for 
    365      *  
    366      * @return as described 
    367      */ 
    368     private TaskEquality compareMouseDragAndDrops(MouseDragAndDrop interaction1, 
    369                                                   MouseDragAndDrop interaction2, 
    370                                                   TaskEquality     equalityLevel) 
    371     { 
    372         if (interaction1.getButton() != interaction2.getButton()) { 
    373             return TaskEquality.UNEQUAL; 
    374         } 
    375          
    376         if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
    377             int x1 = interaction1.getX(); 
    378             int x1Start = interaction1.getXStart(); 
    379             int x2 = interaction2.getX(); 
    380             int x2Start = interaction2.getXStart(); 
    381             int y1 = interaction1.getY(); 
    382             int y1Start = interaction1.getYStart(); 
    383             int y2 = interaction2.getY(); 
    384             int y2Start = interaction2.getYStart(); 
    385          
    386             if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) && (y1 == y2)) { 
    387                 return TaskEquality.LEXICALLY_EQUAL; 
    388             } 
    389         } 
    390          
    391         return TaskEquality.SEMANTICALLY_EQUAL; 
    392     } 
    393  
    394     /** 
    395      * <p> 
    396      * compares two mouse button interactions such as clicks, mouse button down, or double clicks. 
    397      * If both interactions have the same coordinates, they are lexically equal. Otherwise, they 
    398      * are semantically equal. Mouse clicks for which the coordinates make no lexical difference 
    399      * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as 
    400      * lexically equal. 
    401      * </p> 
    402      * <p> 
    403      * The provided equality level can be used to restrict the quality check to the given level. 
    404      * This is done for optimization purposes. The returned equality level is as concrete as 
    405      * the provided one. It may be more concrete if there is no difference regarding the 
    406      * comparison on the levels. 
    407      * </p> 
    408      * 
    409      * @param interaction1  the first mouse button interaction to compare 
    410      * @param interaction2  the second mouse button interaction to compare 
    411      * @param eventTarget   the event target on which the interactions happened (used within 
    412      *                      special comparisons like mouse clicks on buttons, where the coordinates 
    413      *                      can be ignored) 
    414      * @param equalityLevel the equality level to be checked for 
    415      *  
    416      * @return as described 
    417      */ 
    418     private TaskEquality compareMouseButtonInteractions(MouseButtonInteraction interaction1, 
    419                                                         MouseButtonInteraction interaction2, 
    420                                                         IEventTarget           eventTarget, 
    421                                                         TaskEquality           equalityLevel) 
    422     { 
    423         boolean coordinatesMatch = true; 
    424          
    425         if ((interaction1 instanceof MouseDragAndDrop) && 
    426             (interaction2 instanceof MouseDragAndDrop)) 
    427         { 
    428             return compareMouseDragAndDrops 
    429                 ((MouseDragAndDrop) interaction1, (MouseDragAndDrop) interaction2, equalityLevel); 
    430         } 
    431         else if (interaction1.getButton() != interaction2.getButton()) { 
    432             return TaskEquality.UNEQUAL; 
    433         } 
    434         else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) && 
    435                  clickCoordinatesMakeLexicalDifference(eventTarget)) 
    436         { 
    437             int x1 = interaction1.getX(); 
    438             int x2 = interaction2.getX(); 
    439             int y1 = interaction1.getY(); 
    440             int y2 = interaction2.getY(); 
    441  
    442             if ((x1 != x2) || (y1 != y2)) { 
    443                 coordinatesMatch = false; 
    444             } 
    445         } 
    446          
    447         // up to now, they can be equal. Now check the types. Do it as last action as these 
    448         // checks take the most time and should, therefore, only be done latest 
    449         if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) || 
    450             ((interaction1 instanceof MouseDoubleClick) && 
    451              (interaction2 instanceof MouseDoubleClick)) || 
    452             ((interaction1 instanceof MouseButtonDown) && 
    453              (interaction2 instanceof MouseButtonDown)) || 
    454             ((interaction1 instanceof MouseButtonUp) && 
    455              (interaction2 instanceof MouseButtonUp))) 
    456         { 
    457             if (coordinatesMatch) { 
    458                 return TaskEquality.LEXICALLY_EQUAL; 
    459             } 
    460             else { 
    461                 return TaskEquality.SEMANTICALLY_EQUAL; 
    462             } 
    463         } 
    464          
    465         return TaskEquality.UNEQUAL; 
    466     } 
    467  
    468     /** 
    469      * <p> 
    470      * compares two mouse button interactions such as clicks, mouse button down, or double clicks. 
    471      * If both interactions have the same coordinates, they are lexically equal. Otherwise, they 
    472      * are semantically equal. Mouse clicks for which the coordinates make no lexical difference 
    473      * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as 
    474      * lexically equal. 
    475      * </p> 
    476      * <p> 
    477      * The provided equality level can be used to restrict the quality check to the given level. 
    478      * This is done for optimization purposes. The returned equality level is as concrete as 
    479      * the provided one. It may be more concrete if there is no difference regarding the 
    480      * comparison on the levels. 
    481      * </p> 
    482      * 
    483      * @param interaction1  the first mouse button interaction to compare 
    484      * @param interaction2  the second mouse button interaction to compare 
    485      * @param eventTarget   the event target on which the interactions happened (used within 
    486      *                      special comparisons like mouse clicks on buttons, where the coordinates 
    487      *                      can be ignored) 
    488      * @param equalityLevel the equality level to be checked for 
    489      *  
    490      * @return as described 
    491      */ 
    492     private TaskEquality compareScrolls(Scroll       interaction1, 
    493                                         Scroll       interaction2, 
    494                                         TaskEquality equalityLevel) 
    495     { 
    496         if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
    497             int x1 = interaction1.getXPosition(); 
    498             int x2 = interaction2.getXPosition(); 
    499             int y1 = interaction1.getYPosition(); 
    500             int y2 = interaction2.getYPosition(); 
    501          
    502             if ((x1 == x2) && (y1 == y2)) { 
    503                 return TaskEquality.LEXICALLY_EQUAL; 
    504             } 
    505         } 
    506          
    507         return TaskEquality.SEMANTICALLY_EQUAL; 
    508     } 
    509  
    510     /** 
    511      * <p> 
    512      * compares two text inputs. If both text inputs have the same entered text and text input 
    513      * events, they are lexically equal. If they only have the same entered text, they are 
    514      * syntactically equal. If they are only both text inputs, they are semantically equal. 
    515      * (the equality of the event targets is checked beforehand). 
    516      * </p> 
    517      * <p> 
    518      * The provided equality level can be used to restrict the quality check to the given level. 
    519      * This is done for optimization purposes. The returned equality level is as concrete as 
    520      * the provided one. It may be more concrete if there is no difference regarding the 
    521      * comparison on the levels. 
    522      * </p> 
    523      * 
    524      * @param interaction1  the first text input to compare 
    525      * @param interaction2  the second text input to compare 
    526      * @param equalityLevel the equality level to be checked for 
    527      *  
    528      * @return as described 
    529      */ 
    530     private TaskEquality compareTextInputs(TextInput    interaction1, 
    531                                            TextInput    interaction2, 
    532                                            TaskEquality equalityLevel) 
    533     { 
    534         switch (equalityLevel) { 
    535             case LEXICALLY_EQUAL: 
    536                 if (interaction1.getTextInputEvents().equals(interaction2.getTextInputEvents())) { 
    537                     return TaskEquality.LEXICALLY_EQUAL; 
    538                 } 
    539                 // fall through 
    540             case SYNTACTICALLY_EQUAL: 
    541                 if (interaction1.getEnteredText().equals(interaction2.getEnteredText())) { 
    542                     return TaskEquality.SYNTACTICALLY_EQUAL; 
    543                 } 
    544                 // fall through 
    545             case SEMANTICALLY_EQUAL: 
    546                 return TaskEquality.SEMANTICALLY_EQUAL; 
    547             default: 
    548                 return TaskEquality.UNEQUAL; 
    549         } 
    550     } 
    551  
    552     /** 
    553      * <p> 
    554      * compares two value selections. If both value selections have the same selected value, they 
    555      * are syntactically equal, otherwise they are semantically equal. 
    556      * (the equality of the event targets is checked beforehand). 
    557      * </p> 
    558      * <p> 
    559      * The provided equality level can be used to restrict the quality check to the given level. 
    560      * This is done for optimization purposes. The returned equality level is as concrete as 
    561      * the provided one. It may be more concrete if there is no difference regarding the 
    562      * comparison on the levels. 
    563      * </p> 
    564      * 
    565      * @param interaction1  the first value selection to compare 
    566      * @param interaction2  the second value selection to compare 
    567      * @param equalityLevel the equality level to be checked for 
    568      *  
    569      * @return as described 
    570      */ 
    571     private TaskEquality compareValueSelections(ValueSelection<?> interaction1, 
    572                                                 ValueSelection<?> interaction2, 
    573                                                 TaskEquality      equalityLevel) 
    574     { 
    575         if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
    576             Object value1 = interaction1.getSelectedValue(); 
    577             Object value2 = interaction2.getSelectedValue(); 
    578          
    579             if ((value1 == value2) || ((value1 != null) && (value1.equals(value2)))) { 
    580                 return TaskEquality.LEXICALLY_EQUAL; 
    581             } 
    582         } 
    583          
    584         return TaskEquality.SEMANTICALLY_EQUAL; 
    585     } 
    586  
    587     /** 
    588      * <p> 
    589      * Checks, if the coordinates of a click or double click on the provided event target makes 
    590      * a lexical difference. Mouse clicks and double clicks on buttons, check boxes, 
    591      * combo boxes, images, list boxes, menu buttons, radio buttons, shapes, uneditable text, 
    592      * and tool tips have no lexical difference as long as they happen on the same event target. 
    593      * The concrete coordinates are not relevant. 
    594      * </p> 
    595      * 
    596      * @param eventTarget the event target on which the interaction occurred 
    597      *  
    598      * @return if the coordinates are important to be considered for clicks and double clicks, 
    599      *         false else 
    600      */ 
    601     private boolean clickCoordinatesMakeLexicalDifference(IEventTarget eventTarget) { 
    602         if ((eventTarget instanceof IButton) || 
    603             (eventTarget instanceof ICheckBox) || 
    604             (eventTarget instanceof IComboBox) || 
    605             (eventTarget instanceof IImage) || 
    606             (eventTarget instanceof IListBox) || 
    607             (eventTarget instanceof IMenu) || 
    608             (eventTarget instanceof IMenuButton) || 
    609             (eventTarget instanceof IRadioButton) || 
    610             (eventTarget instanceof IShape) || 
    611             (eventTarget instanceof IText) || 
    612             (eventTarget instanceof IToolTip)) 
    613         { 
    614             return false; 
    615         } 
    616         else { 
    617             return true; 
    618         } 
    619     } 
     66 
     67        /* 
     68         * (non-Javadoc) 
     69         *  
     70         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     71         */ 
     72        @Override 
     73        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     74                final TaskEquality equality = getEquality(task1, task2, 
     75                                TaskEquality.LEXICALLY_EQUAL); 
     76                return (equality != null) 
     77                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     78        } 
     79 
     80        /* 
     81         * (non-Javadoc) 
     82         *  
     83         * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 
     84         * areLexicallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 
     85         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
     86         */ 
     87        @Override 
     88        public boolean areLexicallyEqual(ITaskInstance instance1, 
     89                        ITaskInstance instance2) { 
     90                final TaskEquality equality = getEquality(instance1, instance2, 
     91                                TaskEquality.LEXICALLY_EQUAL); 
     92                return (equality != null) 
     93                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     94        } 
     95 
     96        /* 
     97         * (non-Javadoc) 
     98         *  
     99         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     100         */ 
     101        @Override 
     102        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     103                final TaskEquality equality = getEquality(task1, task2, 
     104                                TaskEquality.SEMANTICALLY_EQUAL); 
     105                return (equality != null) 
     106                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     107        } 
     108 
     109        /* 
     110         * (non-Javadoc) 
     111         *  
     112         * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 
     113         * areSemanticallyEqual 
     114         * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 
     115         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
     116         */ 
     117        @Override 
     118        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     119                        ITaskInstance instance2) { 
     120                final TaskEquality equality = getEquality(instance1, instance2, 
     121                                TaskEquality.SEMANTICALLY_EQUAL); 
     122                return (equality != null) 
     123                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     124        } 
     125 
     126        /* 
     127         * (non-Javadoc) 
     128         *  
     129         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     130         */ 
     131        @Override 
     132        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     133                final TaskEquality equality = getEquality(task1, task2, 
     134                                TaskEquality.SYNTACTICALLY_EQUAL); 
     135                return (equality != null) 
     136                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     137        } 
     138 
     139        /* 
     140         * (non-Javadoc) 
     141         *  
     142         * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 
     143         * areSyntacticallyEqual 
     144         * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 
     145         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
     146         */ 
     147        @Override 
     148        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     149                        ITaskInstance instance2) { 
     150                final TaskEquality equality = getEquality(instance1, instance2, 
     151                                TaskEquality.SYNTACTICALLY_EQUAL); 
     152                return (equality != null) 
     153                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     154        } 
     155 
     156        /** 
     157         * <p> 
     158         * Checks, if the coordinates of a click or double click on the provided 
     159         * event target makes a lexical difference. Mouse clicks and double clicks 
     160         * on buttons, check boxes, combo boxes, images, list boxes, menu buttons, 
     161         * radio buttons, shapes, uneditable text, and tool tips have no lexical 
     162         * difference as long as they happen on the same event target. The concrete 
     163         * coordinates are not relevant. 
     164         * </p> 
     165         * 
     166         * @param eventTarget 
     167         *            the event target on which the interaction occurred 
     168         *  
     169         * @return if the coordinates are important to be considered for clicks and 
     170         *         double clicks, false else 
     171         */ 
     172        private boolean clickCoordinatesMakeLexicalDifference( 
     173                        IEventTarget eventTarget) { 
     174                if ((eventTarget instanceof IButton) 
     175                                || (eventTarget instanceof ICheckBox) 
     176                                || (eventTarget instanceof IComboBox) 
     177                                || (eventTarget instanceof IImage) 
     178                                || (eventTarget instanceof IListBox) 
     179                                || (eventTarget instanceof IMenu) 
     180                                || (eventTarget instanceof IMenuButton) 
     181                                || (eventTarget instanceof IRadioButton) 
     182                                || (eventTarget instanceof IShape) 
     183                                || (eventTarget instanceof IText) 
     184                                || (eventTarget instanceof IToolTip)) { 
     185                        return false; 
     186                } else { 
     187                        return true; 
     188                } 
     189        } 
     190 
     191        /* 
     192         * (non-Javadoc) 
     193         *  
     194         * @see TaskComparisonRule#compare(ITask, ITask) 
     195         */ 
     196        @Override 
     197        public TaskEquality compare(ITask task1, ITask task2) { 
     198                return getEquality(task1, task2, null); 
     199        } 
     200 
     201        /* 
     202         * (non-Javadoc) 
     203         *  
     204         * @see 
     205         * de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#compare 
     206         * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 
     207         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
     208         */ 
     209        @Override 
     210        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     211                return getEquality(instance1, instance2, null); 
     212        } 
     213 
     214        /** 
     215         * <p> 
     216         * compares two interactions. The method delegates to other, more specific 
     217         * compare method, e.g., {@link #compareTextInputs(TextInput, TextInput)} 
     218         * and {@link #compareValueSelections(ValueSelection, ValueSelection)}, if 
     219         * any exist for the concrete interaction types. Otherwise it uses the 
     220         * equals method of the interactions for comparison. In this case, if the 
     221         * interactions equals method returns true, this method returns lexical 
     222         * equality. 
     223         * </p> 
     224         * <p> 
     225         * The provided equality level can be used to restrict the quality check to 
     226         * the given level. This is done for optimization purposes. The returned 
     227         * equality level can be at most as concrete as the provided one. If the 
     228         * provided one is null, it is expected to be lexical equality. 
     229         * </p> 
     230         * 
     231         * @param interaction1 
     232         *            the first interaction to compare 
     233         * @param interaction2 
     234         *            the second interaction to compare 
     235         * @param eventTarget 
     236         *            the event target on which the interactions happened (used 
     237         *            within special comparisons like mouse clicks on buttons, where 
     238         *            the coordinates can be ignored) 
     239         * @param equalityLevel 
     240         *            the equality level to be checked for 
     241         *  
     242         * @return as described 
     243         */ 
     244        private TaskEquality compareInteractions(IInteraction interaction1, 
     245                        IInteraction interaction2, IEventTarget eventTarget, 
     246                        TaskEquality equalityLevel) { 
     247                TaskEquality level = equalityLevel; 
     248 
     249                if (level == null) { 
     250                        level = TaskEquality.LEXICALLY_EQUAL; 
     251                } 
     252 
     253                if (interaction1 == interaction2) { 
     254                        return TaskEquality.LEXICALLY_EQUAL; 
     255                } else if ((interaction1 instanceof KeyInteraction) 
     256                                && (interaction2 instanceof KeyInteraction)) { 
     257                        return compareKeyInteractions((KeyInteraction) interaction1, 
     258                                        (KeyInteraction) interaction2, level); 
     259                } else if ((interaction1 instanceof MouseButtonInteraction) 
     260                                && (interaction2 instanceof MouseButtonInteraction)) { 
     261                        return compareMouseButtonInteractions( 
     262                                        (MouseButtonInteraction) interaction1, 
     263                                        (MouseButtonInteraction) interaction2, eventTarget, level); 
     264                } else if ((interaction1 instanceof Scroll) 
     265                                && (interaction2 instanceof Scroll)) { 
     266                        return compareScrolls((Scroll) interaction1, (Scroll) interaction2, 
     267                                        level); 
     268                } else if ((interaction1 instanceof TextInput) 
     269                                && (interaction2 instanceof TextInput)) { 
     270                        return compareTextInputs((TextInput) interaction1, 
     271                                        (TextInput) interaction2, level); 
     272                } else if ((interaction1 instanceof ValueSelection) 
     273                                && (interaction2 instanceof ValueSelection)) { 
     274                        return compareValueSelections((ValueSelection<?>) interaction1, 
     275                                        (ValueSelection<?>) interaction2, level); 
     276                } else if (interaction1.equals(interaction2)) { 
     277                        return TaskEquality.LEXICALLY_EQUAL; 
     278                } else { 
     279                        return TaskEquality.UNEQUAL; 
     280                } 
     281        } 
     282 
     283        /** 
     284         * <p> 
     285         * compares two key interactions. If both are of the same type and if both 
     286         * have the same key, they are lexically equal. If both are only of the same 
     287         * type, they are semantically equal. Otherwise, they are unequal. 
     288         * </p> 
     289         * <p> 
     290         * The provided equality level can be used to restrict the quality check to 
     291         * the given level. This is done for optimization purposes. The returned 
     292         * equality level is as concrete as the provided one. It may be more 
     293         * concrete if there is no difference regarding the comparison on the 
     294         * levels. 
     295         * </p> 
     296         * 
     297         * @param interaction1 
     298         *            the first key interaction 
     299         * @param interaction2 
     300         *            the second key interaction 
     301         * @param equalityLevel 
     302         *            the equality level to be checked for 
     303         *  
     304         * @return as described 
     305         */ 
     306        private TaskEquality compareKeyInteractions(KeyInteraction interaction1, 
     307                        KeyInteraction interaction2, TaskEquality equalityLevel) { 
     308                if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) 
     309                                || ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) 
     310                                || ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped))) { 
     311                        if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) 
     312                                        && (interaction1.getKey() == interaction2.getKey())) { 
     313                                return TaskEquality.LEXICALLY_EQUAL; 
     314                        } else { 
     315                                return TaskEquality.SEMANTICALLY_EQUAL; 
     316                        } 
     317                } 
     318 
     319                return TaskEquality.UNEQUAL; 
     320        } 
     321 
     322        /** 
     323         * <p> 
     324         * compares two mouse button interactions such as clicks, mouse button down, 
     325         * or double clicks. If both interactions have the same coordinates, they 
     326         * are lexically equal. Otherwise, they are semantically equal. Mouse clicks 
     327         * for which the coordinates make no lexical difference (see 
     328         * {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated 
     329         * as lexically equal. 
     330         * </p> 
     331         * <p> 
     332         * The provided equality level can be used to restrict the quality check to 
     333         * the given level. This is done for optimization purposes. The returned 
     334         * equality level is as concrete as the provided one. It may be more 
     335         * concrete if there is no difference regarding the comparison on the 
     336         * levels. 
     337         * </p> 
     338         * 
     339         * @param interaction1 
     340         *            the first mouse button interaction to compare 
     341         * @param interaction2 
     342         *            the second mouse button interaction to compare 
     343         * @param eventTarget 
     344         *            the event target on which the interactions happened (used 
     345         *            within special comparisons like mouse clicks on buttons, where 
     346         *            the coordinates can be ignored) 
     347         * @param equalityLevel 
     348         *            the equality level to be checked for 
     349         *  
     350         * @return as described 
     351         */ 
     352        private TaskEquality compareMouseButtonInteractions( 
     353                        MouseButtonInteraction interaction1, 
     354                        MouseButtonInteraction interaction2, IEventTarget eventTarget, 
     355                        TaskEquality equalityLevel) { 
     356                boolean coordinatesMatch = true; 
     357 
     358                if ((interaction1 instanceof MouseDragAndDrop) 
     359                                && (interaction2 instanceof MouseDragAndDrop)) { 
     360                        return compareMouseDragAndDrops((MouseDragAndDrop) interaction1, 
     361                                        (MouseDragAndDrop) interaction2, equalityLevel); 
     362                } else if (interaction1.getButton() != interaction2.getButton()) { 
     363                        return TaskEquality.UNEQUAL; 
     364                } else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) 
     365                                && clickCoordinatesMakeLexicalDifference(eventTarget)) { 
     366                        final int x1 = interaction1.getX(); 
     367                        final int x2 = interaction2.getX(); 
     368                        final int y1 = interaction1.getY(); 
     369                        final int y2 = interaction2.getY(); 
     370 
     371                        if ((x1 != x2) || (y1 != y2)) { 
     372                                coordinatesMatch = false; 
     373                        } 
     374                } 
     375 
     376                // up to now, they can be equal. Now check the types. Do it as last 
     377                // action as these 
     378                // checks take the most time and should, therefore, only be done latest 
     379                if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) 
     380                                || ((interaction1 instanceof MouseDoubleClick) && (interaction2 instanceof MouseDoubleClick)) 
     381                                || ((interaction1 instanceof MouseButtonDown) && (interaction2 instanceof MouseButtonDown)) 
     382                                || ((interaction1 instanceof MouseButtonUp) && (interaction2 instanceof MouseButtonUp))) { 
     383                        if (coordinatesMatch) { 
     384                                return TaskEquality.LEXICALLY_EQUAL; 
     385                        } else { 
     386                                return TaskEquality.SEMANTICALLY_EQUAL; 
     387                        } 
     388                } 
     389 
     390                return TaskEquality.UNEQUAL; 
     391        } 
     392 
     393        /** 
     394         * <p> 
     395         * compares two mouse drag and drops. If both drag and drops have the same 
     396         * start and end coordinates, they are lexically equal. Otherwise, they are 
     397         * semantically equal. 
     398         * </p> 
     399         * <p> 
     400         * The provided equality level can be used to restrict the quality check to 
     401         * the given level. This is done for optimization purposes. The returned 
     402         * equality level is as concrete as the provided one. It may be more 
     403         * concrete if there is no difference regarding the comparison on the 
     404         * levels. 
     405         * </p> 
     406         * 
     407         * @param interaction1 
     408         *            the first mouse drag and drop to compare 
     409         * @param interaction2 
     410         *            the second mouse drag and drop to compare 
     411         * @param equalityLevel 
     412         *            the equality level to be checked for 
     413         *  
     414         * @return as described 
     415         */ 
     416        private TaskEquality compareMouseDragAndDrops( 
     417                        MouseDragAndDrop interaction1, MouseDragAndDrop interaction2, 
     418                        TaskEquality equalityLevel) { 
     419                if (interaction1.getButton() != interaction2.getButton()) { 
     420                        return TaskEquality.UNEQUAL; 
     421                } 
     422 
     423                if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
     424                        final int x1 = interaction1.getX(); 
     425                        final int x1Start = interaction1.getXStart(); 
     426                        final int x2 = interaction2.getX(); 
     427                        final int x2Start = interaction2.getXStart(); 
     428                        final int y1 = interaction1.getY(); 
     429                        final int y1Start = interaction1.getYStart(); 
     430                        final int y2 = interaction2.getY(); 
     431                        final int y2Start = interaction2.getYStart(); 
     432 
     433                        if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) 
     434                                        && (y1 == y2)) { 
     435                                return TaskEquality.LEXICALLY_EQUAL; 
     436                        } 
     437                } 
     438 
     439                return TaskEquality.SEMANTICALLY_EQUAL; 
     440        } 
     441 
     442        /** 
     443         * <p> 
     444         * compares two mouse button interactions such as clicks, mouse button down, 
     445         * or double clicks. If both interactions have the same coordinates, they 
     446         * are lexically equal. Otherwise, they are semantically equal. Mouse clicks 
     447         * for which the coordinates make no lexical difference (see 
     448         * {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated 
     449         * as lexically equal. 
     450         * </p> 
     451         * <p> 
     452         * The provided equality level can be used to restrict the quality check to 
     453         * the given level. This is done for optimization purposes. The returned 
     454         * equality level is as concrete as the provided one. It may be more 
     455         * concrete if there is no difference regarding the comparison on the 
     456         * levels. 
     457         * </p> 
     458         * 
     459         * @param interaction1 
     460         *            the first mouse button interaction to compare 
     461         * @param interaction2 
     462         *            the second mouse button interaction to compare 
     463         * @param eventTarget 
     464         *            the event target on which the interactions happened (used 
     465         *            within special comparisons like mouse clicks on buttons, where 
     466         *            the coordinates can be ignored) 
     467         * @param equalityLevel 
     468         *            the equality level to be checked for 
     469         *  
     470         * @return as described 
     471         */ 
     472        private TaskEquality compareScrolls(Scroll interaction1, 
     473                        Scroll interaction2, TaskEquality equalityLevel) { 
     474                if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
     475                        final int x1 = interaction1.getXPosition(); 
     476                        final int x2 = interaction2.getXPosition(); 
     477                        final int y1 = interaction1.getYPosition(); 
     478                        final int y2 = interaction2.getYPosition(); 
     479 
     480                        if ((x1 == x2) && (y1 == y2)) { 
     481                                return TaskEquality.LEXICALLY_EQUAL; 
     482                        } 
     483                } 
     484 
     485                return TaskEquality.SEMANTICALLY_EQUAL; 
     486        } 
     487 
     488        /** 
     489         * <p> 
     490         * compares two text inputs. If both text inputs have the same entered text 
     491         * and text input events, they are lexically equal. If they only have the 
     492         * same entered text, they are syntactically equal. If they are only both 
     493         * text inputs, they are semantically equal. (the equality of the event 
     494         * targets is checked beforehand). 
     495         * </p> 
     496         * <p> 
     497         * The provided equality level can be used to restrict the quality check to 
     498         * the given level. This is done for optimization purposes. The returned 
     499         * equality level is as concrete as the provided one. It may be more 
     500         * concrete if there is no difference regarding the comparison on the 
     501         * levels. 
     502         * </p> 
     503         * 
     504         * @param interaction1 
     505         *            the first text input to compare 
     506         * @param interaction2 
     507         *            the second text input to compare 
     508         * @param equalityLevel 
     509         *            the equality level to be checked for 
     510         *  
     511         * @return as described 
     512         */ 
     513        private TaskEquality compareTextInputs(TextInput interaction1, 
     514                        TextInput interaction2, TaskEquality equalityLevel) { 
     515                switch (equalityLevel) { 
     516                case LEXICALLY_EQUAL: 
     517                        if (interaction1.getTextInputEvents().equals( 
     518                                        interaction2.getTextInputEvents())) { 
     519                                return TaskEquality.LEXICALLY_EQUAL; 
     520                        } 
     521                        // fall through 
     522                case SYNTACTICALLY_EQUAL: 
     523                        if (interaction1.getEnteredText().equals( 
     524                                        interaction2.getEnteredText())) { 
     525                                return TaskEquality.SYNTACTICALLY_EQUAL; 
     526                        } 
     527                        // fall through 
     528                case SEMANTICALLY_EQUAL: 
     529                        return TaskEquality.SEMANTICALLY_EQUAL; 
     530                default: 
     531                        return TaskEquality.UNEQUAL; 
     532                } 
     533        } 
     534 
     535        /** 
     536         * <p> 
     537         * compares two value selections. If both value selections have the same 
     538         * selected value, they are syntactically equal, otherwise they are 
     539         * semantically equal. (the equality of the event targets is checked 
     540         * beforehand). 
     541         * </p> 
     542         * <p> 
     543         * The provided equality level can be used to restrict the quality check to 
     544         * the given level. This is done for optimization purposes. The returned 
     545         * equality level is as concrete as the provided one. It may be more 
     546         * concrete if there is no difference regarding the comparison on the 
     547         * levels. 
     548         * </p> 
     549         * 
     550         * @param interaction1 
     551         *            the first value selection to compare 
     552         * @param interaction2 
     553         *            the second value selection to compare 
     554         * @param equalityLevel 
     555         *            the equality level to be checked for 
     556         *  
     557         * @return as described 
     558         */ 
     559        private TaskEquality compareValueSelections(ValueSelection<?> interaction1, 
     560                        ValueSelection<?> interaction2, TaskEquality equalityLevel) { 
     561                if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 
     562                        final Object value1 = interaction1.getSelectedValue(); 
     563                        final Object value2 = interaction2.getSelectedValue(); 
     564 
     565                        if ((value1 == value2) 
     566                                        || ((value1 != null) && (value1.equals(value2)))) { 
     567                                return TaskEquality.LEXICALLY_EQUAL; 
     568                        } 
     569                } 
     570 
     571                return TaskEquality.SEMANTICALLY_EQUAL; 
     572        } 
     573 
     574        /** 
     575         *  
     576         */ 
     577        private TaskEquality getEquality(ITask task1, ITask task2, 
     578                        TaskEquality requiredEqualityLevel) { 
     579                final Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 
     580                final Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 
     581 
     582                final TaskEquality checkedEquality = requiredEqualityLevel != null ? requiredEqualityLevel 
     583                                : TaskEquality.SEMANTICALLY_EQUAL; 
     584 
     585                TaskEquality commonDenominator = TaskEquality.LEXICALLY_EQUAL; 
     586 
     587                for (final ITaskInstance instance1 : taskInstances1) { 
     588                        TaskEquality mostConcreteEquality = null; 
     589 
     590                        for (final ITaskInstance instance2 : taskInstances2) { 
     591                                final TaskEquality equality = getEquality(instance1, instance2, 
     592                                                requiredEqualityLevel); 
     593 
     594                                if ((equality != null) 
     595                                                && ((mostConcreteEquality == null) || (equality 
     596                                                                .isAtLeast(mostConcreteEquality)))) { 
     597                                        mostConcreteEquality = equality; 
     598 
     599                                        if (((requiredEqualityLevel != null) && (mostConcreteEquality 
     600                                                        .isAtLeast(requiredEqualityLevel))) 
     601                                                        || (mostConcreteEquality 
     602                                                                        .isAtLeast(TaskEquality.LEXICALLY_EQUAL))) { 
     603                                                break; 
     604                                        } 
     605                                } 
     606                        } 
     607 
     608                        commonDenominator = commonDenominator 
     609                                        .getCommonDenominator(mostConcreteEquality); 
     610 
     611                        if (!commonDenominator.isAtLeast(checkedEquality)) { 
     612                                return TaskEquality.UNEQUAL; 
     613                        } 
     614                } 
     615 
     616                return commonDenominator; 
     617        } 
     618 
     619        /** 
     620         *  
     621         */ 
     622        private TaskEquality getEquality(ITaskInstance instance1, 
     623                        ITaskInstance instance2, TaskEquality requiredEqualityLevel) { 
     624                final IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 
     625                final IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 
     626 
     627                if (!eventTask1.getEvent().getTarget() 
     628                                .equals(eventTask2.getEvent().getTarget())) { 
     629                        return TaskEquality.UNEQUAL; 
     630                } 
     631 
     632                final IInteraction interaction1 = (IInteraction) eventTask1.getEvent() 
     633                                .getType(); 
     634                final IInteraction interaction2 = (IInteraction) eventTask2.getEvent() 
     635                                .getType(); 
     636 
     637                return compareInteractions(interaction1, interaction2, eventTask1 
     638                                .getEvent().getTarget(), requiredEqualityLevel); 
     639        } 
     640 
     641        /* 
     642         * (non-Javadoc) 
     643         *  
     644         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     645         */ 
     646        @Override 
     647        public boolean isApplicable(ITask task1, ITask task2) { 
     648                for (final ITaskInstance instance : task1.getInstances()) { 
     649                        if ((!(instance instanceof IEventTaskInstance)) 
     650                                        || (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) { 
     651                                return false; 
     652                        } 
     653                } 
     654 
     655                for (final ITaskInstance instance : task2.getInstances()) { 
     656                        if ((!(instance instanceof IEventTaskInstance)) 
     657                                        || (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) { 
     658                                return false; 
     659                        } 
     660                } 
     661 
     662                return true; 
     663        } 
     664 
     665        /* 
     666         * (non-Javadoc) 
     667         *  
     668         * @see 
     669         * de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#isApplicable 
     670         * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 
     671         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 
     672         */ 
     673        @Override 
     674        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     675                return (instance1 instanceof IEventTaskInstance) 
     676                                && (instance2 instanceof IEventTaskInstance) 
     677                                && (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction) 
     678                                && (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction); 
     679        } 
    620680 
    621681} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java

    r1294 r1733  
    2323/** 
    2424 * <p> 
    25  * This class is capable of comparing Iterations. Iterations equal at distinct levels 
    26  * in distinct situations. The following table shows the results of the comparison for the 
    27  * specific situations (the parameters are commutative). In any other situation, the comparison 
    28  * returns <code>NodeEquality.UNEQUAL</code>: 
     25 * This class is capable of comparing Iterations. Iterations equal at distinct 
     26 * levels in distinct situations. The following table shows the results of the 
     27 * comparison for the specific situations (the parameters are commutative). In 
     28 * any other situation, the comparison returns <code>NodeEquality.UNEQUAL</code> 
     29 * : 
    2930 * </p> 
    3031 *  
    3132 * <table border="1"> 
    32  *   <tr> 
    33  *     <th>iteration 1</th> 
    34  *     <th>iteration 2</th> 
    35  *     <th>comparison result</th> 
    36  *   </tr> 
    37  *   <tr> 
    38  *     <td>any iteration</td> 
    39  *     <td>any iteration with a child that is lexically equal to the child of iteration 1</td> 
    40  *     <td><code>NodeEquality.LEXICALLY_EQUAL</code></td> 
    41  *   </tr> 
    42  *   <tr> 
    43  *     <td>any iteration</td> 
    44  *     <td>any iteration with a child that is syntactically equal to the child of iteration 1</td> 
    45  *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
    46  *   </tr> 
    47  *   <tr> 
    48  *     <td>any iteration</td> 
    49  *     <td>any iteration with a child that is semantically equal to the child of iteration 1</td> 
    50  *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
    51  *   </tr> 
    52  *   <tr> 
    53  *     <td>an iteration with a selection of syntactically equal children</td> 
    54  *     <td>an iteration with a child that is syntactically equal to the children of the child 
    55  *     selection of iteration 1</td> 
    56  *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
    57  *   </tr> 
    58  *   <tr> 
    59  *     <td>an iteration with a selection of syntactically equal children</td> 
    60  *     <td>an iteration with a selection of syntactically equal children that are all syntactically 
    61  *     equal to the selection of children of iteration 1</td> 
    62  *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
    63  *   </tr> 
    64  *   <tr> 
    65  *     <td>an iteration with a selection of semantically equal children</td> 
    66  *     <td>an iteration with a child that is semantically equal to the children of the child 
    67  *     selection of iteration 1</td> 
    68  *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
    69  *   </tr> 
    70  *   <tr> 
    71  *     <td>an iteration with a selection of semantically equal children</td> 
    72  *     <td>an iteration with a selection of semantically equal children that are all semantically 
    73  *     equal to the selection of children of iteration 1</td> 
    74  *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
    75  *   </tr> 
     33 * <tr> 
     34 * <th>iteration 1</th> 
     35 * <th>iteration 2</th> 
     36 * <th>comparison result</th> 
     37 * </tr> 
     38 * <tr> 
     39 * <td>any iteration</td> 
     40 * <td>any iteration with a child that is lexically equal to the child of 
     41 * iteration 1</td> 
     42 * <td><code>NodeEquality.LEXICALLY_EQUAL</code></td> 
     43 * </tr> 
     44 * <tr> 
     45 * <td>any iteration</td> 
     46 * <td>any iteration with a child that is syntactically equal to the child of 
     47 * iteration 1</td> 
     48 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
     49 * </tr> 
     50 * <tr> 
     51 * <td>any iteration</td> 
     52 * <td>any iteration with a child that is semantically equal to the child of 
     53 * iteration 1</td> 
     54 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
     55 * </tr> 
     56 * <tr> 
     57 * <td>an iteration with a selection of syntactically equal children</td> 
     58 * <td>an iteration with a child that is syntactically equal to the children of 
     59 * the child selection of iteration 1</td> 
     60 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
     61 * </tr> 
     62 * <tr> 
     63 * <td>an iteration with a selection of syntactically equal children</td> 
     64 * <td>an iteration with a selection of syntactically equal children that are 
     65 * all syntactically equal to the selection of children of iteration 1</td> 
     66 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 
     67 * </tr> 
     68 * <tr> 
     69 * <td>an iteration with a selection of semantically equal children</td> 
     70 * <td>an iteration with a child that is semantically equal to the children of 
     71 * the child selection of iteration 1</td> 
     72 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
     73 * </tr> 
     74 * <tr> 
     75 * <td>an iteration with a selection of semantically equal children</td> 
     76 * <td>an iteration with a selection of semantically equal children that are all 
     77 * semantically equal to the selection of children of iteration 1</td> 
     78 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 
     79 * </tr> 
    7680 * </table> 
    7781 *  
     
    8084 */ 
    8185public class IterationComparisonRule implements TaskComparisonRule { 
    82      
    83     /* (non-Javadoc) 
    84      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    85      */ 
    86     @Override 
    87     public boolean isApplicable(ITask task1, ITask task2) { 
    88         return (task1 instanceof IIteration) && (task2 instanceof IIteration); 
    89     } 
    90  
    91     /* (non-Javadoc) 
    92      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    93      */ 
    94     @Override 
    95     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    96         ITask child1 = ((IIteration) task1).getMarkedTask(); 
    97         ITask child2 = ((IIteration) task2).getMarkedTask(); 
    98          
    99         if (child1 != null) { 
    100             if (child2 == null) { 
    101                 return false; 
    102             } 
    103             else { 
    104                 // iterations may have 3 different structures. 
    105                 // 1. they have one child, which is the iterated one 
    106                 // 2. they have a sequence of children, which is iterated 
    107                 // 3. they have a selection of different iterated variants (usually the variants 
    108                 //    are semantically equal) 
    109                 // ignore the type of the children but check them for equality. 
    110                  
    111                 return getNodeEquality(child1, child2).isAtLeast(TaskEquality.LEXICALLY_EQUAL); 
    112             } 
    113         } 
    114         else if (child2 == null) { 
    115             return true; 
    116         } 
    117          
    118         return false; 
    119     } 
    120  
    121     /* (non-Javadoc) 
    122      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    123      */ 
    124     @Override 
    125     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    126         return areLexicallyEqual(task1, task2); 
    127     } 
    128  
    129     /* (non-Javadoc) 
    130      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    131      */ 
    132     @Override 
    133     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    134         return compare(task1, task2).isAtLeast(TaskEquality.SEMANTICALLY_EQUAL); 
    135     } 
    136  
    137     /* (non-Javadoc) 
    138      * @see TaskComparisonRule#compare(ITask, ITask) 
    139      */ 
    140     @Override 
    141     public TaskEquality compare(ITask task1, ITask task2) { 
    142         ITask child1 = ((IIteration) task1).getMarkedTask(); 
    143         ITask child2 = ((IIteration) task2).getMarkedTask(); 
    144  
    145         // if both iterations do not have children, they are equal although this doesn't make sense 
    146         if ((child1 == null) && (child2 == null)) { 
    147             return TaskEquality.LEXICALLY_EQUAL; 
    148         } 
    149         else if ((child1 == null) || (child2 == null)) { 
    150             return TaskEquality.UNEQUAL; 
    151         } 
    152  
    153         // iterations may have 3 different structures. 
    154         // 1. they have one child, which is the iterated one 
    155         // 2. they have a sequence of children, which is iterated 
    156         // 3. they have a selection of different iterated variants (usually the variants are 
    157         // semantically equal) 
    158         // 
    159         // the permutations of the three variants in combination must be checked 
    160  
    161         // check if both tasks are the same variants of iterations and if their children are equal. 
    162         // This condition matches, if both iterations are the same variants of iteration. I.e. three 
    163         // combinations of the permutation are handled herewith. 
    164         TaskEquality taskEquality = getNodeEquality(child1, child2); 
    165          
    166         if (taskEquality != null) { 
    167             return taskEquality; 
    168         } 
    169  
    170         // compare one iteration with a single task as a child and another one with a selection of 
    171         // semantically equal tasks 
    172         return selectionChildrenSemanticallyEqualNode(child1, child2); 
    173          
    174         // all other combinations (i.e. sequence with single child and sequence with selection) 
    175         // can not match 
    176     } 
    177  
    178     /* (non-Javadoc) 
    179      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    180      */ 
    181     @Override 
    182     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    183         return isApplicable(instance1.getTask(), instance2.getTask()); 
    184     } 
    185  
    186     /* (non-Javadoc) 
    187      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    188      */ 
    189     @Override 
    190     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    191         IIterationInstance iteration1 = (IIterationInstance) instance1; 
    192         IIterationInstance iteration2 = (IIterationInstance) instance2; 
    193  
    194         // if both sequences do not have children, they are equal although this doesn't make sense 
    195         if ((iteration1.size() == 0) && (iteration2.size() == 0)) { 
    196             return true; 
    197         } 
    198  
    199         if (iteration1.size() != iteration2.size()) { 
    200             return false; 
    201         } 
    202  
    203         for (int i = 0; i < iteration1.size(); i++) { 
    204             ITaskInstance child1 = iteration1.get(i); 
    205             ITaskInstance child2 = iteration2.get(i); 
    206  
    207             TaskEquality taskEquality = 
    208                 callRuleManager(child1, child2, TaskEquality.LEXICALLY_EQUAL); 
    209  
    210             if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 
    211                 return false; 
    212             } 
    213         } 
    214  
    215         return true; 
    216     } 
    217  
    218     /* (non-Javadoc) 
    219      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    220      */ 
    221     @Override 
    222     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    223         return areLexicallyEqual(instance1, instance2); 
    224     } 
    225  
    226     /* (non-Javadoc) 
    227      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    228      */ 
    229     @Override 
    230     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    231         return areLexicallyEqual(instance1, instance2); 
    232     } 
    233  
    234     /* (non-Javadoc) 
    235      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    236      */ 
    237     @Override 
    238     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    239         if (areLexicallyEqual(instance1, instance2)) { 
    240             return TaskEquality.LEXICALLY_EQUAL; 
    241         } 
    242         else { 
    243             return TaskEquality.UNEQUAL; 
    244         } 
    245     } 
    246  
    247     /** 
    248      * <p> 
    249      * compares two tasks with each other by calling the rule manager. If the rule manager returns 
    250      * identity, then the returned equality is set to lexically equal. The reason is, that 
    251      * the children of the iterations are compared and that therefore the distinct iterations 
    252      * can be at most lexically equal. 
    253      * </p> 
    254      *  
    255      * @param child1 the first task to be compared 
    256      * @param child2 the second task to be compared 
    257      *  
    258      * @return the determined equality being at most lexical equality. 
    259      */ 
    260     private TaskEquality getNodeEquality(ITask child1, ITask child2) { 
    261         TaskEquality taskEquality = callRuleManager(child1, child2, null); 
    262  
    263         if (taskEquality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)) { 
    264             // prevent, that identical is returned, because the iterations itself are not identical 
    265             // although the iterated tasks are 
    266             if (taskEquality == TaskEquality.IDENTICAL) { 
    267                 return TaskEquality.LEXICALLY_EQUAL; 
    268             } 
    269             else { 
    270                 return taskEquality; 
    271             } 
    272         } 
    273          
    274         return TaskEquality.UNEQUAL; 
    275     } 
    276  
    277     /** 
    278      * <p> 
    279      * compares two tasks. One of them must be a selection, the other one can be any task. 
    280      * The method returns a task equality that is not <code>NodeEquality.UNEQUAL</code> 
    281      * if the other task is at least semantically equal to the children of the selection. It 
    282      * returns more concrete equalities, if the equality between the other task and the children 
    283      * of the selection is more concrete. 
    284      * </p>  
    285      *  
    286      * @param task1 the first task to compare 
    287      * @param task2 the second task to compare 
    288      *  
    289      * @return as described 
    290      */ 
    291     private TaskEquality selectionChildrenSemanticallyEqualNode(ITask task1, ITask task2) { 
    292         ISelection selection = null; 
    293         ITask task = null; 
    294         if (task1 instanceof ISelection) { 
    295             selection = (ISelection) task1; 
    296             task = task2; 
    297         } 
    298         else if (task2 instanceof ISelection) { 
    299             selection = (ISelection) task2; 
    300             task = task1; 
    301         } 
    302         else { 
    303             return TaskEquality.UNEQUAL; 
    304         } 
    305  
    306         // Iterations, where one has a selection and the other one not can at most be syntactically 
    307         // equal but not identical 
    308         TaskEquality commonDenominatorForAllComparisons = TaskEquality.SYNTACTICALLY_EQUAL; 
    309  
    310         for (ITask child : selection.getChildren()) { 
    311             TaskEquality taskEquality = 
    312                   callRuleManager(task, child, commonDenominatorForAllComparisons); 
    313  
    314             if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 
    315                 return TaskEquality.UNEQUAL; 
    316             } 
    317              
    318             commonDenominatorForAllComparisons = 
    319                 commonDenominatorForAllComparisons.getCommonDenominator(taskEquality); 
    320         } 
    321  
    322         return commonDenominatorForAllComparisons; 
    323     } 
    324  
    325     /** 
    326      * <p> 
    327      * used to to call the task equality rule manager for the comparison of the two provided 
    328      * children. If no required equality level is provided, than the most concrete equality is 
    329      * returned. Otherwise, the required equality is returned as long as the children are equal 
    330      * on that level. 
    331      * </p>  
    332      *  
    333      * @param child1                the first task to be compared 
    334      * @param child2                the second task to be compared 
    335      * @param requiredEqualityLevel the equality level to be checked for 
    336      *  
    337      * @return the determined equality 
    338      */ 
    339     private TaskEquality callRuleManager(ITask        child1, 
    340                                          ITask        child2, 
    341                                          TaskEquality requiredEqualityLevel) 
    342     { 
    343         if (requiredEqualityLevel == null) { 
    344             return TaskEqualityRuleManager.getInstance().compare(child1, child2); 
    345         } 
    346         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    347                     (child1, child2, requiredEqualityLevel)) 
    348         { 
    349             return requiredEqualityLevel; 
    350         } 
    351         else { 
    352             return TaskEquality.UNEQUAL; 
    353         } 
    354     } 
    355      
    356     /** 
    357      * <p> 
    358      * used to to call the task equality rule manager for the comparison of the two provided 
    359      * children. If no required equality level is provided, than the most concrete equality is 
    360      * returned. Otherwise, the required equality is returned as long as the children are equal 
    361      * on that level. 
    362      * </p>  
    363      *  
    364      * @param taskInstance1         the first task instance to be compared 
    365      * @param taskInstance2         the second task instance to be compared 
    366      * @param requiredEqualityLevel the equality level to be checked for 
    367      *  
    368      * @return the determined equality 
    369      */ 
    370     private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
    371                                          ITaskInstance taskInstance2, 
    372                                          TaskEquality  requiredEqualityLevel) 
    373     { 
    374         if (requiredEqualityLevel == null) { 
    375             return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 
    376         } 
    377         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    378                      (taskInstance1, taskInstance2, requiredEqualityLevel)) 
    379         { 
    380             return requiredEqualityLevel; 
    381         } 
    382         else { 
    383             return TaskEquality.UNEQUAL; 
    384         } 
    385     } 
     86 
     87        /* 
     88         * (non-Javadoc) 
     89         *  
     90         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     91         */ 
     92        @Override 
     93        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     94                final ITask child1 = ((IIteration) task1).getMarkedTask(); 
     95                final ITask child2 = ((IIteration) task2).getMarkedTask(); 
     96 
     97                if (child1 != null) { 
     98                        if (child2 == null) { 
     99                                return false; 
     100                        } else { 
     101                                // iterations may have 3 different structures. 
     102                                // 1. they have one child, which is the iterated one 
     103                                // 2. they have a sequence of children, which is iterated 
     104                                // 3. they have a selection of different iterated variants 
     105                                // (usually the variants 
     106                                // are semantically equal) 
     107                                // ignore the type of the children but check them for equality. 
     108 
     109                                return getNodeEquality(child1, child2).isAtLeast( 
     110                                                TaskEquality.LEXICALLY_EQUAL); 
     111                        } 
     112                } else if (child2 == null) { 
     113                        return true; 
     114                } 
     115 
     116                return false; 
     117        } 
     118 
     119        /* 
     120         * (non-Javadoc) 
     121         *  
     122         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     123         */ 
     124        @Override 
     125        public boolean areLexicallyEqual(ITaskInstance instance1, 
     126                        ITaskInstance instance2) { 
     127                final IIterationInstance iteration1 = (IIterationInstance) instance1; 
     128                final IIterationInstance iteration2 = (IIterationInstance) instance2; 
     129 
     130                // if both sequences do not have children, they are equal although this 
     131                // doesn't make sense 
     132                if ((iteration1.size() == 0) && (iteration2.size() == 0)) { 
     133                        return true; 
     134                } 
     135 
     136                if (iteration1.size() != iteration2.size()) { 
     137                        return false; 
     138                } 
     139 
     140                for (int i = 0; i < iteration1.size(); i++) { 
     141                        final ITaskInstance child1 = iteration1.get(i); 
     142                        final ITaskInstance child2 = iteration2.get(i); 
     143 
     144                        final TaskEquality taskEquality = callRuleManager(child1, child2, 
     145                                        TaskEquality.LEXICALLY_EQUAL); 
     146 
     147                        if ((taskEquality == null) 
     148                                        || (taskEquality == TaskEquality.UNEQUAL)) { 
     149                                return false; 
     150                        } 
     151                } 
     152 
     153                return true; 
     154        } 
     155 
     156        /* 
     157         * (non-Javadoc) 
     158         *  
     159         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     160         */ 
     161        @Override 
     162        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     163                return compare(task1, task2).isAtLeast(TaskEquality.SEMANTICALLY_EQUAL); 
     164        } 
     165 
     166        /* 
     167         * (non-Javadoc) 
     168         *  
     169         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     170         * ITaskInstance) 
     171         */ 
     172        @Override 
     173        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     174                        ITaskInstance instance2) { 
     175                return areLexicallyEqual(instance1, instance2); 
     176        } 
     177 
     178        /* 
     179         * (non-Javadoc) 
     180         *  
     181         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     182         */ 
     183        @Override 
     184        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     185                return areLexicallyEqual(task1, task2); 
     186        } 
     187 
     188        /* 
     189         * (non-Javadoc) 
     190         *  
     191         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     192         * ITaskInstance) 
     193         */ 
     194        @Override 
     195        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     196                        ITaskInstance instance2) { 
     197                return areLexicallyEqual(instance1, instance2); 
     198        } 
     199 
     200        /** 
     201         * <p> 
     202         * used to to call the task equality rule manager for the comparison of the 
     203         * two provided children. If no required equality level is provided, than 
     204         * the most concrete equality is returned. Otherwise, the required equality 
     205         * is returned as long as the children are equal on that level. 
     206         * </p> 
     207         *  
     208         * @param child1 
     209         *            the first task to be compared 
     210         * @param child2 
     211         *            the second task to be compared 
     212         * @param requiredEqualityLevel 
     213         *            the equality level to be checked for 
     214         *  
     215         * @return the determined equality 
     216         */ 
     217        private TaskEquality callRuleManager(ITask child1, ITask child2, 
     218                        TaskEquality requiredEqualityLevel) { 
     219                if (requiredEqualityLevel == null) { 
     220                        return TaskEqualityRuleManager.getInstance() 
     221                                        .compare(child1, child2); 
     222                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     223                                child1, child2, requiredEqualityLevel)) { 
     224                        return requiredEqualityLevel; 
     225                } else { 
     226                        return TaskEquality.UNEQUAL; 
     227                } 
     228        } 
     229 
     230        /** 
     231         * <p> 
     232         * used to to call the task equality rule manager for the comparison of the 
     233         * two provided children. If no required equality level is provided, than 
     234         * the most concrete equality is returned. Otherwise, the required equality 
     235         * is returned as long as the children are equal on that level. 
     236         * </p> 
     237         *  
     238         * @param taskInstance1 
     239         *            the first task instance to be compared 
     240         * @param taskInstance2 
     241         *            the second task instance to be compared 
     242         * @param requiredEqualityLevel 
     243         *            the equality level to be checked for 
     244         *  
     245         * @return the determined equality 
     246         */ 
     247        private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
     248                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     249                if (requiredEqualityLevel == null) { 
     250                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 
     251                                        taskInstance2); 
     252                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     253                                taskInstance1, taskInstance2, requiredEqualityLevel)) { 
     254                        return requiredEqualityLevel; 
     255                } else { 
     256                        return TaskEquality.UNEQUAL; 
     257                } 
     258        } 
     259 
     260        /* 
     261         * (non-Javadoc) 
     262         *  
     263         * @see TaskComparisonRule#compare(ITask, ITask) 
     264         */ 
     265        @Override 
     266        public TaskEquality compare(ITask task1, ITask task2) { 
     267                final ITask child1 = ((IIteration) task1).getMarkedTask(); 
     268                final ITask child2 = ((IIteration) task2).getMarkedTask(); 
     269 
     270                // if both iterations do not have children, they are equal although this 
     271                // doesn't make sense 
     272                if ((child1 == null) && (child2 == null)) { 
     273                        return TaskEquality.LEXICALLY_EQUAL; 
     274                } else if ((child1 == null) || (child2 == null)) { 
     275                        return TaskEquality.UNEQUAL; 
     276                } 
     277 
     278                // iterations may have 3 different structures. 
     279                // 1. they have one child, which is the iterated one 
     280                // 2. they have a sequence of children, which is iterated 
     281                // 3. they have a selection of different iterated variants (usually the 
     282                // variants are 
     283                // semantically equal) 
     284                // 
     285                // the permutations of the three variants in combination must be checked 
     286 
     287                // check if both tasks are the same variants of iterations and if their 
     288                // children are equal. 
     289                // This condition matches, if both iterations are the same variants of 
     290                // iteration. I.e. three 
     291                // combinations of the permutation are handled herewith. 
     292                final TaskEquality taskEquality = getNodeEquality(child1, child2); 
     293 
     294                if (taskEquality != null) { 
     295                        return taskEquality; 
     296                } 
     297 
     298                // compare one iteration with a single task as a child and another one 
     299                // with a selection of 
     300                // semantically equal tasks 
     301                return selectionChildrenSemanticallyEqualNode(child1, child2); 
     302 
     303                // all other combinations (i.e. sequence with single child and sequence 
     304                // with selection) 
     305                // can not match 
     306        } 
     307 
     308        /* 
     309         * (non-Javadoc) 
     310         *  
     311         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     312         */ 
     313        @Override 
     314        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     315                if (areLexicallyEqual(instance1, instance2)) { 
     316                        return TaskEquality.LEXICALLY_EQUAL; 
     317                } else { 
     318                        return TaskEquality.UNEQUAL; 
     319                } 
     320        } 
     321 
     322        /** 
     323         * <p> 
     324         * compares two tasks with each other by calling the rule manager. If the 
     325         * rule manager returns identity, then the returned equality is set to 
     326         * lexically equal. The reason is, that the children of the iterations are 
     327         * compared and that therefore the distinct iterations can be at most 
     328         * lexically equal. 
     329         * </p> 
     330         *  
     331         * @param child1 
     332         *            the first task to be compared 
     333         * @param child2 
     334         *            the second task to be compared 
     335         *  
     336         * @return the determined equality being at most lexical equality. 
     337         */ 
     338        private TaskEquality getNodeEquality(ITask child1, ITask child2) { 
     339                final TaskEquality taskEquality = callRuleManager(child1, child2, null); 
     340 
     341                if (taskEquality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)) { 
     342                        // prevent, that identical is returned, because the iterations 
     343                        // itself are not identical 
     344                        // although the iterated tasks are 
     345                        if (taskEquality == TaskEquality.IDENTICAL) { 
     346                                return TaskEquality.LEXICALLY_EQUAL; 
     347                        } else { 
     348                                return taskEquality; 
     349                        } 
     350                } 
     351 
     352                return TaskEquality.UNEQUAL; 
     353        } 
     354 
     355        /* 
     356         * (non-Javadoc) 
     357         *  
     358         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     359         */ 
     360        @Override 
     361        public boolean isApplicable(ITask task1, ITask task2) { 
     362                return (task1 instanceof IIteration) && (task2 instanceof IIteration); 
     363        } 
     364 
     365        /* 
     366         * (non-Javadoc) 
     367         *  
     368         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     369         */ 
     370        @Override 
     371        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     372                return isApplicable(instance1.getTask(), instance2.getTask()); 
     373        } 
     374 
     375        /** 
     376         * <p> 
     377         * compares two tasks. One of them must be a selection, the other one can be 
     378         * any task. The method returns a task equality that is not 
     379         * <code>NodeEquality.UNEQUAL</code> if the other task is at least 
     380         * semantically equal to the children of the selection. It returns more 
     381         * concrete equalities, if the equality between the other task and the 
     382         * children of the selection is more concrete. 
     383         * </p> 
     384         *  
     385         * @param task1 
     386         *            the first task to compare 
     387         * @param task2 
     388         *            the second task to compare 
     389         *  
     390         * @return as described 
     391         */ 
     392        private TaskEquality selectionChildrenSemanticallyEqualNode(ITask task1, 
     393                        ITask task2) { 
     394                ISelection selection = null; 
     395                ITask task = null; 
     396                if (task1 instanceof ISelection) { 
     397                        selection = (ISelection) task1; 
     398                        task = task2; 
     399                } else if (task2 instanceof ISelection) { 
     400                        selection = (ISelection) task2; 
     401                        task = task1; 
     402                } else { 
     403                        return TaskEquality.UNEQUAL; 
     404                } 
     405 
     406                // Iterations, where one has a selection and the other one not can at 
     407                // most be syntactically 
     408                // equal but not identical 
     409                TaskEquality commonDenominatorForAllComparisons = TaskEquality.SYNTACTICALLY_EQUAL; 
     410 
     411                for (final ITask child : selection.getChildren()) { 
     412                        final TaskEquality taskEquality = callRuleManager(task, child, 
     413                                        commonDenominatorForAllComparisons); 
     414 
     415                        if ((taskEquality == null) 
     416                                        || (taskEquality == TaskEquality.UNEQUAL)) { 
     417                                return TaskEquality.UNEQUAL; 
     418                        } 
     419 
     420                        commonDenominatorForAllComparisons = commonDenominatorForAllComparisons 
     421                                        .getCommonDenominator(taskEquality); 
     422                } 
     423 
     424                return commonDenominatorForAllComparisons; 
     425        } 
    386426} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java

    r1294 r1733  
    2424/** 
    2525 * <p> 
    26  * this task comparison rule is capable of comparing selections. If both selections do not have 
    27  * children, they are treated as lexically equal. If they have children, each child of both 
    28  * selections is compared to each child of the respective other selection. The resulting equality 
    29  * is the most concrete one of all these comparisons. I.e. if all children are at least lexically 
    30  * equal, then the selections are lexically equal. If all children are at least syntactically 
    31  * equal, then the selections are syntactically equal. If all children are at least semantically 
    32  * equal, then the selections are semantically equal. If only one of the selections has children, 
    33  * then the selections are unequal. The comparison is broken up, if only a specific equality is 
    34  * checked for and this equality is ensured. 
     26 * this task comparison rule is capable of comparing selections. If both 
     27 * selections do not have children, they are treated as lexically equal. If they 
     28 * have children, each child of both selections is compared to each child of the 
     29 * respective other selection. The resulting equality is the most concrete one 
     30 * of all these comparisons. I.e. if all children are at least lexically equal, 
     31 * then the selections are lexically equal. If all children are at least 
     32 * syntactically equal, then the selections are syntactically equal. If all 
     33 * children are at least semantically equal, then the selections are 
     34 * semantically equal. If only one of the selections has children, then the 
     35 * selections are unequal. The comparison is broken up, if only a specific 
     36 * equality is checked for and this equality is ensured. 
    3537 * </p> 
    3638 *  
     
    4042public class SelectionComparisonRule implements TaskComparisonRule { 
    4143 
    42     /* (non-Javadoc) 
    43      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    44      */ 
    45     @Override 
    46     public boolean isApplicable(ITask task1, ITask task2) { 
    47         return (task1 instanceof ISelection) && (task2 instanceof ISelection); 
    48     } 
    49  
    50     /* (non-Javadoc) 
    51      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    52      */ 
    53     @Override 
    54     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    55         TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 
    56         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    57     } 
    58  
    59     /* (non-Javadoc) 
    60      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    61      */ 
    62     @Override 
    63     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    64         TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 
    65         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    66     } 
    67  
    68     /* (non-Javadoc) 
    69      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    70      */ 
    71     @Override 
    72     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    73         TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 
    74         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    75     } 
    76  
    77     /* (non-Javadoc) 
    78      * @see TaskComparisonRule#compare(ITask, ITask) 
    79      */ 
    80     @Override 
    81     public TaskEquality compare(ITask task1, ITask task2) { 
    82         return getEquality(task1, task2, null); 
    83     } 
    84  
    85     /* (non-Javadoc) 
    86      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    87      */ 
    88     @Override 
    89     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    90         return isApplicable(instance1.getTask(), instance2.getTask()); 
    91     } 
    92  
    93     /* (non-Javadoc) 
    94      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    95      */ 
    96     @Override 
    97     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    98         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 
    99         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    100     } 
    101  
    102     /* (non-Javadoc) 
    103      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    104      */ 
    105     @Override 
    106     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    107         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 
    108         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    109     } 
    110  
    111     /* (non-Javadoc) 
    112      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    113      */ 
    114     @Override 
    115     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    116         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 
    117         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    118     } 
    119  
    120     /* (non-Javadoc) 
    121      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    122      */ 
    123     @Override 
    124     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    125         return getEquality(instance1, instance2, null); 
    126     } 
    127  
    128     /** 
    129      * <p> 
    130      * compares two selections with each other checking for the provided required level of 
    131      * equality. If this level is ensured, the method immediately returns. The more concrete 
    132      * the required equality level, the more checks this method performs. 
    133      * </p> 
    134      *  
    135      * @param task1                 the first task to be compared 
    136      * @param task2                 the second task to be compared 
    137      * @param requiredEqualityLevel the equality level to be checked for 
    138      *  
    139      * @return the determined equality. 
    140      */ 
    141     private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 
    142         List<ITask> children1 = ((ISelection) task1).getChildren(); 
    143         List<ITask> children2 = ((ISelection) task2).getChildren(); 
    144  
    145         // if both selections do not have children, they are lexically equal. If only one of them 
    146         // has children, they are unequal. 
    147         if ((children1.size() == 0) && (children2.size() == 0)) { 
    148             return TaskEquality.LEXICALLY_EQUAL; 
    149         } 
    150         else if ((children1.size() == 0) || (children2.size() == 0)) { 
    151             return TaskEquality.UNEQUAL; 
    152         } 
    153  
    154         if (requiredEqualityLevel == null) { 
    155             // calculate the common equality level for all children of both selections. 
    156             // do it in both directions to ensure commutative comparison 
    157             return getMostConcreteEqualityLevel(children1, children2); 
    158         } 
    159         else { 
    160             // we are searching for a specific equality 
    161             if (checkEqualityLevel(children1, children2, requiredEqualityLevel)) { 
    162                 return requiredEqualityLevel; 
    163             } 
    164             else { 
    165                 return TaskEquality.UNEQUAL; 
    166             } 
    167         } 
    168     } 
    169  
    170     /** 
    171      * <p> 
    172      * determines the most concrete equality level for all tasks in the first list compared to all 
    173      * tasks in the second list. It is sufficient, if there is one task in one list for which there 
    174      * exist an equal task in the other list. 
    175      * </p> 
    176      * 
    177      * @param children1 the first list to be compared 
    178      * @param children2 the second list to be compared 
    179      *  
    180      * @return the most concrete task equality identified for all tasks in the first list with 
    181      *         respect to the second list 
    182      */ 
    183     private TaskEquality getMostConcreteEqualityLevel(List<ITask> children1, List<ITask> children2) 
    184     { 
    185         TaskEquality childEquality; 
    186         TaskEquality currentEquality; 
    187         for (ITask child1 : children1) { 
    188             childEquality = null; 
    189             for (ITask child2 : children2) { 
    190                 currentEquality = callRuleManager(child1, child2, null); 
    191                 if ((currentEquality != null) && (currentEquality != TaskEquality.UNEQUAL)) { 
    192                     if (childEquality == null) { 
    193                         childEquality = currentEquality; 
    194                     } 
    195                     else { 
    196                         childEquality = childEquality.getCommonDenominator(currentEquality); 
    197                     } 
    198                      
    199                     if (childEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) { 
    200                         // as we calculate the most concrete equality, we can break up here 
    201                         return TaskEquality.LEXICALLY_EQUAL; 
    202                     } 
    203                 } 
    204             } 
    205         } 
    206  
    207         // as the comparison should be commutative, we do not need to check, if in list 2 there is 
    208         // a child equal to one in list 1 
    209         return TaskEquality.UNEQUAL; 
    210     } 
    211  
    212     /** 
    213      * <p> 
    214      * ensures for the two given lists, that for at least one task in the first list there is a task 
    215      * in the second list being on the given level equal to the task in the first list. 
    216      * </p>  
    217      *  
    218      * @param children1             the first list to be compared 
    219      * @param children2             the second list to be compared 
    220      * @param requiredEqualityLevel the equality level to be checked for 
    221      *  
    222      * @return true if there is a task in the first list that has an equal task in the second list 
    223      *         when considering the given equality level, false else. 
    224      */ 
    225     private boolean checkEqualityLevel(List<ITask>  children1, 
    226                                        List<ITask>  children2, 
    227                                        TaskEquality requiredEqualityLevel) 
    228     { 
    229         TaskEquality currentEquality; 
    230         for (ITask child1 : children1) { 
    231             for (ITask child2 : children2) { 
    232                 currentEquality = callRuleManager(child1, child2, requiredEqualityLevel); 
    233                 if ((currentEquality != null) && (currentEquality.isAtLeast(requiredEqualityLevel))) 
    234                 { 
    235                     // we found at least one equal child with sufficient equality in the 
    236                     // second list. So be can break up for this child. 
    237                     return true; 
    238                 } 
    239             } 
    240         } 
    241  
    242         return false; 
    243     } 
    244  
    245     /** 
    246      * <p> 
    247      * used to to call the task equality rule manager for the comparison of the two provided 
    248      * children. If no required equality level is provided, than the most concrete equality is 
    249      * returned. Otherwise, the required equality is returned as long as the children are equal 
    250      * on that level. 
    251      * </p>  
    252      *  
    253      * @param child1                the first task to be compared 
    254      * @param child2                the second task to be compared 
    255      * @param requiredEqualityLevel the equality level to be checked for 
    256      *  
    257      * @return the determined equality 
    258      */ 
    259     private TaskEquality callRuleManager(ITask        child1, 
    260                                          ITask        child2, 
    261                                          TaskEquality requiredEqualityLevel) 
    262     { 
    263         if (requiredEqualityLevel == null) { 
    264             return TaskEqualityRuleManager.getInstance().compare(child1, child2); 
    265         } 
    266         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    267                      (child1, child2, requiredEqualityLevel)) 
    268         { 
    269             return requiredEqualityLevel; 
    270         } 
    271         else { 
    272             return TaskEquality.UNEQUAL; 
    273         } 
    274     } 
    275  
    276     /** 
    277      * <p> 
    278      * compares two selection instances with each other checking for the provided required level of 
    279      * equality. If this level is ensured, the method immediately returns. The more concrete 
    280      * the required equality level, the more checks this method performs. 
    281      * </p> 
    282      *  
    283      * @param taskInstance1         the first task instance to be compared 
    284      * @param taskInstance2         the second task instance to be compared 
    285      * @param requiredEqualityLevel the equality level to be checked for 
    286      *  
    287      * @return the determined equality. 
    288      */ 
    289     private TaskEquality getEquality(ITaskInstance taskInstance1, 
    290                                      ITaskInstance taskInstance2, 
    291                                      TaskEquality  requiredEqualityLevel) 
    292     { 
    293         ITaskInstance child1 = ((ISelectionInstance) taskInstance1).getChild(); 
    294         ITaskInstance child2 = ((ISelectionInstance) taskInstance2).getChild(); 
    295  
    296         // if both selections do not have children, they are lexically equal. If only one of them 
    297         // has children, they are unequal. 
    298         if ((child1 == null) && (child2 == null)) { 
    299             return TaskEquality.LEXICALLY_EQUAL; 
    300         } 
    301         else if ((child1 == null) || (child2 == null)) { 
    302             return TaskEquality.UNEQUAL; 
    303         } 
    304  
    305         TaskEquality equality = callRuleManager(child1, child2, requiredEqualityLevel); 
    306          
    307         if (equality == TaskEquality.IDENTICAL) { 
    308             // two different selection instances can be at most lexically equal even if their 
    309             // children are identical 
    310             return TaskEquality.LEXICALLY_EQUAL; 
    311         } 
    312         else { 
    313             return equality; 
    314         } 
    315     } 
    316  
    317     /** 
    318      * <p> 
    319      * used to to call the task equality rule manager for the comparison of the two provided 
    320      * children. If no required equality level is provided, than the most concrete equality is 
    321      * returned. Otherwise, the required equality is returned as long as the children are equal 
    322      * on that level. 
    323      * </p>  
    324      *  
    325      * @param taskInstance1         the first task instance to be compared 
    326      * @param taskInstance2         the second task instance to be compared 
    327      * @param requiredEqualityLevel the equality level to be checked for 
    328      *  
    329      * @return the determined equality 
    330      */ 
    331     private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
    332                                          ITaskInstance taskInstance2, 
    333                                          TaskEquality  requiredEqualityLevel) 
    334     { 
    335         if (requiredEqualityLevel == null) { 
    336             return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 
    337         } 
    338         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    339                      (taskInstance1, taskInstance2, requiredEqualityLevel)) 
    340         { 
    341             return requiredEqualityLevel; 
    342         } 
    343         else { 
    344             return TaskEquality.UNEQUAL; 
    345         } 
    346     } 
     44        /* 
     45         * (non-Javadoc) 
     46         *  
     47         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     48         */ 
     49        @Override 
     50        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     51                final TaskEquality equality = getEquality(task1, task2, 
     52                                TaskEquality.LEXICALLY_EQUAL); 
     53                return (equality != null) 
     54                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     55        } 
     56 
     57        /* 
     58         * (non-Javadoc) 
     59         *  
     60         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     61         */ 
     62        @Override 
     63        public boolean areLexicallyEqual(ITaskInstance instance1, 
     64                        ITaskInstance instance2) { 
     65                final TaskEquality equality = getEquality(instance1, instance2, 
     66                                TaskEquality.LEXICALLY_EQUAL); 
     67                return (equality != null) 
     68                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     69        } 
     70 
     71        /* 
     72         * (non-Javadoc) 
     73         *  
     74         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     75         */ 
     76        @Override 
     77        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     78                final TaskEquality equality = getEquality(task1, task2, 
     79                                TaskEquality.SEMANTICALLY_EQUAL); 
     80                return (equality != null) 
     81                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     82        } 
     83 
     84        /* 
     85         * (non-Javadoc) 
     86         *  
     87         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     88         * ITaskInstance) 
     89         */ 
     90        @Override 
     91        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     92                        ITaskInstance instance2) { 
     93                final TaskEquality equality = getEquality(instance1, instance2, 
     94                                TaskEquality.SEMANTICALLY_EQUAL); 
     95                return (equality != null) 
     96                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     97        } 
     98 
     99        /* 
     100         * (non-Javadoc) 
     101         *  
     102         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     103         */ 
     104        @Override 
     105        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     106                final TaskEquality equality = getEquality(task1, task2, 
     107                                TaskEquality.SYNTACTICALLY_EQUAL); 
     108                return (equality != null) 
     109                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     110        } 
     111 
     112        /* 
     113         * (non-Javadoc) 
     114         *  
     115         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     116         * ITaskInstance) 
     117         */ 
     118        @Override 
     119        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     120                        ITaskInstance instance2) { 
     121                final TaskEquality equality = getEquality(instance1, instance2, 
     122                                TaskEquality.SYNTACTICALLY_EQUAL); 
     123                return (equality != null) 
     124                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     125        } 
     126 
     127        /** 
     128         * <p> 
     129         * used to to call the task equality rule manager for the comparison of the 
     130         * two provided children. If no required equality level is provided, than 
     131         * the most concrete equality is returned. Otherwise, the required equality 
     132         * is returned as long as the children are equal on that level. 
     133         * </p> 
     134         *  
     135         * @param child1 
     136         *            the first task to be compared 
     137         * @param child2 
     138         *            the second task to be compared 
     139         * @param requiredEqualityLevel 
     140         *            the equality level to be checked for 
     141         *  
     142         * @return the determined equality 
     143         */ 
     144        private TaskEquality callRuleManager(ITask child1, ITask child2, 
     145                        TaskEquality requiredEqualityLevel) { 
     146                if (requiredEqualityLevel == null) { 
     147                        return TaskEqualityRuleManager.getInstance() 
     148                                        .compare(child1, child2); 
     149                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     150                                child1, child2, requiredEqualityLevel)) { 
     151                        return requiredEqualityLevel; 
     152                } else { 
     153                        return TaskEquality.UNEQUAL; 
     154                } 
     155        } 
     156 
     157        /** 
     158         * <p> 
     159         * used to to call the task equality rule manager for the comparison of the 
     160         * two provided children. If no required equality level is provided, than 
     161         * the most concrete equality is returned. Otherwise, the required equality 
     162         * is returned as long as the children are equal on that level. 
     163         * </p> 
     164         *  
     165         * @param taskInstance1 
     166         *            the first task instance to be compared 
     167         * @param taskInstance2 
     168         *            the second task instance to be compared 
     169         * @param requiredEqualityLevel 
     170         *            the equality level to be checked for 
     171         *  
     172         * @return the determined equality 
     173         */ 
     174        private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
     175                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     176                if (requiredEqualityLevel == null) { 
     177                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 
     178                                        taskInstance2); 
     179                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     180                                taskInstance1, taskInstance2, requiredEqualityLevel)) { 
     181                        return requiredEqualityLevel; 
     182                } else { 
     183                        return TaskEquality.UNEQUAL; 
     184                } 
     185        } 
     186 
     187        /** 
     188         * <p> 
     189         * ensures for the two given lists, that for at least one task in the first 
     190         * list there is a task in the second list being on the given level equal to 
     191         * the task in the first list. 
     192         * </p> 
     193         *  
     194         * @param children1 
     195         *            the first list to be compared 
     196         * @param children2 
     197         *            the second list to be compared 
     198         * @param requiredEqualityLevel 
     199         *            the equality level to be checked for 
     200         *  
     201         * @return true if there is a task in the first list that has an equal task 
     202         *         in the second list when considering the given equality level, 
     203         *         false else. 
     204         */ 
     205        private boolean checkEqualityLevel(List<ITask> children1, 
     206                        List<ITask> children2, TaskEquality requiredEqualityLevel) { 
     207                TaskEquality currentEquality; 
     208                for (final ITask child1 : children1) { 
     209                        for (final ITask child2 : children2) { 
     210                                currentEquality = callRuleManager(child1, child2, 
     211                                                requiredEqualityLevel); 
     212                                if ((currentEquality != null) 
     213                                                && (currentEquality.isAtLeast(requiredEqualityLevel))) { 
     214                                        // we found at least one equal child with sufficient 
     215                                        // equality in the 
     216                                        // second list. So be can break up for this child. 
     217                                        return true; 
     218                                } 
     219                        } 
     220                } 
     221 
     222                return false; 
     223        } 
     224 
     225        /* 
     226         * (non-Javadoc) 
     227         *  
     228         * @see TaskComparisonRule#compare(ITask, ITask) 
     229         */ 
     230        @Override 
     231        public TaskEquality compare(ITask task1, ITask task2) { 
     232                return getEquality(task1, task2, null); 
     233        } 
     234 
     235        /* 
     236         * (non-Javadoc) 
     237         *  
     238         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     239         */ 
     240        @Override 
     241        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     242                return getEquality(instance1, instance2, null); 
     243        } 
     244 
     245        /** 
     246         * <p> 
     247         * compares two selections with each other checking for the provided 
     248         * required level of equality. If this level is ensured, the method 
     249         * immediately returns. The more concrete the required equality level, the 
     250         * more checks this method performs. 
     251         * </p> 
     252         *  
     253         * @param task1 
     254         *            the first task to be compared 
     255         * @param task2 
     256         *            the second task to be compared 
     257         * @param requiredEqualityLevel 
     258         *            the equality level to be checked for 
     259         *  
     260         * @return the determined equality. 
     261         */ 
     262        private TaskEquality getEquality(ITask task1, ITask task2, 
     263                        TaskEquality requiredEqualityLevel) { 
     264                final List<ITask> children1 = ((ISelection) task1).getChildren(); 
     265                final List<ITask> children2 = ((ISelection) task2).getChildren(); 
     266 
     267                // if both selections do not have children, they are lexically equal. If 
     268                // only one of them 
     269                // has children, they are unequal. 
     270                if ((children1.size() == 0) && (children2.size() == 0)) { 
     271                        return TaskEquality.LEXICALLY_EQUAL; 
     272                } else if ((children1.size() == 0) || (children2.size() == 0)) { 
     273                        return TaskEquality.UNEQUAL; 
     274                } 
     275 
     276                if (requiredEqualityLevel == null) { 
     277                        // calculate the common equality level for all children of both 
     278                        // selections. 
     279                        // do it in both directions to ensure commutative comparison 
     280                        return getMostConcreteEqualityLevel(children1, children2); 
     281                } else { 
     282                        // we are searching for a specific equality 
     283                        if (checkEqualityLevel(children1, children2, requiredEqualityLevel)) { 
     284                                return requiredEqualityLevel; 
     285                        } else { 
     286                                return TaskEquality.UNEQUAL; 
     287                        } 
     288                } 
     289        } 
     290 
     291        /** 
     292         * <p> 
     293         * compares two selection instances with each other checking for the 
     294         * provided required level of equality. If this level is ensured, the method 
     295         * immediately returns. The more concrete the required equality level, the 
     296         * more checks this method performs. 
     297         * </p> 
     298         *  
     299         * @param taskInstance1 
     300         *            the first task instance to be compared 
     301         * @param taskInstance2 
     302         *            the second task instance to be compared 
     303         * @param requiredEqualityLevel 
     304         *            the equality level to be checked for 
     305         *  
     306         * @return the determined equality. 
     307         */ 
     308        private TaskEquality getEquality(ITaskInstance taskInstance1, 
     309                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     310                final ITaskInstance child1 = ((ISelectionInstance) taskInstance1) 
     311                                .getChild(); 
     312                final ITaskInstance child2 = ((ISelectionInstance) taskInstance2) 
     313                                .getChild(); 
     314 
     315                // if both selections do not have children, they are lexically equal. If 
     316                // only one of them 
     317                // has children, they are unequal. 
     318                if ((child1 == null) && (child2 == null)) { 
     319                        return TaskEquality.LEXICALLY_EQUAL; 
     320                } else if ((child1 == null) || (child2 == null)) { 
     321                        return TaskEquality.UNEQUAL; 
     322                } 
     323 
     324                final TaskEquality equality = callRuleManager(child1, child2, 
     325                                requiredEqualityLevel); 
     326 
     327                if (equality == TaskEquality.IDENTICAL) { 
     328                        // two different selection instances can be at most lexically equal 
     329                        // even if their 
     330                        // children are identical 
     331                        return TaskEquality.LEXICALLY_EQUAL; 
     332                } else { 
     333                        return equality; 
     334                } 
     335        } 
     336 
     337        /** 
     338         * <p> 
     339         * determines the most concrete equality level for all tasks in the first 
     340         * list compared to all tasks in the second list. It is sufficient, if there 
     341         * is one task in one list for which there exist an equal task in the other 
     342         * list. 
     343         * </p> 
     344         * 
     345         * @param children1 
     346         *            the first list to be compared 
     347         * @param children2 
     348         *            the second list to be compared 
     349         *  
     350         * @return the most concrete task equality identified for all tasks in the 
     351         *         first list with respect to the second list 
     352         */ 
     353        private TaskEquality getMostConcreteEqualityLevel(List<ITask> children1, 
     354                        List<ITask> children2) { 
     355                TaskEquality childEquality; 
     356                TaskEquality currentEquality; 
     357                for (final ITask child1 : children1) { 
     358                        childEquality = null; 
     359                        for (final ITask child2 : children2) { 
     360                                currentEquality = callRuleManager(child1, child2, null); 
     361                                if ((currentEquality != null) 
     362                                                && (currentEquality != TaskEquality.UNEQUAL)) { 
     363                                        if (childEquality == null) { 
     364                                                childEquality = currentEquality; 
     365                                        } else { 
     366                                                childEquality = childEquality 
     367                                                                .getCommonDenominator(currentEquality); 
     368                                        } 
     369 
     370                                        if (childEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) { 
     371                                                // as we calculate the most concrete equality, we can 
     372                                                // break up here 
     373                                                return TaskEquality.LEXICALLY_EQUAL; 
     374                                        } 
     375                                } 
     376                        } 
     377                } 
     378 
     379                // as the comparison should be commutative, we do not need to check, if 
     380                // in list 2 there is 
     381                // a child equal to one in list 1 
     382                return TaskEquality.UNEQUAL; 
     383        } 
     384 
     385        /* 
     386         * (non-Javadoc) 
     387         *  
     388         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     389         */ 
     390        @Override 
     391        public boolean isApplicable(ITask task1, ITask task2) { 
     392                return (task1 instanceof ISelection) && (task2 instanceof ISelection); 
     393        } 
     394 
     395        /* 
     396         * (non-Javadoc) 
     397         *  
     398         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     399         */ 
     400        @Override 
     401        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     402                return isApplicable(instance1.getTask(), instance2.getTask()); 
     403        } 
    347404} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java

    r1294 r1733  
    2424/** 
    2525 * <p> 
    26  * This rule is capable of comparing sequences. If both sequences do not have children, they are 
    27  * treated as lexically equal. Sequences are lexically equal, if they have the same number and 
    28  * order of lexically equal children. The rule can not decide, if two sequences are syntactically 
    29  * or semantically equal. 
     26 * This rule is capable of comparing sequences. If both sequences do not have 
     27 * children, they are treated as lexically equal. Sequences are lexically equal, 
     28 * if they have the same number and order of lexically equal children. The rule 
     29 * can not decide, if two sequences are syntactically or semantically equal. 
    3030 * </p> 
    3131 *  
     
    3535public class SequenceComparisonRule implements TaskComparisonRule { 
    3636 
    37     /* (non-Javadoc) 
    38      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    39      */ 
    40     @Override 
    41     public boolean isApplicable(ITask task1, ITask task2) { 
    42         return (task1 instanceof ISequence) && (task2 instanceof ISequence); 
    43     } 
    44  
    45     /* (non-Javadoc) 
    46      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    47      */ 
    48     @Override 
    49     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    50         TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 
    51         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    52     } 
    53  
    54     /* (non-Javadoc) 
    55      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    56      */ 
    57     @Override 
    58     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    59         TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 
    60         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    61     } 
    62  
    63     /* (non-Javadoc) 
    64      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    65      */ 
    66     @Override 
    67     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    68         TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 
    69         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    70     } 
    71  
    72     /* (non-Javadoc) 
    73      * @see TaskComparisonRule#compare(ITask, ITask) 
    74      */ 
    75     @Override 
    76     public TaskEquality compare(ITask task1, ITask task2) { 
    77         return getEquality(task1, task2, null); 
    78     } 
    79  
    80     /* (non-Javadoc) 
    81      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    82      */ 
    83     @Override 
    84     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    85         return isApplicable(instance1.getTask(), instance2.getTask()); 
    86     } 
    87  
    88     /* (non-Javadoc) 
    89      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    90      */ 
    91     @Override 
    92     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    93         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 
    94         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    95     } 
    96  
    97     /* (non-Javadoc) 
    98      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    99      */ 
    100     @Override 
    101     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    102         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 
    103         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    104     } 
    105  
    106     /* (non-Javadoc) 
    107      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    108      */ 
    109     @Override 
    110     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    111         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 
    112         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    113     } 
    114  
    115     /* (non-Javadoc) 
    116      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    117      */ 
    118     @Override 
    119     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    120         return getEquality(instance1, instance2, null); 
    121     } 
    122  
    123     /** 
    124      * <p> 
    125      * compares two sequences with each other checking for the provided required level of 
    126      * equality. If this level is ensured, the method immediately returns. The more concrete 
    127      * the required equality level, the more checks this method performs. 
    128      * </p> 
    129      *  
    130      * @param task1                 the first task to be compared 
    131      * @param task2                 the second task to be compared 
    132      * @param requiredEqualityLevel the equality level to be checked for 
    133      *  
    134      * @return the determined equality. 
    135      */ 
    136     private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 
    137         List<ITask> children1 = ((ISequence) task1).getChildren(); 
    138         List<ITask> children2 = ((ISequence) task2).getChildren(); 
    139  
    140         // if both sequences do not have children, they are equal although this doesn't make sense 
    141         if ((children1.size() == 0) && (children2.size() == 0)) { 
    142             return TaskEquality.LEXICALLY_EQUAL; 
    143         } 
    144  
    145         if (children1.size() != children2.size()) { 
    146             return TaskEquality.UNEQUAL; 
    147         } 
    148  
    149         TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 
    150         for (int i = 0; i < children1.size(); i++) { 
    151             ITask child1 = children1.get(i); 
    152             ITask child2 = children2.get(i); 
    153  
    154             TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel); 
    155  
    156             if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 
    157                 return TaskEquality.UNEQUAL; 
    158             } 
    159              
    160             resultingEquality = resultingEquality.getCommonDenominator(taskEquality); 
    161         } 
    162  
    163         return resultingEquality; 
    164     } 
    165  
    166     /** 
    167      * <p> 
    168      * used to to call the task equality rule manager for the comparison of the two provided 
    169      * children. If no required equality level is provided, than the most concrete equality is 
    170      * returned. Otherwise, the required equality is returned as long as the children are equal 
    171      * on that level. 
    172      * </p>  
    173      *  
    174      * @param child1                the first task to be compared 
    175      * @param child2                the second task to be compared 
    176      * @param requiredEqualityLevel the equality level to be checked for 
    177      *  
    178      * @return the determined equality 
    179      */ 
    180     private TaskEquality callRuleManager(ITask        child1, 
    181                                          ITask        child2, 
    182                                          TaskEquality requiredEqualityLevel) 
    183     { 
    184         if (requiredEqualityLevel == null) { 
    185             return TaskEqualityRuleManager.getInstance().compare(child1, child2); 
    186         } 
    187         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    188                     (child1, child2, requiredEqualityLevel)) 
    189         { 
    190             return requiredEqualityLevel; 
    191         } 
    192         else { 
    193             return TaskEquality.UNEQUAL; 
    194         } 
    195     } 
    196  
    197     /** 
    198      * <p> 
    199      * compares two sequence instances with each other checking for the provided required level of 
    200      * equality. If this level is ensured, the method immediately returns. The more concrete 
    201      * the required equality level, the more checks this method performs. 
    202      * </p> 
    203      *  
    204      * @param taskInstance1         the first task instance to be compared 
    205      * @param taskInstance2         the second task instance to be compared 
    206      * @param requiredEqualityLevel the equality level to be checked for 
    207      *  
    208      * @return the determined equality. 
    209      */ 
    210     private TaskEquality getEquality(ITaskInstance taskInstance1, 
    211                                      ITaskInstance taskInstance2, 
    212                                      TaskEquality  requiredEqualityLevel) 
    213     { 
    214         ISequenceInstance sequence1 = (ISequenceInstance) taskInstance1; 
    215         ISequenceInstance sequence2 = (ISequenceInstance) taskInstance2; 
    216  
    217         // if both sequences do not have children, they are equal although this doesn't make sense 
    218         if ((sequence1.size() == 0) && (sequence2.size() == 0)) { 
    219             return TaskEquality.LEXICALLY_EQUAL; 
    220         } 
    221  
    222         if (sequence1.size() != sequence2.size()) { 
    223             return TaskEquality.UNEQUAL; 
    224         } 
    225  
    226         TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 
    227         for (int i = 0; i < sequence1.size(); i++) { 
    228             ITaskInstance child1 = sequence1.get(i); 
    229             ITaskInstance child2 = sequence2.get(i); 
    230  
    231             TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel); 
    232  
    233             if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 
    234                 return TaskEquality.UNEQUAL; 
    235             } 
    236              
    237             resultingEquality = resultingEquality.getCommonDenominator(taskEquality); 
    238         } 
    239  
    240         return resultingEquality; 
    241     } 
    242      
    243     /** 
    244      * <p> 
    245      * used to to call the task equality rule manager for the comparison of the two provided 
    246      * children. If no required equality level is provided, than the most concrete equality is 
    247      * returned. Otherwise, the required equality is returned as long as the children are equal 
    248      * on that level. 
    249      * </p>  
    250      *  
    251      * @param taskInstance1         the first task instance to be compared 
    252      * @param taskInstance2         the second task instance to be compared 
    253      * @param requiredEqualityLevel the equality level to be checked for 
    254      *  
    255      * @return the determined equality 
    256      */ 
    257     private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
    258                                          ITaskInstance taskInstance2, 
    259                                          TaskEquality  requiredEqualityLevel) 
    260     { 
    261         if (requiredEqualityLevel == null) { 
    262             return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 
    263         } 
    264         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    265                      (taskInstance1, taskInstance2, requiredEqualityLevel)) 
    266         { 
    267             return requiredEqualityLevel; 
    268         } 
    269         else { 
    270             return TaskEquality.UNEQUAL; 
    271         } 
    272     } 
     37        /* 
     38         * (non-Javadoc) 
     39         *  
     40         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     41         */ 
     42        @Override 
     43        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     44                final TaskEquality equality = getEquality(task1, task2, 
     45                                TaskEquality.LEXICALLY_EQUAL); 
     46                return (equality != null) 
     47                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     48        } 
     49 
     50        /* 
     51         * (non-Javadoc) 
     52         *  
     53         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     54         */ 
     55        @Override 
     56        public boolean areLexicallyEqual(ITaskInstance instance1, 
     57                        ITaskInstance instance2) { 
     58                final TaskEquality equality = getEquality(instance1, instance2, 
     59                                TaskEquality.LEXICALLY_EQUAL); 
     60                return (equality != null) 
     61                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     62        } 
     63 
     64        /* 
     65         * (non-Javadoc) 
     66         *  
     67         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     68         */ 
     69        @Override 
     70        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     71                final TaskEquality equality = getEquality(task1, task2, 
     72                                TaskEquality.SEMANTICALLY_EQUAL); 
     73                return (equality != null) 
     74                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     75        } 
     76 
     77        /* 
     78         * (non-Javadoc) 
     79         *  
     80         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     81         * ITaskInstance) 
     82         */ 
     83        @Override 
     84        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     85                        ITaskInstance instance2) { 
     86                final TaskEquality equality = getEquality(instance1, instance2, 
     87                                TaskEquality.SEMANTICALLY_EQUAL); 
     88                return (equality != null) 
     89                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     90        } 
     91 
     92        /* 
     93         * (non-Javadoc) 
     94         *  
     95         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     96         */ 
     97        @Override 
     98        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     99                final TaskEquality equality = getEquality(task1, task2, 
     100                                TaskEquality.SYNTACTICALLY_EQUAL); 
     101                return (equality != null) 
     102                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     103        } 
     104 
     105        /* 
     106         * (non-Javadoc) 
     107         *  
     108         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     109         * ITaskInstance) 
     110         */ 
     111        @Override 
     112        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     113                        ITaskInstance instance2) { 
     114                final TaskEquality equality = getEquality(instance1, instance2, 
     115                                TaskEquality.SYNTACTICALLY_EQUAL); 
     116                return (equality != null) 
     117                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     118        } 
     119 
     120        /** 
     121         * <p> 
     122         * used to to call the task equality rule manager for the comparison of the 
     123         * two provided children. If no required equality level is provided, than 
     124         * the most concrete equality is returned. Otherwise, the required equality 
     125         * is returned as long as the children are equal on that level. 
     126         * </p> 
     127         *  
     128         * @param child1 
     129         *            the first task to be compared 
     130         * @param child2 
     131         *            the second task to be compared 
     132         * @param requiredEqualityLevel 
     133         *            the equality level to be checked for 
     134         *  
     135         * @return the determined equality 
     136         */ 
     137        private TaskEquality callRuleManager(ITask child1, ITask child2, 
     138                        TaskEquality requiredEqualityLevel) { 
     139                if (requiredEqualityLevel == null) { 
     140                        return TaskEqualityRuleManager.getInstance() 
     141                                        .compare(child1, child2); 
     142                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     143                                child1, child2, requiredEqualityLevel)) { 
     144                        return requiredEqualityLevel; 
     145                } else { 
     146                        return TaskEquality.UNEQUAL; 
     147                } 
     148        } 
     149 
     150        /** 
     151         * <p> 
     152         * used to to call the task equality rule manager for the comparison of the 
     153         * two provided children. If no required equality level is provided, than 
     154         * the most concrete equality is returned. Otherwise, the required equality 
     155         * is returned as long as the children are equal on that level. 
     156         * </p> 
     157         *  
     158         * @param taskInstance1 
     159         *            the first task instance to be compared 
     160         * @param taskInstance2 
     161         *            the second task instance to be compared 
     162         * @param requiredEqualityLevel 
     163         *            the equality level to be checked for 
     164         *  
     165         * @return the determined equality 
     166         */ 
     167        private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
     168                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     169                if (requiredEqualityLevel == null) { 
     170                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 
     171                                        taskInstance2); 
     172                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     173                                taskInstance1, taskInstance2, requiredEqualityLevel)) { 
     174                        return requiredEqualityLevel; 
     175                } else { 
     176                        return TaskEquality.UNEQUAL; 
     177                } 
     178        } 
     179 
     180        /* 
     181         * (non-Javadoc) 
     182         *  
     183         * @see TaskComparisonRule#compare(ITask, ITask) 
     184         */ 
     185        @Override 
     186        public TaskEquality compare(ITask task1, ITask task2) { 
     187                return getEquality(task1, task2, null); 
     188        } 
     189 
     190        /* 
     191         * (non-Javadoc) 
     192         *  
     193         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     194         */ 
     195        @Override 
     196        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     197                return getEquality(instance1, instance2, null); 
     198        } 
     199 
     200        /** 
     201         * <p> 
     202         * compares two sequences with each other checking for the provided required 
     203         * level of equality. If this level is ensured, the method immediately 
     204         * returns. The more concrete the required equality level, the more checks 
     205         * this method performs. 
     206         * </p> 
     207         *  
     208         * @param task1 
     209         *            the first task to be compared 
     210         * @param task2 
     211         *            the second task to be compared 
     212         * @param requiredEqualityLevel 
     213         *            the equality level to be checked for 
     214         *  
     215         * @return the determined equality. 
     216         */ 
     217        private TaskEquality getEquality(ITask task1, ITask task2, 
     218                        TaskEquality requiredEqualityLevel) { 
     219                final List<ITask> children1 = ((ISequence) task1).getChildren(); 
     220                final List<ITask> children2 = ((ISequence) task2).getChildren(); 
     221 
     222                // if both sequences do not have children, they are equal although this 
     223                // doesn't make sense 
     224                if ((children1.size() == 0) && (children2.size() == 0)) { 
     225                        return TaskEquality.LEXICALLY_EQUAL; 
     226                } 
     227 
     228                if (children1.size() != children2.size()) { 
     229                        return TaskEquality.UNEQUAL; 
     230                } 
     231 
     232                TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 
     233                for (int i = 0; i < children1.size(); i++) { 
     234                        final ITask child1 = children1.get(i); 
     235                        final ITask child2 = children2.get(i); 
     236 
     237                        final TaskEquality taskEquality = callRuleManager(child1, child2, 
     238                                        requiredEqualityLevel); 
     239 
     240                        if ((taskEquality == null) 
     241                                        || (taskEquality == TaskEquality.UNEQUAL)) { 
     242                                return TaskEquality.UNEQUAL; 
     243                        } 
     244 
     245                        resultingEquality = resultingEquality 
     246                                        .getCommonDenominator(taskEquality); 
     247                } 
     248 
     249                return resultingEquality; 
     250        } 
     251 
     252        /** 
     253         * <p> 
     254         * compares two sequence instances with each other checking for the provided 
     255         * required level of equality. If this level is ensured, the method 
     256         * immediately returns. The more concrete the required equality level, the 
     257         * more checks this method performs. 
     258         * </p> 
     259         *  
     260         * @param taskInstance1 
     261         *            the first task instance to be compared 
     262         * @param taskInstance2 
     263         *            the second task instance to be compared 
     264         * @param requiredEqualityLevel 
     265         *            the equality level to be checked for 
     266         *  
     267         * @return the determined equality. 
     268         */ 
     269        private TaskEquality getEquality(ITaskInstance taskInstance1, 
     270                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     271                final ISequenceInstance sequence1 = (ISequenceInstance) taskInstance1; 
     272                final ISequenceInstance sequence2 = (ISequenceInstance) taskInstance2; 
     273 
     274                // if both sequences do not have children, they are equal although this 
     275                // doesn't make sense 
     276                if ((sequence1.size() == 0) && (sequence2.size() == 0)) { 
     277                        return TaskEquality.LEXICALLY_EQUAL; 
     278                } 
     279 
     280                if (sequence1.size() != sequence2.size()) { 
     281                        return TaskEquality.UNEQUAL; 
     282                } 
     283 
     284                TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 
     285                for (int i = 0; i < sequence1.size(); i++) { 
     286                        final ITaskInstance child1 = sequence1.get(i); 
     287                        final ITaskInstance child2 = sequence2.get(i); 
     288 
     289                        final TaskEquality taskEquality = callRuleManager(child1, child2, 
     290                                        requiredEqualityLevel); 
     291 
     292                        if ((taskEquality == null) 
     293                                        || (taskEquality == TaskEquality.UNEQUAL)) { 
     294                                return TaskEquality.UNEQUAL; 
     295                        } 
     296 
     297                        resultingEquality = resultingEquality 
     298                                        .getCommonDenominator(taskEquality); 
     299                } 
     300 
     301                return resultingEquality; 
     302        } 
     303 
     304        /* 
     305         * (non-Javadoc) 
     306         *  
     307         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     308         */ 
     309        @Override 
     310        public boolean isApplicable(ITask task1, ITask task2) { 
     311                return (task1 instanceof ISequence) && (task2 instanceof ISequence); 
     312        } 
     313 
     314        /* 
     315         * (non-Javadoc) 
     316         *  
     317         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     318         */ 
     319        @Override 
     320        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     321                return isApplicable(instance1.getTask(), instance2.getTask()); 
     322        } 
    273323} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java

    r1294 r1733  
    2323 * <p> 
    2424 * This class is capable of comparing any task which is not an iteration with an 
    25  * iteration. This is needed, because iterations may iterate exactly that task. In this 
    26  * case, the iteration would be equal to that task if it was executed exactly once. The rule 
    27  * returns lexically equal, it the child of the iteration is lexically equal to the task 
    28  * or if the child of the iteration is a selection and this selections contains a lexically equal 
    29  * task. The same applies for syntactical and semantical equality. 
     25 * iteration. This is needed, because iterations may iterate exactly that task. 
     26 * In this case, the iteration would be equal to that task if it was executed 
     27 * exactly once. The rule returns lexically equal, it the child of the iteration 
     28 * is lexically equal to the task or if the child of the iteration is a 
     29 * selection and this selections contains a lexically equal task. The same 
     30 * applies for syntactical and semantical equality. 
    3031 * </p> 
    31  
     32 *  
    3233 * @author Patrick Harms 
    3334 */ 
    3435public class TaskAndIterationComparisonRule implements TaskComparisonRule { 
    35      
    36     /* (non-Javadoc) 
    37      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    38      */ 
    39     @Override 
    40     public boolean isApplicable(ITask task1, ITask task2) { 
    41         return ((task1 instanceof IIteration) && (!(task2 instanceof IIteration))) || 
    42                ((task2 instanceof IIteration) && (!(task1 instanceof IIteration))); 
    43     } 
    44  
    45     /* (non-Javadoc) 
    46      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    47      */ 
    48     @Override 
    49     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    50         TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 
    51         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    52     } 
    53  
    54     /* (non-Javadoc) 
    55      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    56      */ 
    57     @Override 
    58     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    59         TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 
    60         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    61     } 
    62  
    63     /* (non-Javadoc) 
    64      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    65      */ 
    66     @Override 
    67     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    68         TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 
    69         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    70     } 
    71  
    72     /* (non-Javadoc) 
    73      * @see TaskComparisonRule#compare(ITask, ITask) 
    74      */ 
    75     @Override 
    76     public TaskEquality compare(ITask task1, ITask task2) { 
    77         return getEquality(task1, task2, null); 
    78     } 
    79  
    80     /* (non-Javadoc) 
    81      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    82      */ 
    83     @Override 
    84     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    85         return isApplicable(instance1.getTask(), instance2.getTask()); 
    86     } 
    87  
    88     /* (non-Javadoc) 
    89      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    90      */ 
    91     @Override 
    92     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    93         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 
    94         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    95     } 
    96  
    97     /* (non-Javadoc) 
    98      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    99      */ 
    100     @Override 
    101     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    102         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 
    103         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    104     } 
    105  
    106     /* (non-Javadoc) 
    107      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    108      */ 
    109     @Override 
    110     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    111         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 
    112         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    113     } 
    114  
    115     /* (non-Javadoc) 
    116      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    117      */ 
    118     @Override 
    119     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    120         return getEquality(instance1, instance2, null); 
    121     } 
    122  
    123     /** 
    124      * <p> 
    125      * compares two tasks with each other checking for the provided required level of 
    126      * equality. One of the tasks must be an iteration, the other one not. If this is not the 
    127      * case, the method returns null. The returned equality level is at most lexical equality 
    128      * as the iteration can not be identical to something not being an iteration. 
    129      * </p> 
    130      *  
    131      * @param task1                 the first task to be compared 
    132      * @param task2                 the second task to be compared 
    133      * @param requiredEqualityLevel the equality level to be checked for 
    134      *  
    135      * @return the determined equality. 
    136      */ 
    137     private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 
    138         IIteration iteration = null; 
    139         ITask task = null; 
    140          
    141         if (task1 instanceof IIteration) { 
    142             if (task2 instanceof IIteration) { 
    143                 // the rule is not responsible for two iterations 
    144                 return null; 
    145             } 
    146              
    147             iteration = (IIteration) task1; 
    148             task = task2; 
    149         } 
    150         else if (task2 instanceof IIteration) { 
    151             if (task1 instanceof IIteration) { 
    152                 // the rule is not responsible for two iterations 
    153                 return null; 
    154             } 
    155              
    156             iteration = (IIteration) task2; 
    157             task = task1; 
    158         } 
    159         else { 
    160             return null; 
    161         } 
    162  
    163         ITask child = iteration.getMarkedTask(); 
    164          
    165         // now, that we found the iteration and the task, lets compare the child of the iteration 
    166         // with the task. 
    167         if (child == null) { 
    168             return null; 
    169         } 
    170  
    171         TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 
    172  
    173         // although the subtask may be identical to the task, we can not return identical, as 
    174         // the iteration is not identical to the task, but at most lexically equal 
    175         if (taskEquality == TaskEquality.IDENTICAL) { 
    176             return TaskEquality.LEXICALLY_EQUAL; 
    177         } 
    178         else { 
    179             return taskEquality; 
    180         } 
    181  
    182     } 
    183      
    184     /** 
    185      * <p> 
    186      * used to to call the task equality rule manager for the comparison of the two provided 
    187      * children. If no required equality level is provided, than the most concrete equality is 
    188      * returned. Otherwise, the required equality is returned as long as the children are equal 
    189      * on that level. 
    190      * </p>  
    191      *  
    192      * @param child1                the first task to be compared 
    193      * @param child2                the second task to be compared 
    194      * @param requiredEqualityLevel the equality level to be checked for 
    195      *  
    196      * @return the determined equality 
    197      */ 
    198     private TaskEquality callRuleManager(ITask        child1, 
    199                                          ITask        child2, 
    200                                          TaskEquality requiredEqualityLevel) 
    201     { 
    202         if (requiredEqualityLevel == null) { 
    203             return TaskEqualityRuleManager.getInstance().compare(child1, child2); 
    204         } 
    205         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    206                      (child1, child2, requiredEqualityLevel)) 
    207         { 
    208             return requiredEqualityLevel; 
    209         } 
    210         else { 
    211             return TaskEquality.UNEQUAL; 
    212         } 
    213     } 
    214  
    215     /** 
    216      * <p> 
    217      * compares two task instances with each other checking for the provided required level of 
    218      * equality. One of the task instances must be a iteration, the other one not. If this is not 
    219      * the case, the method returns null. The returned equality level is at most lexical equality 
    220      * as the iteration can not be identical to something not being a iteration. 
    221      * </p> 
    222      *  
    223      * @param taskInstance1         the first task instance to be compared 
    224      * @param taskInstance2         the second task instance to be compared 
    225      * @param requiredEqualityLevel the equality level to be checked for 
    226      *  
    227      * @return the determined equality. 
    228      */ 
    229     private TaskEquality getEquality(ITaskInstance taskInstance1, 
    230                                      ITaskInstance taskInstance2, 
    231                                      TaskEquality  requiredEqualityLevel) 
    232     { 
    233         IIterationInstance iteration = null; 
    234         ITaskInstance task = null; 
    235          
    236         if (taskInstance1 instanceof IIterationInstance) { 
    237             if (taskInstance2 instanceof IIterationInstance) { 
    238                 // the rule is not responsible for two iterations 
    239                 return null; 
    240             } 
    241              
    242             iteration = (IIterationInstance) taskInstance1; 
    243             task = taskInstance2; 
    244         } 
    245         else if (taskInstance2 instanceof IIterationInstance) { 
    246             if (taskInstance1 instanceof IIterationInstance) { 
    247                 // the rule is not responsible for two iterations 
    248                 return null; 
    249             } 
    250              
    251             iteration = (IIterationInstance) taskInstance2; 
    252             task = taskInstance1; 
    253         } 
    254         else { 
    255             return null; 
    256         } 
    257  
    258         // now, that we found the iteration and the task, lets compare the children of the iteration 
    259         // with the task. 
    260          
    261         if (iteration.size() < 1) { 
    262             return null; 
    263         } 
    264  
    265         TaskEquality mostConcreteNodeEquality = null; 
    266          
    267         for (ITaskInstance child : iteration) { 
    268             TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 
    269              
    270             if (taskEquality != TaskEquality.UNEQUAL) { 
    271                 if (mostConcreteNodeEquality == null) { 
    272                     mostConcreteNodeEquality = taskEquality; 
    273                 } 
    274                 else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 
    275                     mostConcreteNodeEquality = taskEquality; 
    276                      
    277                 } 
    278                  
    279                 if ((requiredEqualityLevel != null) && 
    280                     (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel))) 
    281                 { 
    282                     // if we found one child of the selection that is as equal as required, then 
    283                     // we can consider the selection to be sufficiently equal to the other task. 
    284                     // So we break up checking further children. 
    285                     break; 
    286                 } 
    287             } 
    288         } 
    289          
    290         // although the subtask may be identical to the task, we can not return identical, as 
    291         // the selection is not identical to the task, but at most lexically equal 
    292         if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 
    293             return TaskEquality.LEXICALLY_EQUAL; 
    294         } 
    295         else { 
    296             return mostConcreteNodeEquality; 
    297         } 
    298  
    299     } 
    300      
    301     /** 
    302      * <p> 
    303      * used to to call the task equality rule manager for the comparison of the two provided 
    304      * children. If no required equality level is provided, than the most concrete equality is 
    305      * returned. Otherwise, the required equality is returned as long as the children are equal 
    306      * on that level. 
    307      * </p>  
    308      *  
    309      * @param taskInstance1         the first task instance to be compared 
    310      * @param taskInstance2         the second task instance to be compared 
    311      * @param requiredEqualityLevel the equality level to be checked for 
    312      *  
    313      * @return the determined equality 
    314      */ 
    315     private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
    316                                          ITaskInstance taskInstance2, 
    317                                          TaskEquality  requiredEqualityLevel) 
    318     { 
    319         if (requiredEqualityLevel == null) { 
    320             return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 
    321         } 
    322         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    323                      (taskInstance1, taskInstance2, requiredEqualityLevel)) 
    324         { 
    325             return requiredEqualityLevel; 
    326         } 
    327         else { 
    328             return TaskEquality.UNEQUAL; 
    329         } 
    330     } 
     36 
     37        /* 
     38         * (non-Javadoc) 
     39         *  
     40         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     41         */ 
     42        @Override 
     43        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     44                final TaskEquality equality = getEquality(task1, task2, 
     45                                TaskEquality.LEXICALLY_EQUAL); 
     46                return (equality != null) 
     47                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     48        } 
     49 
     50        /* 
     51         * (non-Javadoc) 
     52         *  
     53         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     54         */ 
     55        @Override 
     56        public boolean areLexicallyEqual(ITaskInstance instance1, 
     57                        ITaskInstance instance2) { 
     58                final TaskEquality equality = getEquality(instance1, instance2, 
     59                                TaskEquality.LEXICALLY_EQUAL); 
     60                return (equality != null) 
     61                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     62        } 
     63 
     64        /* 
     65         * (non-Javadoc) 
     66         *  
     67         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     68         */ 
     69        @Override 
     70        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     71                final TaskEquality equality = getEquality(task1, task2, 
     72                                TaskEquality.SEMANTICALLY_EQUAL); 
     73                return (equality != null) 
     74                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     75        } 
     76 
     77        /* 
     78         * (non-Javadoc) 
     79         *  
     80         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     81         * ITaskInstance) 
     82         */ 
     83        @Override 
     84        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     85                        ITaskInstance instance2) { 
     86                final TaskEquality equality = getEquality(instance1, instance2, 
     87                                TaskEquality.SEMANTICALLY_EQUAL); 
     88                return (equality != null) 
     89                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     90        } 
     91 
     92        /* 
     93         * (non-Javadoc) 
     94         *  
     95         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     96         */ 
     97        @Override 
     98        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     99                final TaskEquality equality = getEquality(task1, task2, 
     100                                TaskEquality.SYNTACTICALLY_EQUAL); 
     101                return (equality != null) 
     102                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     103        } 
     104 
     105        /* 
     106         * (non-Javadoc) 
     107         *  
     108         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     109         * ITaskInstance) 
     110         */ 
     111        @Override 
     112        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     113                        ITaskInstance instance2) { 
     114                final TaskEquality equality = getEquality(instance1, instance2, 
     115                                TaskEquality.SYNTACTICALLY_EQUAL); 
     116                return (equality != null) 
     117                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     118        } 
     119 
     120        /** 
     121         * <p> 
     122         * used to to call the task equality rule manager for the comparison of the 
     123         * two provided children. If no required equality level is provided, than 
     124         * the most concrete equality is returned. Otherwise, the required equality 
     125         * is returned as long as the children are equal on that level. 
     126         * </p> 
     127         *  
     128         * @param child1 
     129         *            the first task to be compared 
     130         * @param child2 
     131         *            the second task to be compared 
     132         * @param requiredEqualityLevel 
     133         *            the equality level to be checked for 
     134         *  
     135         * @return the determined equality 
     136         */ 
     137        private TaskEquality callRuleManager(ITask child1, ITask child2, 
     138                        TaskEquality requiredEqualityLevel) { 
     139                if (requiredEqualityLevel == null) { 
     140                        return TaskEqualityRuleManager.getInstance() 
     141                                        .compare(child1, child2); 
     142                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     143                                child1, child2, requiredEqualityLevel)) { 
     144                        return requiredEqualityLevel; 
     145                } else { 
     146                        return TaskEquality.UNEQUAL; 
     147                } 
     148        } 
     149 
     150        /** 
     151         * <p> 
     152         * used to to call the task equality rule manager for the comparison of the 
     153         * two provided children. If no required equality level is provided, than 
     154         * the most concrete equality is returned. Otherwise, the required equality 
     155         * is returned as long as the children are equal on that level. 
     156         * </p> 
     157         *  
     158         * @param taskInstance1 
     159         *            the first task instance to be compared 
     160         * @param taskInstance2 
     161         *            the second task instance to be compared 
     162         * @param requiredEqualityLevel 
     163         *            the equality level to be checked for 
     164         *  
     165         * @return the determined equality 
     166         */ 
     167        private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
     168                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     169                if (requiredEqualityLevel == null) { 
     170                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 
     171                                        taskInstance2); 
     172                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     173                                taskInstance1, taskInstance2, requiredEqualityLevel)) { 
     174                        return requiredEqualityLevel; 
     175                } else { 
     176                        return TaskEquality.UNEQUAL; 
     177                } 
     178        } 
     179 
     180        /* 
     181         * (non-Javadoc) 
     182         *  
     183         * @see TaskComparisonRule#compare(ITask, ITask) 
     184         */ 
     185        @Override 
     186        public TaskEquality compare(ITask task1, ITask task2) { 
     187                return getEquality(task1, task2, null); 
     188        } 
     189 
     190        /* 
     191         * (non-Javadoc) 
     192         *  
     193         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     194         */ 
     195        @Override 
     196        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     197                return getEquality(instance1, instance2, null); 
     198        } 
     199 
     200        /** 
     201         * <p> 
     202         * compares two tasks with each other checking for the provided required 
     203         * level of equality. One of the tasks must be an iteration, the other one 
     204         * not. If this is not the case, the method returns null. The returned 
     205         * equality level is at most lexical equality as the iteration can not be 
     206         * identical to something not being an iteration. 
     207         * </p> 
     208         *  
     209         * @param task1 
     210         *            the first task to be compared 
     211         * @param task2 
     212         *            the second task to be compared 
     213         * @param requiredEqualityLevel 
     214         *            the equality level to be checked for 
     215         *  
     216         * @return the determined equality. 
     217         */ 
     218        private TaskEquality getEquality(ITask task1, ITask task2, 
     219                        TaskEquality requiredEqualityLevel) { 
     220                IIteration iteration = null; 
     221                ITask task = null; 
     222 
     223                if (task1 instanceof IIteration) { 
     224                        if (task2 instanceof IIteration) { 
     225                                // the rule is not responsible for two iterations 
     226                                return null; 
     227                        } 
     228 
     229                        iteration = (IIteration) task1; 
     230                        task = task2; 
     231                } else if (task2 instanceof IIteration) { 
     232                        if (task1 instanceof IIteration) { 
     233                                // the rule is not responsible for two iterations 
     234                                return null; 
     235                        } 
     236 
     237                        iteration = (IIteration) task2; 
     238                        task = task1; 
     239                } else { 
     240                        return null; 
     241                } 
     242 
     243                final ITask child = iteration.getMarkedTask(); 
     244 
     245                // now, that we found the iteration and the task, lets compare the child 
     246                // of the iteration 
     247                // with the task. 
     248                if (child == null) { 
     249                        return null; 
     250                } 
     251 
     252                final TaskEquality taskEquality = callRuleManager(child, task, 
     253                                requiredEqualityLevel); 
     254 
     255                // although the subtask may be identical to the task, we can not return 
     256                // identical, as 
     257                // the iteration is not identical to the task, but at most lexically 
     258                // equal 
     259                if (taskEquality == TaskEquality.IDENTICAL) { 
     260                        return TaskEquality.LEXICALLY_EQUAL; 
     261                } else { 
     262                        return taskEquality; 
     263                } 
     264 
     265        } 
     266 
     267        /** 
     268         * <p> 
     269         * compares two task instances with each other checking for the provided 
     270         * required level of equality. One of the task instances must be a 
     271         * iteration, the other one not. If this is not the case, the method returns 
     272         * null. The returned equality level is at most lexical equality as the 
     273         * iteration can not be identical to something not being a iteration. 
     274         * </p> 
     275         *  
     276         * @param taskInstance1 
     277         *            the first task instance to be compared 
     278         * @param taskInstance2 
     279         *            the second task instance to be compared 
     280         * @param requiredEqualityLevel 
     281         *            the equality level to be checked for 
     282         *  
     283         * @return the determined equality. 
     284         */ 
     285        private TaskEquality getEquality(ITaskInstance taskInstance1, 
     286                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     287                IIterationInstance iteration = null; 
     288                ITaskInstance task = null; 
     289 
     290                if (taskInstance1 instanceof IIterationInstance) { 
     291                        if (taskInstance2 instanceof IIterationInstance) { 
     292                                // the rule is not responsible for two iterations 
     293                                return null; 
     294                        } 
     295 
     296                        iteration = (IIterationInstance) taskInstance1; 
     297                        task = taskInstance2; 
     298                } else if (taskInstance2 instanceof IIterationInstance) { 
     299                        if (taskInstance1 instanceof IIterationInstance) { 
     300                                // the rule is not responsible for two iterations 
     301                                return null; 
     302                        } 
     303 
     304                        iteration = (IIterationInstance) taskInstance2; 
     305                        task = taskInstance1; 
     306                } else { 
     307                        return null; 
     308                } 
     309 
     310                // now, that we found the iteration and the task, lets compare the 
     311                // children of the iteration 
     312                // with the task. 
     313 
     314                if (iteration.size() < 1) { 
     315                        return null; 
     316                } 
     317 
     318                TaskEquality mostConcreteNodeEquality = null; 
     319 
     320                for (final ITaskInstance child : iteration) { 
     321                        final TaskEquality taskEquality = callRuleManager(child, task, 
     322                                        requiredEqualityLevel); 
     323 
     324                        if (taskEquality != TaskEquality.UNEQUAL) { 
     325                                if (mostConcreteNodeEquality == null) { 
     326                                        mostConcreteNodeEquality = taskEquality; 
     327                                } else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 
     328                                        mostConcreteNodeEquality = taskEquality; 
     329 
     330                                } 
     331 
     332                                if ((requiredEqualityLevel != null) 
     333                                                && (mostConcreteNodeEquality 
     334                                                                .isAtLeast(requiredEqualityLevel))) { 
     335                                        // if we found one child of the selection that is as equal 
     336                                        // as required, then 
     337                                        // we can consider the selection to be sufficiently equal to 
     338                                        // the other task. 
     339                                        // So we break up checking further children. 
     340                                        break; 
     341                                } 
     342                        } 
     343                } 
     344 
     345                // although the subtask may be identical to the task, we can not return 
     346                // identical, as 
     347                // the selection is not identical to the task, but at most lexically 
     348                // equal 
     349                if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 
     350                        return TaskEquality.LEXICALLY_EQUAL; 
     351                } else { 
     352                        return mostConcreteNodeEquality; 
     353                } 
     354 
     355        } 
     356 
     357        /* 
     358         * (non-Javadoc) 
     359         *  
     360         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     361         */ 
     362        @Override 
     363        public boolean isApplicable(ITask task1, ITask task2) { 
     364                return ((task1 instanceof IIteration) && (!(task2 instanceof IIteration))) 
     365                                || ((task2 instanceof IIteration) && (!(task1 instanceof IIteration))); 
     366        } 
     367 
     368        /* 
     369         * (non-Javadoc) 
     370         *  
     371         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     372         */ 
     373        @Override 
     374        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     375                return isApplicable(instance1.getTask(), instance2.getTask()); 
     376        } 
    331377} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java

    r1294 r1733  
    2525 * <p> 
    2626 * This class is capable of comparing any task which is not a selection with a 
    27  * selection. This is needed, because selections may contain exactly that task. Therefore, if 
    28  * this task is selected out of a selection the selection is equal to the task itself.  
    29  * The rule returns lexically equal, if the selection contains a lexically equal task. The same 
    30  * applies for syntactical and semantical equality. 
     27 * selection. This is needed, because selections may contain exactly that task. 
     28 * Therefore, if this task is selected out of a selection the selection is equal 
     29 * to the task itself. The rule returns lexically equal, if the selection 
     30 * contains a lexically equal task. The same applies for syntactical and 
     31 * semantical equality. 
    3132 * </p> 
    32  
     33 *  
    3334 * @author Patrick Harms 
    3435 */ 
    3536public class TaskAndSelectionComparisonRule implements TaskComparisonRule { 
    36      
    37     /* (non-Javadoc) 
    38      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    39      */ 
    40     @Override 
    41     public boolean isApplicable(ITask task1, ITask task2) { 
    42         return ((task1 instanceof ISelection) && (!(task2 instanceof ISelection))) || 
    43                ((task2 instanceof ISelection) && (!(task1 instanceof ISelection))); 
    44     } 
    45  
    46     /* (non-Javadoc) 
    47      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    48      */ 
    49     @Override 
    50     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    51         TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 
    52         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    53     } 
    54  
    55     /* (non-Javadoc) 
    56      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    57      */ 
    58     @Override 
    59     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    60         TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 
    61         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    62     } 
    63  
    64     /* (non-Javadoc) 
    65      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    66      */ 
    67     @Override 
    68     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    69         TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 
    70         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    71     } 
    72  
    73     /* (non-Javadoc) 
    74      * @see TaskComparisonRule#compare(ITask, ITask) 
    75      */ 
    76     @Override 
    77     public TaskEquality compare(ITask task1, ITask task2) { 
    78         return getEquality(task1, task2, null); 
    79     } 
    80      
    81     /* (non-Javadoc) 
    82      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    83      */ 
    84     @Override 
    85     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    86         return isApplicable(instance1.getTask(), instance2.getTask()); 
    87     } 
    88  
    89     /* (non-Javadoc) 
    90      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    91      */ 
    92     @Override 
    93     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    94         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 
    95         return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
    96     } 
    97  
    98     /* (non-Javadoc) 
    99      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    100      */ 
    101     @Override 
    102     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    103         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 
    104         return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
    105     } 
    106  
    107     /* (non-Javadoc) 
    108      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    109      */ 
    110     @Override 
    111     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    112         TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 
    113         return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
    114     } 
    115  
    116     /* (non-Javadoc) 
    117      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    118      */ 
    119     @Override 
    120     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    121         return getEquality(instance1, instance2, null); 
    122     } 
    123  
    124     /** 
    125      * <p> 
    126      * compares two tasks with each other checking for the provided required level of 
    127      * equality. One of the tasks must be a selection, the other one not. If this is not the 
    128      * case, the method returns null. The returned equality level is at most lexical equality 
    129      * as the selection can not be identical to something not being a selection. 
    130      * </p> 
    131      *  
    132      * @param task1                 the first task to be compared 
    133      * @param task2                 the second task to be compared 
    134      * @param requiredEqualityLevel the equality level to be checked for 
    135      *  
    136      * @return the determined equality. 
    137      */ 
    138     private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 
    139         ISelection selection = null; 
    140         ITask task = null; 
    141          
    142         if (task1 instanceof ISelection) { 
    143             if (task2 instanceof ISelection) { 
    144                 // the rule is not responsible for two selections 
    145                 return null; 
    146             } 
    147              
    148             selection = (ISelection) task1; 
    149             task = task2; 
    150         } 
    151         else if (task2 instanceof ISelection) { 
    152             if (task1 instanceof ISelection) { 
    153                 // the rule is not responsible for two selections 
    154                 return null; 
    155             } 
    156              
    157             selection = (ISelection) task2; 
    158             task = task1; 
    159         } 
    160         else { 
    161             return null; 
    162         } 
    163  
    164         // now, that we found the selection and the task, lets compare the children of the selection 
    165         // with the task. 
    166         List<ITask> children = selection.getChildren(); 
    167          
    168         if (children.size() < 1) { 
    169             return null; 
    170         } 
    171  
    172         TaskEquality mostConcreteNodeEquality = null; 
    173          
    174         for (ITask child : children) { 
    175             TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 
    176              
    177             if (taskEquality != TaskEquality.UNEQUAL) { 
    178                 if (mostConcreteNodeEquality == null) { 
    179                     mostConcreteNodeEquality = taskEquality; 
    180                 } 
    181                 else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 
    182                     mostConcreteNodeEquality = taskEquality; 
    183                      
    184                 } 
    185                  
    186                 if ((requiredEqualityLevel != null) && 
    187                     (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel))) 
    188                 { 
    189                     // if we found one child of the selection that is as equal as required, then 
    190                     // we can consider the selection to be sufficiently equal to the other task. 
    191                     // So we break up checking further children. 
    192                     break; 
    193                 } 
    194             } 
    195         } 
    196          
    197         // although the subtask may be identical to the task, we can not return identical, as 
    198         // the selection is not identical to the task, but at most lexically equal 
    199         if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 
    200             return TaskEquality.LEXICALLY_EQUAL; 
    201         } 
    202         else { 
    203             return mostConcreteNodeEquality; 
    204         } 
    205  
    206     } 
    207      
    208     /** 
    209      * <p> 
    210      * used to to call the task equality rule manager for the comparison of the two provided 
    211      * children. If no required equality level is provided, than the most concrete equality is 
    212      * returned. Otherwise, the required equality is returned as long as the children are equal 
    213      * on that level. 
    214      * </p>  
    215      *  
    216      * @param child1                the first task to be compared 
    217      * @param child2                the second task to be compared 
    218      * @param requiredEqualityLevel the equality level to be checked for 
    219      *  
    220      * @return the determined equality 
    221      */ 
    222     private TaskEquality callRuleManager(ITask        child1, 
    223                                          ITask        child2, 
    224                                          TaskEquality requiredEqualityLevel) 
    225     { 
    226         if (requiredEqualityLevel == null) { 
    227             return TaskEqualityRuleManager.getInstance().compare(child1, child2); 
    228         } 
    229         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    230                      (child1, child2, requiredEqualityLevel)) 
    231         { 
    232             return requiredEqualityLevel; 
    233         } 
    234         else { 
    235             return TaskEquality.UNEQUAL; 
    236         } 
    237     } 
    238  
    239     /** 
    240      * <p> 
    241      * compares two task instances with each other checking for the provided required level of 
    242      * equality. One of the task instances must be a selection, the other one not. If this is not 
    243      * the case, the method returns null. The returned equality level is at most lexical equality 
    244      * as the selection can not be identical to something not being a selection. 
    245      * </p> 
    246      *  
    247      * @param taskInstance1         the first task instance to be compared 
    248      * @param taskInstance2         the second task instance to be compared 
    249      * @param requiredEqualityLevel the equality level to be checked for 
    250      *  
    251      * @return the determined equality. 
    252      */ 
    253     private TaskEquality getEquality(ITaskInstance taskInstance1, 
    254                                      ITaskInstance taskInstance2, 
    255                                      TaskEquality  requiredEqualityLevel) 
    256     { 
    257         ISelectionInstance selection = null; 
    258         ITaskInstance task = null; 
    259          
    260         if (taskInstance1 instanceof ISelectionInstance) { 
    261             if (taskInstance2 instanceof ISelectionInstance) { 
    262                 // the rule is not responsible for two selections 
    263                 return null; 
    264             } 
    265              
    266             selection = (ISelectionInstance) taskInstance1; 
    267             task = taskInstance2; 
    268         } 
    269         else if (taskInstance2 instanceof ISelectionInstance) { 
    270             if (taskInstance1 instanceof ISelectionInstance) { 
    271                 // the rule is not responsible for two selections 
    272                 return null; 
    273             } 
    274              
    275             selection = (ISelectionInstance) taskInstance2; 
    276             task = taskInstance1; 
    277         } 
    278         else { 
    279             return null; 
    280         } 
    281  
    282         // now, that we found the selection and the task, lets compare the child of the selection 
    283         // with the task. 
    284         ITaskInstance child = selection.getChild(); 
    285          
    286         if (child == null) { 
    287             return null; 
    288         } 
    289  
    290         TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 
    291  
    292         // although the subtask may be identical to the task, we can not return identical, as 
    293         // the selection is not identical to the task, but at most lexically equal 
    294         if (taskEquality == TaskEquality.IDENTICAL) { 
    295             return TaskEquality.LEXICALLY_EQUAL; 
    296         } 
    297         else { 
    298             return taskEquality; 
    299         } 
    300  
    301     } 
    302      
    303     /** 
    304      * <p> 
    305      * used to to call the task equality rule manager for the comparison of the two provided 
    306      * children. If no required equality level is provided, than the most concrete equality is 
    307      * returned. Otherwise, the required equality is returned as long as the children are equal 
    308      * on that level. 
    309      * </p>  
    310      *  
    311      * @param taskInstance1         the first task instance to be compared 
    312      * @param taskInstance2         the second task instance to be compared 
    313      * @param requiredEqualityLevel the equality level to be checked for 
    314      *  
    315      * @return the determined equality 
    316      */ 
    317     private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
    318                                          ITaskInstance taskInstance2, 
    319                                          TaskEquality  requiredEqualityLevel) 
    320     { 
    321         if (requiredEqualityLevel == null) { 
    322             return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 
    323         } 
    324         else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    325                      (taskInstance1, taskInstance2, requiredEqualityLevel)) 
    326         { 
    327             return requiredEqualityLevel; 
    328         } 
    329         else { 
    330             return TaskEquality.UNEQUAL; 
    331         } 
    332     } 
     37 
     38        /* 
     39         * (non-Javadoc) 
     40         *  
     41         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     42         */ 
     43        @Override 
     44        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     45                final TaskEquality equality = getEquality(task1, task2, 
     46                                TaskEquality.LEXICALLY_EQUAL); 
     47                return (equality != null) 
     48                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     49        } 
     50 
     51        /* 
     52         * (non-Javadoc) 
     53         *  
     54         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     55         */ 
     56        @Override 
     57        public boolean areLexicallyEqual(ITaskInstance instance1, 
     58                        ITaskInstance instance2) { 
     59                final TaskEquality equality = getEquality(instance1, instance2, 
     60                                TaskEquality.LEXICALLY_EQUAL); 
     61                return (equality != null) 
     62                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 
     63        } 
     64 
     65        /* 
     66         * (non-Javadoc) 
     67         *  
     68         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     69         */ 
     70        @Override 
     71        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     72                final TaskEquality equality = getEquality(task1, task2, 
     73                                TaskEquality.SEMANTICALLY_EQUAL); 
     74                return (equality != null) 
     75                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     76        } 
     77 
     78        /* 
     79         * (non-Javadoc) 
     80         *  
     81         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     82         * ITaskInstance) 
     83         */ 
     84        @Override 
     85        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     86                        ITaskInstance instance2) { 
     87                final TaskEquality equality = getEquality(instance1, instance2, 
     88                                TaskEquality.SEMANTICALLY_EQUAL); 
     89                return (equality != null) 
     90                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 
     91        } 
     92 
     93        /* 
     94         * (non-Javadoc) 
     95         *  
     96         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     97         */ 
     98        @Override 
     99        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     100                final TaskEquality equality = getEquality(task1, task2, 
     101                                TaskEquality.SYNTACTICALLY_EQUAL); 
     102                return (equality != null) 
     103                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     104        } 
     105 
     106        /* 
     107         * (non-Javadoc) 
     108         *  
     109         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     110         * ITaskInstance) 
     111         */ 
     112        @Override 
     113        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     114                        ITaskInstance instance2) { 
     115                final TaskEquality equality = getEquality(instance1, instance2, 
     116                                TaskEquality.SYNTACTICALLY_EQUAL); 
     117                return (equality != null) 
     118                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 
     119        } 
     120 
     121        /** 
     122         * <p> 
     123         * used to to call the task equality rule manager for the comparison of the 
     124         * two provided children. If no required equality level is provided, than 
     125         * the most concrete equality is returned. Otherwise, the required equality 
     126         * is returned as long as the children are equal on that level. 
     127         * </p> 
     128         *  
     129         * @param child1 
     130         *            the first task to be compared 
     131         * @param child2 
     132         *            the second task to be compared 
     133         * @param requiredEqualityLevel 
     134         *            the equality level to be checked for 
     135         *  
     136         * @return the determined equality 
     137         */ 
     138        private TaskEquality callRuleManager(ITask child1, ITask child2, 
     139                        TaskEquality requiredEqualityLevel) { 
     140                if (requiredEqualityLevel == null) { 
     141                        return TaskEqualityRuleManager.getInstance() 
     142                                        .compare(child1, child2); 
     143                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     144                                child1, child2, requiredEqualityLevel)) { 
     145                        return requiredEqualityLevel; 
     146                } else { 
     147                        return TaskEquality.UNEQUAL; 
     148                } 
     149        } 
     150 
     151        /** 
     152         * <p> 
     153         * used to to call the task equality rule manager for the comparison of the 
     154         * two provided children. If no required equality level is provided, than 
     155         * the most concrete equality is returned. Otherwise, the required equality 
     156         * is returned as long as the children are equal on that level. 
     157         * </p> 
     158         *  
     159         * @param taskInstance1 
     160         *            the first task instance to be compared 
     161         * @param taskInstance2 
     162         *            the second task instance to be compared 
     163         * @param requiredEqualityLevel 
     164         *            the equality level to be checked for 
     165         *  
     166         * @return the determined equality 
     167         */ 
     168        private TaskEquality callRuleManager(ITaskInstance taskInstance1, 
     169                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     170                if (requiredEqualityLevel == null) { 
     171                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 
     172                                        taskInstance2); 
     173                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 
     174                                taskInstance1, taskInstance2, requiredEqualityLevel)) { 
     175                        return requiredEqualityLevel; 
     176                } else { 
     177                        return TaskEquality.UNEQUAL; 
     178                } 
     179        } 
     180 
     181        /* 
     182         * (non-Javadoc) 
     183         *  
     184         * @see TaskComparisonRule#compare(ITask, ITask) 
     185         */ 
     186        @Override 
     187        public TaskEquality compare(ITask task1, ITask task2) { 
     188                return getEquality(task1, task2, null); 
     189        } 
     190 
     191        /* 
     192         * (non-Javadoc) 
     193         *  
     194         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     195         */ 
     196        @Override 
     197        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     198                return getEquality(instance1, instance2, null); 
     199        } 
     200 
     201        /** 
     202         * <p> 
     203         * compares two tasks with each other checking for the provided required 
     204         * level of equality. One of the tasks must be a selection, the other one 
     205         * not. If this is not the case, the method returns null. The returned 
     206         * equality level is at most lexical equality as the selection can not be 
     207         * identical to something not being a selection. 
     208         * </p> 
     209         *  
     210         * @param task1 
     211         *            the first task to be compared 
     212         * @param task2 
     213         *            the second task to be compared 
     214         * @param requiredEqualityLevel 
     215         *            the equality level to be checked for 
     216         *  
     217         * @return the determined equality. 
     218         */ 
     219        private TaskEquality getEquality(ITask task1, ITask task2, 
     220                        TaskEquality requiredEqualityLevel) { 
     221                ISelection selection = null; 
     222                ITask task = null; 
     223 
     224                if (task1 instanceof ISelection) { 
     225                        if (task2 instanceof ISelection) { 
     226                                // the rule is not responsible for two selections 
     227                                return null; 
     228                        } 
     229 
     230                        selection = (ISelection) task1; 
     231                        task = task2; 
     232                } else if (task2 instanceof ISelection) { 
     233                        if (task1 instanceof ISelection) { 
     234                                // the rule is not responsible for two selections 
     235                                return null; 
     236                        } 
     237 
     238                        selection = (ISelection) task2; 
     239                        task = task1; 
     240                } else { 
     241                        return null; 
     242                } 
     243 
     244                // now, that we found the selection and the task, lets compare the 
     245                // children of the selection 
     246                // with the task. 
     247                final List<ITask> children = selection.getChildren(); 
     248 
     249                if (children.size() < 1) { 
     250                        return null; 
     251                } 
     252 
     253                TaskEquality mostConcreteNodeEquality = null; 
     254 
     255                for (final ITask child : children) { 
     256                        final TaskEquality taskEquality = callRuleManager(child, task, 
     257                                        requiredEqualityLevel); 
     258 
     259                        if (taskEquality != TaskEquality.UNEQUAL) { 
     260                                if (mostConcreteNodeEquality == null) { 
     261                                        mostConcreteNodeEquality = taskEquality; 
     262                                } else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 
     263                                        mostConcreteNodeEquality = taskEquality; 
     264 
     265                                } 
     266 
     267                                if ((requiredEqualityLevel != null) 
     268                                                && (mostConcreteNodeEquality 
     269                                                                .isAtLeast(requiredEqualityLevel))) { 
     270                                        // if we found one child of the selection that is as equal 
     271                                        // as required, then 
     272                                        // we can consider the selection to be sufficiently equal to 
     273                                        // the other task. 
     274                                        // So we break up checking further children. 
     275                                        break; 
     276                                } 
     277                        } 
     278                } 
     279 
     280                // although the subtask may be identical to the task, we can not return 
     281                // identical, as 
     282                // the selection is not identical to the task, but at most lexically 
     283                // equal 
     284                if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 
     285                        return TaskEquality.LEXICALLY_EQUAL; 
     286                } else { 
     287                        return mostConcreteNodeEquality; 
     288                } 
     289 
     290        } 
     291 
     292        /** 
     293         * <p> 
     294         * compares two task instances with each other checking for the provided 
     295         * required level of equality. One of the task instances must be a 
     296         * selection, the other one not. If this is not the case, the method returns 
     297         * null. The returned equality level is at most lexical equality as the 
     298         * selection can not be identical to something not being a selection. 
     299         * </p> 
     300         *  
     301         * @param taskInstance1 
     302         *            the first task instance to be compared 
     303         * @param taskInstance2 
     304         *            the second task instance to be compared 
     305         * @param requiredEqualityLevel 
     306         *            the equality level to be checked for 
     307         *  
     308         * @return the determined equality. 
     309         */ 
     310        private TaskEquality getEquality(ITaskInstance taskInstance1, 
     311                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 
     312                ISelectionInstance selection = null; 
     313                ITaskInstance task = null; 
     314 
     315                if (taskInstance1 instanceof ISelectionInstance) { 
     316                        if (taskInstance2 instanceof ISelectionInstance) { 
     317                                // the rule is not responsible for two selections 
     318                                return null; 
     319                        } 
     320 
     321                        selection = (ISelectionInstance) taskInstance1; 
     322                        task = taskInstance2; 
     323                } else if (taskInstance2 instanceof ISelectionInstance) { 
     324                        if (taskInstance1 instanceof ISelectionInstance) { 
     325                                // the rule is not responsible for two selections 
     326                                return null; 
     327                        } 
     328 
     329                        selection = (ISelectionInstance) taskInstance2; 
     330                        task = taskInstance1; 
     331                } else { 
     332                        return null; 
     333                } 
     334 
     335                // now, that we found the selection and the task, lets compare the child 
     336                // of the selection 
     337                // with the task. 
     338                final ITaskInstance child = selection.getChild(); 
     339 
     340                if (child == null) { 
     341                        return null; 
     342                } 
     343 
     344                final TaskEquality taskEquality = callRuleManager(child, task, 
     345                                requiredEqualityLevel); 
     346 
     347                // although the subtask may be identical to the task, we can not return 
     348                // identical, as 
     349                // the selection is not identical to the task, but at most lexically 
     350                // equal 
     351                if (taskEquality == TaskEquality.IDENTICAL) { 
     352                        return TaskEquality.LEXICALLY_EQUAL; 
     353                } else { 
     354                        return taskEquality; 
     355                } 
     356 
     357        } 
     358 
     359        /* 
     360         * (non-Javadoc) 
     361         *  
     362         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     363         */ 
     364        @Override 
     365        public boolean isApplicable(ITask task1, ITask task2) { 
     366                return ((task1 instanceof ISelection) && (!(task2 instanceof ISelection))) 
     367                                || ((task2 instanceof ISelection) && (!(task1 instanceof ISelection))); 
     368        } 
     369 
     370        /* 
     371         * (non-Javadoc) 
     372         *  
     373         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     374         */ 
     375        @Override 
     376        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     377                return isApplicable(instance1.getTask(), instance2.getTask()); 
     378        } 
    333379} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparisonRule.java

    r1294 r1733  
    2020/** 
    2121 * <p> 
    22  * A task comparison rule is used by the {@link TaskEqualityRuleManager} to compare tasks and 
    23  * task instances with each other. It provides several methods to be called for a comparison. 
     22 * A task comparison rule is used by the {@link TaskEqualityRuleManager} to 
     23 * compare tasks and task instances with each other. It provides several methods 
     24 * to be called for a comparison. 
    2425 * </p> 
    2526 *  
     
    2930public interface TaskComparisonRule { 
    3031 
    31     /** 
    32      * <p> 
    33      * checks if the rule is applicable for comparing the two provided tasks 
    34      * </p> 
    35      *  
    36      * @param task1 the first task to compare 
    37      * @param task2 the second task to compare 
    38      *  
    39      * @return true, if the rule is applicable, false else 
    40      */ 
    41     public boolean isApplicable(ITask task1, ITask task2); 
     32        /** 
     33         * <p> 
     34         * checks, if the provided tasks are lexically equal 
     35         * </p> 
     36         *  
     37         * @param task1 
     38         *            the first task to compare 
     39         * @param task2 
     40         *            the second task to compare 
     41         *  
     42         * @return true, if the tasks are equal, false else 
     43         */ 
     44        public boolean areLexicallyEqual(ITask task1, ITask task2); 
    4245 
    43     /** 
    44      * <p> 
    45      * checks, if the provided tasks are lexically equal 
    46      * </p> 
    47      *  
    48      * @param task1 the first task to compare 
    49      * @param task2 the second task to compare 
    50      *  
    51      * @return true, if the tasks are equal, false else 
    52      */ 
    53     public boolean areLexicallyEqual(ITask task1, ITask task2); 
     46        /** 
     47         * <p> 
     48         * checks, if the provided task instances are lexically equal 
     49         * </p> 
     50         *  
     51         * @param instance1 
     52         *            the first task instance to compare 
     53         * @param instance2 
     54         *            the second task instance to compare 
     55         *  
     56         * @return true, if the tasks are equal, false else 
     57         */ 
     58        public boolean areLexicallyEqual(ITaskInstance instance1, 
     59                        ITaskInstance instance2); 
    5460 
    55     /** 
    56      * <p> 
    57      * checks, if the provided tasks are syntactically equal 
    58      * </p> 
    59      *  
    60      * @param task1 the first task to compare 
    61      * @param task2 the second task to compare 
    62      *  
    63      * @return true, if the tasks are equal, false else 
    64      */ 
    65     public boolean areSyntacticallyEqual(ITask task1, ITask task2); 
     61        /** 
     62         * <p> 
     63         * checks, if the provided tasks are semantically equal 
     64         * </p> 
     65         *  
     66         * @param task1 
     67         *            the first task to compare 
     68         * @param task2 
     69         *            the second task to compare 
     70         *  
     71         * @return true, if the tasks are equal, false else 
     72         */ 
     73        public boolean areSemanticallyEqual(ITask task1, ITask task2); 
    6674 
    67     /** 
    68      * <p> 
    69      * checks, if the provided tasks are semantically equal 
    70      * </p> 
    71      *  
    72      * @param task1 the first task to compare 
    73      * @param task2 the second task to compare 
    74      *  
    75      * @return true, if the tasks are equal, false else 
    76      */ 
    77     public boolean areSemanticallyEqual(ITask task1, ITask task2); 
     75        /** 
     76         * <p> 
     77         * checks, if the provided task instances are semantically equal 
     78         * </p> 
     79         *  
     80         * @param instance1 
     81         *            the first task instance to compare 
     82         * @param instance2 
     83         *            the second task instance to compare 
     84         *  
     85         * @return true, if the tasks are equal, false else 
     86         */ 
     87        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     88                        ITaskInstance instance2); 
    7889 
    79     /** 
    80     * <p> 
    81      * compares two tasks with each other. The result of the method is either a task equality or 
    82      * null. If it is null, it means, that the rule is not able to correctly compare the two given 
    83      * tasks 
    84      * </p> 
    85      *  
    86      * @param task1 the first task to compare 
    87      * @param task2 the second task to compare 
    88     *  
    89      * @return as described 
    90     */ 
    91     public TaskEquality compare(ITask task1, ITask task2); 
     90        /** 
     91        * <p> 
     92         * checks, if the provided tasks are syntactically equal 
     93         * </p> 
     94         *  
     95         * @param task1 
     96         *            the first task to compare 
     97         * @param task2 
     98         *            the second task to compare 
     99        *  
     100         * @return true, if the tasks are equal, false else 
     101        */ 
     102        public boolean areSyntacticallyEqual(ITask task1, ITask task2); 
    92103 
    93     /** 
    94      * <p> 
    95      * checks if the rule is applicable for comparing the two provided task instances 
    96      * </p> 
    97      *  
    98      * @param instance1 the first task instance to compare 
    99      * @param instance2 the second task instance to compare 
    100      *  
    101      * @return true, if the rule is applicable, false else 
    102      */ 
    103     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2); 
     104        /** 
     105         * <p> 
     106         * checks, if the provided task instances are syntactically equal 
     107         * </p> 
     108         *  
     109         * @param instance1 
     110         *            the first task instance to compare 
     111         * @param instance2 
     112         *            the second task instance to compare 
     113         *  
     114         * @return true, if the tasks are equal, false else 
     115         */ 
     116        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     117                        ITaskInstance instance2); 
    104118 
    105     /** 
    106      * <p> 
    107      * checks, if the provided task instances are lexically equal 
    108      * </p> 
    109      *  
    110      * @param instance1 the first task instance to compare 
    111      * @param instance2 the second task instance to compare 
    112      *  
    113      * @return true, if the tasks are equal, false else 
    114      */ 
    115     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2); 
     119        /** 
     120         * <p> 
     121         * compares two tasks with each other. The result of the method is either a 
     122         * task equality or null. If it is null, it means, that the rule is not able 
     123         * to correctly compare the two given tasks 
     124         * </p> 
     125         *  
     126         * @param task1 
     127         *            the first task to compare 
     128         * @param task2 
     129         *            the second task to compare 
     130         *  
     131         * @return as described 
     132         */ 
     133        public TaskEquality compare(ITask task1, ITask task2); 
    116134 
    117     /** 
    118      * <p> 
    119      * checks, if the provided task instances are syntactically equal 
    120      * </p> 
    121      *  
    122      * @param instance1 the first task instance to compare 
    123      * @param instance2 the second task instance to compare 
    124      *  
    125      * @return true, if the tasks are equal, false else 
    126      */ 
    127     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2); 
     135        /** 
     136         * <p> 
     137         * compares two task instances with each other. The result of the method is 
     138         * either a task instance equality or null. If it is null, it means, that 
     139         * the rule is not able to correctly compare the two given task instances 
     140         * </p> 
     141         *  
     142         * @param instance1 
     143         *            the first task instance to compare 
     144         * @param instance2 
     145         *            the second task instance to compare 
     146         *  
     147         * @return as described 
     148         */ 
     149        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2); 
    128150 
    129     /** 
    130      * <p> 
    131      * checks, if the provided task instances are semantically equal 
    132      * </p> 
    133      *  
    134      * @param instance1 the first task instance to compare 
    135      * @param instance2 the second task instance to compare 
    136      *  
    137      * @return true, if the tasks are equal, false else 
    138      */ 
    139     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2); 
     151        /** 
     152         * <p> 
     153         * checks if the rule is applicable for comparing the two provided tasks 
     154         * </p> 
     155         *  
     156         * @param task1 
     157         *            the first task to compare 
     158         * @param task2 
     159         *            the second task to compare 
     160         *  
     161         * @return true, if the rule is applicable, false else 
     162         */ 
     163        public boolean isApplicable(ITask task1, ITask task2); 
    140164 
    141     /** 
    142      * <p> 
    143      * compares two task instances with each other. The result of the method is either a task 
    144      * instance equality or null. If it is null, it means, that the rule is not able to correctly 
    145      * compare the two given task instances 
    146      * </p> 
    147      *  
    148      * @param instance1 the first task instance to compare 
    149      * @param instance2 the second task instance to compare 
    150      *  
    151      * @return as described 
    152      */ 
    153     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2); 
     165        /** 
     166         * <p> 
     167         * checks if the rule is applicable for comparing the two provided task 
     168         * instances 
     169         * </p> 
     170         *  
     171         * @param instance1 
     172         *            the first task instance to compare 
     173         * @param instance2 
     174         *            the second task instance to compare 
     175         *  
     176         * @return true, if the rule is applicable, false else 
     177         */ 
     178        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2); 
    154179 
    155180} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEquality.java

    r1156 r1733  
    1717/** 
    1818 * <p> 
    19  * A task equality denotes, how equal two tasks are. There are different equality levels 
    20  * which are similar to the usual design levels of GUI design. These levels are 
     19 * A task equality denotes, how equal two tasks are. There are different 
     20 * equality levels which are similar to the usual design levels of GUI design. 
     21 * These levels are 
    2122 * <ul> 
    22  *   <li>conceptual design: defines the concepts to be edited using a GUI</li> 
    23  *   <li>semantical design: defines the possible functions for editing the concepts</li> 
    24  *   <li>syntactical design: defines, which steps are needed to execute the functions</li> 
    25  *   <li>lexical design: defines on the key stroke level, how the steps for executing a function 
    26  *       can be performed</li> 
     23 * <li>conceptual design: defines the concepts to be edited using a GUI</li> 
     24 * <li>semantical design: defines the possible functions for editing the 
     25 * concepts</li> 
     26 * <li>syntactical design: defines, which steps are needed to execute the 
     27 * functions</li> 
     28 * <li>lexical design: defines on the key stroke level, how the steps for 
     29 * executing a function can be performed</li> 
    2730 * </ul> 
    28  * It is not possible to compare two tasks conceptually. But the other design levels can be 
    29  * identified and compared. 
     31 * It is not possible to compare two tasks conceptually. But the other design 
     32 * levels can be identified and compared. 
    3033 * </p> 
    3134 * <p> 
    32  * Tasks can be identical. This is the case if in the java virtual machine, their comparison 
    33  * using the <code>==</code> operator or the equals method return true. 
     35 * Tasks can be identical. This is the case if in the java virtual machine, 
     36 * their comparison using the <code>==</code> operator or the equals method 
     37 * return true. 
    3438 * </p> 
    3539 * <p> 
    36  * Tasks are lexically equal, if they represent the same events on a key stroke level to be 
    37  * carried out to execute the task. Identical tasks are also syntactically equal. 
     40 * Tasks are lexically equal, if they represent the same events on a key stroke 
     41 * level to be carried out to execute the task. Identical tasks are also 
     42 * syntactically equal. 
    3843 * </p> 
    3944 * <p> 
    40  * Nodes are syntactically equal, if they differ in their events on key stroke level, but the 
    41  * syntactical result is the same. For example, entering the text "hello" into a text field can 
    42  * be done by entering the letters in their correct order, but also by copying the text into the 
    43  * text field. The syntactical result is the same: The text "hello" was entered. But the tasks 
    44  * lexically differ because the events on key stroke level are different. On the other hand, 
    45  * lexically equal tasks are also syntactically equal.   
     45 * Nodes are syntactically equal, if they differ in their events on key stroke 
     46 * level, but the syntactical result is the same. For example, entering the text 
     47 * "hello" into a text field can be done by entering the letters in their 
     48 * correct order, but also by copying the text into the text field. The 
     49 * syntactical result is the same: The text "hello" was entered. But the tasks 
     50 * lexically differ because the events on key stroke level are different. On the 
     51 * other hand, lexically equal tasks are also syntactically equal. 
    4652 * </p> 
    4753 * <p> 
    48  * Tasks are semantically equal, if they execute the same function for editing the concepts. An 
    49  * example are a click on a button and a short cut, both executing the same function. These tasks 
    50  * are syntactically and, therefore, also lexically different, but semantically equal. 
    51  * Syntactically equal tasks are always also semantically equal. 
     54 * Tasks are semantically equal, if they execute the same function for editing 
     55 * the concepts. An example are a click on a button and a short cut, both 
     56 * executing the same function. These tasks are syntactically and, therefore, 
     57 * also lexically different, but semantically equal. Syntactically equal tasks 
     58 * are always also semantically equal. 
    5259 * </p> 
    5360 *  
     
    5663 */ 
    5764public enum TaskEquality { 
    58     IDENTICAL, 
    59     LEXICALLY_EQUAL, 
    60     SYNTACTICALLY_EQUAL, 
    61     SEMANTICALLY_EQUAL, 
    62     UNEQUAL; 
     65        IDENTICAL, LEXICALLY_EQUAL, SYNTACTICALLY_EQUAL, SEMANTICALLY_EQUAL, UNEQUAL; 
    6366 
    64     /** 
    65      * <p> 
    66      * Checks for the current task equality, if it is at least identical to the 
    67      * provided one or even more concrete. As an example, the task equality identical also 
    68      * indicates, that the tasks are e.g. lexically, syntactically and semantically equal. 
    69      * Therefore, the method called on <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code> 
    70      * as parameter will return true. If this method is called on <code>SYNTACTICALLY_EQUAL</code> 
    71      * with the parameter <code>IDENTICAL</code> instead, it returns false; 
    72      * </p> 
    73      * 
    74      * @param taskEquality the task equality to compare with. 
    75      *  
    76      * @return as described 
    77      */ 
    78     public boolean isAtLeast(TaskEquality taskEquality) 
    79     { 
    80         switch (taskEquality) { 
    81             case IDENTICAL: 
    82                 return 
    83                     (this == IDENTICAL); 
    84             case LEXICALLY_EQUAL: 
    85                 return 
    86                     (this == IDENTICAL) || 
    87                     (this == LEXICALLY_EQUAL); 
    88             case SYNTACTICALLY_EQUAL: 
    89                 return 
    90                     (this == IDENTICAL) || 
    91                     (this == LEXICALLY_EQUAL) || 
    92                     (this == SYNTACTICALLY_EQUAL); 
    93             case SEMANTICALLY_EQUAL: 
    94                 return 
    95                     (this == IDENTICAL) || 
    96                     (this == LEXICALLY_EQUAL) || 
    97                     (this == SYNTACTICALLY_EQUAL) || 
    98                     (this == SEMANTICALLY_EQUAL); 
    99             case UNEQUAL: 
    100                 return 
    101                     (this == UNEQUAL); 
    102             default : 
    103                 return false; 
    104         } 
    105     } 
     67        /** 
     68         * <p> 
     69         * returns the common denominator of this task equality and the provided 
     70         * one. I.e. if one equality is e.g. syntactical and the other one only 
     71         * semantical, then semantical is returned. 
     72         * </p> 
     73         * 
     74         * @param otherEquality 
     75         *            the equality, to compare this with 
     76         *  
     77         * @return as described 
     78         */ 
     79        public TaskEquality getCommonDenominator(TaskEquality otherEquality) { 
     80                if (this.isAtLeast(otherEquality)) { 
     81                        return otherEquality; 
     82                } else if (otherEquality.isAtLeast(this)) { 
     83                        return this; 
     84                } else { 
     85                        return TaskEquality.UNEQUAL; 
     86                } 
     87        } 
    10688 
    107     /** 
    108      * <p> 
    109      * returns the common denominator of this task equality and the provided one. I.e. if one 
    110      * equality is e.g. syntactical and the other one only semantical, then semantical is returned. 
    111      * </p> 
    112      * 
    113      * @param otherEquality the equality, to compare this with 
    114      *  
    115      * @return as described 
    116      */ 
    117     public TaskEquality getCommonDenominator(TaskEquality otherEquality) { 
    118         if (this.isAtLeast(otherEquality)) { 
    119             return otherEquality; 
    120         } 
    121         else if (otherEquality.isAtLeast(this)) { 
    122             return this; 
    123         } 
    124         else { 
    125             return TaskEquality.UNEQUAL; 
    126         } 
    127     } 
     89        /** 
     90         * <p> 
     91         * Checks for the current task equality, if it is at least identical to the 
     92         * provided one or even more concrete. As an example, the task equality 
     93         * identical also indicates, that the tasks are e.g. lexically, 
     94         * syntactically and semantically equal. Therefore, the method called on 
     95         * <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code> as parameter 
     96         * will return true. If this method is called on 
     97         * <code>SYNTACTICALLY_EQUAL</code> with the parameter 
     98         * <code>IDENTICAL</code> instead, it returns false; 
     99         * </p> 
     100         * 
     101         * @param taskEquality 
     102         *            the task equality to compare with. 
     103         *  
     104         * @return as described 
     105         */ 
     106        public boolean isAtLeast(TaskEquality taskEquality) { 
     107                switch (taskEquality) { 
     108                case IDENTICAL: 
     109                        return (this == IDENTICAL); 
     110                case LEXICALLY_EQUAL: 
     111                        return (this == IDENTICAL) || (this == LEXICALLY_EQUAL); 
     112                case SYNTACTICALLY_EQUAL: 
     113                        return (this == IDENTICAL) || (this == LEXICALLY_EQUAL) 
     114                                        || (this == SYNTACTICALLY_EQUAL); 
     115                case SEMANTICALLY_EQUAL: 
     116                        return (this == IDENTICAL) || (this == LEXICALLY_EQUAL) 
     117                                        || (this == SYNTACTICALLY_EQUAL) 
     118                                        || (this == SEMANTICALLY_EQUAL); 
     119                case UNEQUAL: 
     120                        return (this == UNEQUAL); 
     121                default: 
     122                        return false; 
     123                } 
     124        } 
    128125} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java

    r1294 r1733  
    2323/** 
    2424 * <p> 
    25  * The task equality rule manager is capable of comparing tasks and task instances based on its 
    26  * internal list of comparison rules. These rules are asked for comparing the two provided tasks or 
    27  * task instance. If a rule returns a task equality other than null, this equality is returned. 
    28  * Otherwise the next rule is asked. 
     25 * The task equality rule manager is capable of comparing tasks and task 
     26 * instances based on its internal list of comparison rules. These rules are 
     27 * asked for comparing the two provided tasks or task instance. If a rule 
     28 * returns a task equality other than null, this equality is returned. Otherwise 
     29 * the next rule is asked. 
    2930 * </p> 
    3031 *  
     
    3233 */ 
    3334public class TaskEqualityRuleManager { 
    34      
    35     /** 
    36      * <p> 
    37      * the singleton instance of this class 
    38      * </p> 
    39      */ 
    40     private static final TaskEqualityRuleManager instance = new TaskEqualityRuleManager(); 
    41  
    42     /** 
    43      * <p> 
    44      * the rules that can be used for comparing tasks 
    45      * </p> 
    46      */ 
    47     private List<TaskComparisonRule> mRuleIndex = null; 
    48  
    49     /** 
    50      * <p> 
    51      * initializes the task equality rule manager by filling the internal list of comparison rules. 
    52      * </p> 
    53      */ 
    54     private TaskEqualityRuleManager() { 
    55         mRuleIndex = new ArrayList<TaskComparisonRule>(); 
    56         mRuleIndex.add(new TaskIdentityRule()); 
    57         mRuleIndex.add(new GUIEventTaskComparisonRule()); 
    58         mRuleIndex.add(new EventTaskComparisonRule()); 
    59         mRuleIndex.add(new IterationComparisonRule()); 
    60         mRuleIndex.add(new SequenceComparisonRule()); 
    61         mRuleIndex.add(new SelectionComparisonRule()); 
    62         mRuleIndex.add(new TaskAndIterationComparisonRule()); 
    63         mRuleIndex.add(new TaskAndSelectionComparisonRule()); 
    64     } 
    65  
    66  
    67     /** 
    68      * <p> 
    69      * returns the singleton instance of this class 
    70      * </p> 
    71      *  
    72      * @return as described 
    73      */ 
    74     public static TaskEqualityRuleManager getInstance() { 
    75         return instance; 
    76     } 
    77  
    78     /** 
    79      * <p> 
    80      * this method performs a comparison of the two provided tasks. It iterates its internal 
    81      * comparison rules. If the first rule returns a task equality other than null, 
    82      * this equality is returned. Otherwise the next rule is tried. If no rule returns an equality 
    83      * <code>NodeEquality.UNEQUAL</code> is returned. 
    84      * </p> 
    85      *  
    86      * @param task1 the first task to be compared 
    87      * @param task2 the second task to be compared 
    88      *  
    89      * @return as described 
    90      *  
    91      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    92      *                               manager before a call to this method. 
    93      */ 
    94     public TaskEquality compare(ITask task1, ITask task2) 
    95         throws IllegalStateException 
    96     { 
    97         if (mRuleIndex == null) { 
    98             throw new IllegalStateException("not initialized"); 
    99         } 
    100          
    101         // LOG.info("checking for equality of " + task1 + " and " + task2); 
    102         TaskEquality taskEquality = null; 
    103  
    104         for (TaskComparisonRule rule : mRuleIndex) { 
    105             if (rule.isApplicable(task1, task2)) { 
    106                 taskEquality = rule.compare(task1, task2); 
    107                 if (taskEquality != null) { 
    108                     // LOG.warning("used rule " + rule + " for equality check"); 
    109                     return taskEquality; 
    110                 } 
    111             } 
    112         } 
    113  
    114         // LOG.warning("no rule could be applied --> handling tasks as unequal"); 
    115  
    116         return TaskEquality.UNEQUAL; 
    117     } 
    118  
    119     /** 
    120      * <p> 
    121      * this method two tasks with respect to the fiven equality level and returns true, if this 
    122      * level is given. 
    123      * </p> 
    124      *  
    125      * @param task1         the first task to be compared 
    126      * @param task2         the second task to be compared 
    127      * @param equalityLevel the level of equality to be checked for 
    128      *  
    129      * @return as described 
    130      *  
    131      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    132      *                               manager before a call to this method. 
    133      */ 
    134     public boolean areAtLeastEqual(ITask task1, ITask task2, TaskEquality equalityLevel) { 
    135         if (equalityLevel == null) { 
    136             throw new IllegalArgumentException("required equality level must not be null"); 
    137         } 
    138          
    139         switch (equalityLevel) { 
    140             case IDENTICAL: 
    141                 return areIdentical(task1, task2); 
    142             case LEXICALLY_EQUAL: 
    143                 return areLexicallyEqual(task1, task2); 
    144             case SYNTACTICALLY_EQUAL: 
    145                 return areSyntacticallyEqual(task1, task2); 
    146             case SEMANTICALLY_EQUAL: 
    147                 return areSemanticallyEqual(task1, task2); 
    148             case UNEQUAL: 
    149                 return !areSemanticallyEqual(task1, task2); 
    150             default: 
    151                 throw new IllegalArgumentException("unknown required equality: " + equalityLevel); 
    152         } 
    153     } 
    154  
    155     /** 
    156      * <p> 
    157      * this method checks if the two given tasks are identical. For this, it iterates its internal 
    158      * comparison rules. If the first rule returns true, than this method returns true as well. 
    159      * If no rule returns true, this method returns false. 
    160      * </p> 
    161      *  
    162      * @param task1 the first task to be compared 
    163      * @param task2 the second task to be compared 
    164      *  
    165      * @return as described 
    166      *  
    167      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    168      *                               manager before a call to this method. 
    169      */ 
    170     public boolean areIdentical(ITask task1, ITask task2) { 
    171         if (mRuleIndex == null) { 
    172             throw new IllegalStateException("not initialized"); 
    173         } 
    174          
    175         for (TaskComparisonRule rule : mRuleIndex) { 
    176             if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) { 
    177                  return true; 
    178             } 
    179         } 
    180  
    181         return false; 
    182     } 
    183  
    184     /** 
    185      * <p> 
    186      * this method checks if the two given tasks are lexically equal. For this, it iterates its 
    187      * internal comparison rules. If the first rule returns true, than this method returns true 
    188      * as well. If no rule returns true, this method returns false. 
    189      * </p> 
    190      *  
    191      * @param task1 the first task to be compared 
    192      * @param task2 the second task to be compared 
    193      *  
    194      * @return as described 
    195      *  
    196      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    197      *                               manager before a call to this method. 
    198      */ 
    199     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    200         if (mRuleIndex == null) { 
    201             throw new IllegalStateException("not initialized"); 
    202         } 
    203          
    204         for (TaskComparisonRule rule : mRuleIndex) { 
    205             if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) { 
    206                  return true; 
    207             } 
    208         } 
    209  
    210         return false; 
    211     } 
    212  
    213     /** 
    214      * <p> 
    215      * this method checks if the two given tasks are syntactically equal. For this, it iterates its 
    216      * internal comparison rules. If the first rule returns true, than this method returns true 
    217      * as well. If no rule returns true, this method returns false. 
    218      * </p> 
    219      *  
    220      * @param task1 the first task to be compared 
    221      * @param task2 the second task to be compared 
    222      *  
    223      * @return as described 
    224      *  
    225      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    226      *                               manager before a call to this method. 
    227      */ 
    228     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    229         if (mRuleIndex == null) { 
    230             throw new IllegalStateException("not initialized"); 
    231         } 
    232          
    233         for (TaskComparisonRule rule : mRuleIndex) { 
    234             if (rule.isApplicable(task1, task2) && rule.areSyntacticallyEqual(task1, task2)) { 
    235                  return true; 
    236             } 
    237         } 
    238  
    239         return false; 
    240     } 
    241  
    242     /** 
    243      * <p> 
    244      * this method checks if the two given tasks are semantically equal. For this, it iterates its 
    245      * internal comparison rules. If the first rule returns true, than this method returns true 
    246      * as well. If no rule returns true, this method returns false. 
    247      * </p> 
    248      *  
    249      * @param task1 the first task to be compared 
    250      * @param task2 the second task to be compared 
    251      *  
    252      * @return as described 
    253      *  
    254      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    255      *                               manager before a call to this method. 
    256      */ 
    257     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    258         if (mRuleIndex == null) { 
    259             throw new IllegalStateException("not initialized"); 
    260         } 
    261          
    262         for (TaskComparisonRule rule : mRuleIndex) { 
    263             if (rule.isApplicable(task1, task2) && rule.areSemanticallyEqual(task1, task2)) { 
    264                  return true; 
    265             } 
    266         } 
    267  
    268         return false; 
    269     } 
    270  
    271     /** 
    272      * <p> 
    273      * this method performs a comparison of the two provided task instances. It iterates its 
    274      * internal comparison rules. If the first rule returns a task instance equality other than 
    275      * null, this equality is returned. Otherwise the next rule is tried. If no rule returns an 
    276      * equality <code>TaskEquality.UNEQUAL</code> is returned. 
    277      * </p> 
    278      *  
    279      * @param instance1 the first task instance to be compared 
    280      * @param instance2 the second task instance to be compared 
    281      *  
    282      * @return as described 
    283      *  
    284      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    285      *                               manager before a call to this method. 
    286      */ 
    287     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) 
    288         throws IllegalStateException 
    289     { 
    290         if (mRuleIndex == null) { 
    291             throw new IllegalStateException("not initialized"); 
    292         } 
    293          
    294         // LOG.info("checking for equality of " + instance1 + " and " + instance2); 
    295         TaskEquality instanceEquality = null; 
    296  
    297         for (TaskComparisonRule rule : mRuleIndex) { 
    298             if (rule.isApplicable(instance1, instance2)) { 
    299                 instanceEquality = rule.compare(instance1, instance2); 
    300                 if (instanceEquality != null) { 
    301                     // LOG.warning("used rule " + rule + " for equality check"); 
    302                     return instanceEquality; 
    303                 } 
    304             } 
    305         } 
    306  
    307         // LOG.warning("no rule could be applied --> handling tasks as unequal"); 
    308  
    309         return TaskEquality.UNEQUAL; 
    310     } 
    311  
    312     /** 
    313      * <p> 
    314      * this method compares two task instances with respect to the given equality level and returns 
    315      * true, if this level is given. 
    316      * </p> 
    317      *  
    318      * @param instance1     the first task instance to be compared 
    319      * @param instance2     the second task instance to be compared 
    320      * @param equalityLevel the level of equality to be checked for 
    321      *  
    322      * @return as described 
    323      *  
    324      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    325      *                               manager before a call to this method. 
    326      */ 
    327     public boolean areAtLeastEqual(ITaskInstance        instance1, 
    328                                    ITaskInstance        instance2, 
    329                                    TaskEquality equalityLevel) 
    330     { 
    331         if (equalityLevel == null) { 
    332             throw new IllegalArgumentException("required equality level must not be null"); 
    333         } 
    334          
    335         switch (equalityLevel) { 
    336             case IDENTICAL: 
    337                 return areIdentical(instance1, instance2); 
    338             case LEXICALLY_EQUAL: 
    339                 return areLexicallyEqual(instance1, instance2); 
    340             case SYNTACTICALLY_EQUAL: 
    341                 return areSyntacticallyEqual(instance1, instance2); 
    342             case SEMANTICALLY_EQUAL: 
    343                 return areSemanticallyEqual(instance1, instance2); 
    344             case UNEQUAL: 
    345                 return !areSemanticallyEqual(instance1, instance2); 
    346             default: 
    347                 throw new IllegalArgumentException("unknown required equality: " + equalityLevel); 
    348         } 
    349     } 
    350  
    351     /** 
    352      * <p> 
    353      * this method checks if the two given task instances are identical. For this, it iterates its 
    354      * internal comparison rules. If the first rule returns true, than this method returns true 
    355      * as well. If no rule returns true, this method returns false. 
    356      * </p> 
    357      *  
    358      * @param instance1 the first task instance to be compared 
    359      * @param instance2 the second task instance to be compared 
    360      *  
    361      * @return as described 
    362      *  
    363      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    364      *                               manager before a call to this method. 
    365      */ 
    366     public boolean areIdentical(ITaskInstance instance1, ITaskInstance instance2) { 
    367         if (mRuleIndex == null) { 
    368             throw new IllegalStateException("not initialized"); 
    369         } 
    370          
    371         for (TaskComparisonRule rule : mRuleIndex) { 
    372             if (rule.isApplicable(instance1, instance2) && 
    373                 rule.areLexicallyEqual(instance1, instance2)) 
    374             { 
    375                 return true; 
    376             } 
    377         } 
    378  
    379         return false; 
    380     } 
    381  
    382     /** 
    383      * <p> 
    384      * this method checks if the two given task instances are lexically equal. For this, it 
    385      * iterates its internal comparison rules. If the first rule returns true, than this method 
    386      * returns true, as well. If no rule returns true, this method returns false. 
    387      * </p> 
    388      *  
    389      * @param instance1 the first task instance to be compared 
    390      * @param instance2 the second task instance to be compared 
    391      *  
    392      * @return as described 
    393      *  
    394      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    395      *                               manager before a call to this method. 
    396      */ 
    397     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    398         if (mRuleIndex == null) { 
    399             throw new IllegalStateException("not initialized"); 
    400         } 
    401          
    402         for (TaskComparisonRule rule : mRuleIndex) { 
    403             if (rule.isApplicable(instance1, instance2) && 
    404                 rule.areLexicallyEqual(instance1, instance2)) 
    405             { 
    406                 return true; 
    407             } 
    408         } 
    409  
    410         return false; 
    411     } 
    412  
    413     /** 
    414      * <p> 
    415      * this method checks if the two given task instances are syntactically equal. For this, it 
    416      * iterates its internal comparison rules. If the first rule returns true, than this method 
    417      * returns true, as well. If no rule returns true, this method returns false. 
    418      * </p> 
    419      *  
    420      * @param instance1 the first task instance to be compared 
    421      * @param instance2 the second task instance to be compared 
    422      *  
    423      * @return as described 
    424      *  
    425      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    426      *                               manager before a call to this method. 
    427      */ 
    428     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    429         if (mRuleIndex == null) { 
    430             throw new IllegalStateException("not initialized"); 
    431         } 
    432          
    433         for (TaskComparisonRule rule : mRuleIndex) { 
    434             if (rule.isApplicable(instance1, instance2) && 
    435                 rule.areSyntacticallyEqual(instance1, instance2)) 
    436             { 
    437                 return true; 
    438             } 
    439         } 
    440  
    441         return false; 
    442     } 
    443  
    444     /** 
    445      * <p> 
    446      * this method checks if the two given task instances are semantically equal. For this, it 
    447      * iterates its internal comparison rules. If the first rule returns true, than this method 
    448      * returns true, as well. If no rule returns true, this method returns false. 
    449      * </p> 
    450      *  
    451      * @param instance1 the first task instance to be compared 
    452      * @param instance2 the second task instance to be compared 
    453      *  
    454      * @return as described 
    455      *  
    456      * @throws IllegalStateException in the case, the {@link #init()} method was not called on the 
    457      *                               manager before a call to this method. 
    458      */ 
    459     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    460         if (mRuleIndex == null) { 
    461             throw new IllegalStateException("not initialized"); 
    462         } 
    463          
    464         for (TaskComparisonRule rule : mRuleIndex) { 
    465             if (rule.isApplicable(instance1, instance2) && 
    466                 rule.areSemanticallyEqual(instance1, instance2)) 
    467             { 
    468                  return true; 
    469             } 
    470         } 
    471  
    472         return false; 
    473     } 
     35 
     36        /** 
     37         * <p> 
     38         * returns the singleton instance of this class 
     39         * </p> 
     40         *  
     41         * @return as described 
     42         */ 
     43        public static TaskEqualityRuleManager getInstance() { 
     44                return instance; 
     45        } 
     46 
     47        /** 
     48         * <p> 
     49         * the singleton instance of this class 
     50         * </p> 
     51         */ 
     52        private static final TaskEqualityRuleManager instance = new TaskEqualityRuleManager(); 
     53 
     54        /** 
     55         * <p> 
     56         * the rules that can be used for comparing tasks 
     57         * </p> 
     58         */ 
     59        private List<TaskComparisonRule> mRuleIndex = null; 
     60 
     61        /** 
     62         * <p> 
     63         * initializes the task equality rule manager by filling the internal list 
     64         * of comparison rules. 
     65         * </p> 
     66         */ 
     67        private TaskEqualityRuleManager() { 
     68                mRuleIndex = new ArrayList<TaskComparisonRule>(); 
     69                mRuleIndex.add(new TaskIdentityRule()); 
     70                mRuleIndex.add(new GUIEventTaskComparisonRule()); 
     71                mRuleIndex.add(new EventTaskComparisonRule()); 
     72                mRuleIndex.add(new IterationComparisonRule()); 
     73                mRuleIndex.add(new SequenceComparisonRule()); 
     74                mRuleIndex.add(new SelectionComparisonRule()); 
     75                mRuleIndex.add(new TaskAndIterationComparisonRule()); 
     76                mRuleIndex.add(new TaskAndSelectionComparisonRule()); 
     77        } 
     78 
     79        /** 
     80         * <p> 
     81         * this method two tasks with respect to the fiven equality level and 
     82         * returns true, if this level is given. 
     83         * </p> 
     84         *  
     85         * @param task1 
     86         *            the first task to be compared 
     87         * @param task2 
     88         *            the second task to be compared 
     89         * @param equalityLevel 
     90         *            the level of equality to be checked for 
     91         *  
     92         * @return as described 
     93         *  
     94         * @throws IllegalStateException 
     95         *             in the case, the {@link #init()} method was not called on the 
     96         *             manager before a call to this method. 
     97         */ 
     98        public boolean areAtLeastEqual(ITask task1, ITask task2, 
     99                        TaskEquality equalityLevel) { 
     100                if (equalityLevel == null) { 
     101                        throw new IllegalArgumentException( 
     102                                        "required equality level must not be null"); 
     103                } 
     104 
     105                switch (equalityLevel) { 
     106                case IDENTICAL: 
     107                        return areIdentical(task1, task2); 
     108                case LEXICALLY_EQUAL: 
     109                        return areLexicallyEqual(task1, task2); 
     110                case SYNTACTICALLY_EQUAL: 
     111                        return areSyntacticallyEqual(task1, task2); 
     112                case SEMANTICALLY_EQUAL: 
     113                        return areSemanticallyEqual(task1, task2); 
     114                case UNEQUAL: 
     115                        return !areSemanticallyEqual(task1, task2); 
     116                default: 
     117                        throw new IllegalArgumentException("unknown required equality: " 
     118                                        + equalityLevel); 
     119                } 
     120        } 
     121 
     122        /** 
     123         * <p> 
     124         * this method compares two task instances with respect to the given 
     125         * equality level and returns true, if this level is given. 
     126         * </p> 
     127         *  
     128         * @param instance1 
     129         *            the first task instance to be compared 
     130         * @param instance2 
     131         *            the second task instance to be compared 
     132         * @param equalityLevel 
     133         *            the level of equality to be checked for 
     134         *  
     135         * @return as described 
     136         *  
     137         * @throws IllegalStateException 
     138         *             in the case, the {@link #init()} method was not called on the 
     139         *             manager before a call to this method. 
     140         */ 
     141        public boolean areAtLeastEqual(ITaskInstance instance1, 
     142                        ITaskInstance instance2, TaskEquality equalityLevel) { 
     143                if (equalityLevel == null) { 
     144                        throw new IllegalArgumentException( 
     145                                        "required equality level must not be null"); 
     146                } 
     147 
     148                switch (equalityLevel) { 
     149                case IDENTICAL: 
     150                        return areIdentical(instance1, instance2); 
     151                case LEXICALLY_EQUAL: 
     152                        return areLexicallyEqual(instance1, instance2); 
     153                case SYNTACTICALLY_EQUAL: 
     154                        return areSyntacticallyEqual(instance1, instance2); 
     155                case SEMANTICALLY_EQUAL: 
     156                        return areSemanticallyEqual(instance1, instance2); 
     157                case UNEQUAL: 
     158                        return !areSemanticallyEqual(instance1, instance2); 
     159                default: 
     160                        throw new IllegalArgumentException("unknown required equality: " 
     161                                        + equalityLevel); 
     162                } 
     163        } 
     164 
     165        /** 
     166         * <p> 
     167         * this method checks if the two given tasks are identical. For this, it 
     168         * iterates its internal comparison rules. If the first rule returns true, 
     169         * than this method returns true as well. If no rule returns true, this 
     170         * method returns false. 
     171         * </p> 
     172         *  
     173         * @param task1 
     174         *            the first task to be compared 
     175         * @param task2 
     176         *            the second task to be compared 
     177         *  
     178         * @return as described 
     179         *  
     180         * @throws IllegalStateException 
     181         *             in the case, the {@link #init()} method was not called on the 
     182         *             manager before a call to this method. 
     183         */ 
     184        public boolean areIdentical(ITask task1, ITask task2) { 
     185                if (mRuleIndex == null) { 
     186                        throw new IllegalStateException("not initialized"); 
     187                } 
     188 
     189                for (final TaskComparisonRule rule : mRuleIndex) { 
     190                        if (rule.isApplicable(task1, task2) 
     191                                        && rule.areLexicallyEqual(task1, task2)) { 
     192                                return true; 
     193                        } 
     194                } 
     195 
     196                return false; 
     197        } 
     198 
     199        /** 
     200         * <p> 
     201         * this method checks if the two given task instances are identical. For 
     202         * this, it iterates its internal comparison rules. If the first rule 
     203         * returns true, than this method returns true as well. If no rule returns 
     204         * true, this method returns false. 
     205         * </p> 
     206         *  
     207         * @param instance1 
     208         *            the first task instance to be compared 
     209         * @param instance2 
     210         *            the second task instance to be compared 
     211         *  
     212         * @return as described 
     213         *  
     214         * @throws IllegalStateException 
     215         *             in the case, the {@link #init()} method was not called on the 
     216         *             manager before a call to this method. 
     217         */ 
     218        public boolean areIdentical(ITaskInstance instance1, ITaskInstance instance2) { 
     219                if (mRuleIndex == null) { 
     220                        throw new IllegalStateException("not initialized"); 
     221                } 
     222 
     223                for (final TaskComparisonRule rule : mRuleIndex) { 
     224                        if (rule.isApplicable(instance1, instance2) 
     225                                        && rule.areLexicallyEqual(instance1, instance2)) { 
     226                                return true; 
     227                        } 
     228                } 
     229 
     230                return false; 
     231        } 
     232 
     233        /** 
     234         * <p> 
     235         * this method checks if the two given tasks are lexically equal. For this, 
     236         * it iterates its internal comparison rules. If the first rule returns 
     237         * true, than this method returns true as well. If no rule returns true, 
     238         * this method returns false. 
     239         * </p> 
     240         *  
     241         * @param task1 
     242         *            the first task to be compared 
     243         * @param task2 
     244         *            the second task to be compared 
     245         *  
     246         * @return as described 
     247         *  
     248         * @throws IllegalStateException 
     249         *             in the case, the {@link #init()} method was not called on the 
     250         *             manager before a call to this method. 
     251         */ 
     252        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     253                if (mRuleIndex == null) { 
     254                        throw new IllegalStateException("not initialized"); 
     255                } 
     256 
     257                for (final TaskComparisonRule rule : mRuleIndex) { 
     258                        if (rule.isApplicable(task1, task2) 
     259                                        && rule.areLexicallyEqual(task1, task2)) { 
     260                                return true; 
     261                        } 
     262                } 
     263 
     264                return false; 
     265        } 
     266 
     267        /** 
     268         * <p> 
     269         * this method checks if the two given task instances are lexically equal. 
     270         * For this, it iterates its internal comparison rules. If the first rule 
     271         * returns true, than this method returns true, as well. If no rule returns 
     272         * true, this method returns false. 
     273         * </p> 
     274         *  
     275         * @param instance1 
     276         *            the first task instance to be compared 
     277         * @param instance2 
     278         *            the second task instance to be compared 
     279         *  
     280         * @return as described 
     281         *  
     282         * @throws IllegalStateException 
     283         *             in the case, the {@link #init()} method was not called on the 
     284         *             manager before a call to this method. 
     285         */ 
     286        public boolean areLexicallyEqual(ITaskInstance instance1, 
     287                        ITaskInstance instance2) { 
     288                if (mRuleIndex == null) { 
     289                        throw new IllegalStateException("not initialized"); 
     290                } 
     291 
     292                for (final TaskComparisonRule rule : mRuleIndex) { 
     293                        if (rule.isApplicable(instance1, instance2) 
     294                                        && rule.areLexicallyEqual(instance1, instance2)) { 
     295                                return true; 
     296                        } 
     297                } 
     298 
     299                return false; 
     300        } 
     301 
     302        /** 
     303         * <p> 
     304         * this method checks if the two given tasks are semantically equal. For 
     305         * this, it iterates its internal comparison rules. If the first rule 
     306         * returns true, than this method returns true as well. If no rule returns 
     307         * true, this method returns false. 
     308         * </p> 
     309         *  
     310         * @param task1 
     311         *            the first task to be compared 
     312         * @param task2 
     313         *            the second task to be compared 
     314         *  
     315         * @return as described 
     316         *  
     317         * @throws IllegalStateException 
     318         *             in the case, the {@link #init()} method was not called on the 
     319         *             manager before a call to this method. 
     320         */ 
     321        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     322                if (mRuleIndex == null) { 
     323                        throw new IllegalStateException("not initialized"); 
     324                } 
     325 
     326                for (final TaskComparisonRule rule : mRuleIndex) { 
     327                        if (rule.isApplicable(task1, task2) 
     328                                        && rule.areSemanticallyEqual(task1, task2)) { 
     329                                return true; 
     330                        } 
     331                } 
     332 
     333                return false; 
     334        } 
     335 
     336        /** 
     337         * <p> 
     338         * this method checks if the two given task instances are semantically 
     339         * equal. For this, it iterates its internal comparison rules. If the first 
     340         * rule returns true, than this method returns true, as well. If no rule 
     341         * returns true, this method returns false. 
     342         * </p> 
     343         *  
     344         * @param instance1 
     345         *            the first task instance to be compared 
     346         * @param instance2 
     347         *            the second task instance to be compared 
     348         *  
     349         * @return as described 
     350         *  
     351         * @throws IllegalStateException 
     352         *             in the case, the {@link #init()} method was not called on the 
     353         *             manager before a call to this method. 
     354         */ 
     355        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     356                        ITaskInstance instance2) { 
     357                if (mRuleIndex == null) { 
     358                        throw new IllegalStateException("not initialized"); 
     359                } 
     360 
     361                for (final TaskComparisonRule rule : mRuleIndex) { 
     362                        if (rule.isApplicable(instance1, instance2) 
     363                                        && rule.areSemanticallyEqual(instance1, instance2)) { 
     364                                return true; 
     365                        } 
     366                } 
     367 
     368                return false; 
     369        } 
     370 
     371        /** 
     372         * <p> 
     373         * this method checks if the two given tasks are syntactically equal. For 
     374         * this, it iterates its internal comparison rules. If the first rule 
     375         * returns true, than this method returns true as well. If no rule returns 
     376         * true, this method returns false. 
     377         * </p> 
     378         *  
     379         * @param task1 
     380         *            the first task to be compared 
     381         * @param task2 
     382         *            the second task to be compared 
     383         *  
     384         * @return as described 
     385         *  
     386         * @throws IllegalStateException 
     387         *             in the case, the {@link #init()} method was not called on the 
     388         *             manager before a call to this method. 
     389         */ 
     390        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     391                if (mRuleIndex == null) { 
     392                        throw new IllegalStateException("not initialized"); 
     393                } 
     394 
     395                for (final TaskComparisonRule rule : mRuleIndex) { 
     396                        if (rule.isApplicable(task1, task2) 
     397                                        && rule.areSyntacticallyEqual(task1, task2)) { 
     398                                return true; 
     399                        } 
     400                } 
     401 
     402                return false; 
     403        } 
     404 
     405        /** 
     406         * <p> 
     407         * this method checks if the two given task instances are syntactically 
     408         * equal. For this, it iterates its internal comparison rules. If the first 
     409         * rule returns true, than this method returns true, as well. If no rule 
     410         * returns true, this method returns false. 
     411         * </p> 
     412         *  
     413         * @param instance1 
     414         *            the first task instance to be compared 
     415         * @param instance2 
     416         *            the second task instance to be compared 
     417         *  
     418         * @return as described 
     419         *  
     420         * @throws IllegalStateException 
     421         *             in the case, the {@link #init()} method was not called on the 
     422         *             manager before a call to this method. 
     423         */ 
     424        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     425                        ITaskInstance instance2) { 
     426                if (mRuleIndex == null) { 
     427                        throw new IllegalStateException("not initialized"); 
     428                } 
     429 
     430                for (final TaskComparisonRule rule : mRuleIndex) { 
     431                        if (rule.isApplicable(instance1, instance2) 
     432                                        && rule.areSyntacticallyEqual(instance1, instance2)) { 
     433                                return true; 
     434                        } 
     435                } 
     436 
     437                return false; 
     438        } 
     439 
     440        /** 
     441         * <p> 
     442         * this method performs a comparison of the two provided tasks. It iterates 
     443         * its internal comparison rules. If the first rule returns a task equality 
     444         * other than null, this equality is returned. Otherwise the next rule is 
     445         * tried. If no rule returns an equality <code>NodeEquality.UNEQUAL</code> 
     446         * is returned. 
     447         * </p> 
     448         *  
     449         * @param task1 
     450         *            the first task to be compared 
     451         * @param task2 
     452         *            the second task to be compared 
     453         *  
     454         * @return as described 
     455         *  
     456         * @throws IllegalStateException 
     457         *             in the case, the {@link #init()} method was not called on the 
     458         *             manager before a call to this method. 
     459         */ 
     460        public TaskEquality compare(ITask task1, ITask task2) 
     461                        throws IllegalStateException { 
     462                if (mRuleIndex == null) { 
     463                        throw new IllegalStateException("not initialized"); 
     464                } 
     465 
     466                // LOG.info("checking for equality of " + task1 + " and " + task2); 
     467                TaskEquality taskEquality = null; 
     468 
     469                for (final TaskComparisonRule rule : mRuleIndex) { 
     470                        if (rule.isApplicable(task1, task2)) { 
     471                                taskEquality = rule.compare(task1, task2); 
     472                                if (taskEquality != null) { 
     473                                        // LOG.warning("used rule " + rule + " for equality check"); 
     474                                        return taskEquality; 
     475                                } 
     476                        } 
     477                } 
     478 
     479                // LOG.warning("no rule could be applied --> handling tasks as unequal"); 
     480 
     481                return TaskEquality.UNEQUAL; 
     482        } 
     483 
     484        /** 
     485         * <p> 
     486         * this method performs a comparison of the two provided task instances. It 
     487         * iterates its internal comparison rules. If the first rule returns a task 
     488         * instance equality other than null, this equality is returned. Otherwise 
     489         * the next rule is tried. If no rule returns an equality 
     490         * <code>TaskEquality.UNEQUAL</code> is returned. 
     491         * </p> 
     492         *  
     493         * @param instance1 
     494         *            the first task instance to be compared 
     495         * @param instance2 
     496         *            the second task instance to be compared 
     497         *  
     498         * @return as described 
     499         *  
     500         * @throws IllegalStateException 
     501         *             in the case, the {@link #init()} method was not called on the 
     502         *             manager before a call to this method. 
     503         */ 
     504        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) 
     505                        throws IllegalStateException { 
     506                if (mRuleIndex == null) { 
     507                        throw new IllegalStateException("not initialized"); 
     508                } 
     509 
     510                // LOG.info("checking for equality of " + instance1 + " and " + 
     511                // instance2); 
     512                TaskEquality instanceEquality = null; 
     513 
     514                for (final TaskComparisonRule rule : mRuleIndex) { 
     515                        if (rule.isApplicable(instance1, instance2)) { 
     516                                instanceEquality = rule.compare(instance1, instance2); 
     517                                if (instanceEquality != null) { 
     518                                        // LOG.warning("used rule " + rule + " for equality check"); 
     519                                        return instanceEquality; 
     520                                } 
     521                        } 
     522                } 
     523 
     524                // LOG.warning("no rule could be applied --> handling tasks as unequal"); 
     525 
     526                return TaskEquality.UNEQUAL; 
     527        } 
    474528 
    475529} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java

    r1294 r1733  
    2020/** 
    2121 * <p> 
    22  * This comparison rule returns <code>TaskEquality.IDENTICAL</code> if the comparison of the two 
    23  * tasks using the <code>==</code> operator returns true. Else it returns null to denote, that 
    24  * it can not compare the tasks. 
     22 * This comparison rule returns <code>TaskEquality.IDENTICAL</code> if the 
     23 * comparison of the two tasks using the <code>==</code> operator returns true. 
     24 * Else it returns null to denote, that it can not compare the tasks. 
    2525 * </p> 
    2626 *  
     
    3030public class TaskIdentityRule implements TaskComparisonRule { 
    3131 
    32     /* (non-Javadoc) 
    33      * @see TaskComparisonRule#isApplicable(ITask, ITask) 
    34      */ 
    35     @Override 
    36     public boolean isApplicable(ITask task1, ITask task2) { 
    37         return (task1 == task2); 
    38     } 
     32        /* 
     33         * (non-Javadoc) 
     34         *  
     35         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
     36         */ 
     37        @Override 
     38        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     39                return (task1 == task2); 
     40        } 
    3941 
    40     /* (non-Javadoc) 
    41      * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 
    42      */ 
    43     @Override 
    44     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    45         return (task1 == task2); 
    46     } 
     42        /* 
     43         * (non-Javadoc) 
     44         *  
     45         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
     46         */ 
     47        @Override 
     48        public boolean areLexicallyEqual(ITaskInstance instance1, 
     49                        ITaskInstance instance2) { 
     50                return (instance1.getTask() == instance2.getTask()); 
     51        } 
    4752 
    48     /* (non-Javadoc) 
    49      * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
    50      */ 
    51     @Override 
    52     public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
    53         return (task1 == task2); 
    54     } 
     53        /* 
     54         * (non-Javadoc) 
     55         *  
     56         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
     57         */ 
     58        @Override 
     59        public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
     60                return (task1 == task2); 
     61        } 
    5562 
    56     /* (non-Javadoc) 
    57      * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 
    58      */ 
    59     @Override 
    60     public boolean areSemanticallyEqual(ITask task1, ITask task2) { 
    61         return (task1 == task2); 
    62     } 
     63        /* 
     64         * (non-Javadoc) 
     65         *  
     66         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 
     67         * ITaskInstance) 
     68         */ 
     69        @Override 
     70        public boolean areSemanticallyEqual(ITaskInstance instance1, 
     71                        ITaskInstance instance2) { 
     72                return (instance1.getTask() == instance2.getTask()); 
     73        } 
    6374 
    64     /* (non-Javadoc) 
    65      * @see TaskComparisonRule#compare(ITask, ITask) 
    66      */ 
    67     @Override 
    68     public TaskEquality compare(ITask task1, ITask task2) { 
    69         if (isApplicable(task1, task2)) { 
    70             return TaskEquality.IDENTICAL; 
    71         } 
    72         else { 
    73             return null; 
    74         } 
    75     } 
     75        /* 
     76         * (non-Javadoc) 
     77         *  
     78         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 
     79         */ 
     80        @Override 
     81        public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 
     82                return (task1 == task2); 
     83        } 
    7684 
    77     /* (non-Javadoc) 
    78      * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
    79      */ 
    80     @Override 
    81     public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
    82         return (instance1.getTask() == instance2.getTask()); 
    83     } 
     85        /* 
     86         * (non-Javadoc) 
     87         *  
     88         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 
     89         * ITaskInstance) 
     90         */ 
     91        @Override 
     92        public boolean areSyntacticallyEqual(ITaskInstance instance1, 
     93                        ITaskInstance instance2) { 
     94                return (instance1.getTask() == instance2.getTask()); 
     95        } 
    8496 
    85     /* (non-Javadoc) 
    86      * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 
    87      */ 
    88     @Override 
    89     public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    90         return (instance1.getTask() == instance2.getTask()); 
    91     } 
     97        /* 
     98         * (non-Javadoc) 
     99         *  
     100         * @see TaskComparisonRule#compare(ITask, ITask) 
     101         */ 
     102        @Override 
     103        public TaskEquality compare(ITask task1, ITask task2) { 
     104                if (isApplicable(task1, task2)) { 
     105                        return TaskEquality.IDENTICAL; 
     106                } else { 
     107                        return null; 
     108                } 
     109        } 
    92110 
    93     /* (non-Javadoc) 
    94      * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 
    95      */ 
    96     @Override 
    97     public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    98         return (instance1.getTask() == instance2.getTask()); 
    99     } 
     111        /* 
     112         * (non-Javadoc) 
     113         *  
     114         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
     115         */ 
     116        @Override 
     117        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
     118                if (isApplicable(instance1, instance2)) { 
     119                        return TaskEquality.IDENTICAL; 
     120                } else { 
     121                        return null; 
     122                } 
     123        } 
    100124 
    101     /* (non-Javadoc) 
    102      * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 
    103      */ 
    104     @Override 
    105     public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 
    106         return (instance1.getTask() == instance2.getTask()); 
    107     } 
     125        /* 
     126         * (non-Javadoc) 
     127         *  
     128         * @see TaskComparisonRule#isApplicable(ITask, ITask) 
     129         */ 
     130        @Override 
     131        public boolean isApplicable(ITask task1, ITask task2) { 
     132                return (task1 == task2); 
     133        } 
    108134 
    109     /* (non-Javadoc) 
    110      * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 
    111      */ 
    112     @Override 
    113     public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 
    114         if (isApplicable(instance1, instance2)) { 
    115             return TaskEquality.IDENTICAL; 
    116         } 
    117         else { 
    118             return null; 
    119         } 
    120     } 
     135        /* 
     136         * (non-Javadoc) 
     137         *  
     138         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 
     139         */ 
     140        @Override 
     141        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 
     142                return (instance1.getTask() == instance2.getTask()); 
     143        } 
    121144 
    122145} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ISessionScopeRule.java

    r1146 r1733  
    2121/** 
    2222 * <p> 
    23  * A session scope rule is able to detected temporal relationships between task instances of the 
    24  * sessions provided to the {@link #apply(List<IUserSession>)} method. The rule creates temporal 
    25  * relationships between the tasks of the task instances, i.e. substructures in the task tree, if 
    26  * it detects a temporal relationship and instantiates the temporal relationships according to 
    27  * their occurrences. 
     23 * A session scope rule is able to detected temporal relationships between task 
     24 * instances of the sessions provided to the {@link #apply(List<IUserSession>)} 
     25 * method. The rule creates temporal relationships between the tasks of the task 
     26 * instances, i.e. substructures in the task tree, if it detects a temporal 
     27 * relationship and instantiates the temporal relationships according to their 
     28 * occurrences. 
    2829 * </p> 
    2930 *  
     
    3233interface ISessionScopeRule extends ITemporalRelationshipRule { 
    3334 
    34     /** 
    35      * <p> 
    36      * Applies the rule to the given sessions. The returned rule application result is null, if the 
    37      * rule can not be applied, i.e. it does not detect a temporal relationship. It returns a rule 
    38      * application result with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if 
    39      * the rule was applied. The result contains all newly created tasks and task instances. 
    40      * </p> 
    41      *  
    42      * @param sessions the session on which the rule shall be applied 
    43      *                     
    44      * @return the rule application result as described. 
    45      */ 
    46     RuleApplicationResult apply(List<IUserSession> sessions); 
     35        /** 
     36         * <p> 
     37         * Applies the rule to the given sessions. The returned rule application 
     38         * result is null, if the rule can not be applied, i.e. it does not detect a 
     39         * temporal relationship. It returns a rule application result with a status 
     40         * {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if the rule was 
     41         * applied. The result contains all newly created tasks and task instances. 
     42         * </p> 
     43         *  
     44         * @param sessions 
     45         *            the session on which the rule shall be applied 
     46         *  
     47         * @return the rule application result as described. 
     48         */ 
     49        RuleApplicationResult apply(List<IUserSession> sessions); 
    4750 
    4851} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITaskInstanceScopeRule.java

    r1294 r1733  
    1919/** 
    2020 * <p> 
    21  * a task instance scope rule is able to detected temporal relationships between the children of 
    22  * a task instance provided to the {@link #apply(ITaskInstance)} method. A rule creates temporal 
    23  * relationships between the task instances, i.e. substructures in the task tree, if 
    24  * it detects a temporal relationship and instantiates the temporal relationships accordingly. 
     21 * a task instance scope rule is able to detected temporal relationships between 
     22 * the children of a task instance provided to the {@link #apply(ITaskInstance)} 
     23 * method. A rule creates temporal relationships between the task instances, 
     24 * i.e. substructures in the task tree, if it detects a temporal relationship 
     25 * and instantiates the temporal relationships accordingly. 
    2526 * </p> 
    2627 *  
     
    2930interface ITaskInstanceScopeRule extends ITemporalRelationshipRule { 
    3031 
    31   /** 
    32    * <p> 
    33    * applies the rule to the given task instance. The returned rule application result is null, 
    34    * if the rule can not be applied, i.e. it does not detect a temporal relationship. It returns a 
    35    * rule application result with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} 
    36    * if the rule was applied. The result contains all newly created parent tasks and task instances. 
    37    * </p> 
    38    *  
    39    * @param taskInstance the task instances to apply the rule on 
    40    *                     
    41    * @return the rule application result as described. 
    42    */ 
    43   RuleApplicationResult apply(ITaskInstance taskInstance); 
    44    
     32        /** 
     33         * <p> 
     34         * applies the rule to the given task instance. The returned rule 
     35         * application result is null, if the rule can not be applied, i.e. it does 
     36         * not detect a temporal relationship. It returns a rule application result 
     37         * with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if 
     38         * the rule was applied. The result contains all newly created parent tasks 
     39         * and task instances. 
     40         * </p> 
     41         *  
     42         * @param taskInstance 
     43         *            the task instances to apply the rule on 
     44         *  
     45         * @return the rule application result as described. 
     46         */ 
     47        RuleApplicationResult apply(ITaskInstance taskInstance); 
     48 
    4549} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITemporalRelationshipRule.java

    r1294 r1733  
    1717/** 
    1818 * <p> 
    19  * a temporal relationship rule is the main interface for all rules applied for generating 
    20  * temporal relationships in a task tree. It is just a marker interface. More important are the 
    21  * sub interfaces {@link ISessionScopeRule} and {@link ITaskInstanceScopeRule}. 
     19 * a temporal relationship rule is the main interface for all rules applied for 
     20 * generating temporal relationships in a task tree. It is just a marker 
     21 * interface. More important are the sub interfaces {@link ISessionScopeRule} 
     22 * and {@link ITaskInstanceScopeRule}. 
    2223 * </p> 
    2324 *  
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java

    r1707 r1733  
    2424/** 
    2525 * <p> 
    26  * The rule application result describes the result of applying a {@link ITemporalRelationshipRule}. 
    27  * It contains a {@link RuleApplicationStatus} and a list of all parent task instances and tasks 
    28  * that were created during a rule application. See the description of 
     26 * The rule application result describes the result of applying a 
     27 * {@link ITemporalRelationshipRule}. It contains a 
     28 * {@link RuleApplicationStatus} and a list of all parent task instances and 
     29 * tasks that were created during a rule application. See the description of 
    2930 * {@link ITemporalRelationshipRule} for more details. 
    3031 * </p> 
     
    3435class RuleApplicationResult implements Serializable { 
    3536 
    36  
    3737        /** 
    3838         *  
     
    4141 
    4242        /** */ 
    43     private RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED; 
     43        private RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED; 
    4444 
    45     /** */ 
    46     private List<ITask> newParentTasks = new ArrayList<ITask>(); 
     45        /** */ 
     46        private final List<ITask> newParentTasks = new ArrayList<ITask>(); 
    4747 
    48     /** */ 
    49     private List<ITaskInstance> newParentInstances = new ArrayList<ITaskInstance>(); 
     48        /** */ 
     49        private final List<ITaskInstance> newParentInstances = new ArrayList<ITaskInstance>(); 
    5050 
    51     /** 
    52      * <p> 
    53      * create a rule application result with a status {@link RuleApplicationStatus#RULE_NOT_APPLIED} 
    54      * </p> 
    55      */ 
    56     RuleApplicationResult() { 
    57         // this is the default indicating nothing so far 
    58     } 
     51        /** 
     52         * <p> 
     53         * create a rule application result with a status 
     54         * {@link RuleApplicationStatus#RULE_NOT_APPLIED} 
     55         * </p> 
     56         */ 
     57        RuleApplicationResult() { 
     58                // this is the default indicating nothing so far 
     59        } 
    5960 
    60     /** 
    61     * <p> 
    62      * set the rule application status 
    63     * </p> 
    64     */ 
    65     void setRuleApplicationStatus(RuleApplicationStatus status) { 
    66         this.status = status; 
    67     } 
     61        /** 
     62        * <p> 
     63         * add a further parent task created during the rule application 
     64        * </p> 
     65        */ 
     66        void addNewlyCreatedTask(ITask newParent) { 
     67                newParentTasks.add(newParent); 
     68        } 
    6869 
    69     /** 
    70     * <p> 
    71      * return the rule application status 
    72     * </p> 
    73     */ 
    74     RuleApplicationStatus getRuleApplicationStatus() { 
    75         return status; 
    76     } 
     70        /** 
     71        * <p> 
     72         * add a further parent task instance created during the rule application 
     73        * </p> 
     74        */ 
     75        void addNewlyCreatedTaskInstance(ITaskInstance newParent) { 
     76                newParentInstances.add(newParent); 
     77        } 
    7778 
    78     /** 
    79     * <p> 
    80      * add a further parent task created during the rule application 
    81     * </p> 
    82     */ 
    83     void addNewlyCreatedTask(ITask newParent) { 
    84         newParentTasks.add(newParent); 
    85     } 
     79        /** 
     80        * <p> 
     81         * return all parent task instances created during the rule application 
     82        * </p> 
     83        */ 
     84        List<ITaskInstance> getNewlyCreatedTaskInstances() { 
     85                return newParentInstances; 
     86        } 
    8687 
    87     /** 
    88     * <p> 
    89     * return all parent tasks created during the rule application 
    90     * </p> 
    91     */ 
    92     List<ITask> getNewlyCreatedTasks() { 
    93         return newParentTasks; 
    94     } 
     88        /** 
     89        * <p> 
     90        * return all parent tasks created during the rule application 
     91        * </p> 
     92        */ 
     93        List<ITask> getNewlyCreatedTasks() { 
     94                return newParentTasks; 
     95        } 
    9596 
    96     /** 
    97     * <p> 
    98      * add a further parent task instance created during the rule application 
    99     * </p> 
    100     */ 
    101     void addNewlyCreatedTaskInstance(ITaskInstance newParent) { 
    102         newParentInstances.add(newParent); 
    103     } 
     97        /** 
     98        * <p> 
     99         * return the rule application status 
     100        * </p> 
     101        */ 
     102        RuleApplicationStatus getRuleApplicationStatus() { 
     103                return status; 
     104        } 
    104105 
    105     /** 
    106     * <p> 
    107      * return all parent task instances created during the rule application 
    108     * </p> 
    109     */ 
    110     List<ITaskInstance> getNewlyCreatedTaskInstances() { 
    111         return newParentInstances; 
    112     } 
     106        /** 
     107        * <p> 
     108         * set the rule application status 
     109        * </p> 
     110        */ 
     111        void setRuleApplicationStatus(RuleApplicationStatus status) { 
     112                this.status = status; 
     113        } 
    113114 
    114115} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java

    r1281 r1733  
    1717/** 
    1818 * <p> 
    19  * The rule application status describes the result of applying a {@link ITemporalRelationshipRule}. 
    20  * See the description of {@link ITemporalRelationshipRule} for more details. 
     19 * The rule application status describes the result of applying a 
     20 * {@link ITemporalRelationshipRule}. See the description of 
     21 * {@link ITemporalRelationshipRule} for more details. 
    2122 * </p> 
    2223 *  
     
    2425 */ 
    2526enum RuleApplicationStatus { 
    26     FINISHED, 
    27     NOT_APPLIED; 
     27        FINISHED, NOT_APPLIED; 
    2828} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java

    r1731 r1733  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
    17 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 
    18 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 
    1917import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 
    2018import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional; 
     
    2422import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
    2523import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance; 
    26 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 
    2724import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    2825import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; 
     
    4239        /** 
    4340         * <p> 
    44          * counter for generating unique ids. Starts at 0 for each new program start 
    45          * </p> 
    46          */ 
    47         private static int idCounter = 0; 
    48  
    49         public static int missedOptionals = 0; 
    50          
     41         * replaces a sub sequence for a specified range of elements in the provided 
     42         * task instances list by a sub task instance 
     43         * </p> 
     44         * 
     45         * @param parent 
     46         *            the list of which the range shall be replaced 
     47         * @param startIndex 
     48         *            the start index of the range 
     49         * @param endIndex 
     50         *            the end index of the range (inclusive) 
     51         * @param model 
     52         *            the task model (required for instantiating the sub sequence) 
     53         * @param taskFactory 
     54         *            the task factory used for instantiating the sub sequence 
     55         * @param taskBuilder 
     56         *            the task builder to perform changes in the task structure 
     57         *  
     58         * @return the replacement for the range 
     59         * @throws 
     60         */ 
     61        static ISequenceInstance createNewSubSequenceInRange( 
     62                        ITaskInstanceList parent, int startIndex, int endIndex, 
     63                        ISequence model, ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
     64                final ISequenceInstance subsequence = taskFactory 
     65                                .createNewTaskInstance(model); 
     66 
     67                // TODO: Debug output 
     68                /* 
     69                 * System.out.println("PRINTING MODEL: "); for (int i = 0; i < 
     70                 * subsequence.getSequence().getChildren().size(); i++) { 
     71                 * System.out.println(subsequence.getSequence().getChildren().get(i)); 
     72                 *  
     73                 * if (subsequence.getSequence().getChildren().get(i).getType() == 
     74                 * "selection") { for (int j = 0; j < ((ISelection) 
     75                 * subsequence.getSequence().getChildren().get(i)) 
     76                 * .getChildren().size(); j++) { if(((IStructuringTemporalRelationship) 
     77                 * subsequence 
     78                 * .getSequence().getChildren().get(i)).getChildren().get(j).getType() 
     79                 * =="sequence") { ISequence foo = (ISequence) ((ISelection) 
     80                 * (subsequence 
     81                 * .getSequence().getChildren().get(i))).getChildren().get(j); 
     82                 * System.out.println("\t" + foo); for(int k=0; k< 
     83                 * foo.getChildren().size();k++) { System.out.println("\t\t" 
     84                 * +foo.getChildren().get(k)); } System.out.println(); } else{ 
     85                 * System.out.println("\t" + ((ISelection) 
     86                 * subsequence.getSequence().getChildren().get(i)) 
     87                 * .getChildren().get(j)); } 
     88                 *  
     89                 * } } 
     90                 *  
     91                 * } System.out.println(); 
     92                 */ 
     93 
     94                // TODO: This is dirty! 
     95                missedOptionals = 0; 
     96                int modelindex = 0; 
     97                for (int i = startIndex; i <= endIndex; i++) { 
     98 
     99                        if (modelindex == model.getChildren().size()) { 
     100                                break; 
     101                        } 
     102                        final ITask tempTask = model.getChildren().get(modelindex); 
     103                        // System.out.println("Trying to add " + parent.get(startIndex) 
     104                        // + " to the model instance " + tempTask); 
     105                        if (tempTask.getType() == "optionality") { 
     106 
     107                                if (((IMarkingTemporalRelationship) tempTask).getMarkedTask() == parent 
     108                                                .get(startIndex).getTask()) { 
     109                                        // System.out.println("Adding OptionalInstance " + 
     110                                        // parent.get(startIndex) + " to " + tempTask.getType()); 
     111                                        final IOptionalInstance optional = taskFactory 
     112                                                        .createNewTaskInstance((IOptional) tempTask); 
     113                                        taskBuilder.setChild(optional, parent.get(startIndex)); 
     114                                        taskBuilder.addChild(subsequence, optional); 
     115                                } else { 
     116                                        // System.out.println("Adding Empty optional, not deleting anything from the input sequence"); 
     117                                        final IOptionalInstance optional = taskFactory 
     118                                                        .createNewTaskInstance((IOptional) tempTask); 
     119                                        taskBuilder.addChild(subsequence, optional); 
     120                                        modelindex++; 
     121                                        missedOptionals++; 
     122                                        continue; 
     123                                } 
     124                        } else if (tempTask.getType() == "selection") { 
     125                                final ISelectionInstance selection = taskFactory 
     126                                                .createNewTaskInstance((ISelection) tempTask); 
     127                                final ISelection tmpSel = (ISelection) tempTask; 
     128                                if ((tmpSel.getChildren().get(0).getType() == "sequence") 
     129                                                && (tmpSel.getChildren().get(1).getType() == "sequence")) { 
     130                                        ISequenceInstance selseq = null; 
     131                                        // The selection I create can just have 2 children 
     132                                        if (parent.get(startIndex).getTask().getId() == ((ISequence) tmpSel 
     133                                                        .getChildren().get(0)).getChildren().get(0).getId()) { 
     134                                                selseq = taskFactory 
     135                                                                .createNewTaskInstance((ISequence) tmpSel 
     136                                                                                .getChildren().get(0)); 
     137                                        } else if (parent.get(startIndex).getTask().getId() == ((ISequence) tmpSel 
     138                                                        .getChildren().get(1)).getChildren().get(0).getId()) { 
     139                                                selseq = taskFactory 
     140                                                                .createNewTaskInstance((ISequence) tmpSel 
     141                                                                                .getChildren().get(1)); 
     142                                        } else if ((parent.get(startIndex).getTask().getId() == tmpSel 
     143                                                        .getChildren().get(0).getId()) 
     144                                                        || (parent.get(startIndex).getTask().getId() == tmpSel 
     145                                                                        .getChildren().get(1).getId())) { 
     146                                                // System.out.println("Session ID: " + 
     147                                                // parent.get(startIndex).getTask().getId() + 
     148                                                // " tmpSel(0): " + tmpSel.getChildren().get(0).getId() 
     149                                                // + " tmpSel(1): " +tmpSel.getChildren().get(1).getId() 
     150                                                // ); 
     151                                                continue; 
     152                                        } 
     153 
     154                                        for (int k = 0; k < selseq.getSequence().getChildren() 
     155                                                        .size(); k++) { 
     156                                                // System.out.println("Trying to add " + 
     157                                                // parent.get(startIndex) + " to " + selseq); 
     158                                                taskBuilder.addChild(selseq, parent.get(startIndex)); 
     159                                                taskBuilder.removeTaskInstance(parent, startIndex); 
     160                                                i++; 
     161                                                // System.out.println("I:" + i); 
     162                                        } 
     163                                        // System.out.println("Trying to add " + selseq + " to " + 
     164                                        // tmpSel); 
     165                                        taskBuilder.setChild(selection, selseq); 
     166                                        taskBuilder.addChild(subsequence, selection); 
     167                                        modelindex++; 
     168                                        continue; 
     169                                } else { 
     170                                        // System.out.println("Trying to adding SelectionInstance " 
     171                                        // + parent.get(startIndex) + " to " + tempTask); 
     172                                        taskBuilder.setChild(selection, parent.get(startIndex)); 
     173                                        taskBuilder.addChild(subsequence, selection); 
     174                                } 
     175                        } else if (tempTask.getType() == "sequence") { 
     176                                // System.out.println("Adding SequenceInstance " + 
     177                                // parent.get(startIndex) + " to " + tempTask); 
     178                                taskBuilder.addChild(subsequence, parent.get(startIndex)); 
     179                        } else if (tempTask.getType() == "iteration") { 
     180                                // System.out.println("Adding IterationInstance " + 
     181                                // parent.get(startIndex) + " to " + tempTask); 
     182                                taskBuilder.addChild(subsequence, parent.get(startIndex)); 
     183                        } else { 
     184                                // System.out.println("Adding EventInstance " + 
     185                                // parent.get(startIndex) + " to " + tempTask); 
     186                                // System.out.println("Foo"); 
     187                                taskBuilder.addChild(subsequence, parent.get(startIndex)); 
     188                        } 
     189                        taskBuilder.removeTaskInstance(parent, startIndex); 
     190                        modelindex++; 
     191                } 
     192 
     193                taskBuilder.addTaskInstance(parent, startIndex, subsequence); 
     194 
     195                return subsequence; 
     196        } 
     197 
     198        /** 
     199         * <p> 
     200         * returns the next available id (uses the id counter) 
     201         * </p> 
     202         *  
     203         * @return the next available id 
     204         */ 
     205        static synchronized String getNewId() { 
     206                return Integer.toString(idCounter++); 
     207        } 
     208 
    51209        /** 
    52210         * <p> 
     
    73231                        int startIndex, int endIndex, ISequence model, 
    74232                        ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
    75                 ISequenceInstance subsequence = taskFactory 
     233                final ISequenceInstance subsequence = taskFactory 
    76234                                .createNewTaskInstance(model); 
    77235 
     
    83241        } 
    84242 
    85         /** 
    86          * <p> 
    87          * replaces a sub sequence for a specified range of elements in the provided 
    88          * task instances list by a sub task instance 
    89          * </p> 
    90          * 
    91          * @param parent 
    92          *            the list of which the range shall be replaced 
    93          * @param startIndex 
    94          *            the start index of the range 
    95          * @param endIndex 
    96          *            the end index of the range (inclusive) 
    97          * @param model 
    98          *            the task model (required for instantiating the sub sequence) 
    99          * @param taskFactory 
    100          *            the task factory used for instantiating the sub sequence 
    101          * @param taskBuilder 
    102          *            the task builder to perform changes in the task structure 
    103          *  
    104          * @return the replacement for the range 
    105          * @throws   
    106          */ 
    107         static ISequenceInstance createNewSubSequenceInRange( 
    108                         ITaskInstanceList parent, int startIndex, int endIndex, 
    109                         ISequence model, ITaskFactory taskFactory, ITaskBuilder taskBuilder)   { 
    110                 ISequenceInstance subsequence = taskFactory 
    111                                 .createNewTaskInstance(model); 
    112                  
    113                  
    114                 // TODO: Debug output 
    115                 /* 
    116                 System.out.println("PRINTING MODEL: "); 
    117                 for (int i = 0; i < subsequence.getSequence().getChildren().size(); i++) { 
    118                         System.out.println(subsequence.getSequence().getChildren().get(i)); 
    119  
    120                         if (subsequence.getSequence().getChildren().get(i).getType() == "selection") { 
    121                                 for (int j = 0; j < ((ISelection) subsequence.getSequence().getChildren().get(i)) 
    122                                                 .getChildren().size(); j++) { 
    123                                         if(((IStructuringTemporalRelationship) subsequence.getSequence().getChildren().get(i)).getChildren().get(j).getType() =="sequence") 
    124                                         { 
    125                                                 ISequence foo =  (ISequence) ((ISelection) (subsequence.getSequence().getChildren().get(i))).getChildren().get(j); 
    126                                                 System.out.println("\t" + foo); 
    127                                                 for(int k=0; k< foo.getChildren().size();k++) { 
    128                                                         System.out.println("\t\t" +foo.getChildren().get(k)); 
    129                                                 } 
    130                                                 System.out.println(); 
    131                                         } 
    132                                         else{ 
    133                                                 System.out.println("\t" 
    134                                                                 + ((ISelection) subsequence.getSequence().getChildren().get(i)) 
    135                                                                                 .getChildren().get(j)); 
    136                                         } 
    137                                  
    138                                 } 
    139                         } 
    140                  
    141                 } 
    142                 System.out.println(); 
    143                 */ 
    144                  
    145                 //TODO: This is dirty! 
    146                 missedOptionals=0; 
    147                 int modelindex=0; 
    148                 for (int i = startIndex; i <= endIndex; i++) { 
    149                          
    150                         if(modelindex == model.getChildren().size()) { 
    151                                 break; 
    152                         } 
    153                         ITask tempTask = model.getChildren().get(modelindex); 
    154                         //System.out.println("Trying to add " + parent.get(startIndex) 
    155                         //      + " to the model instance " + tempTask); 
    156                         if (tempTask.getType() == "optionality") { 
    157                                                  
    158                                         if(((IMarkingTemporalRelationship) tempTask).getMarkedTask() == parent.get(startIndex).getTask()) { 
    159                                                 //System.out.println("Adding OptionalInstance " + parent.get(startIndex) + " to " + tempTask.getType()); 
    160                                                 IOptionalInstance optional = taskFactory.createNewTaskInstance((IOptional) tempTask); 
    161                                                 taskBuilder.setChild(optional, parent.get(startIndex)); 
    162                                                 taskBuilder.addChild(subsequence, optional); 
    163                                         } 
    164                                         else { 
    165                                                 //System.out.println("Adding Empty optional, not deleting anything from the input sequence"); 
    166                                                 IOptionalInstance optional = taskFactory.createNewTaskInstance((IOptional) tempTask); 
    167                                                 taskBuilder.addChild(subsequence, optional); 
    168                                                 modelindex++; 
    169                                                 missedOptionals++; 
    170                                                 continue; 
    171                                         }                                
    172                         } else if (tempTask.getType() == "selection") { 
    173                                 ISelectionInstance selection = taskFactory.createNewTaskInstance((ISelection) tempTask); 
    174                                 ISelection tmpSel = (ISelection)tempTask; 
    175                                 if(tmpSel.getChildren().get(0).getType() == "sequence" && tmpSel.getChildren().get(1).getType()=="sequence") { 
    176                                         ISequenceInstance selseq = null; 
    177                                         //The selection I create can just have 2 children 
    178                                         if(parent.get(startIndex).getTask().getId() == ((ISequence)tmpSel.getChildren().get(0)).getChildren().get(0).getId()) { 
    179                                                 selseq = taskFactory.createNewTaskInstance((ISequence) tmpSel.getChildren().get(0)); 
    180                                         } 
    181                                         else if(parent.get(startIndex).getTask().getId() == ((ISequence)tmpSel.getChildren().get(1)).getChildren().get(0).getId()) { 
    182                                                 selseq = taskFactory.createNewTaskInstance((ISequence) tmpSel.getChildren().get(1)); 
    183                                         } 
    184                                         else if(parent.get(startIndex).getTask().getId() == tmpSel.getChildren().get(0).getId() || parent.get(startIndex).getTask().getId() == tmpSel.getChildren().get(1).getId() ) { 
    185                                                 //System.out.println("Session ID: " + parent.get(startIndex).getTask().getId() + " tmpSel(0): " + tmpSel.getChildren().get(0).getId() + " tmpSel(1): " +tmpSel.getChildren().get(1).getId()  ); 
    186                                                 continue; 
    187                                         } 
    188                                                  
    189                                         for (int k=0;k<selseq.getSequence().getChildren().size();k++) { 
    190                                                 //System.out.println("Trying to add " + parent.get(startIndex) + " to " + selseq); 
    191                                                 taskBuilder.addChild(selseq,parent.get(startIndex)); 
    192                                                 taskBuilder.removeTaskInstance(parent, startIndex); 
    193                                                 i++; 
    194                                                 //System.out.println("I:" + i); 
    195                                         } 
    196                                         //System.out.println("Trying to add " + selseq + " to " + tmpSel); 
    197                                         taskBuilder.setChild(selection, selseq); 
    198                                         taskBuilder.addChild(subsequence, selection); 
    199                                         modelindex++; 
    200                                         continue; 
    201                                 } 
    202                                 else 
    203                                 { 
    204                                         //System.out.println("Trying to adding SelectionInstance " + parent.get(startIndex) + " to " + tempTask); 
    205                                         taskBuilder.setChild(selection, parent.get(startIndex)); 
    206                                         taskBuilder.addChild(subsequence,selection); 
    207                                 } 
    208                         } else if (tempTask.getType() == "sequence") { 
    209                                 //System.out.println("Adding SequenceInstance " + parent.get(startIndex) + " to " + tempTask); 
    210                                 taskBuilder.addChild(subsequence, parent.get(startIndex)); 
    211                         } else if (tempTask.getType() == "iteration") { 
    212                                 //System.out.println("Adding IterationInstance " + parent.get(startIndex) + " to " + tempTask); 
    213                                 taskBuilder.addChild(subsequence, parent.get(startIndex)); 
    214                         } else { 
    215                                 //System.out.println("Adding EventInstance " + parent.get(startIndex) + " to " + tempTask); 
    216                                 //System.out.println("Foo"); 
    217                                 taskBuilder.addChild(subsequence, parent.get(startIndex)); 
    218                         } 
    219                         taskBuilder.removeTaskInstance(parent, startIndex); 
    220                         modelindex++; 
    221                 } 
    222                  
    223                 taskBuilder.addTaskInstance(parent, startIndex, subsequence); 
    224  
    225                 return subsequence; 
    226         } 
    227  
    228          
    229243        // Print out the progress 
    230         static void printProgressPercentage(String message,int count, int size) { 
     244        static void printProgressPercentage(String message, int count, int size) { 
    231245                if (size > 100) { 
    232                         if ((count % (size / 100) == 0)) { 
     246                        if (((count % (size / 100)) == 0)) { 
    233247                                // Console.traceln(Level.INFO,("Thread" + 
    234248                                // Thread.currentThread().getName() + ": " + Math.round((float) 
    235249                                // count/size*100))+ "%"); 
    236                                 System.out.println(message + " in thread" + Thread.currentThread().getName() 
    237                                                 + ": " + Math.round((float) count / size * 100) + "%"); 
     250                                System.out.println(message + " in thread" 
     251                                                + Thread.currentThread().getName() + ": " 
     252                                                + Math.round(((float) count / size) * 100) + "%"); 
    238253                        } 
    239254                } else { 
     
    241256                        // Thread.currentThread().getName() + ": " +Math.round((float) 
    242257                        // count/size*100))+ "%"); 
    243                         System.out.println(message + " in thread" + Thread.currentThread().getName() 
    244                                         + ": " + Math.round((float) count / size * 100) + "%"); 
     258                        System.out.println(message + " in thread" 
     259                                        + Thread.currentThread().getName() + ": " 
     260                                        + Math.round(((float) count / size) * 100) + "%"); 
    245261 
    246262                } 
    247263        } 
    248264 
    249          
    250         /** 
    251          * <p> 
    252          * returns the next available id (uses the id counter) 
    253          * </p> 
    254          *  
    255          * @return the next available id 
    256          */ 
    257         static synchronized String getNewId() { 
    258                 return Integer.toString(idCounter++); 
    259         } 
     265        /** 
     266         * <p> 
     267         * counter for generating unique ids. Starts at 0 for each new program start 
     268         * </p> 
     269         */ 
     270        private static int idCounter = 0; 
     271 
     272        public static int missedOptionals = 0; 
    260273 
    261274        /** 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java

    r1401 r1733  
    4545/** 
    4646 * <p> 
    47  * This class implements the major rule for creating task trees based on a set of recorded 
    48  * user sessions. For this, it first harmonizes all tasks. This eases later comparison. Then it 
    49  * searches the sessions for iterations and replaces them accordingly. Then it searches for sub 
    50  * sequences being the longest and occurring most often. For each found sub sequence, it replaces 
    51  * the occurrences by creating appropriate {@link ISequence}s. Afterwards, again searches for 
    52  * iterations and then again for sub sequences until no more replacements are done. 
     47 * This class implements the major rule for creating task trees based on a set 
     48 * of recorded user sessions. For this, it first harmonizes all tasks. This 
     49 * eases later comparison. Then it searches the sessions for iterations and 
     50 * replaces them accordingly. Then it searches for sub sequences being the 
     51 * longest and occurring most often. For each found sub sequence, it replaces 
     52 * the occurrences by creating appropriate {@link ISequence}s. Afterwards, again 
     53 * searches for iterations and then again for sub sequences until no more 
     54 * replacements are done. 
    5355 * </p> 
    5456 * <p> 
    55  * For determining the longest sequence occurring most often, the implementation uses a  
    56  * {@link Trie}. The depth of the tree is initially 3. If the algorithm has a longest sequence 
    57  * occurring most often whose length is equal to the depth of the trie, it recalculates the trie 
    58  * with an increased depth.  
     57 * For determining the longest sequence occurring most often, the implementation 
     58 * uses a {@link Trie}. The depth of the tree is initially 3. If the algorithm 
     59 * has a longest sequence occurring most often whose length is equal to the 
     60 * depth of the trie, it recalculates the trie with an increased depth. 
    5961 * </p> 
    6062 *  
     
    6264 */ 
    6365class SequenceForTaskDetectionRule implements ISessionScopeRule { 
    64      
    65     /** 
    66      * <p> 
    67      * the task factory to be used for creating substructures for the temporal 
    68      * relationships identified during rul application 
    69      * </p> 
    70      */ 
    71     private ITaskFactory taskFactory; 
    72     /** 
    73      * <p> 
    74      * the task builder to be used for creating substructures for the temporal relationships 
    75      * identified during rule application 
    76      * </p> 
    77      */ 
    78     private ITaskBuilder taskBuilder; 
    79  
    80     /** 
    81      * <p> 
    82      * the task handling strategy to be used for comparing tasks for preparation, i.e., before 
    83      * the tasks are harmonized 
    84      * </p> 
    85      */ 
    86     private TaskHandlingStrategy preparationTaskHandlingStrategy; 
    87      
    88     /** 
    89      * <p> 
    90      * the task handling strategy to be used for comparing tasks during iteration detection an trie 
    91      * generation, i.e., after the tasks are harmonized  
    92      * </p> 
    93      */ 
    94     private TaskHandlingStrategy identityTaskHandlingStrategy;; 
    95      
    96     /** 
    97      * <p> 
    98      * instantiates the rule and initializes it with a task equality to be considered when 
    99      * comparing tasks as well as a task factory and builder to be used for creating task 
    100      * structures. 
    101      * </p> 
    102      *  
    103      * @param minimalTaskEquality the task equality to be considered when comparing tasks 
    104      * @param taskFactory         the task factory to be used for creating substructures 
    105      * @param taskBuilder         the task builder to be used for creating substructures 
    106      */ 
    107     SequenceForTaskDetectionRule(TaskEquality minimalTaskEquality, 
    108                                  ITaskFactory taskFactory, 
    109                                  ITaskBuilder taskBuilder) 
    110     { 
    111         this.taskFactory = taskFactory; 
    112         this.taskBuilder = taskBuilder; 
    113          
    114         this.preparationTaskHandlingStrategy = new TaskHandlingStrategy(minimalTaskEquality); 
    115         this.identityTaskHandlingStrategy = new TaskHandlingStrategy(TaskEquality.IDENTICAL); 
    116     } 
    117  
    118     /* (non-Javadoc) 
    119      * @see java.lang.Object#toString() 
    120      */ 
    121     @Override 
    122     public String toString() { 
    123         return "SequenceForTaskDetectionRule"; 
    124     } 
    125  
    126     /* (non-Javadoc) 
    127      * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply(java.util.List) 
    128      */ 
    129     @Override 
    130     public RuleApplicationResult apply(List<IUserSession> sessions) { 
    131         RuleApplicationData appData = new RuleApplicationData(sessions); 
    132          
    133         // this is the real rule application. Loop while something is replaced. 
    134         harmonizeEventTaskInstancesModel(appData); 
    135         do { 
    136             System.out.println(); 
    137              
    138             appData.getStopWatch().start("whole loop"); 
    139             detectAndReplaceIterations(appData); 
    140  
    141             appData.getStopWatch().start("task replacement"); 
    142             detectAndReplaceTasks(appData); 
    143             appData.getStopWatch().stop("task replacement"); 
    144             appData.getStopWatch().stop("whole loop"); 
    145              
    146             //((TaskTreeNodeComparator) taskComparator).getStopWatch().dumpStatistics(System.out); 
    147             //((TaskTreeNodeComparator) taskComparator).getStopWatch().reset(); 
    148              
    149             appData.getStopWatch().dumpStatistics(System.out); 
    150             appData.getStopWatch().reset(); 
    151              
    152         } 
    153         while (appData.detectedAndReplacedTasks()); 
    154          
    155         Console.println 
    156             ("created " + appData.getResult().getNewlyCreatedTasks().size() + 
    157              " new tasks and " + appData.getResult().getNewlyCreatedTaskInstances().size() + 
    158              " appropriate instances\n"); 
    159          
    160         if ((appData.getResult().getNewlyCreatedTasks().size() > 0) || 
    161             (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) 
    162         { 
    163             appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 
    164         } 
    165          
    166         return appData.getResult(); 
    167     } 
    168  
    169     /** 
    170      * <p> 
    171      * harmonizes the event task instances by unifying tasks. This is done, as initially the 
    172      * event tasks being equal with respect to the considered task equality are distinct objects. 
    173      * The comparison of these distinct objects is more time consuming than comparing the object 
    174      * references. 
    175      * </p> 
    176      * 
    177      * @param appData the rule application data combining all data used for applying this rule 
    178      */ 
    179     private void harmonizeEventTaskInstancesModel(RuleApplicationData appData) { 
    180         Console.traceln(Level.INFO, "harmonizing task model of event task instances"); 
    181         appData.getStopWatch().start("harmonizing event tasks"); 
    182  
    183         SymbolMap<ITaskInstance, ITask> uniqueTasks = 
    184             preparationTaskHandlingStrategy.createSymbolMap(); 
    185         TaskInstanceComparator comparator = preparationTaskHandlingStrategy.getTaskComparator(); 
    186          
    187         int unifiedTasks = 0; 
    188         ITask task; 
    189         List<IUserSession> sessions = appData.getSessions(); 
    190         int sessionNo = 0; 
    191         for (IUserSession session : sessions) { 
    192             Console.traceln(Level.FINE, "handling " + (++sessionNo) + ". " + session); 
    193             for (ITaskInstance taskInstance : session) { 
    194                 task = uniqueTasks.getValue(taskInstance); 
    195                  
    196                 if (task == null) { 
    197                     uniqueTasks.addSymbol(taskInstance, taskInstance.getTask()); 
    198                 } 
    199                 else { 
    200                     taskBuilder.setTask(taskInstance, task); 
    201                     unifiedTasks++; 
    202                 } 
    203             } 
    204              
    205             comparator.clearBuffers(); 
    206         } 
    207          
    208         appData.getStopWatch().stop("harmonizing event tasks"); 
    209         Console.traceln(Level.INFO, "harmonized " + unifiedTasks + " task occurrences (still " + 
    210                         uniqueTasks.size() + " different tasks)"); 
    211  
    212         appData.getStopWatch().dumpStatistics(System.out); 
    213         appData.getStopWatch().reset(); 
    214     } 
    215  
    216     /** 
    217      * <p> 
    218      * searches for direct iterations of single tasks in all sequences and replaces them with 
    219      * {@link IIteration}s, respectively appropriate instances. Also all single occurrences of 
    220      * a task that is iterated somewhen are replaced with iterations to have again an efficient 
    221      * way for task comparisons.  
    222      * </p> 
    223      *  
    224      * @param appData the rule application data combining all data used for applying this rule 
    225      */ 
    226     private void detectAndReplaceIterations(RuleApplicationData appData) { 
    227         Console.traceln(Level.FINE, "detecting iterations"); 
    228         appData.getStopWatch().start("detecting iterations"); 
    229          
    230         List<IUserSession> sessions = appData.getSessions(); 
    231          
    232         Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
    233          
    234         if (iteratedTasks.size() > 0) { 
    235             replaceIterationsOf(iteratedTasks, sessions, appData); 
    236         } 
    237          
    238         appData.getStopWatch().stop("detecting iterations"); 
    239         Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() + " iterated tasks"); 
    240     } 
    241  
    242     /** 
    243      * <p> 
    244      * searches the provided sessions for task iterations. If a task is iterated, it is added 
    245      * to the returned set. 
    246      * </p> 
    247      *  
    248      * @param the session to search for iterations in 
    249      *  
    250      * @return a set of tasks being iterated somewhere 
    251      */ 
    252     private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
    253         Set<ITask> iteratedTasks = new HashSet<ITask>(); 
    254         for (IUserSession session : sessions) { 
    255             for (int i = 0; i < (session.size() - 1); i++) { 
    256                 // we prepared the task instances to refer to unique tasks, if they are treated 
    257                 // as equal. Therefore, we just compare the identity of the tasks of the task 
    258                 // instances 
    259                 if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
    260                     iteratedTasks.add(session.get(i).getTask()); 
    261                 } 
    262             } 
    263         } 
    264          
    265         return iteratedTasks; 
    266     } 
    267  
    268     /** 
    269      * <p> 
    270      * replaces all occurrences of all tasks provided in the set with iterations 
    271      * </p> 
    272      * 
    273      * @param iteratedTasks the tasks to be replaced with iterations 
    274      * @param sessions      the sessions in which the tasks are to be replaced 
    275      * @param appData       the rule application data combining all data used for applying this rule 
    276      */ 
    277     private void replaceIterationsOf(Set<ITask>          iteratedTasks, 
    278                                      List<IUserSession>  sessions, 
    279                                      RuleApplicationData appData) 
    280     { 
    281         Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
    282         Map<IIteration, List<IIterationInstance>> iterationInstances = 
    283                 new HashMap<IIteration, List<IIterationInstance>>(); 
    284              
    285         for (ITask iteratedTask : iteratedTasks) { 
    286             IIteration iteration = taskFactory.createNewIteration(); 
    287             iterations.put(iteratedTask, iteration); 
    288             iterationInstances.put(iteration, new LinkedList<IIterationInstance>()); 
    289         } 
    290          
    291         IIterationInstance iterationInstance; 
    292          
    293         for (IUserSession session : sessions) { 
    294             int index = 0; 
    295             iterationInstance = null; 
    296  
    297             while (index < session.size()) { 
    298                 // we prepared the task instances to refer to unique tasks, if they are treated 
    299                 // as equal. Therefore, we just compare the identity of the tasks of the task 
    300                 // instances 
    301                 ITask currentTask = session.get(index).getTask(); 
    302                 IIteration iteration = iterations.get(currentTask); 
    303                 if (iteration != null) { 
    304                     if ((iterationInstance == null) || (iterationInstance.getTask() != iteration)) 
    305                     { 
    306                         iterationInstance = taskFactory.createNewTaskInstance(iteration); 
    307                         iterationInstances.get(iteration).add(iterationInstance); 
    308                         taskBuilder.addTaskInstance(session, index, iterationInstance); 
    309                         index++; 
    310                     } 
    311                      
    312                     taskBuilder.addChild(iterationInstance, session.get(index)); 
    313                     taskBuilder.removeTaskInstance(session, index); 
    314                 } 
    315                 else { 
    316                     if (iterationInstance != null) { 
    317                         iterationInstance = null; 
    318                     } 
    319                     index++; 
    320                 } 
    321             } 
    322         } 
    323          
    324         for (Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances.entrySet()) 
    325         { 
    326             harmonizeIterationInstancesModel(entry.getKey(), entry.getValue()); 
    327         } 
    328     } 
    329  
    330     /** 
    331      * <p> 
    332      * TODO clarify why this is done 
    333      * </p> 
    334      */ 
    335     private void harmonizeIterationInstancesModel(IIteration               iteration, 
    336                                                   List<IIterationInstance> iterationInstances) 
    337     { 
    338         List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
    339         TaskInstanceComparator comparator = preparationTaskHandlingStrategy.getTaskComparator(); 
    340          
    341         // merge the lexically different variants of iterated task to a unique list  
    342         for (IIterationInstance iterationInstance : iterationInstances) { 
    343             for (ITaskInstance executionVariant : iterationInstance) { 
    344                 ITask candidate = executionVariant.getTask(); 
    345              
    346                 boolean found = false; 
    347                 for (ITask taskVariant : iteratedTaskVariants) { 
    348                     if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
    349                         taskBuilder.setTask(executionVariant, taskVariant); 
    350                         found = true; 
    351                         break; 
    352                     } 
    353                 } 
    354                  
    355                 if (!found) { 
    356                     iteratedTaskVariants.add(candidate); 
    357                 } 
    358             } 
    359         } 
    360          
    361         // if there are more than one lexically different variant of iterated tasks, adapt the 
    362         // iteration model to be a selection of different variants. In this case also adapt 
    363         // the generated iteration instances to correctly contain selection instances. If there 
    364         // is only one variant of an iterated task, simply set this as the marked task of the 
    365         // iteration. In this case, the instances can be preserved as is 
    366         if (iteratedTaskVariants.size() > 1) { 
    367             ISelection selection = taskFactory.createNewSelection(); 
    368              
    369             for (ITask variant : iteratedTaskVariants) { 
    370                 taskBuilder.addChild(selection, variant); 
    371             } 
    372              
    373             taskBuilder.setMarkedTask(iteration, selection); 
    374              
    375             for (IIterationInstance instance : iterationInstances) { 
    376                 for (int i = 0; i < instance.size(); i++) { 
    377                     ISelectionInstance selectionInstance = 
    378                         taskFactory.createNewTaskInstance(selection); 
    379                     taskBuilder.setChild(selectionInstance, instance.get(i)); 
    380                     taskBuilder.setTaskInstance(instance, i, selectionInstance); 
    381                 } 
    382             } 
    383         } 
    384         else { 
    385             taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
    386         } 
    387     } 
    388  
    389     /** 
    390      * TODO go on commenting 
    391      * @param appData the rule application data combining all data used for applying this rule 
    392      */ 
    393     private void detectAndReplaceTasks(RuleApplicationData appData) { 
    394         Console.traceln(Level.FINE, "detecting and replacing tasks"); 
    395         appData.getStopWatch().start("detecting tasks"); 
    396          
    397         getSequencesOccuringMostOften(appData); 
    398  
    399         appData.getStopWatch().stop("detecting tasks"); 
    400         appData.getStopWatch().start("replacing tasks"); 
    401          
    402         replaceSequencesOccurringMostOften(appData); 
    403          
    404         appData.getStopWatch().stop("replacing tasks"); 
    405         Console.traceln(Level.INFO, "detected and replaced " + appData.getLastFoundTasks().size() + 
    406                         " tasks occuring " + appData.getLastFoundTasks().getOccurrenceCount() + 
    407                         " times"); 
    408     } 
    409  
    410     /** 
    411      * @param appData the rule application data combining all data used for applying this rule 
    412      */ 
    413     private void getSequencesOccuringMostOften(RuleApplicationData appData) { 
    414         Console.traceln(Level.FINE, "determining most prominent tasks"); 
    415  
    416         Tasks tasks; 
    417         boolean createNewTrie = (appData.getLastTrie() == null) || 
    418             appData.detectedAndReplacedTasks(); // tree has changed 
    419          
    420         do { 
    421             if (createNewTrie) { 
    422                 createNewTrie(appData); 
    423             } 
    424              
    425             MaxCountAndLongestTasksFinder finder = new MaxCountAndLongestTasksFinder(); 
    426             appData.getLastTrie().process(finder); 
    427          
    428             tasks = finder.getFoundTasks(); 
    429              
    430             createNewTrie = false; 
    431              
    432             for (List<ITaskInstance> task : tasks) { 
    433                 if (task.size() >= appData.getTrainedSequenceLength()) { 
    434                     // Trie must be recreated with a longer sequence length to be sure that 
    435                     // the found sequences occurring most often are found in their whole length 
    436                     appData.setTrainedSequenceLength(appData.getTrainedSequenceLength() + 1); 
    437                     createNewTrie = true; 
    438                     break; 
    439                 } 
    440             } 
    441         } 
    442         while (createNewTrie); 
    443          
    444         // create a normal trie for comparison 
    445         /*System.out.println("creating test trie for comparison"); 
    446          
    447         appData.getStopWatch().start("testtrie"); 
    448         Trie<ITaskInstance> trie = new Trie<ITaskInstance>(identityTaskComparator); 
    449          
    450         for (IUserSession session : appData.getSessions()) { 
    451             trie.train(session.getExecutedTasks(), appData.getTrainedSequenceLength()); 
    452         } 
    453          
    454         appData.getStopWatch().stop("testtrie"); 
    455          
    456         MaxCountAndLongestTasksFinder finder = new MaxCountAndLongestTasksFinder(); 
    457         trie.process(finder); 
    458  
    459         boolean allTasksEqual = finder.getFoundTasks().size() == tasks.size(); 
    460          
    461         allTasksEqual &= finder.getFoundTasks().occurrenceCount == tasks.occurrenceCount; 
    462          
    463         for (List<ITaskInstance> task1 : finder.getFoundTasks()) { 
    464             boolean foundTask = false; 
    465             for (List<ITaskInstance> task2 : tasks) { 
    466                 boolean tasksEqual = false; 
    467                 if (task1.size() == task2.size()) { 
    468                     tasksEqual = true; 
    469                     for (int i = 0; i < task1.size(); i++) { 
    470                         if (!identityTaskComparator.equals(task1.get(i).getTask(), task2.get(i).getTask())) 
    471                         { 
    472                             tasksEqual = false; 
    473                         } 
    474                     } 
    475                 } 
    476                  
    477                 if (tasksEqual) { 
    478                     foundTask = true; 
    479                     break; 
    480                 } 
    481             } 
    482              
    483             if (!foundTask) { 
    484                 System.out.println("different is " + task1); 
    485                 allTasksEqual = false; 
    486                 break; 
    487             } 
    488         } 
    489          
    490         if (!allTasksEqual) { 
    491             System.out.println(finder.getFoundTasks()); 
    492             System.out.println(tasks); 
    493              
    494             throw new IllegalArgumentException("both tries calculated different subsequences"); 
    495         } 
    496          
    497         /*TrieStatisticsDumper dumper = new TrieStatisticsDumper(); 
    498         appData.getLastTrie().process(dumper); 
    499         dumper.dumpCounters();*/ 
    500          
    501         appData.setLastFoundTasks(tasks); 
    502  
    503         Console.traceln(Level.FINE, "found " + appData.getLastFoundTasks().size() + " tasks " + 
    504                         "occurring " + appData.getLastFoundTasks().getOccurrenceCount() + " times"); 
    505     } 
    506  
    507     /** 
    508      * @param appData the rule application data combining all data used for applying this rule 
    509      */ 
    510     private void createNewTrie(RuleApplicationData appData) { 
    511         Console.traceln(Level.FINER, "training trie with a maximum sequence length of " + 
    512                         appData.getTrainedSequenceLength()); 
    513  
    514         appData.getStopWatch().start("training trie"); 
    515          
    516         // we prepared the task instances to refer to unique tasks, if they are treated 
    517         // as equal. Therefore, we just compare the identity of the tasks of the task 
    518         // instances 
    519         appData.setLastTrie(new TaskInstanceTrie(identityTaskHandlingStrategy)); 
    520      
    521         appData.getLastTrie().trainSessions 
    522             (appData.getSessions(), appData.getTrainedSequenceLength()); 
    523          
    524         appData.getStopWatch().stop("training trie"); 
    525     } 
    526  
    527     /** 
    528      * @param appData the rule application data combining all data used for applying this rule 
    529      */ 
    530     private void replaceSequencesOccurringMostOften(RuleApplicationData appData) { 
    531         appData.detectedAndReplacedTasks(false); 
    532  
    533         if ((appData.getLastFoundTasks().size() > 0) && 
    534             (appData.getLastFoundTasks().getOccurrenceCount() > 1)) 
    535         { 
    536             Console.traceln(Level.FINER, "replacing tasks occurrences"); 
    537  
    538             for (List<ITaskInstance> task : appData.getLastFoundTasks()) { 
    539                 ISequence sequence = taskFactory.createNewSequence(); 
    540                  
    541                 Console.traceln(Level.FINEST, "replacing " + sequence.getId() + ": " + task); 
    542  
    543                 List<ISequenceInstance> sequenceInstances = 
    544                     replaceTaskOccurrences(task, appData.getSessions(), sequence); 
    545                  
    546                 harmonizeSequenceInstancesModel(sequence, sequenceInstances,task.size()); 
    547                 appData.detectedAndReplacedTasks 
    548                     (appData.detectedAndReplacedTasks() || (sequenceInstances.size() > 0)); 
    549  
    550                 if (sequenceInstances.size() < appData.getLastFoundTasks().getOccurrenceCount()) { 
    551                     Console.traceln(Level.FINE, sequence.getId() + ": replaced task only " + 
    552                                     sequenceInstances.size() + " times instead of expected " + 
    553                                     appData.getLastFoundTasks().getOccurrenceCount()); 
    554                 } 
    555             } 
    556         } 
    557          
    558     } 
    559  
    560     /** 
    561      * 
    562      */ 
    563     private void harmonizeSequenceInstancesModel(ISequence               sequence, 
    564                                                  List<ISequenceInstance> sequenceInstances, 
    565                                                  int                     sequenceLength) 
    566     { 
    567         TaskInstanceComparator comparator = preparationTaskHandlingStrategy.getTaskComparator(); 
    568          
    569         // ensure for each subtask that lexically different variants are preserved 
    570         for (int subTaskIndex = 0; subTaskIndex < sequenceLength; subTaskIndex++) { 
    571             List<ITask> subTaskVariants = new LinkedList<ITask>(); 
    572              
    573             for (ISequenceInstance sequenceInstance : sequenceInstances) { 
    574                 ITask candidate = sequenceInstance.get(subTaskIndex).getTask(); 
    575                  
    576                 boolean found = false; 
    577                  
    578                 for (int i = 0; i < subTaskVariants.size(); i++) { 
    579                     if (comparator.areLexicallyEqual(subTaskVariants.get(i), candidate)) { 
    580                         taskBuilder.setTask 
    581                             (sequenceInstance.get(subTaskIndex), subTaskVariants.get(i)); 
    582                          
    583                         found = true; 
    584                         break; 
    585                     } 
    586                 } 
    587                  
    588                 if (!found) { 
    589                     subTaskVariants.add(candidate); 
    590                 } 
    591             } 
    592              
    593             // if there are more than one lexically different variant of the sub task at 
    594             // the considered position, adapt the sequence model at that position to have 
    595             // a selection of the different variants. In this case also adapt the 
    596             // generated sequence instances to correctly contain selection instances. If 
    597             // there is only one variant of sub tasks at the given position, simply set 
    598             // this variant as the sub task of the selection. In this case, the instances 
    599             // can be preserved as is 
    600             if (subTaskVariants.size() > 1) { 
    601                 ISelection selection = taskFactory.createNewSelection(); 
    602                  
    603                 for (ITask variant : subTaskVariants) { 
    604                     taskBuilder.addChild(selection, variant); 
    605                 } 
    606                  
    607                 taskBuilder.addChild(sequence, selection); 
    608                  
    609                 for (ISequenceInstance instance : sequenceInstances) { 
    610                     ISelectionInstance selectionInstance = 
    611                         taskFactory.createNewTaskInstance(selection); 
    612                     taskBuilder.setChild(selectionInstance, instance.get(subTaskIndex)); 
    613                     taskBuilder.setTaskInstance(instance, subTaskIndex, selectionInstance); 
    614                 } 
    615             } 
    616             else if (subTaskVariants.size() == 1) { 
    617                 taskBuilder.addChild(sequence, subTaskVariants.get(0)); 
    618             } 
    619         } 
    620     } 
    621  
    622     /** 
    623      * @param tree 
    624      */ 
    625     private List<ISequenceInstance> replaceTaskOccurrences(List<ITaskInstance> task, 
    626                                                            List<IUserSession>  sessions, 
    627                                                            ISequence           temporalTaskModel) 
    628     { 
    629         List<ISequenceInstance> sequenceInstances = new LinkedList<ISequenceInstance>(); 
    630          
    631         for (IUserSession session : sessions) { 
    632             int index = -1; 
    633                  
    634             do { 
    635                 index = getSubListIndex(session, task, ++index); 
    636  
    637                 if (index > -1) { 
    638                     sequenceInstances.add 
    639                         (RuleUtils.createNewSubSequenceInRange 
    640                              (session, index, index + task.size() - 1, temporalTaskModel, 
    641                               taskFactory, taskBuilder)); 
    642                 } 
    643             } 
    644             while (index > -1); 
    645         } 
    646          
    647         return sequenceInstances; 
    648     } 
    649  
    650     /** 
    651      * @param trie 
    652      * @param object 
    653      * @return 
    654      */ 
    655     private int getSubListIndex(ITaskInstanceList   list, 
    656                                 List<ITaskInstance> subList, 
    657                                 int                 startIndex) 
    658     { 
    659         boolean matchFound; 
    660         int result = -1; 
    661          
    662         for (int i = startIndex; i <= list.size() - subList.size(); i++) { 
    663             matchFound = true; 
    664              
    665             for (int j = 0; j < subList.size(); j++) { 
    666                 // we prepared the task instances to refer to unique tasks, if they are treated 
    667                 // as equal. Therefore, we just compare the identity of the tasks of the task 
    668                 // instances 
    669                 if (list.get(i + j).getTask() != subList.get(j).getTask()) { 
    670                     matchFound = false; 
    671                     break; 
    672                 } 
    673             } 
    674              
    675             if (matchFound) { 
    676                 result = i; 
    677                 break; 
    678             } 
    679         } 
    680          
    681         return result; 
    682     } 
    683  
    684     /** 
    685      * @param trie 
    686      * @param object 
    687      * @return 
    688      */ 
    689     private int getSubListIndex(List<ITaskInstance> list, 
    690                                 List<ITaskInstance> subList, 
    691                                 int                 startIndex) 
    692     { 
    693         boolean matchFound; 
    694         int result = -1; 
    695          
    696         for (int i = startIndex; i <= list.size() - subList.size(); i++) { 
    697             matchFound = true; 
    698              
    699             for (int j = 0; j < subList.size(); j++) { 
    700                 // we prepared the task instances to refer to unique tasks, if they are treated 
    701                 // as equal. Therefore, we just compare the identity of the tasks of the task 
    702                 // instances 
    703                 if (list.get(i + j) != subList.get(j)) { 
    704                     matchFound = false; 
    705                     break; 
    706                 } 
    707             } 
    708              
    709             if (matchFound) { 
    710                 result = i; 
    711                 break; 
    712             } 
    713         } 
    714          
    715         return result; 
    716     } 
    717      
    718     /** 
    719      * @author Patrick Harms 
    720      */ 
    721     private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskInstance> { 
    722          
    723         /** 
    724          *  
    725          */ 
    726         private int currentCount; 
    727          
    728         /** 
    729          *  
    730          */ 
    731         private List<List<ITaskInstance>> foundTasks = new LinkedList<List<ITaskInstance>>(); 
    732  
    733         /** 
    734          * 
    735          */ 
    736         public MaxCountAndLongestTasksFinder() { 
    737             super(); 
    738             this.currentCount = 0; 
    739         } 
    740  
    741         /* (non-Javadoc) 
    742          * @see de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, int) 
    743          */ 
    744         @Override 
    745         public TrieProcessor.Result process(List<ITaskInstance> foundTask, int count) { 
    746             if (foundTask.size() < 2) { 
    747                 // ignore single tasks 
    748                 return TrieProcessor.Result.CONTINUE; 
    749             } 
    750              
    751             if (count < 2) { 
    752                 // ignore singular occurrences 
    753                 return TrieProcessor.Result.SKIP_NODE; 
    754             } 
    755  
    756             if (this.currentCount > count) { 
    757                 // ignore this children of this task, as they may have only smaller counts than 
    758                 // the already found tasks 
    759                 return TrieProcessor.Result.SKIP_NODE; 
    760             } 
    761              
    762             if (this.currentCount < count) { 
    763                 // the provided task occurs more often that all tasks found so far. 
    764                 // clear all found tasks and use the new count as the one searched for 
    765                 foundTasks.clear(); 
    766                 this.currentCount = count; 
    767             } 
    768              
    769             if (this.currentCount == count) { 
    770                 // the task is of interest. Sort it into the other found tasks so that 
    771                 // the longest come first 
    772                 boolean added = false; 
    773                 for (int i = 0; i < foundTasks.size(); i++) { 
    774                     if (foundTasks.get(i).size() < foundTask.size()) { 
    775                         // defensive copy 
    776                         foundTasks.add(i, new LinkedList<ITaskInstance>(foundTask)); // defensive copy 
    777                         added = true; 
    778                         break; 
    779                     } 
    780                 } 
    781                  
    782                 if (!added) { 
    783                     foundTasks.add(new LinkedList<ITaskInstance>(foundTask)); // defensive copy 
    784                 } 
    785             } 
    786              
    787             return TrieProcessor.Result.CONTINUE; 
    788         } 
    789  
    790         /** 
    791          *  @return 
    792          */ 
    793         public Tasks getFoundTasks() { 
    794             removePermutationsOfShorterTasks(); 
    795             return new Tasks(currentCount, foundTasks); 
    796         } 
    797  
    798         /** 
    799          * 
    800          */ 
    801         private void removePermutationsOfShorterTasks() { 
    802             // now iterate the sorted list and for each task remove all other tasks that are shorter 
    803             // (i.e. come later in the sorted list) and that represent a subpart of the task 
    804             for (int i = 0; i < foundTasks.size(); i++) { 
    805                 for (int j = i + 1; j < foundTasks.size();) { 
    806                     if (foundTasks.get(j).size() < foundTasks.get(i).size()) { 
    807                         // found a task that is a potential subtask. Check for this and remove the 
    808                         // subtask if needed 
    809                         List<ITaskInstance> longTask = foundTasks.get(i); 
    810                         List<ITaskInstance> shortTask = foundTasks.get(j); 
    811                          
    812                         if (getSubListIndex(longTask, shortTask, 0) > -1) { 
    813                             foundTasks.remove(j); 
    814                         } 
    815                         else { 
    816                             j++; 
    817                         } 
    818                     } 
    819                     else { 
    820                         j++; 
    821                     } 
    822                 } 
    823             } 
    824         } 
    825  
    826     } 
    827      
    828 //    /** 
    829 //     * @author Patrick Harms 
    830 //     */ 
    831 //    private class TrieStatisticsDumper implements TrieProcessor<ITaskInstance> { 
    832 //         
    833 //        /** 
    834 //         *  
    835 //         */ 
    836 //        private Map<Integer, Integer> counters = new HashMap<Integer, Integer>(); 
    837 //         
    838 //        /* (non-Javadoc) 
    839 //         * @see de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, int) 
    840 //         */ 
    841 //        @Override 
    842 //        public TrieProcessor.Result process(List<ITaskInstance> subsequence, int count) { 
    843 //            if (subsequence.size() == 1) { 
    844 //                Integer value = counters.get(count); 
    845 //                 
    846 //                if (value == null) { 
    847 //                    value = 0; 
    848 //                } 
    849 //                 
    850 //                counters.put(count, value + 1); 
    851 //                 
    852 //                return TrieProcessor.Result.CONTINUE; 
    853 //            } 
    854 //            else { 
    855 //                // ignore singular occurrences 
    856 //                return TrieProcessor.Result.SKIP_NODE; 
    857 //            } 
    858 //        } 
    859 // 
    860 //        /** 
    861 //         *  @return 
    862 //         */ 
    863 //        public void dumpCounters() { 
    864 //            int dumpedCounters = 0; 
    865 //             
    866 //            int count = 1; 
    867 //            while (dumpedCounters < counters.size()) { 
    868 //                Integer value = counters.get(count++); 
    869 //                if (value != null) { 
    870 //                    System.out.println(value + " symbols occurred " + count + " times"); 
    871 //                    dumpedCounters++; 
    872 //                } 
    873 //            } 
    874 //        } 
    875 // 
    876 //    } 
    877      
    878     /** 
    879      *  
    880      */ 
    881     private static class RuleApplicationData { 
    882          
    883         /** 
    884          *  
    885          */ 
    886         private List<IUserSession> sessions; 
    887          
    888         /** 
    889          *  
    890          */ 
    891         private TaskInstanceTrie lastTrie; 
    892          
    893         /** 
    894          * default and minimum trained sequence length is 3 
    895          */ 
    896         private int trainedSequenceLength = 3; 
    897          
    898         /** 
    899          *  
    900          */ 
    901         private Tasks lastFoundTasks = new Tasks(Integer.MAX_VALUE, null); 
    902          
    903         /** 
    904          *  
    905          */ 
    906         private boolean detectedAndReplacedTasks; 
    907          
    908         /** 
    909          *  
    910          */ 
    911         private RuleApplicationResult result = new RuleApplicationResult(); 
    912          
    913         /** 
    914          *  
    915          */ 
    916         private StopWatch stopWatch = new StopWatch(); 
    917          
    918         /** 
    919          *  
    920          */ 
    921         private RuleApplicationData(List<IUserSession> sessions) { 
    922             this.sessions = sessions; 
    923         } 
    924  
    925         /** 
    926          * @return the tree 
    927          */ 
    928         private List<IUserSession> getSessions() { 
    929             return sessions; 
    930         } 
    931  
    932         /** 
    933          * @param lastTrie the lastTrie to set 
    934          */ 
    935         private void setLastTrie(TaskInstanceTrie lastTrie) { 
    936             this.lastTrie = lastTrie; 
    937         } 
    938  
    939         /** 
    940          * @return the lastTrie 
    941          */ 
    942         private TaskInstanceTrie getLastTrie() { 
    943             return lastTrie; 
    944         } 
    945  
    946         /** 
    947          * @param trainedSequenceLength the trainedSequenceLength to set 
    948          */ 
    949         private void setTrainedSequenceLength(int trainedSequenceLength) { 
    950             this.trainedSequenceLength = trainedSequenceLength; 
    951         } 
    952  
    953         /** 
    954          * @return the trainedSequenceLength 
    955          */ 
    956         private int getTrainedSequenceLength() { 
    957             return trainedSequenceLength; 
    958         } 
    959  
    960         /** 
    961          * @param lastFoundSequences the lastFoundSequences to set 
    962          */ 
    963         private void setLastFoundTasks(Tasks lastFoundSequences) { 
    964             this.lastFoundTasks = lastFoundSequences; 
    965         } 
    966  
    967         /** 
    968          * @return the lastFoundSequences 
    969          */ 
    970         private Tasks getLastFoundTasks() { 
    971             return lastFoundTasks; 
    972         } 
    973  
    974         /** 
    975          * 
    976          */ 
    977         private void detectedAndReplacedTasks(boolean detectedAndReplacedTasks) { 
    978             this.detectedAndReplacedTasks = detectedAndReplacedTasks; 
    979         } 
    980  
    981         /** 
    982          * 
    983          */ 
    984         private boolean detectedAndReplacedTasks() { 
    985             return detectedAndReplacedTasks; 
    986         } 
    987          
    988         /** 
    989          * @return the result 
    990          */ 
    991         private RuleApplicationResult getResult() { 
    992             return result; 
    993         } 
    994  
    995         /** 
    996          * @return the stopWatch 
    997          */ 
    998         private StopWatch getStopWatch() { 
    999             return stopWatch; 
    1000         } 
    1001  
    1002     } 
    1003      
    1004  
    1005     /** 
    1006      * @author Patrick Harms 
    1007      */ 
    1008     private static class Tasks implements Iterable<List<ITaskInstance>> { 
    1009          
    1010         /** 
    1011          *  
    1012          */ 
    1013         private int occurrenceCount; 
    1014          
    1015         /** 
    1016          *  
    1017          */ 
    1018         private List<List<ITaskInstance>> sequences; 
    1019  
    1020         /** 
    1021          * @param occurrenceCount 
    1022          * @param sequences 
    1023          */ 
    1024         private Tasks(int occurrenceCount, List<List<ITaskInstance>> sequences) { 
    1025             super(); 
    1026             this.occurrenceCount = occurrenceCount; 
    1027             this.sequences = sequences; 
    1028         } 
    1029  
    1030         /** 
    1031          * @return 
    1032          */ 
    1033         private int getOccurrenceCount() { 
    1034             return occurrenceCount; 
    1035         } 
    1036  
    1037         /** 
    1038          * @return 
    1039          */ 
    1040         private int size() { 
    1041             return this.sequences.size(); 
    1042         } 
    1043  
    1044         /** 
    1045          *  
    1046          */ 
    1047  
    1048         /* (non-Javadoc) 
    1049          * @see java.lang.Iterable#iterator() 
    1050          */ 
    1051         @Override 
    1052         public Iterator<List<ITaskInstance>> iterator() { 
    1053             return this.sequences.iterator(); 
    1054         } 
    1055  
    1056         /* (non-Javadoc) 
    1057          * @see java.lang.Object#toString() 
    1058          */ 
    1059         @Override 
    1060         public String toString() { 
    1061             StringBuffer result = new StringBuffer(); 
    1062             result.append(this.occurrenceCount); 
    1063             result.append(" occurrences:\n"); 
    1064              
    1065             for (List<ITaskInstance> task : sequences) { 
    1066                 result.append(task); 
    1067                 result.append("\n"); 
    1068             } 
    1069              
    1070             return result.toString(); 
    1071         } 
    1072  
    1073     } 
    1074      
    1075     // methods for internal testing 
    1076 //    private void checkMatchingOfSessions(List<List<Event>>  flattenedSessions, 
    1077 //                                         List<IUserSession> sessions, 
    1078 //                                         String             when) 
    1079 //    { 
    1080 //        List<List<Event>> currentFlattenedSessions = flattenSessions(sessions); 
    1081 //        if (flattenedSessions.size() != currentFlattenedSessions.size()) { 
    1082 //            System.out.println("################## number of sessions changed after " + when); 
    1083 //        } 
    1084 //        else { 
    1085 //            for (int i = 0; i < flattenedSessions.size(); i++) { 
    1086 //                List<Event> expected = flattenedSessions.get(i); 
    1087 //                List<Event> current = currentFlattenedSessions.get(i); 
    1088 //             
    1089 //                if (expected.size() != current.size()) { 
    1090 //                    System.out.println 
    1091 //                        ("################## length of session " + i + " changed after " + when); 
    1092 //                } 
    1093 //                else { 
    1094 //                    for (int j = 0; j < expected.size(); j++) { 
    1095 //                        if (!expected.get(j).equals(current.get(j))) { 
    1096 //                            System.out.println("################## event " + j + " of session " + 
    1097 //                                               i + " changed after " + when); 
    1098 //                        } 
    1099 //                    } 
    1100 //                } 
    1101 //            }      
    1102 //        } 
    1103 //    } 
    1104 // 
    1105 //    private List<List<Event>> flattenSessions(List<IUserSession> sessions) { 
    1106 //        List<List<Event>> flattenedSessions = new ArrayList<List<Event>>(); 
    1107 //        for (IUserSession session : sessions) { 
    1108 //            List<Event> flattenedUserSession = new ArrayList<Event>(); 
    1109 //            flatten(session, flattenedUserSession); 
    1110 //            flattenedSessions.add(flattenedUserSession); 
    1111 //        } 
    1112 // 
    1113 //        return flattenedSessions; 
    1114 //    } 
    1115 // 
    1116 //    private void flatten(IUserSession iUserSession, List<Event> flattenedUserSession) { 
    1117 //        for (ITaskInstance instance : iUserSession) { 
    1118 //            flatten(instance, flattenedUserSession); 
    1119 //        } 
    1120 //    } 
    1121 // 
    1122 //    private void flatten(ITaskInstance instance, List<Event> flattenedUserSession) { 
    1123 //        if (instance instanceof ITaskInstanceList) { 
    1124 //            for (ITaskInstance child : (ITaskInstanceList) instance) { 
    1125 //                flatten(child, flattenedUserSession); 
    1126 //            } 
    1127 //        } 
    1128 //        else if (instance instanceof ISelectionInstance) { 
    1129 //            flatten(((ISelectionInstance) instance).getChild(), flattenedUserSession); 
    1130 //        } 
    1131 //        else if (instance instanceof IOptionalInstance) { 
    1132 //            flatten(((IOptionalInstance) instance).getChild(), flattenedUserSession); 
    1133 //        } 
    1134 //        else if (instance instanceof IEventTaskInstance) { 
    1135 //            flattenedUserSession.add(((IEventTaskInstance) instance).getEvent()); 
    1136 //        } 
    1137 //    } 
     66 
     67        /** 
     68         * @author Patrick Harms 
     69         */ 
     70        private class MaxCountAndLongestTasksFinder implements 
     71                        TrieProcessor<ITaskInstance> { 
     72 
     73                /** 
     74                 *  
     75                 */ 
     76                private int currentCount; 
     77 
     78                /** 
     79                 *  
     80                 */ 
     81                private final List<List<ITaskInstance>> foundTasks = new LinkedList<List<ITaskInstance>>(); 
     82 
     83                /** 
     84                 * 
     85                 */ 
     86                public MaxCountAndLongestTasksFinder() { 
     87                        super(); 
     88                        this.currentCount = 0; 
     89                } 
     90 
     91                /** 
     92                 * @return 
     93                 */ 
     94                public Tasks getFoundTasks() { 
     95                        removePermutationsOfShorterTasks(); 
     96                        return new Tasks(currentCount, foundTasks); 
     97                } 
     98 
     99                /* 
     100                 * (non-Javadoc) 
     101                 *  
     102                 * @see 
     103                 * de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util 
     104                 * .List, int) 
     105                 */ 
     106                @Override 
     107                public TrieProcessor.Result process(List<ITaskInstance> foundTask, 
     108                                int count) { 
     109                        if (foundTask.size() < 2) { 
     110                                // ignore single tasks 
     111                                return TrieProcessor.Result.CONTINUE; 
     112                        } 
     113 
     114                        if (count < 2) { 
     115                                // ignore singular occurrences 
     116                                return TrieProcessor.Result.SKIP_NODE; 
     117                        } 
     118 
     119                        if (this.currentCount > count) { 
     120                                // ignore this children of this task, as they may have only 
     121                                // smaller counts than 
     122                                // the already found tasks 
     123                                return TrieProcessor.Result.SKIP_NODE; 
     124                        } 
     125 
     126                        if (this.currentCount < count) { 
     127                                // the provided task occurs more often that all tasks found so 
     128                                // far. 
     129                                // clear all found tasks and use the new count as the one 
     130                                // searched for 
     131                                foundTasks.clear(); 
     132                                this.currentCount = count; 
     133                        } 
     134 
     135                        if (this.currentCount == count) { 
     136                                // the task is of interest. Sort it into the other found tasks 
     137                                // so that 
     138                                // the longest come first 
     139                                boolean added = false; 
     140                                for (int i = 0; i < foundTasks.size(); i++) { 
     141                                        if (foundTasks.get(i).size() < foundTask.size()) { 
     142                                                // defensive copy 
     143                                                foundTasks.add(i, new LinkedList<ITaskInstance>( 
     144                                                                foundTask)); // defensive copy 
     145                                                added = true; 
     146                                                break; 
     147                                        } 
     148                                } 
     149 
     150                                if (!added) { 
     151                                        foundTasks.add(new LinkedList<ITaskInstance>(foundTask)); // defensive 
     152                                                                                                                                                                // copy 
     153                                } 
     154                        } 
     155 
     156                        return TrieProcessor.Result.CONTINUE; 
     157                } 
     158 
     159                /** 
     160                 * 
     161                 */ 
     162                private void removePermutationsOfShorterTasks() { 
     163                        // now iterate the sorted list and for each task remove all other 
     164                        // tasks that are shorter 
     165                        // (i.e. come later in the sorted list) and that represent a subpart 
     166                        // of the task 
     167                        for (int i = 0; i < foundTasks.size(); i++) { 
     168                                for (int j = i + 1; j < foundTasks.size();) { 
     169                                        if (foundTasks.get(j).size() < foundTasks.get(i).size()) { 
     170                                                // found a task that is a potential subtask. Check for 
     171                                                // this and remove the 
     172                                                // subtask if needed 
     173                                                final List<ITaskInstance> longTask = foundTasks.get(i); 
     174                                                final List<ITaskInstance> shortTask = foundTasks.get(j); 
     175 
     176                                                if (getSubListIndex(longTask, shortTask, 0) > -1) { 
     177                                                        foundTasks.remove(j); 
     178                                                } else { 
     179                                                        j++; 
     180                                                } 
     181                                        } else { 
     182                                                j++; 
     183                                        } 
     184                                } 
     185                        } 
     186                } 
     187 
     188        } 
     189 
     190        /** 
     191         *  
     192         */ 
     193        private static class RuleApplicationData { 
     194 
     195                /** 
     196                 *  
     197                 */ 
     198                private final List<IUserSession> sessions; 
     199 
     200                /** 
     201                 *  
     202                 */ 
     203                private TaskInstanceTrie lastTrie; 
     204 
     205                /** 
     206                 * default and minimum trained sequence length is 3 
     207                 */ 
     208                private int trainedSequenceLength = 3; 
     209 
     210                /** 
     211                 *  
     212                 */ 
     213                private Tasks lastFoundTasks = new Tasks(Integer.MAX_VALUE, null); 
     214 
     215                /** 
     216                 *  
     217                 */ 
     218                private boolean detectedAndReplacedTasks; 
     219 
     220                /** 
     221                 *  
     222                 */ 
     223                private final RuleApplicationResult result = new RuleApplicationResult(); 
     224 
     225                /** 
     226                 *  
     227                 */ 
     228                private final StopWatch stopWatch = new StopWatch(); 
     229 
     230                /** 
     231                 *  
     232                 */ 
     233                private RuleApplicationData(List<IUserSession> sessions) { 
     234                        this.sessions = sessions; 
     235                } 
     236 
     237                /** 
     238                 * 
     239                 */ 
     240                private boolean detectedAndReplacedTasks() { 
     241                        return detectedAndReplacedTasks; 
     242                } 
     243 
     244                /** 
     245                 * 
     246                 */ 
     247                private void detectedAndReplacedTasks(boolean detectedAndReplacedTasks) { 
     248                        this.detectedAndReplacedTasks = detectedAndReplacedTasks; 
     249                } 
     250 
     251                /** 
     252                 * @return the lastFoundSequences 
     253                 */ 
     254                private Tasks getLastFoundTasks() { 
     255                        return lastFoundTasks; 
     256                } 
     257 
     258                /** 
     259                 * @return the lastTrie 
     260                 */ 
     261                private TaskInstanceTrie getLastTrie() { 
     262                        return lastTrie; 
     263                } 
     264 
     265                /** 
     266                 * @return the result 
     267                 */ 
     268                private RuleApplicationResult getResult() { 
     269                        return result; 
     270                } 
     271 
     272                /** 
     273                 * @return the tree 
     274                 */ 
     275                private List<IUserSession> getSessions() { 
     276                        return sessions; 
     277                } 
     278 
     279                /** 
     280                 * @return the stopWatch 
     281                 */ 
     282                private StopWatch getStopWatch() { 
     283                        return stopWatch; 
     284                } 
     285 
     286                /** 
     287                 * @return the trainedSequenceLength 
     288                 */ 
     289                private int getTrainedSequenceLength() { 
     290                        return trainedSequenceLength; 
     291                } 
     292 
     293                /** 
     294                 * @param lastFoundSequences 
     295                 *            the lastFoundSequences to set 
     296                 */ 
     297                private void setLastFoundTasks(Tasks lastFoundSequences) { 
     298                        this.lastFoundTasks = lastFoundSequences; 
     299                } 
     300 
     301                /** 
     302                 * @param lastTrie 
     303                 *            the lastTrie to set 
     304                 */ 
     305                private void setLastTrie(TaskInstanceTrie lastTrie) { 
     306                        this.lastTrie = lastTrie; 
     307                } 
     308 
     309                /** 
     310                 * @param trainedSequenceLength 
     311                 *            the trainedSequenceLength to set 
     312                 */ 
     313                private void setTrainedSequenceLength(int trainedSequenceLength) { 
     314                        this.trainedSequenceLength = trainedSequenceLength; 
     315                } 
     316 
     317        } 
     318 
     319        /** 
     320         * @author Patrick Harms 
     321         */ 
     322        private static class Tasks implements Iterable<List<ITaskInstance>> { 
     323 
     324                /** 
     325                 *  
     326                 */ 
     327                private final int occurrenceCount; 
     328 
     329                /** 
     330                 *  
     331                 */ 
     332                private final List<List<ITaskInstance>> sequences; 
     333 
     334                /** 
     335                 * @param occurrenceCount 
     336                 * @param sequences 
     337                 */ 
     338                private Tasks(int occurrenceCount, List<List<ITaskInstance>> sequences) { 
     339                        super(); 
     340                        this.occurrenceCount = occurrenceCount; 
     341                        this.sequences = sequences; 
     342                } 
     343 
     344                /** 
     345                 * @return 
     346                 */ 
     347                private int getOccurrenceCount() { 
     348                        return occurrenceCount; 
     349                } 
     350 
     351                /** 
     352                 *  
     353                 */ 
     354 
     355                /* 
     356                 * (non-Javadoc) 
     357                 *  
     358                 * @see java.lang.Iterable#iterator() 
     359                 */ 
     360                @Override 
     361                public Iterator<List<ITaskInstance>> iterator() { 
     362                        return this.sequences.iterator(); 
     363                } 
     364 
     365                /** 
     366                 * @return 
     367                 */ 
     368                private int size() { 
     369                        return this.sequences.size(); 
     370                } 
     371 
     372                /* 
     373                 * (non-Javadoc) 
     374                 *  
     375                 * @see java.lang.Object#toString() 
     376                 */ 
     377                @Override 
     378                public String toString() { 
     379                        final StringBuffer result = new StringBuffer(); 
     380                        result.append(this.occurrenceCount); 
     381                        result.append(" occurrences:\n"); 
     382 
     383                        for (final List<ITaskInstance> task : sequences) { 
     384                                result.append(task); 
     385                                result.append("\n"); 
     386                        } 
     387 
     388                        return result.toString(); 
     389                } 
     390 
     391        } 
     392 
     393        /** 
     394         * <p> 
     395         * the task factory to be used for creating substructures for the temporal 
     396         * relationships identified during rul application 
     397         * </p> 
     398         */ 
     399        private final ITaskFactory taskFactory;; 
     400 
     401        /** 
     402         * <p> 
     403         * the task builder to be used for creating substructures for the temporal 
     404         * relationships identified during rule application 
     405         * </p> 
     406         */ 
     407        private final ITaskBuilder taskBuilder; 
     408 
     409        /** 
     410         * <p> 
     411         * the task handling strategy to be used for comparing tasks for 
     412         * preparation, i.e., before the tasks are harmonized 
     413         * </p> 
     414         */ 
     415        private final TaskHandlingStrategy preparationTaskHandlingStrategy; 
     416 
     417        /** 
     418         * <p> 
     419         * the task handling strategy to be used for comparing tasks during 
     420         * iteration detection an trie generation, i.e., after the tasks are 
     421         * harmonized 
     422         * </p> 
     423         */ 
     424        private final TaskHandlingStrategy identityTaskHandlingStrategy; 
     425 
     426        /** 
     427         * <p> 
     428         * instantiates the rule and initializes it with a task equality to be 
     429         * considered when comparing tasks as well as a task factory and builder to 
     430         * be used for creating task structures. 
     431         * </p> 
     432         *  
     433         * @param minimalTaskEquality 
     434         *            the task equality to be considered when comparing tasks 
     435         * @param taskFactory 
     436         *            the task factory to be used for creating substructures 
     437         * @param taskBuilder 
     438         *            the task builder to be used for creating substructures 
     439         */ 
     440        SequenceForTaskDetectionRule(TaskEquality minimalTaskEquality, 
     441                        ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
     442                this.taskFactory = taskFactory; 
     443                this.taskBuilder = taskBuilder; 
     444 
     445                this.preparationTaskHandlingStrategy = new TaskHandlingStrategy( 
     446                                minimalTaskEquality); 
     447                this.identityTaskHandlingStrategy = new TaskHandlingStrategy( 
     448                                TaskEquality.IDENTICAL); 
     449        } 
     450 
     451        /* 
     452         * (non-Javadoc) 
     453         *  
     454         * @see 
     455         * de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply 
     456         * (java.util.List) 
     457         */ 
     458        @Override 
     459        public RuleApplicationResult apply(List<IUserSession> sessions) { 
     460                final RuleApplicationData appData = new RuleApplicationData(sessions); 
     461 
     462                // this is the real rule application. Loop while something is replaced. 
     463                harmonizeEventTaskInstancesModel(appData); 
     464                do { 
     465                        System.out.println(); 
     466 
     467                        appData.getStopWatch().start("whole loop"); 
     468                        detectAndReplaceIterations(appData); 
     469 
     470                        appData.getStopWatch().start("task replacement"); 
     471                        detectAndReplaceTasks(appData); 
     472                        appData.getStopWatch().stop("task replacement"); 
     473                        appData.getStopWatch().stop("whole loop"); 
     474 
     475                        // ((TaskTreeNodeComparator) 
     476                        // taskComparator).getStopWatch().dumpStatistics(System.out); 
     477                        // ((TaskTreeNodeComparator) taskComparator).getStopWatch().reset(); 
     478 
     479                        appData.getStopWatch().dumpStatistics(System.out); 
     480                        appData.getStopWatch().reset(); 
     481 
     482                } while (appData.detectedAndReplacedTasks()); 
     483 
     484                Console.println("created " 
     485                                + appData.getResult().getNewlyCreatedTasks().size() 
     486                                + " new tasks and " 
     487                                + appData.getResult().getNewlyCreatedTaskInstances().size() 
     488                                + " appropriate instances\n"); 
     489 
     490                if ((appData.getResult().getNewlyCreatedTasks().size() > 0) 
     491                                || (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) { 
     492                        appData.getResult().setRuleApplicationStatus( 
     493                                        RuleApplicationStatus.FINISHED); 
     494                } 
     495 
     496                return appData.getResult(); 
     497        } 
     498 
     499        /** 
     500         * @param appData 
     501         *            the rule application data combining all data used for applying 
     502         *            this rule 
     503         */ 
     504        private void createNewTrie(RuleApplicationData appData) { 
     505                Console.traceln( 
     506                                Level.FINER, 
     507                                "training trie with a maximum sequence length of " 
     508                                                + appData.getTrainedSequenceLength()); 
     509 
     510                appData.getStopWatch().start("training trie"); 
     511 
     512                // we prepared the task instances to refer to unique tasks, if they are 
     513                // treated 
     514                // as equal. Therefore, we just compare the identity of the tasks of the 
     515                // task 
     516                // instances 
     517                appData.setLastTrie(new TaskInstanceTrie(identityTaskHandlingStrategy)); 
     518 
     519                appData.getLastTrie().trainSessions(appData.getSessions(), 
     520                                appData.getTrainedSequenceLength()); 
     521 
     522                appData.getStopWatch().stop("training trie"); 
     523        } 
     524 
     525        /** 
     526         * <p> 
     527         * searches for direct iterations of single tasks in all sequences and 
     528         * replaces them with {@link IIteration}s, respectively appropriate 
     529         * instances. Also all single occurrences of a task that is iterated 
     530         * somewhen are replaced with iterations to have again an efficient way for 
     531         * task comparisons. 
     532         * </p> 
     533         *  
     534         * @param appData 
     535         *            the rule application data combining all data used for applying 
     536         *            this rule 
     537         */ 
     538        private void detectAndReplaceIterations(RuleApplicationData appData) { 
     539                Console.traceln(Level.FINE, "detecting iterations"); 
     540                appData.getStopWatch().start("detecting iterations"); 
     541 
     542                final List<IUserSession> sessions = appData.getSessions(); 
     543 
     544                final Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
     545 
     546                if (iteratedTasks.size() > 0) { 
     547                        replaceIterationsOf(iteratedTasks, sessions, appData); 
     548                } 
     549 
     550                appData.getStopWatch().stop("detecting iterations"); 
     551                Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() 
     552                                + " iterated tasks"); 
     553        } 
     554 
     555        /** 
     556         * TODO go on commenting 
     557         *  
     558         * @param appData 
     559         *            the rule application data combining all data used for applying 
     560         *            this rule 
     561         */ 
     562        private void detectAndReplaceTasks(RuleApplicationData appData) { 
     563                Console.traceln(Level.FINE, "detecting and replacing tasks"); 
     564                appData.getStopWatch().start("detecting tasks"); 
     565 
     566                getSequencesOccuringMostOften(appData); 
     567 
     568                appData.getStopWatch().stop("detecting tasks"); 
     569                appData.getStopWatch().start("replacing tasks"); 
     570 
     571                replaceSequencesOccurringMostOften(appData); 
     572 
     573                appData.getStopWatch().stop("replacing tasks"); 
     574                Console.traceln(Level.INFO, "detected and replaced " 
     575                                + appData.getLastFoundTasks().size() + " tasks occuring " 
     576                                + appData.getLastFoundTasks().getOccurrenceCount() + " times"); 
     577        } 
     578 
     579        /** 
     580         * @param appData 
     581         *            the rule application data combining all data used for applying 
     582         *            this rule 
     583         */ 
     584        private void getSequencesOccuringMostOften(RuleApplicationData appData) { 
     585                Console.traceln(Level.FINE, "determining most prominent tasks"); 
     586 
     587                Tasks tasks; 
     588                boolean createNewTrie = (appData.getLastTrie() == null) 
     589                                || appData.detectedAndReplacedTasks(); // tree has changed 
     590 
     591                do { 
     592                        if (createNewTrie) { 
     593                                createNewTrie(appData); 
     594                        } 
     595 
     596                        final MaxCountAndLongestTasksFinder finder = new MaxCountAndLongestTasksFinder(); 
     597                        appData.getLastTrie().process(finder); 
     598 
     599                        tasks = finder.getFoundTasks(); 
     600 
     601                        createNewTrie = false; 
     602 
     603                        for (final List<ITaskInstance> task : tasks) { 
     604                                if (task.size() >= appData.getTrainedSequenceLength()) { 
     605                                        // Trie must be recreated with a longer sequence length to 
     606                                        // be sure that 
     607                                        // the found sequences occurring most often are found in 
     608                                        // their whole length 
     609                                        appData.setTrainedSequenceLength(appData 
     610                                                        .getTrainedSequenceLength() + 1); 
     611                                        createNewTrie = true; 
     612                                        break; 
     613                                } 
     614                        } 
     615                } while (createNewTrie); 
     616 
     617                // create a normal trie for comparison 
     618                /* 
     619                 * System.out.println("creating test trie for comparison"); 
     620                 *  
     621                 * appData.getStopWatch().start("testtrie"); Trie<ITaskInstance> trie = 
     622                 * new Trie<ITaskInstance>(identityTaskComparator); 
     623                 *  
     624                 * for (IUserSession session : appData.getSessions()) { 
     625                 * trie.train(session.getExecutedTasks(), 
     626                 * appData.getTrainedSequenceLength()); } 
     627                 *  
     628                 * appData.getStopWatch().stop("testtrie"); 
     629                 *  
     630                 * MaxCountAndLongestTasksFinder finder = new 
     631                 * MaxCountAndLongestTasksFinder(); trie.process(finder); 
     632                 *  
     633                 * boolean allTasksEqual = finder.getFoundTasks().size() == 
     634                 * tasks.size(); 
     635                 *  
     636                 * allTasksEqual &= finder.getFoundTasks().occurrenceCount == 
     637                 * tasks.occurrenceCount; 
     638                 *  
     639                 * for (List<ITaskInstance> task1 : finder.getFoundTasks()) { boolean 
     640                 * foundTask = false; for (List<ITaskInstance> task2 : tasks) { boolean 
     641                 * tasksEqual = false; if (task1.size() == task2.size()) { tasksEqual = 
     642                 * true; for (int i = 0; i < task1.size(); i++) { if 
     643                 * (!identityTaskComparator.equals(task1.get(i).getTask(), 
     644                 * task2.get(i).getTask())) { tasksEqual = false; } } } 
     645                 *  
     646                 * if (tasksEqual) { foundTask = true; break; } } 
     647                 *  
     648                 * if (!foundTask) { System.out.println("different is " + task1); 
     649                 * allTasksEqual = false; break; } } 
     650                 *  
     651                 * if (!allTasksEqual) { System.out.println(finder.getFoundTasks()); 
     652                 * System.out.println(tasks); 
     653                 *  
     654                 * throw new 
     655                 * IllegalArgumentException("both tries calculated different subsequences" 
     656                 * ); } 
     657                 *  
     658                 * /*TrieStatisticsDumper dumper = new TrieStatisticsDumper(); 
     659                 * appData.getLastTrie().process(dumper); dumper.dumpCounters(); 
     660                 */ 
     661 
     662                appData.setLastFoundTasks(tasks); 
     663 
     664                Console.traceln(Level.FINE, "found " 
     665                                + appData.getLastFoundTasks().size() + " tasks " + "occurring " 
     666                                + appData.getLastFoundTasks().getOccurrenceCount() + " times"); 
     667        } 
     668 
     669        /** 
     670         * @param trie 
     671         * @param object 
     672         * @return 
     673         */ 
     674        private int getSubListIndex(ITaskInstanceList list, 
     675                        List<ITaskInstance> subList, int startIndex) { 
     676                boolean matchFound; 
     677                int result = -1; 
     678 
     679                for (int i = startIndex; i <= (list.size() - subList.size()); i++) { 
     680                        matchFound = true; 
     681 
     682                        for (int j = 0; j < subList.size(); j++) { 
     683                                // we prepared the task instances to refer to unique tasks, if 
     684                                // they are treated 
     685                                // as equal. Therefore, we just compare the identity of the 
     686                                // tasks of the task 
     687                                // instances 
     688                                if (list.get(i + j).getTask() != subList.get(j).getTask()) { 
     689                                        matchFound = false; 
     690                                        break; 
     691                                } 
     692                        } 
     693 
     694                        if (matchFound) { 
     695                                result = i; 
     696                                break; 
     697                        } 
     698                } 
     699 
     700                return result; 
     701        } 
     702 
     703        /** 
     704         * @param trie 
     705         * @param object 
     706         * @return 
     707         */ 
     708        private int getSubListIndex(List<ITaskInstance> list, 
     709                        List<ITaskInstance> subList, int startIndex) { 
     710                boolean matchFound; 
     711                int result = -1; 
     712 
     713                for (int i = startIndex; i <= (list.size() - subList.size()); i++) { 
     714                        matchFound = true; 
     715 
     716                        for (int j = 0; j < subList.size(); j++) { 
     717                                // we prepared the task instances to refer to unique tasks, if 
     718                                // they are treated 
     719                                // as equal. Therefore, we just compare the identity of the 
     720                                // tasks of the task 
     721                                // instances 
     722                                if (list.get(i + j) != subList.get(j)) { 
     723                                        matchFound = false; 
     724                                        break; 
     725                                } 
     726                        } 
     727 
     728                        if (matchFound) { 
     729                                result = i; 
     730                                break; 
     731                        } 
     732                } 
     733 
     734                return result; 
     735        } 
     736 
     737        /** 
     738         * <p> 
     739         * harmonizes the event task instances by unifying tasks. This is done, as 
     740         * initially the event tasks being equal with respect to the considered task 
     741         * equality are distinct objects. The comparison of these distinct objects 
     742         * is more time consuming than comparing the object references. 
     743         * </p> 
     744         * 
     745         * @param appData 
     746         *            the rule application data combining all data used for applying 
     747         *            this rule 
     748         */ 
     749        private void harmonizeEventTaskInstancesModel(RuleApplicationData appData) { 
     750                Console.traceln(Level.INFO, 
     751                                "harmonizing task model of event task instances"); 
     752                appData.getStopWatch().start("harmonizing event tasks"); 
     753 
     754                final SymbolMap<ITaskInstance, ITask> uniqueTasks = preparationTaskHandlingStrategy 
     755                                .createSymbolMap(); 
     756                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     757                                .getTaskComparator(); 
     758 
     759                int unifiedTasks = 0; 
     760                ITask task; 
     761                final List<IUserSession> sessions = appData.getSessions(); 
     762                int sessionNo = 0; 
     763                for (final IUserSession session : sessions) { 
     764                        Console.traceln(Level.FINE, "handling " + (++sessionNo) + ". " 
     765                                        + session); 
     766                        for (final ITaskInstance taskInstance : session) { 
     767                                task = uniqueTasks.getValue(taskInstance); 
     768 
     769                                if (task == null) { 
     770                                        uniqueTasks.addSymbol(taskInstance, taskInstance.getTask()); 
     771                                } else { 
     772                                        taskBuilder.setTask(taskInstance, task); 
     773                                        unifiedTasks++; 
     774                                } 
     775                        } 
     776 
     777                        comparator.clearBuffers(); 
     778                } 
     779 
     780                appData.getStopWatch().stop("harmonizing event tasks"); 
     781                Console.traceln(Level.INFO, "harmonized " + unifiedTasks 
     782                                + " task occurrences (still " + uniqueTasks.size() 
     783                                + " different tasks)"); 
     784 
     785                appData.getStopWatch().dumpStatistics(System.out); 
     786                appData.getStopWatch().reset(); 
     787        } 
     788 
     789        /** 
     790         * <p> 
     791         * TODO clarify why this is done 
     792         * </p> 
     793         */ 
     794        private void harmonizeIterationInstancesModel(IIteration iteration, 
     795                        List<IIterationInstance> iterationInstances) { 
     796                final List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
     797                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     798                                .getTaskComparator(); 
     799 
     800                // merge the lexically different variants of iterated task to a unique 
     801                // list 
     802                for (final IIterationInstance iterationInstance : iterationInstances) { 
     803                        for (final ITaskInstance executionVariant : iterationInstance) { 
     804                                final ITask candidate = executionVariant.getTask(); 
     805 
     806                                boolean found = false; 
     807                                for (final ITask taskVariant : iteratedTaskVariants) { 
     808                                        if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
     809                                                taskBuilder.setTask(executionVariant, taskVariant); 
     810                                                found = true; 
     811                                                break; 
     812                                        } 
     813                                } 
     814 
     815                                if (!found) { 
     816                                        iteratedTaskVariants.add(candidate); 
     817                                } 
     818                        } 
     819                } 
     820 
     821                // if there are more than one lexically different variant of iterated 
     822                // tasks, adapt the 
     823                // iteration model to be a selection of different variants. In this case 
     824                // also adapt 
     825                // the generated iteration instances to correctly contain selection 
     826                // instances. If there 
     827                // is only one variant of an iterated task, simply set this as the 
     828                // marked task of the 
     829                // iteration. In this case, the instances can be preserved as is 
     830                if (iteratedTaskVariants.size() > 1) { 
     831                        final ISelection selection = taskFactory.createNewSelection(); 
     832 
     833                        for (final ITask variant : iteratedTaskVariants) { 
     834                                taskBuilder.addChild(selection, variant); 
     835                        } 
     836 
     837                        taskBuilder.setMarkedTask(iteration, selection); 
     838 
     839                        for (final IIterationInstance instance : iterationInstances) { 
     840                                for (int i = 0; i < instance.size(); i++) { 
     841                                        final ISelectionInstance selectionInstance = taskFactory 
     842                                                        .createNewTaskInstance(selection); 
     843                                        taskBuilder.setChild(selectionInstance, instance.get(i)); 
     844                                        taskBuilder.setTaskInstance(instance, i, selectionInstance); 
     845                                } 
     846                        } 
     847                } else { 
     848                        taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
     849                } 
     850        } 
     851 
     852        /** 
     853         * 
     854         */ 
     855        private void harmonizeSequenceInstancesModel(ISequence sequence, 
     856                        List<ISequenceInstance> sequenceInstances, int sequenceLength) { 
     857                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     858                                .getTaskComparator(); 
     859 
     860                // ensure for each subtask that lexically different variants are 
     861                // preserved 
     862                for (int subTaskIndex = 0; subTaskIndex < sequenceLength; subTaskIndex++) { 
     863                        final List<ITask> subTaskVariants = new LinkedList<ITask>(); 
     864 
     865                        for (final ISequenceInstance sequenceInstance : sequenceInstances) { 
     866                                final ITask candidate = sequenceInstance.get(subTaskIndex) 
     867                                                .getTask(); 
     868 
     869                                boolean found = false; 
     870 
     871                                for (int i = 0; i < subTaskVariants.size(); i++) { 
     872                                        if (comparator.areLexicallyEqual(subTaskVariants.get(i), 
     873                                                        candidate)) { 
     874                                                taskBuilder.setTask(sequenceInstance.get(subTaskIndex), 
     875                                                                subTaskVariants.get(i)); 
     876 
     877                                                found = true; 
     878                                                break; 
     879                                        } 
     880                                } 
     881 
     882                                if (!found) { 
     883                                        subTaskVariants.add(candidate); 
     884                                } 
     885                        } 
     886 
     887                        // if there are more than one lexically different variant of the sub 
     888                        // task at 
     889                        // the considered position, adapt the sequence model at that 
     890                        // position to have 
     891                        // a selection of the different variants. In this case also adapt 
     892                        // the 
     893                        // generated sequence instances to correctly contain selection 
     894                        // instances. If 
     895                        // there is only one variant of sub tasks at the given position, 
     896                        // simply set 
     897                        // this variant as the sub task of the selection. In this case, the 
     898                        // instances 
     899                        // can be preserved as is 
     900                        if (subTaskVariants.size() > 1) { 
     901                                final ISelection selection = taskFactory.createNewSelection(); 
     902 
     903                                for (final ITask variant : subTaskVariants) { 
     904                                        taskBuilder.addChild(selection, variant); 
     905                                } 
     906 
     907                                taskBuilder.addChild(sequence, selection); 
     908 
     909                                for (final ISequenceInstance instance : sequenceInstances) { 
     910                                        final ISelectionInstance selectionInstance = taskFactory 
     911                                                        .createNewTaskInstance(selection); 
     912                                        taskBuilder.setChild(selectionInstance, 
     913                                                        instance.get(subTaskIndex)); 
     914                                        taskBuilder.setTaskInstance(instance, subTaskIndex, 
     915                                                        selectionInstance); 
     916                                } 
     917                        } else if (subTaskVariants.size() == 1) { 
     918                                taskBuilder.addChild(sequence, subTaskVariants.get(0)); 
     919                        } 
     920                } 
     921        } 
     922 
     923        /** 
     924         * <p> 
     925         * replaces all occurrences of all tasks provided in the set with iterations 
     926         * </p> 
     927         * 
     928         * @param iteratedTasks 
     929         *            the tasks to be replaced with iterations 
     930         * @param sessions 
     931         *            the sessions in which the tasks are to be replaced 
     932         * @param appData 
     933         *            the rule application data combining all data used for applying 
     934         *            this rule 
     935         */ 
     936        private void replaceIterationsOf(Set<ITask> iteratedTasks, 
     937                        List<IUserSession> sessions, RuleApplicationData appData) { 
     938                final Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
     939                final Map<IIteration, List<IIterationInstance>> iterationInstances = new HashMap<IIteration, List<IIterationInstance>>(); 
     940 
     941                for (final ITask iteratedTask : iteratedTasks) { 
     942                        final IIteration iteration = taskFactory.createNewIteration(); 
     943                        iterations.put(iteratedTask, iteration); 
     944                        iterationInstances.put(iteration, 
     945                                        new LinkedList<IIterationInstance>()); 
     946                } 
     947 
     948                IIterationInstance iterationInstance; 
     949 
     950                for (final IUserSession session : sessions) { 
     951                        int index = 0; 
     952                        iterationInstance = null; 
     953 
     954                        while (index < session.size()) { 
     955                                // we prepared the task instances to refer to unique tasks, if 
     956                                // they are treated 
     957                                // as equal. Therefore, we just compare the identity of the 
     958                                // tasks of the task 
     959                                // instances 
     960                                final ITask currentTask = session.get(index).getTask(); 
     961                                final IIteration iteration = iterations.get(currentTask); 
     962                                if (iteration != null) { 
     963                                        if ((iterationInstance == null) 
     964                                                        || (iterationInstance.getTask() != iteration)) { 
     965                                                iterationInstance = taskFactory 
     966                                                                .createNewTaskInstance(iteration); 
     967                                                iterationInstances.get(iteration) 
     968                                                                .add(iterationInstance); 
     969                                                taskBuilder.addTaskInstance(session, index, 
     970                                                                iterationInstance); 
     971                                                index++; 
     972                                        } 
     973 
     974                                        taskBuilder.addChild(iterationInstance, session.get(index)); 
     975                                        taskBuilder.removeTaskInstance(session, index); 
     976                                } else { 
     977                                        if (iterationInstance != null) { 
     978                                                iterationInstance = null; 
     979                                        } 
     980                                        index++; 
     981                                } 
     982                        } 
     983                } 
     984 
     985                for (final Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances 
     986                                .entrySet()) { 
     987                        harmonizeIterationInstancesModel(entry.getKey(), entry.getValue()); 
     988                } 
     989        } 
     990 
     991        /** 
     992         * @param appData 
     993         *            the rule application data combining all data used for applying 
     994         *            this rule 
     995         */ 
     996        private void replaceSequencesOccurringMostOften(RuleApplicationData appData) { 
     997                appData.detectedAndReplacedTasks(false); 
     998 
     999                if ((appData.getLastFoundTasks().size() > 0) 
     1000                                && (appData.getLastFoundTasks().getOccurrenceCount() > 1)) { 
     1001                        Console.traceln(Level.FINER, "replacing tasks occurrences"); 
     1002 
     1003                        for (final List<ITaskInstance> task : appData.getLastFoundTasks()) { 
     1004                                final ISequence sequence = taskFactory.createNewSequence(); 
     1005 
     1006                                Console.traceln(Level.FINEST, "replacing " + sequence.getId() 
     1007                                                + ": " + task); 
     1008 
     1009                                final List<ISequenceInstance> sequenceInstances = replaceTaskOccurrences( 
     1010                                                task, appData.getSessions(), sequence); 
     1011 
     1012                                harmonizeSequenceInstancesModel(sequence, sequenceInstances, 
     1013                                                task.size()); 
     1014                                appData.detectedAndReplacedTasks(appData 
     1015                                                .detectedAndReplacedTasks() 
     1016                                                || (sequenceInstances.size() > 0)); 
     1017 
     1018                                if (sequenceInstances.size() < appData.getLastFoundTasks() 
     1019                                                .getOccurrenceCount()) { 
     1020                                        Console.traceln(Level.FINE, 
     1021                                                        sequence.getId() 
     1022                                                                        + ": replaced task only " 
     1023                                                                        + sequenceInstances.size() 
     1024                                                                        + " times instead of expected " 
     1025                                                                        + appData.getLastFoundTasks() 
     1026                                                                                        .getOccurrenceCount()); 
     1027                                } 
     1028                        } 
     1029                } 
     1030 
     1031        } 
     1032 
     1033        /** 
     1034         * @param tree 
     1035         */ 
     1036        private List<ISequenceInstance> replaceTaskOccurrences( 
     1037                        List<ITaskInstance> task, List<IUserSession> sessions, 
     1038                        ISequence temporalTaskModel) { 
     1039                final List<ISequenceInstance> sequenceInstances = new LinkedList<ISequenceInstance>(); 
     1040 
     1041                for (final IUserSession session : sessions) { 
     1042                        int index = -1; 
     1043 
     1044                        do { 
     1045                                index = getSubListIndex(session, task, ++index); 
     1046 
     1047                                if (index > -1) { 
     1048                                        sequenceInstances 
     1049                                                        .add(RuleUtils.createNewSubSequenceInRange(session, 
     1050                                                                        index, (index + task.size()) - 1, 
     1051                                                                        temporalTaskModel, taskFactory, taskBuilder)); 
     1052                                } 
     1053                        } while (index > -1); 
     1054                } 
     1055 
     1056                return sequenceInstances; 
     1057        } 
     1058 
     1059        // /** 
     1060        // * @author Patrick Harms 
     1061        // */ 
     1062        // private class TrieStatisticsDumper implements 
     1063        // TrieProcessor<ITaskInstance> { 
     1064        // 
     1065        // /** 
     1066        // * 
     1067        // */ 
     1068        // private Map<Integer, Integer> counters = new HashMap<Integer, Integer>(); 
     1069        // 
     1070        // /* (non-Javadoc) 
     1071        // * @see 
     1072        // de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, 
     1073        // int) 
     1074        // */ 
     1075        // @Override 
     1076        // public TrieProcessor.Result process(List<ITaskInstance> subsequence, int 
     1077        // count) { 
     1078        // if (subsequence.size() == 1) { 
     1079        // Integer value = counters.get(count); 
     1080        // 
     1081        // if (value == null) { 
     1082        // value = 0; 
     1083        // } 
     1084        // 
     1085        // counters.put(count, value + 1); 
     1086        // 
     1087        // return TrieProcessor.Result.CONTINUE; 
     1088        // } 
     1089        // else { 
     1090        // // ignore singular occurrences 
     1091        // return TrieProcessor.Result.SKIP_NODE; 
     1092        // } 
     1093        // } 
     1094        // 
     1095        // /** 
     1096        // * @return 
     1097        // */ 
     1098        // public void dumpCounters() { 
     1099        // int dumpedCounters = 0; 
     1100        // 
     1101        // int count = 1; 
     1102        // while (dumpedCounters < counters.size()) { 
     1103        // Integer value = counters.get(count++); 
     1104        // if (value != null) { 
     1105        // System.out.println(value + " symbols occurred " + count + " times"); 
     1106        // dumpedCounters++; 
     1107        // } 
     1108        // } 
     1109        // } 
     1110        // 
     1111        // } 
     1112 
     1113        /** 
     1114         * <p> 
     1115         * searches the provided sessions for task iterations. If a task is 
     1116         * iterated, it is added to the returned set. 
     1117         * </p> 
     1118         *  
     1119         * @param the 
     1120         *            session to search for iterations in 
     1121         *  
     1122         * @return a set of tasks being iterated somewhere 
     1123         */ 
     1124        private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
     1125                final Set<ITask> iteratedTasks = new HashSet<ITask>(); 
     1126                for (final IUserSession session : sessions) { 
     1127                        for (int i = 0; i < (session.size() - 1); i++) { 
     1128                                // we prepared the task instances to refer to unique tasks, if 
     1129                                // they are treated 
     1130                                // as equal. Therefore, we just compare the identity of the 
     1131                                // tasks of the task 
     1132                                // instances 
     1133                                if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
     1134                                        iteratedTasks.add(session.get(i).getTask()); 
     1135                                } 
     1136                        } 
     1137                } 
     1138 
     1139                return iteratedTasks; 
     1140        } 
     1141 
     1142        /* 
     1143         * (non-Javadoc) 
     1144         *  
     1145         * @see java.lang.Object#toString() 
     1146         */ 
     1147        @Override 
     1148        public String toString() { 
     1149                return "SequenceForTaskDetectionRule"; 
     1150        } 
     1151 
     1152        // methods for internal testing 
     1153        // private void checkMatchingOfSessions(List<List<Event>> flattenedSessions, 
     1154        // List<IUserSession> sessions, 
     1155        // String when) 
     1156        // { 
     1157        // List<List<Event>> currentFlattenedSessions = flattenSessions(sessions); 
     1158        // if (flattenedSessions.size() != currentFlattenedSessions.size()) { 
     1159        // System.out.println("################## number of sessions changed after " 
     1160        // + when); 
     1161        // } 
     1162        // else { 
     1163        // for (int i = 0; i < flattenedSessions.size(); i++) { 
     1164        // List<Event> expected = flattenedSessions.get(i); 
     1165        // List<Event> current = currentFlattenedSessions.get(i); 
     1166        // 
     1167        // if (expected.size() != current.size()) { 
     1168        // System.out.println 
     1169        // ("################## length of session " + i + " changed after " + when); 
     1170        // } 
     1171        // else { 
     1172        // for (int j = 0; j < expected.size(); j++) { 
     1173        // if (!expected.get(j).equals(current.get(j))) { 
     1174        // System.out.println("################## event " + j + " of session " + 
     1175        // i + " changed after " + when); 
     1176        // } 
     1177        // } 
     1178        // } 
     1179        // } 
     1180        // } 
     1181        // } 
     1182        // 
     1183        // private List<List<Event>> flattenSessions(List<IUserSession> sessions) { 
     1184        // List<List<Event>> flattenedSessions = new ArrayList<List<Event>>(); 
     1185        // for (IUserSession session : sessions) { 
     1186        // List<Event> flattenedUserSession = new ArrayList<Event>(); 
     1187        // flatten(session, flattenedUserSession); 
     1188        // flattenedSessions.add(flattenedUserSession); 
     1189        // } 
     1190        // 
     1191        // return flattenedSessions; 
     1192        // } 
     1193        // 
     1194        // private void flatten(IUserSession iUserSession, List<Event> 
     1195        // flattenedUserSession) { 
     1196        // for (ITaskInstance instance : iUserSession) { 
     1197        // flatten(instance, flattenedUserSession); 
     1198        // } 
     1199        // } 
     1200        // 
     1201        // private void flatten(ITaskInstance instance, List<Event> 
     1202        // flattenedUserSession) { 
     1203        // if (instance instanceof ITaskInstanceList) { 
     1204        // for (ITaskInstance child : (ITaskInstanceList) instance) { 
     1205        // flatten(child, flattenedUserSession); 
     1206        // } 
     1207        // } 
     1208        // else if (instance instanceof ISelectionInstance) { 
     1209        // flatten(((ISelectionInstance) instance).getChild(), 
     1210        // flattenedUserSession); 
     1211        // } 
     1212        // else if (instance instanceof IOptionalInstance) { 
     1213        // flatten(((IOptionalInstance) instance).getChild(), flattenedUserSession); 
     1214        // } 
     1215        // else if (instance instanceof IEventTaskInstance) { 
     1216        // flattenedUserSession.add(((IEventTaskInstance) instance).getEvent()); 
     1217        // } 
     1218        // } 
    11381219 
    11391220} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java

    r1732 r1733  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
    17 import java.io.File; 
    1817import java.io.FileInputStream; 
    1918import java.io.FileOutputStream; 
     
    8079public class SequenceForTaskDetectionRuleAlignment implements ISessionScopeRule { 
    8180 
     81        private class ParallelMatchOcurrencesFinder implements Runnable { 
     82                private final RuleApplicationData appData; 
     83                private final int from; 
     84                private final int to; 
     85 
     86                ParallelMatchOcurrencesFinder(RuleApplicationData appData, int from, 
     87                                int to) { 
     88                        this.appData = appData; 
     89                        this.from = from; 
     90                        this.to = to; 
     91                } 
     92 
     93                @Override 
     94                public void run() { 
     95                        int count = 0; 
     96                        final int size = to - from; 
     97 
     98                        for (int i = from; i < to; i++) { 
     99                                final Match pattern = appData.getMatchseqs().get(i); 
     100                                count++; 
     101                                RuleUtils.printProgressPercentage("Match finding progress", 
     102                                                count, size); 
     103                                // Skip sequences with more 0 events (scrolls) than other 
     104                                // events. 
     105                                // Both of the pattern sequences are equally long, so the zero 
     106                                // counts just need to be smaller than the length of one 
     107                                // sequence 
     108                                if ((pattern.getFirstSequence().eventCount(0) 
     109                                                + pattern.getSecondSequence().eventCount(0) + 1) > pattern 
     110                                                .getFirstSequence().size()) { 
     111                                        continue; 
     112                                } 
     113 
     114                                for (int j = 0; j < appData.getNumberSequences().size(); j++) { 
     115                                        final LinkedList<Integer> startpositions = appData 
     116                                                        .getNumberSequences().get(j) 
     117                                                        .containsPattern(pattern); 
     118                                        if (startpositions.size() > 0) { 
     119                                                for (final Iterator<Integer> jt = startpositions 
     120                                                                .iterator(); jt.hasNext();) { 
     121                                                        final int start = jt.next(); 
     122                                                        pattern.addOccurence(new MatchOccurence(start, 
     123                                                                        start + pattern.size(), j)); 
     124                                                } 
     125                                        } 
     126                                } 
     127                        } 
     128                } 
     129        } 
     130 
     131        private class ParallelMatchReplacer implements Runnable { 
     132 
     133                private final RuleApplicationData appData; 
     134                private final int from; 
     135                private final int to; 
     136 
     137                ParallelMatchReplacer(RuleApplicationData appData, int from, int to) { 
     138                        this.appData = appData; 
     139                        this.from = from; 
     140                        this.to = to; 
     141                } 
     142 
     143                @Override 
     144                public void run() { 
     145                        // TODO Cleanup 
     146                        // int count = 0; 
     147                        // int size = to - from; 
     148                        for (int i = from; i < to; i++) { 
     149                                // count++; 
     150                                // Every pattern consists of 2 sequences, therefore the minimum 
     151                                // occurrences here is 2. 
     152                                // We just need the sequences also occurring in other sequences 
     153                                // as well 
     154                                if (appData.getMatchseqs().get(i).occurenceCount() > 2) { 
     155 
     156                                        final ISequence task = matchAsSequence(appData, appData 
     157                                                        .getMatchseqs().get(i)); 
     158                                        invalidOccurence: for (final Iterator<MatchOccurence> it = appData 
     159                                                        .getMatchseqs().get(i).getOccurences().iterator(); it 
     160                                                        .hasNext();) { 
     161                                                final MatchOccurence oc = it.next(); 
     162 
     163                                                // Check if nothing has been replaced in the sequence we 
     164                                                // want to replace now 
     165 
     166                                                synchronized (appData.getReplacedOccurences()) { 
     167                                                        if (appData.getReplacedOccurences().get( 
     168                                                                        oc.getSequenceId()) == null) { 
     169                                                                appData.getReplacedOccurences().put( 
     170                                                                                oc.getSequenceId(), 
     171                                                                                new LinkedList<MatchOccurence>()); 
     172                                                        } else { 
     173                                                                // check if we have any replaced occurence with 
     174                                                                // indexes 
     175                                                                // smaller than ours. If so, we need to adjust 
     176                                                                // our start 
     177                                                                // and endpoints 
     178                                                                // of the replacement. 
     179                                                                // Also do a check if we have replaced this 
     180                                                                // specific 
     181                                                                // MatchOccurence in this sequence already. Jump 
     182                                                                // to the 
     183                                                                // next occurence if this is the case. 
     184                                                                // This is no more neccessary once the matches 
     185                                                                // are 
     186                                                                // harmonized. 
     187                                                                for (final Iterator<MatchOccurence> jt = appData 
     188                                                                                .getReplacedOccurences() 
     189                                                                                .get(oc.getSequenceId()).iterator(); jt 
     190                                                                                .hasNext();) { 
     191                                                                        final MatchOccurence tmpOC = jt.next(); 
     192 
     193                                                                        if ((oc.getStartindex() >= tmpOC 
     194                                                                                        .getStartindex()) 
     195                                                                                        && (oc.getStartindex() <= tmpOC 
     196                                                                                        .getEndindex())) { 
     197                                                                                continue invalidOccurence; 
     198                                                                        } 
     199                                                                        if (oc.getEndindex() >= tmpOC 
     200                                                                                        .getStartindex()) { 
     201                                                                                continue invalidOccurence; 
     202 
     203                                                                        } else if (oc.getStartindex() > tmpOC 
     204                                                                                        .getEndindex()) { 
     205                                                                                final int diff = tmpOC.getEndindex() 
     206                                                                                                - tmpOC.getStartindex(); 
     207                                                                                // Just to be sure. 
     208                                                                                if (diff > 0) { 
     209                                                                                        oc.setStartindex((oc 
     210                                                                                                        .getStartindex() - diff) + 1); 
     211                                                                                        oc.setEndindex((oc.getEndindex() - diff) + 1); 
     212                                                                                } else { 
     213                                                                                        Console.traceln(Level.WARNING, 
     214                                                                                                        "End index of a Match before start. This should never happen"); 
     215                                                                                } 
     216                                                                        } 
     217                                                                } 
     218                                                        } 
     219                                                        System.out.println("Replacing in sequence" 
     220                                                                        + oc.getSequenceId()); 
     221                                                        synchronized (appData) { 
     222                                                                appData.detectedAndReplacedTasks = true; 
     223                                                        } 
     224                                                        synchronized (appData.getSessions().get( 
     225                                                                        oc.getSequenceId())) { 
     226                                                                final ISequenceInstance sequenceInstances = RuleUtils 
     227                                                                                .createNewSubSequenceInRange( 
     228                                                                                                appData.getSessions().get( 
     229                                                                                                                oc.getSequenceId()), 
     230                                                                                                                oc.getStartindex(), 
     231                                                                                                                oc.getEndindex(), task, 
     232                                                                                                                taskFactory, taskBuilder); 
     233                                                                oc.setEndindex((oc.getStartindex() + sequenceInstances 
     234                                                                                .size()) - RuleUtils.missedOptionals); 
     235                                                        } 
     236                                                } 
     237                                                // Adjust the length of the match regarding to the 
     238                                                // length of 
     239                                                // instance. (OptionalInstances may be shorter) 
     240 
     241                                                synchronized (appData.getReplacedOccurences().get( 
     242                                                                oc.getSequenceId())) { 
     243                                                        appData.getReplacedOccurences() 
     244                                                        .get(oc.getSequenceId()).add(oc); 
     245                                                } 
     246                                        } 
     247                                } 
     248                        } 
     249                } 
     250        } 
     251 
     252        private class ParallelPairwiseAligner implements Runnable { 
     253                private final RuleApplicationData appData; 
     254                private final int from; 
     255                private final int to; 
     256 
     257                ParallelPairwiseAligner(RuleApplicationData appData, int from, int to) { 
     258                        this.appData = appData; 
     259                        this.from = from; 
     260                        this.to = to; 
     261                } 
     262 
     263                @Override 
     264                public void run() { 
     265                        int count = 0; 
     266                        final int size = to - from; 
     267 
     268                        for (int i = from; i < to; i++) { 
     269                                final NumberSequence ns1 = appData.getNumberSequences().get(i); 
     270                                count++; 
     271                                RuleUtils.printProgressPercentage("Aligning Progress", count, 
     272                                                size); 
     273                                for (int j = 0; j < appData.getNumberSequences().size(); j++) { 
     274                                        final NumberSequence ns2 = appData.getNumberSequences() 
     275                                                        .get(j); 
     276                                        if (i != j) { 
     277                                                final AlignmentAlgorithm aa = AlignmentAlgorithmFactory 
     278                                                                .create(); 
     279                                                aa.align(ns1, ns2, appData.getSubmat(), 9); 
     280                                                synchronized (appData.getMatchseqs()) { 
     281                                                        appData.getMatchseqs().addAll(aa.getMatches()); 
     282                                                } 
     283                                        } 
     284                                } 
     285                        } 
     286                } 
     287        } 
     288 
     289        /** 
     290         *  
     291         */ 
     292        private static class RuleApplicationData implements Serializable { 
     293 
     294                /** 
     295                 *  
     296                 */ 
     297                private static final long serialVersionUID = -7559657686755522960L; 
     298 
     299                private final HashMap<Integer, ITask> number2task; 
     300 
     301                // TODO: We Actually just need number2task here, this structure can be 
     302                // removed in the future. 
     303                private final HashSet<ITask> uniqueTasks; 
     304 
     305                private final ObjectDistanceSubstitionMatrix submat; 
     306 
     307                public HashMap<Integer, List<MatchOccurence>> replacedOccurences; 
     308 
     309                public LinkedList<Match> matchseqs; 
     310 
     311                private ArrayList<NumberSequence> numberseqs; 
     312 
     313                private final LinkedList<ITask> newTasks; 
     314 
     315                /** 
     316                 *  
     317                 */ 
     318                private final List<IUserSession> sessions; 
     319 
     320                /** 
     321                 *  
     322                 */ 
     323                private boolean detectedAndReplacedTasks; 
     324 
     325                /** 
     326                 *  
     327                 */ 
     328                private final RuleApplicationResult result; 
     329 
     330                /** 
     331                 *  
     332                 */ 
     333                private final StopWatch stopWatch; 
     334 
     335                /** 
     336                 *  
     337                 */ 
     338                private RuleApplicationData(List<IUserSession> sessions) { 
     339                        this.sessions = sessions; 
     340                        numberseqs = new ArrayList<NumberSequence>(); 
     341                        uniqueTasks = new HashSet<ITask>(); 
     342                        number2task = new HashMap<Integer, ITask>(); 
     343                        stopWatch = new StopWatch(); 
     344                        result = new RuleApplicationResult(); 
     345                        submat = new ObjectDistanceSubstitionMatrix(6, -3, false); 
     346                        newTasks = new LinkedList<ITask>(); 
     347                        this.detectedAndReplacedTasks = true; 
     348                } 
     349 
     350                /** 
     351                 * 
     352                 */ 
     353                private boolean detectedAndReplacedTasks() { 
     354                        return detectedAndReplacedTasks; 
     355                } 
     356 
     357                public LinkedList<Match> getMatchseqs() { 
     358                        return matchseqs; 
     359                } 
     360 
     361                public LinkedList<ITask> getNewTasks() { 
     362                        return newTasks; 
     363                } 
     364 
     365                private HashMap<Integer, ITask> getNumber2Task() { 
     366                        return number2task; 
     367                } 
     368 
     369                private ArrayList<NumberSequence> getNumberSequences() { 
     370                        return numberseqs; 
     371                } 
     372 
     373                public HashMap<Integer, List<MatchOccurence>> getReplacedOccurences() { 
     374                        return replacedOccurences; 
     375                } 
     376 
     377                /** 
     378                 * @return the result 
     379                 */ 
     380                private RuleApplicationResult getResult() { 
     381                        return result; 
     382                } 
     383 
     384                /** 
     385                 * @return the UserSessions as List. 
     386                 */ 
     387                private List<IUserSession> getSessions() { 
     388                        return sessions; 
     389                } 
     390 
     391                /** 
     392                 * @return the stopWatch 
     393                 */ 
     394                private StopWatch getStopWatch() { 
     395                        return stopWatch; 
     396                } 
     397 
     398                private ObjectDistanceSubstitionMatrix getSubmat() { 
     399                        return submat; 
     400                } 
     401 
     402                private HashSet<ITask> getUniqueTasks() { 
     403                        return uniqueTasks; 
     404                } 
     405 
     406                private void newTaskCreated(ITask task) { 
     407                        number2task.put(task.getId(), task); 
     408                        newTasks.add(task); 
     409                } 
     410 
     411                synchronized private void resetNewlyCreatedTasks() { 
     412                        uniqueTasks.addAll(newTasks); 
     413                        newTasks.clear(); 
     414                } 
     415 
     416                private void setNumberSequences(ArrayList<NumberSequence> numberseqs) { 
     417                        this.numberseqs = numberseqs; 
     418                } 
     419 
     420                public void setReplacedOccurences( 
     421                                HashMap<Integer, List<MatchOccurence>> replacedOccurences) { 
     422                        this.replacedOccurences = replacedOccurences; 
     423                } 
     424 
     425                private void updateSubstitutionMatrix() { 
     426                        submat.update(getNewTasks()); 
     427                        resetNewlyCreatedTasks(); 
     428                } 
     429 
     430        } 
     431 
    82432        public static int nThreads = Runtime.getRuntime().availableProcessors() - 1; 
    83433 
    84434        private int iteration = 0; 
     435 
    85436        /** 
    86437         * <p> 
     
    89440         * </p> 
    90441         */ 
    91         private ITaskFactory taskFactory; 
     442        private final ITaskFactory taskFactory; 
     443 
    92444        /** 
    93445         * <p> 
     
    96448         * </p> 
    97449         */ 
    98         private ITaskBuilder taskBuilder; 
     450        private final ITaskBuilder taskBuilder; 
    99451 
    100452        /** 
     
    104456         * </p> 
    105457         */ 
    106         private TaskHandlingStrategy preparationTaskHandlingStrategy; 
     458        private final TaskHandlingStrategy preparationTaskHandlingStrategy; 
    107459 
    108460        /** 
     
    133485         * (non-Javadoc) 
    134486         *  
    135          * @see java.lang.Object#toString() 
    136          */ 
    137         @Override 
    138         public String toString() { 
    139                 return "SequenceForTaskDetectionRuleAlignment"; 
    140         } 
    141  
    142         public void saveAppData(String name) { 
    143                 String objectName = name; 
    144                 String filename = name + ".dat"; 
    145                 Object dataObject = GlobalDataContainer.getInstance().getData( 
    146                                 objectName); 
    147                 if (dataObject == null) { 
    148                         CommandHelpers.objectNotFoundMessage(objectName); 
    149                 } 
    150                 FileOutputStream fos = null; 
    151                 ObjectOutputStream out = null; 
    152                 try { 
    153                         fos = new FileOutputStream(filename); 
    154                         out = new ObjectOutputStream(fos); 
    155                         out.writeObject(dataObject); 
    156                         out.close(); 
    157                 } catch (IOException ex) { 
    158                         Console.logException(ex); 
    159                 } 
    160         } 
    161  
    162         public RuleApplicationData loadAppData(String name) { 
    163                 String objectName = name; 
    164                 String filename = name + ".dat"; 
    165  
    166                 Object data = null; 
    167                 FileInputStream fis = null; 
    168                 ObjectInputStream in = null; 
    169                 try { 
    170                         fis = new FileInputStream(filename); 
    171                         in = new ObjectInputStream(fis); 
    172                         data = in.readObject(); 
    173                         in.close(); 
    174                 } catch (IOException ex) { 
    175                         Console.logException(ex); 
    176                 } catch (ClassNotFoundException ex) { 
    177                         Console.logException(ex); 
    178                 } 
    179                 if (GlobalDataContainer.getInstance().addData(objectName, data)) { 
    180                         CommandHelpers.dataOverwritten(objectName); 
    181                 } 
    182                 return (RuleApplicationData) GlobalDataContainer.getInstance().getData( 
    183                                 name); 
    184         } 
    185  
    186         /* 
    187          * (non-Javadoc) 
    188          *  
    189487         * @see 
    190488         * de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply 
     
    193491        @Override 
    194492        public RuleApplicationResult apply(List<IUserSession> sessions) { 
    195                 RuleApplicationData appData = new RuleApplicationData(sessions); 
     493                final RuleApplicationData appData = new RuleApplicationData(sessions); 
    196494                // File harmonized = new File("harmonized.dat"); 
    197495                // if(harmonized.exists() && !harmonized.isDirectory()) { 
     
    232530                        detectAndReplaceIterations(appData); 
    233531                        appData.getStopWatch().start("task replacement"); 
    234                         //appData.updateSubstitutionMatrix(); 
     532                        // appData.updateSubstitutionMatrix(); 
    235533                        detectAndReplaceTasks(appData); // 
    236534                        appData.getStopWatch().stop("task replacement"); 
     
    258556        private ArrayList<NumberSequence> createNumberSequences( 
    259557                        RuleApplicationData appData) { 
    260                 ArrayList<NumberSequence> result = new ArrayList<NumberSequence>(); 
     558                final ArrayList<NumberSequence> result = new ArrayList<NumberSequence>(); 
    261559                for (int i = 0; i < appData.getSessions().size(); i++) { 
    262                         IUserSession session = appData.getSessions().get(i); 
    263                         NumberSequence templist = new NumberSequence(session.size()); 
     560                        final IUserSession session = appData.getSessions().get(i); 
     561                        final NumberSequence templist = new NumberSequence(session.size()); 
    264562                        for (int j = 0; j < session.size(); j++) { 
    265                                 ITaskInstance taskInstance = session.get(j); 
     563                                final ITaskInstance taskInstance = session.get(j); 
    266564                                templist.getSequence()[j] = taskInstance.getTask().getId(); 
    267565                        } 
     
    272570                } 
    273571                return result; 
     572        } 
     573 
     574        /** 
     575         * <p> 
     576         * searches for direct iterations of single tasks in all sequences and 
     577         * replaces them with {@link IIteration}s, respectively appropriate 
     578         * instances. Also all single occurrences of a task that is iterated 
     579         * somewhen are replaced with iterations to have again an efficient way for 
     580         * task comparisons. 
     581         * </p> 
     582         *  
     583         * @param appData 
     584         *            the rule application data combining all data used for applying 
     585         *            this rule 
     586         */ 
     587        private void detectAndReplaceIterations(RuleApplicationData appData) { 
     588                Console.traceln(Level.FINE, "detecting iterations"); 
     589                appData.getStopWatch().start("detecting iterations"); 
     590 
     591                final List<IUserSession> sessions = appData.getSessions(); 
     592 
     593                final Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
     594 
     595                if (iteratedTasks.size() > 0) { 
     596                        replaceIterationsOf(iteratedTasks, sessions, appData); 
     597                } 
     598 
     599                appData.getStopWatch().stop("detecting iterations"); 
     600                Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() 
     601                                + " iterated tasks"); 
     602        } 
     603 
     604        /** 
     605         *  
     606         * @param appData 
     607         *            the rule application data combining all data used for applying 
     608         *            this rule 
     609         */ 
     610        private void detectAndReplaceTasks(RuleApplicationData appData) { 
     611                Console.traceln(Level.FINE, "detecting and replacing tasks"); 
     612                appData.getStopWatch().start("detecting tasks"); 
     613 
     614                // Create NumberSequences 
     615                appData.setNumberSequences(this.createNumberSequences(appData)); 
     616 
     617                // Generate pairwise alignments 
     618                // appData.setMatchseqs(generatePairwiseAlignments(appData)); 
     619                generatePairwiseAlignments(appData); 
     620 
     621                // Searching each match in all other sessions, counting its occurences 
     622                searchMatchesInAllSessions(appData); 
     623 
     624                // Sort results to get the most occurring results 
     625                Console.traceln(Level.INFO, "sorting " + appData.getMatchseqs().size() 
     626                                + " results"); 
     627                final Comparator<Match> comparator = new Comparator<Match>() { 
     628                        @Override 
     629                        public int compare(Match m1, Match m2) { 
     630                                return m2.occurenceCount() - m1.occurenceCount(); 
     631 
     632                        } 
     633                }; 
     634 
     635                Collections.sort(appData.getMatchseqs(), comparator); 
     636                appData.getStopWatch().stop("detecting tasks"); 
     637 
     638                // Replace matches in the sessions 
     639                Console.traceln(Level.INFO, "Replacing matches in sessions"); 
     640                replaceMatches(appData); 
     641                appData.getStopWatch().start("replacing tasks"); 
     642 
     643                // appData.setMatchseqs(null); 
     644                appData.getStopWatch().stop("replacing tasks"); 
     645        } 
     646 
     647        // private LinkedList<Match> generatePairwiseAlignments(RuleApplicationData 
     648        // appData) { 
     649        private void generatePairwiseAlignments(RuleApplicationData appData) { 
     650                final int numberSeqSize = appData.getNumberSequences().size(); 
     651                appData.matchseqs = new LinkedList<Match>(); 
     652                Console.traceln(Level.INFO, "generating pairwise alignments from " 
     653                                + numberSeqSize + " sessions with " + nThreads + " threads"); 
     654 
     655                int newThreads = nThreads; 
     656                if (numberSeqSize < nThreads) { 
     657                        newThreads = numberSeqSize; 
     658                } 
     659 
     660                final ExecutorService executor = Executors 
     661                                .newFixedThreadPool(newThreads); 
     662                final int interval = numberSeqSize / newThreads; 
     663                int rest = numberSeqSize % newThreads; 
     664 
     665                for (int i = 0; i < (numberSeqSize - interval); i += interval) { 
     666                        int offset = 0; 
     667                        if (rest != 0) { 
     668                                offset = 1; 
     669                                rest--; 
     670                        } 
     671                        final int from = i; 
     672                        final int to = i + interval + offset; 
     673                        System.out.println("Creating thread for sessions " + from 
     674                                        + " till " + to); 
     675                        final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner( 
     676                                        appData, from, to); 
     677                        executor.execute(aligner); 
     678                } 
     679                executor.shutdown(); 
     680                try { 
     681                        executor.awaitTermination(2, TimeUnit.HOURS); 
     682                } catch (final InterruptedException e) { 
     683                        // TODO Auto-generated catch block 
     684                        e.printStackTrace(); 
     685                } 
    274686        } 
    275687 
     
    291703                                "harmonizing task model of event task instances"); 
    292704                appData.getStopWatch().start("harmonizing event tasks"); 
    293                 SymbolMap<ITaskInstance, ITask> uniqueTasks = preparationTaskHandlingStrategy 
     705                final SymbolMap<ITaskInstance, ITask> uniqueTasks = preparationTaskHandlingStrategy 
    294706                                .createSymbolMap(); 
    295707 
    296                 TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     708                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
    297709                                .getTaskComparator(); 
    298710 
    299711                int unifiedTasks = 0; 
    300712                ITask task; 
    301                 List<IUserSession> sessions = appData.getSessions(); 
     713                final List<IUserSession> sessions = appData.getSessions(); 
    302714                for (int j = 0; j < sessions.size(); j++) { 
    303                         IUserSession session = sessions.get(j); 
     715                        final IUserSession session = sessions.get(j); 
    304716 
    305717                        for (int i = 0; i < session.size(); i++) { 
    306                                 ITaskInstance taskInstance = session.get(i); 
     718                                final ITaskInstance taskInstance = session.get(i); 
    307719                                task = uniqueTasks.getValue(taskInstance); 
    308720 
     
    332744        /** 
    333745         * <p> 
    334          * searches for direct iterations of single tasks in all sequences and 
    335          * replaces them with {@link IIteration}s, respectively appropriate 
    336          * instances. Also all single occurrences of a task that is iterated 
    337          * somewhen are replaced with iterations to have again an efficient way for 
    338          * task comparisons. 
     746         * TODO clarify why this is done 
    339747         * </p> 
    340          *  
     748         */ 
     749        private void harmonizeIterationInstancesModel(IIteration iteration, 
     750                        List<IIterationInstance> iterationInstances) { 
     751                final List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
     752                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     753                                .getTaskComparator(); 
     754 
     755                // merge the lexically different variants of iterated task to a unique 
     756                // list 
     757                for (final IIterationInstance iterationInstance : iterationInstances) { 
     758                        for (final ITaskInstance executionVariant : iterationInstance) { 
     759                                final ITask candidate = executionVariant.getTask(); 
     760 
     761                                boolean found = false; 
     762                                for (final ITask taskVariant : iteratedTaskVariants) { 
     763                                        if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
     764                                                taskBuilder.setTask(executionVariant, taskVariant); 
     765                                                found = true; 
     766                                                break; 
     767                                        } 
     768                                } 
     769 
     770                                if (!found) { 
     771                                        iteratedTaskVariants.add(candidate); 
     772                                } 
     773                        } 
     774                } 
     775 
     776                // if there are more than one lexically different variant of iterated 
     777                // tasks, adapt the 
     778                // iteration model to be a selection of different variants. In this case 
     779                // also adapt 
     780                // the generated iteration instances to correctly contain selection 
     781                // instances. If there 
     782                // is only one variant of an iterated task, simply set this as the 
     783                // marked task of the 
     784                // iteration. In this case, the instances can be preserved as is 
     785                if (iteratedTaskVariants.size() > 1) { 
     786                        final ISelection selection = taskFactory.createNewSelection(); 
     787 
     788                        for (final ITask variant : iteratedTaskVariants) { 
     789                                taskBuilder.addChild(selection, variant); 
     790                        } 
     791 
     792                        taskBuilder.setMarkedTask(iteration, selection); 
     793 
     794                        for (final IIterationInstance instance : iterationInstances) { 
     795                                for (int i = 0; i < instance.size(); i++) { 
     796                                        final ISelectionInstance selectionInstance = taskFactory 
     797                                                        .createNewTaskInstance(selection); 
     798                                        taskBuilder.setChild(selectionInstance, instance.get(i)); 
     799                                        taskBuilder.setTaskInstance(instance, i, selectionInstance); 
     800                                } 
     801                        } 
     802                } else { 
     803                        taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
     804                } 
     805        } 
     806 
     807        public RuleApplicationData loadAppData(String name) { 
     808                final String objectName = name; 
     809                final String filename = name + ".dat"; 
     810 
     811                Object data = null; 
     812                FileInputStream fis = null; 
     813                ObjectInputStream in = null; 
     814                try { 
     815                        fis = new FileInputStream(filename); 
     816                        in = new ObjectInputStream(fis); 
     817                        data = in.readObject(); 
     818                        in.close(); 
     819                } catch (final IOException ex) { 
     820                        Console.logException(ex); 
     821                } catch (final ClassNotFoundException ex) { 
     822                        Console.logException(ex); 
     823                } 
     824                if (GlobalDataContainer.getInstance().addData(objectName, data)) { 
     825                        CommandHelpers.dataOverwritten(objectName); 
     826                } 
     827                return (RuleApplicationData) GlobalDataContainer.getInstance().getData( 
     828                                name); 
     829        } 
     830 
     831        /** 
    341832         * @param appData 
    342          *            the rule application data combining all data used for applying 
    343          *            this rule 
    344          */ 
    345         private void detectAndReplaceIterations(RuleApplicationData appData) { 
    346                 Console.traceln(Level.FINE, "detecting iterations"); 
    347                 appData.getStopWatch().start("detecting iterations"); 
    348  
    349                 List<IUserSession> sessions = appData.getSessions(); 
    350  
    351                 Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
    352  
    353                 if (iteratedTasks.size() > 0) { 
    354                         replaceIterationsOf(iteratedTasks, sessions, appData); 
    355                 } 
    356  
    357                 appData.getStopWatch().stop("detecting iterations"); 
    358                 Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() 
    359                                 + " iterated tasks"); 
    360         } 
    361  
    362         /** 
    363          * <p> 
    364          * searches the provided sessions for task iterations. If a task is 
    365          * iterated, it is added to the returned set. 
    366          * </p> 
    367          *  
    368          * @param the 
    369          *            session to search for iterations in 
    370          *  
    371          * @return a set of tasks being iterated somewhere 
    372          */ 
    373         private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
    374                 Set<ITask> iteratedTasks = new HashSet<ITask>(); 
    375                 for (IUserSession session : sessions) { 
    376                         for (int i = 0; i < (session.size() - 1); i++) { 
    377                                 // we prepared the task instances to refer to unique tasks, if 
    378                                 // they are treated 
    379                                 // as equal. Therefore, we just compare the identity of the 
    380                                 // tasks of the task 
    381                                 // instances 
    382                                 if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
    383                                         iteratedTasks.add(session.get(i).getTask()); 
     833         *            , Ruleapplication Data needed to keep track of all created 
     834         *            tasks 
     835         * @param m 
     836         *            The match to be converted into a Task 
     837         * @return The task of the match with an ISequence as it's root 
     838         */ 
     839        synchronized public ISequence matchAsSequence(RuleApplicationData appData, 
     840                        Match m) { 
     841                final ISequence sequence = taskFactory.createNewSequence(); 
     842                appData.newTaskCreated(sequence); 
     843 
     844                final int[] first = m.getFirstSequence().getSequence(); 
     845                final int[] second = m.getSecondSequence().getSequence(); 
     846 
     847                // Both sequences of a match are equally long 
     848                for (int i = 0; i < m.getFirstSequence().size(); i++) { 
     849 
     850                        // Two gaps aligned to each other: Have not seen it happening so 
     851                        // far, just to handle it 
     852                        if ((first[i] == -1) && (second[i] == -1)) { 
     853                                // Do nothing here. 
     854                        } 
     855                        // Both events are equal, we can simply add the task referring to 
     856                        // the number 
     857                        else if (first[i] == second[i]) { 
     858                                taskBuilder.addChild(sequence, 
     859                                                appData.getNumber2Task().get(first[i])); 
     860                        } 
     861                        // We have a gap in the first sequence, we need to add the task of 
     862                        // the second sequence as optional 
     863                        else if ((first[i] == -1) && (second[i] != -1)) { 
     864                                final IOptional optional = taskFactory.createNewOptional(); 
     865                                appData.newTaskCreated(optional); 
     866                                taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
     867                                                .get(second[i])); 
     868                                taskBuilder.addChild(sequence, optional); 
     869                        } 
     870                        // We have a gap in the second sequence, we need to add the task of 
     871                        // the first sequence as optional 
     872                        else if ((first[i] != -1) && (second[i] == -1)) { 
     873                                final IOptional optional = taskFactory.createNewOptional(); 
     874                                appData.newTaskCreated(optional); 
     875                                taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
     876                                                .get(first[i])); 
     877                                taskBuilder.addChild(sequence, optional); 
     878                        } 
     879                        // Both tasks are not equal, we need to insert a selection here. 
     880                        // Check if the next position is not a selection 
     881                        else if (i < (first.length - 1)) { 
     882 
     883                                if ((first[i] != second[i]) 
     884                                                && (((first[i + 1] == second[i + 1]) 
     885                                                                || (first[i + 1] == -1) || (second[i + 1] == -1)))) { 
     886 
     887                                        final ISelection selection = taskFactory 
     888                                                        .createNewSelection(); 
     889                                        appData.newTaskCreated(selection); 
     890                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     891                                                        .get(first[i])); 
     892                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     893                                                        .get(second[i])); 
     894                                        taskBuilder.addChild(sequence, selection); 
     895                                } else { 
     896                                        boolean selectionfound = true; 
     897                                        final ISelection selection = taskFactory 
     898                                                        .createNewSelection(); 
     899                                        appData.newTaskCreated(selection); 
     900 
     901                                        final ISequence subsequence1 = taskFactory 
     902                                                        .createNewSequence(); 
     903                                        appData.newTaskCreated(subsequence1); 
     904 
     905                                        final ISequence subsequence2 = taskFactory 
     906                                                        .createNewSequence(); 
     907                                        appData.newTaskCreated(subsequence2); 
     908 
     909                                        taskBuilder.addChild(selection, subsequence1); 
     910                                        taskBuilder.addChild(selection, subsequence2); 
     911                                        taskBuilder.addChild(sequence, selection); 
     912                                        while ((i < (first.length - 1)) && selectionfound) { 
     913                                                selectionfound = false; 
     914                                                taskBuilder.addChild(subsequence1, appData 
     915                                                                .getNumber2Task().get(first[i])); 
     916                                                taskBuilder.addChild(subsequence2, appData 
     917                                                                .getNumber2Task().get(second[i])); 
     918                                                if ((first[i + 1] != second[i + 1]) 
     919                                                                && (first[i + 1] != -1) 
     920                                                                && (second[i + 1] != -1)) { 
     921                                                        selectionfound = true; 
     922                                                } else { 
     923                                                        continue; 
     924                                                } 
     925                                                i++; 
     926                                        } 
     927                                        if ((i == (first.length - 1)) && selectionfound) { 
     928                                                taskBuilder.addChild(subsequence1, appData 
     929                                                                .getNumber2Task().get(first[i])); 
     930                                                taskBuilder.addChild(subsequence2, appData 
     931                                                                .getNumber2Task().get(second[i])); 
     932                                        } 
    384933                                } 
    385                         } 
    386                 } 
    387                 return iteratedTasks; 
     934                        } else { 
     935                                if ((first[i] != second[i])) { 
     936 
     937                                        final ISelection selection = taskFactory 
     938                                                        .createNewSelection(); 
     939                                        appData.newTaskCreated(selection); 
     940                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     941                                                        .get(first[i])); 
     942                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     943                                                        .get(second[i])); 
     944                                        taskBuilder.addChild(sequence, selection); 
     945                                } 
     946                        } 
     947 
     948                } 
     949                return sequence; 
    388950        } 
    389951 
     
    403965        private void replaceIterationsOf(Set<ITask> iteratedTasks, 
    404966                        List<IUserSession> sessions, RuleApplicationData appData) { 
    405                 Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
    406                 Map<IIteration, List<IIterationInstance>> iterationInstances = new HashMap<IIteration, List<IIterationInstance>>(); 
    407  
    408                 for (ITask iteratedTask : iteratedTasks) { 
    409  
    410                         IIteration iteration = taskFactory.createNewIteration(); 
     967                final Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
     968                final Map<IIteration, List<IIterationInstance>> iterationInstances = new HashMap<IIteration, List<IIterationInstance>>(); 
     969 
     970                for (final ITask iteratedTask : iteratedTasks) { 
     971 
     972                        final IIteration iteration = taskFactory.createNewIteration(); 
    411973                        appData.newTaskCreated(iteration); 
    412974                        iterations.put(iteratedTask, iteration); 
     
    417979                IIterationInstance iterationInstance; 
    418980 
    419                 for (IUserSession session : sessions) { 
     981                for (final IUserSession session : sessions) { 
    420982                        int index = 0; 
    421983                        iterationInstance = null; 
     
    427989                                // tasks of the task 
    428990                                // instances 
    429                                 ITask currentTask = session.get(index).getTask(); 
    430                                 IIteration iteration = iterations.get(currentTask); 
     991                                final ITask currentTask = session.get(index).getTask(); 
     992                                final IIteration iteration = iterations.get(currentTask); 
    431993                                if (iteration != null) { 
    432994                                        if ((iterationInstance == null) 
     
    436998                                                iterationInstances.get(iteration) 
    437999                                                                .add(iterationInstance);// TODO:: Don't create 
    438                                                                                                                 // TaskInstances here, 
    439                                                                                                                 // use a set of tasks 
    440                                                                                                                 // instead 
     1000                                                // TaskInstances here, 
     1001                                                // use a set of tasks 
     1002                                                // instead 
    4411003                                                taskBuilder.addTaskInstance(session, index, 
    4421004                                                                iterationInstance); 
     
    4551017                } 
    4561018 
    457                 for (Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances 
     1019                for (final Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances 
    4581020                                .entrySet()) { 
    4591021                        harmonizeIterationInstancesModel(entry.getKey(), entry.getValue()); 
     
    4611023        } 
    4621024 
    463         /** 
    464          * <p> 
    465          * TODO clarify why this is done 
    466          * </p> 
    467          */ 
    468         private void harmonizeIterationInstancesModel(IIteration iteration, 
    469                         List<IIterationInstance> iterationInstances) { 
    470                 List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
    471                 TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
    472                                 .getTaskComparator(); 
    473  
    474                 // merge the lexically different variants of iterated task to a unique 
    475                 // list 
    476                 for (IIterationInstance iterationInstance : iterationInstances) { 
    477                         for (ITaskInstance executionVariant : iterationInstance) { 
    478                                 ITask candidate = executionVariant.getTask(); 
    479  
    480                                 boolean found = false; 
    481                                 for (ITask taskVariant : iteratedTaskVariants) { 
    482                                         if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
    483                                                 taskBuilder.setTask(executionVariant, taskVariant); 
    484                                                 found = true; 
    485                                                 break; 
    486                                         } 
    487                                 } 
    488  
    489                                 if (!found) { 
    490                                         iteratedTaskVariants.add(candidate); 
    491                                 } 
    492                         } 
    493                 } 
    494  
    495                 // if there are more than one lexically different variant of iterated 
    496                 // tasks, adapt the 
    497                 // iteration model to be a selection of different variants. In this case 
    498                 // also adapt 
    499                 // the generated iteration instances to correctly contain selection 
    500                 // instances. If there 
    501                 // is only one variant of an iterated task, simply set this as the 
    502                 // marked task of the 
    503                 // iteration. In this case, the instances can be preserved as is 
    504                 if (iteratedTaskVariants.size() > 1) { 
    505                         ISelection selection = taskFactory.createNewSelection(); 
    506  
    507                         for (ITask variant : iteratedTaskVariants) { 
    508                                 taskBuilder.addChild(selection, variant); 
    509                         } 
    510  
    511                         taskBuilder.setMarkedTask(iteration, selection); 
    512  
    513                         for (IIterationInstance instance : iterationInstances) { 
    514                                 for (int i = 0; i < instance.size(); i++) { 
    515                                         ISelectionInstance selectionInstance = taskFactory 
    516                                                         .createNewTaskInstance(selection); 
    517                                         taskBuilder.setChild(selectionInstance, instance.get(i)); 
    518                                         taskBuilder.setTaskInstance(instance, i, selectionInstance); 
    519                                 } 
    520                         } 
    521                 } else { 
    522                         taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
    523                 } 
    524         } 
    525  
    526         /** 
    527          * @param appData 
    528          * @param m 
    529          * @return 
    530          */ 
    531         synchronized public ISequence matchAsSequence(RuleApplicationData appData, Match m) { 
    532                 ISequence sequence = taskFactory.createNewSequence(); 
    533                 appData.newTaskCreated(sequence); 
    534  
    535                 int[] first = m.getFirstSequence().getSequence(); 
    536                 int[] second = m.getSecondSequence().getSequence(); 
    537  
    538                 // Both sequences of a match are equally long 
    539                 for (int i = 0; i < m.getFirstSequence().size(); i++) { 
    540  
    541                         // Two gaps aligned to each other: Have not seen it happening so 
    542                         // far, just to handle it 
    543                         if (first[i] == -1 && second[i] == -1) { 
    544                                 // Do nothing here. 
    545                         } 
    546                         // Both events are equal, we can simply add the task referring to 
    547                         // the number 
    548                         else if (first[i] == second[i]) { 
    549                                 taskBuilder.addChild(sequence, 
    550                                                 appData.getNumber2Task().get(first[i])); 
    551                         } 
    552                         // We have a gap in the first sequence, we need to add the task of 
    553                         // the second sequence as optional 
    554                         else if (first[i] == -1 && second[i] != -1) { 
    555                                 IOptional optional = taskFactory.createNewOptional(); 
    556                                 appData.newTaskCreated(optional); 
    557                                 taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
    558                                                 .get(second[i])); 
    559                                 taskBuilder.addChild(sequence, optional); 
    560                         } 
    561                         // We have a gap in the second sequence, we need to add the task of 
    562                         // the first sequence as optional 
    563                         else if (first[i] != -1 && second[i] == -1) { 
    564                                 IOptional optional = taskFactory.createNewOptional(); 
    565                                 appData.newTaskCreated(optional); 
    566                                 taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
    567                                                 .get(first[i])); 
    568                                 taskBuilder.addChild(sequence, optional); 
    569                         } 
    570                         // Both tasks are not equal, we need to insert a selection here. 
    571                         // Check if the next position is not a selection 
    572                         else if (i < first.length - 1) { 
    573  
    574                                 if ((first[i] != second[i]) 
    575                                                 && ((first[i + 1] == second[i + 1] 
    576                                                                 || first[i + 1] == -1 || second[i + 1] == -1))) { 
    577  
    578                                         ISelection selection = taskFactory.createNewSelection(); 
    579                                         appData.newTaskCreated(selection); 
    580                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    581                                                         .get(first[i])); 
    582                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    583                                                         .get(second[i])); 
    584                                         taskBuilder.addChild(sequence, selection); 
    585                                 } else { 
    586                                         boolean selectionfound = true; 
    587                                         ISelection selection = taskFactory.createNewSelection(); 
    588                                         appData.newTaskCreated(selection); 
    589  
    590                                         ISequence subsequence1 = taskFactory.createNewSequence(); 
    591                                         appData.newTaskCreated(subsequence1); 
    592  
    593                                         ISequence subsequence2 = taskFactory.createNewSequence(); 
    594                                         appData.newTaskCreated(subsequence2); 
    595  
    596                                         taskBuilder.addChild(selection, subsequence1); 
    597                                         taskBuilder.addChild(selection, subsequence2); 
    598                                         taskBuilder.addChild(sequence, selection); 
    599                                         while (i < first.length - 1 && selectionfound) { 
    600                                                 selectionfound = false; 
    601                                                 taskBuilder.addChild(subsequence1, appData 
    602                                                                 .getNumber2Task().get(first[i])); 
    603                                                 taskBuilder.addChild(subsequence2, appData 
    604                                                                 .getNumber2Task().get(second[i])); 
    605                                                 if (first[i + 1] != second[i + 1] && first[i + 1] != -1 
    606                                                                 && second[i + 1] != -1) { 
    607                                                         selectionfound = true; 
    608                                                 } else { 
    609                                                         continue; 
    610                                                 } 
    611                                                 i++; 
    612                                         } 
    613                                         if (i == first.length - 1 && selectionfound) { 
    614                                                 taskBuilder.addChild(subsequence1, appData 
    615                                                                 .getNumber2Task().get(first[i])); 
    616                                                 taskBuilder.addChild(subsequence2, appData 
    617                                                                 .getNumber2Task().get(second[i])); 
    618                                         } 
    619                                 } 
    620                         } else { 
    621                                 if ((first[i] != second[i])) { 
    622  
    623                                         ISelection selection = taskFactory.createNewSelection(); 
    624                                         appData.newTaskCreated(selection); 
    625                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    626                                                         .get(first[i])); 
    627                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    628                                                         .get(second[i])); 
    629                                         taskBuilder.addChild(sequence, selection); 
    630                                 } 
    631                         } 
    632  
    633                 } 
    634                 return sequence; 
    635         } 
    636  
    637         /** 
    638          *  
    639          * @param appData 
    640          *            the rule application data combining all data used for applying 
    641          *            this rule 
    642          */ 
    643         private void detectAndReplaceTasks(RuleApplicationData appData) { 
    644                 Console.traceln(Level.FINE, "detecting and replacing tasks"); 
    645                 appData.getStopWatch().start("detecting tasks"); 
    646  
    647                 // Create NumberSequences 
    648                 appData.setNumberSequences(this.createNumberSequences(appData)); 
    649  
    650                 // Generate pairwise alignments 
    651                 // appData.setMatchseqs(generatePairwiseAlignments(appData)); 
    652                 generatePairwiseAlignments(appData); 
    653  
    654                 // Searching each match in all other sessions, counting its occurences 
    655                 searchMatchesInAllSessions(appData); 
    656  
    657                 // Sort results to get the most occurring results 
    658                 Console.traceln(Level.INFO, "sorting " + appData.getMatchseqs().size() 
    659                                 + " results"); 
    660                 Comparator<Match> comparator = new Comparator<Match>() { 
    661                         public int compare(Match m1, Match m2) { 
    662                                 return m2.occurenceCount() - m1.occurenceCount(); 
    663  
    664                         } 
    665                 }; 
    666  
    667                 Collections.sort(appData.getMatchseqs(), comparator); 
    668                 appData.getStopWatch().stop("detecting tasks"); 
    669  
    670                 // Replace matches in the sessions 
    671                 Console.traceln(Level.INFO, "Replacing matches in sessions"); 
    672                 replaceMatches(appData); 
    673                 appData.getStopWatch().start("replacing tasks"); 
    674                  
    675                 // appData.setMatchseqs(null); 
    676                 appData.getStopWatch().stop("replacing tasks"); 
    677         } 
    678  
    6791025        private void replaceMatches(RuleApplicationData appData) { 
    6801026                appData.replacedOccurences = new HashMap<Integer, List<MatchOccurence>>(); 
    681                  
    682                 int matchSeqSize = appData.getMatchseqs().size(); 
     1027 
     1028                final int matchSeqSize = appData.getMatchseqs().size(); 
    6831029                int newThreads = nThreads; 
    6841030                if (matchSeqSize < nThreads) { 
    685                         newThreads = matchSeqSize;  
    686                 } 
    687                 ExecutorService executor = Executors.newFixedThreadPool(newThreads); 
    688                 int interval = matchSeqSize / newThreads; 
     1031                        newThreads = matchSeqSize; 
     1032                } 
     1033                final ExecutorService executor = Executors 
     1034                                .newFixedThreadPool(newThreads); 
     1035                final int interval = matchSeqSize / newThreads; 
    6891036                int rest = matchSeqSize % newThreads; 
    690                  
    691                 for (int i = 0; i < matchSeqSize - interval; i += interval) { 
     1037 
     1038                for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
    6921039                        int offset = 0; 
    6931040                        if (rest != 0) { 
     
    6951042                                rest--; 
    6961043                        } 
    697                         int from = i; 
    698                         int to = i + interval + offset; 
    699                         System.out.println("Replacement: Creating thread with matches from " + from 
    700                                         + " to " + to); 
     1044                        final int from = i; 
     1045                        final int to = i + interval + offset; 
     1046                        System.out 
     1047                        .println("Replacement: Creating thread with matches from " 
     1048                                        + from + " to " + to); 
    7011049                        // search each match in every other sequence 
    702                         ParallelMatchReplacer replacer = new ParallelMatchReplacer( 
     1050                        final ParallelMatchReplacer replacer = new ParallelMatchReplacer( 
    7031051                                        appData, from, to); 
    7041052                        executor.execute(replacer); 
     
    7071055                try { 
    7081056                        executor.awaitTermination(2, TimeUnit.HOURS); 
    709                 } catch (InterruptedException e) { 
     1057                } catch (final InterruptedException e) { 
    7101058                        // TODO Auto-generated catch block 
    7111059                        e.printStackTrace(); 
    7121060                } 
     1061        } 
     1062 
     1063        public void saveAppData(String name) { 
     1064                final String objectName = name; 
     1065                final String filename = name + ".dat"; 
     1066                final Object dataObject = GlobalDataContainer.getInstance().getData( 
     1067                                objectName); 
     1068                if (dataObject == null) { 
     1069                        CommandHelpers.objectNotFoundMessage(objectName); 
     1070                } 
     1071                FileOutputStream fos = null; 
     1072                ObjectOutputStream out = null; 
     1073                try { 
     1074                        fos = new FileOutputStream(filename); 
     1075                        out = new ObjectOutputStream(fos); 
     1076                        out.writeObject(dataObject); 
     1077                        out.close(); 
     1078                } catch (final IOException ex) { 
     1079                        Console.logException(ex); 
     1080                } 
     1081        } 
     1082 
     1083        /** 
     1084         * <p> 
     1085         * searches the provided sessions for task iterations. If a task is 
     1086         * iterated, it is added to the returned set. 
     1087         * </p> 
     1088         *  
     1089         * @param the 
     1090         *            session to search for iterations in 
     1091         *  
     1092         * @return a set of tasks being iterated somewhere 
     1093         */ 
     1094        private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
     1095                final Set<ITask> iteratedTasks = new HashSet<ITask>(); 
     1096                for (final IUserSession session : sessions) { 
     1097                        for (int i = 0; i < (session.size() - 1); i++) { 
     1098                                // we prepared the task instances to refer to unique tasks, if 
     1099                                // they are treated 
     1100                                // as equal. Therefore, we just compare the identity of the 
     1101                                // tasks of the task 
     1102                                // instances 
     1103                                if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
     1104                                        iteratedTasks.add(session.get(i).getTask()); 
     1105                                } 
     1106                        } 
     1107                } 
     1108                return iteratedTasks; 
    7131109        } 
    7141110 
     
    7181114                                                + " threads"); 
    7191115                // Prepare parallel search of matchseqs 
    720                  
    721                 int matchSeqSize = appData.getMatchseqs().size(); 
     1116 
     1117                final int matchSeqSize = appData.getMatchseqs().size(); 
    7221118                int newThreads = nThreads; 
    7231119                if (matchSeqSize < nThreads) { 
    724                         newThreads = matchSeqSize;  
    725                 } 
    726                 int interval = matchSeqSize / newThreads; 
     1120                        newThreads = matchSeqSize; 
     1121                } 
     1122                final int interval = matchSeqSize / newThreads; 
    7271123                int rest = matchSeqSize % newThreads; 
    728                 ExecutorService executor = Executors.newFixedThreadPool(nThreads); 
    729                  
    730                 for (int i = 0; i < matchSeqSize - interval; i += interval) { 
     1124                final ExecutorService executor = Executors.newFixedThreadPool(nThreads); 
     1125 
     1126                for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
    7311127                        int offset = 0; 
    7321128                        if (rest != 0) { 
     
    7341130                                rest--; 
    7351131                        } 
    736                         int from = i; 
    737                         int to = i + interval + offset; 
    738                         System.out.println("Match finding: Creating thread with matches from " + from 
    739                                         + " to " + to); 
     1132                        final int from = i; 
     1133                        final int to = i + interval + offset; 
     1134                        System.out 
     1135                        .println("Match finding: Creating thread with matches from " 
     1136                                        + from + " to " + to); 
    7401137                        // search each match in every other sequence 
    741                         ParallelMatchOcurrencesFinder finder = new ParallelMatchOcurrencesFinder( 
     1138                        final ParallelMatchOcurrencesFinder finder = new ParallelMatchOcurrencesFinder( 
    7421139                                        appData, from, to); 
    7431140                        executor.execute(finder); 
     
    7461143                try { 
    7471144                        executor.awaitTermination(2, TimeUnit.HOURS); 
    748                 } catch (InterruptedException e) { 
     1145                } catch (final InterruptedException e) { 
    7491146                        // TODO Auto-generated catch block 
    7501147                        e.printStackTrace(); 
     
    7531150        } 
    7541151 
    755  
    756         private class ParallelMatchReplacer implements Runnable { 
    757  
    758                 private final RuleApplicationData appData; 
    759                 private final int from; 
    760                 private final int to; 
    761  
    762                 ParallelMatchReplacer(RuleApplicationData appData, int from, 
    763                                 int to) { 
    764                         this.appData = appData; 
    765                         this.from = from; 
    766                         this.to = to; 
    767                 } 
    768                 @Override 
    769                 public void run() { 
    770                         int count = 0; 
    771                         int size = to - from; 
    772                         for (int i = from; i < to; i++) { 
    773                         count++; 
    774                         // Every pattern consists of 2 sequences, therefore the minimum 
    775                         // occurrences here is 2. 
    776                         // We just need the sequences also occurring in other sequences as well 
    777                         if (appData.getMatchseqs().get(i).occurenceCount() > 2) { 
    778                                  
    779                                 ISequence task = matchAsSequence(appData, appData.getMatchseqs().get(i)); 
    780                                                         invalidOccurence: for (Iterator<MatchOccurence> it = appData 
    781                                                                         .getMatchseqs().get(i).getOccurences().iterator(); it 
    782                                                                         .hasNext();) { 
    783                                                                 MatchOccurence oc = it.next(); 
    784  
    785                                                                 // Check if nothing has been replaced in the sequence we  
    786                                                                 // want to replace now 
    787                                                                  
    788                                                                 synchronized (appData.getReplacedOccurences()) { 
    789                                                                 if (appData.getReplacedOccurences().get(oc.getSequenceId()) == null) { 
    790                                                                         appData.getReplacedOccurences().put(oc.getSequenceId(), 
    791                                                                                         new LinkedList<MatchOccurence>()); 
    792                                                                 } else { 
    793                                                                         // check if we have any replaced occurence with indexes 
    794                                                                         // smaller than ours. If so, we need to adjust our start 
    795                                                                         // and endpoints 
    796                                                                         // of the replacement. 
    797                                                                         // Also do a check if we have replaced this specific 
    798                                                                         // MatchOccurence in this sequence already. Jump to the 
    799                                                                         // next occurence if this is the case. 
    800                                                                         // This is no more neccessary once the matches are 
    801                                                                         // harmonized. 
    802                                                                         for (Iterator<MatchOccurence> jt = appData.getReplacedOccurences() 
    803                                                                                         .get(oc.getSequenceId()).iterator(); jt 
    804                                                                                         .hasNext();) { 
    805                                                                                 MatchOccurence tmpOC = jt.next(); 
    806  
    807                                                                                 if (oc.getStartindex() >= tmpOC.getStartindex() 
    808                                                                                                 && oc.getStartindex() <= tmpOC 
    809                                                                                                                 .getEndindex()) { 
    810                                                                                         continue invalidOccurence; 
    811                                                                                 } 
    812                                                                                 if (oc.getEndindex() >= tmpOC.getStartindex()) { 
    813                                                                                         continue invalidOccurence; 
    814  
    815                                                                                 } else if (oc.getStartindex() > tmpOC.getEndindex()) { 
    816                                                                                         int diff = tmpOC.getEndindex() 
    817                                                                                                         - tmpOC.getStartindex(); 
    818                                                                                         // Just to be sure. 
    819                                                                                         if (diff > 0) { 
    820                                                                                                 oc.setStartindex(oc.getStartindex() - diff 
    821                                                                                                                 + 1); 
    822                                                                                                 oc.setEndindex(oc.getEndindex() - diff + 1); 
    823                                                                                         } else { 
    824                                                                                                 Console.traceln(Level.WARNING, 
    825                                                                                                                 "End index of a Match before start. This should never happen"); 
    826                                                                                         } 
    827                                                                                 } 
    828                                                                         } 
    829                                                                 } 
    830                                                                 System.out.println("Replacing in sequence" 
    831                                                                                 + oc.getSequenceId()); 
    832                                                                 synchronized(appData) { 
    833                                                                         appData.detectedAndReplacedTasks = true; 
    834                                                                 } 
    835                                                                 synchronized (appData.getSessions().get(oc.getSequenceId())) { 
    836                                                                         ISequenceInstance sequenceInstances = RuleUtils 
    837                                                                                         .createNewSubSequenceInRange(appData.getSessions() 
    838                                                                                                         .get(oc.getSequenceId()), oc 
    839                                                                                                         .getStartindex(), oc.getEndindex(), task, 
    840                                                                                                         taskFactory, taskBuilder); 
    841                                                                         oc.setEndindex(oc.getStartindex() 
    842                                                                                         + sequenceInstances.size() 
    843                                                                                         - RuleUtils.missedOptionals); 
    844                                                                         } 
    845                                                                 } 
    846                                                                 // Adjust the length of the match regarding to the length of 
    847                                                                 // instance. (OptionalInstances may be shorter) 
    848                                                                  
    849                                                                 synchronized(appData.getReplacedOccurences().get(oc.getSequenceId())) { 
    850                                                                         appData.getReplacedOccurences().get(oc.getSequenceId()).add(oc); 
    851                                                                 } 
    852                                                         } 
    853                                                 } 
    854                                         } 
    855                                 }        
    856                         } 
    857                  
    858          
    859  
    860         private class ParallelMatchOcurrencesFinder implements Runnable { 
    861                 private final RuleApplicationData appData; 
    862                 private final int from; 
    863                 private final int to; 
    864  
    865                 ParallelMatchOcurrencesFinder(RuleApplicationData appData, int from, 
    866                                 int to) { 
    867                         this.appData = appData; 
    868                         this.from = from; 
    869                         this.to = to; 
    870                 } 
    871  
    872                 @Override 
    873                 public void run() { 
    874                         int count = 0; 
    875                         int size = to - from; 
    876  
    877                         for (int i = from; i < to; i++) { 
    878                                 Match pattern = appData.getMatchseqs().get(i); 
    879                                 count++; 
    880                                 RuleUtils.printProgressPercentage("Match finding progress",count, size); 
    881                                 // Skip sequences with more 0 events (scrolls) than other 
    882                                 // events. 
    883                                 // Both of the pattern sequences are equally long, so the zero 
    884                                 // counts just need to be smaller than the length of one 
    885                                 // sequence 
    886                                 if (pattern.getFirstSequence().eventCount(0) 
    887                                                 + pattern.getSecondSequence().eventCount(0) + 1 > pattern 
    888                                                 .getFirstSequence().size()) 
    889                                         continue; 
    890  
    891                                 for (int j = 0; j < appData.getNumberSequences().size(); j++) { 
    892                                         LinkedList<Integer> startpositions = appData 
    893                                                         .getNumberSequences().get(j) 
    894                                                         .containsPattern(pattern); 
    895                                         if (startpositions.size() > 0) { 
    896                                                 for (Iterator<Integer> jt = startpositions.iterator(); jt 
    897                                                                 .hasNext();) { 
    898                                                         int start = jt.next(); 
    899                                                         pattern.addOccurence(new MatchOccurence(start, 
    900                                                                         start + pattern.size(), j)); 
    901                                                 } 
    902                                         } 
    903                                 } 
    904                         } 
    905                 } 
    906         } 
    907  
    908         private class ParallelPairwiseAligner implements Runnable { 
    909                 private final RuleApplicationData appData; 
    910                 private final int from; 
    911                 private final int to; 
    912  
    913                 ParallelPairwiseAligner(RuleApplicationData appData, int from, int to) { 
    914                         this.appData = appData; 
    915                         this.from = from; 
    916                         this.to = to; 
    917                 } 
    918  
    919                 @Override 
    920                 public void run() { 
    921                         int count = 0; 
    922                         int size = to - from; 
    923  
    924                         for (int i = from; i < to; i++) { 
    925                                 NumberSequence ns1 = appData.getNumberSequences().get(i); 
    926                                 count++; 
    927                                 RuleUtils.printProgressPercentage("Aligning Progress",count, size); 
    928                                 for (int j = 0; j < appData.getNumberSequences().size(); j++) { 
    929                                         NumberSequence ns2 = appData.getNumberSequences().get(j); 
    930                                         if (i != j) { 
    931                                                 AlignmentAlgorithm aa = AlignmentAlgorithmFactory 
    932                                                                 .create(); 
    933                                                 aa.align(ns1, ns2, appData.getSubmat(), 9); 
    934                                                 synchronized (appData.getMatchseqs()) { 
    935                                                         appData.getMatchseqs().addAll(aa.getMatches()); 
    936                                                 } 
    937                                         } 
    938                                 } 
    939                         } 
    940                 } 
    941         } 
    942  
    943         // private LinkedList<Match> generatePairwiseAlignments(RuleApplicationData 
    944         // appData) { 
    945         private void generatePairwiseAlignments(RuleApplicationData appData) { 
    946                 int numberSeqSize = appData.getNumberSequences().size(); 
    947                 appData.matchseqs = new LinkedList<Match>(); 
    948                 Console.traceln(Level.INFO, "generating pairwise alignments from " 
    949                                 + numberSeqSize + " sessions with " + nThreads + " threads"); 
    950                  
    951                 int newThreads = nThreads; 
    952                 if (numberSeqSize < nThreads) { 
    953                         newThreads = numberSeqSize;  
    954                 } 
    955                  
    956                 ExecutorService executor = Executors.newFixedThreadPool(newThreads); 
    957                 int interval = numberSeqSize / newThreads; 
    958                 int rest = numberSeqSize % newThreads; 
    959  
    960                 for (int i = 0; i < numberSeqSize - interval; i += interval) { 
    961                         int offset = 0; 
    962                         if (rest != 0) { 
    963                                 offset = 1; 
    964                                 rest--; 
    965                         } 
    966                         int from = i; 
    967                         int to = i + interval + offset; 
    968                         System.out.println("Creating thread for sessions " + from 
    969                                         + " till " + to); 
    970                         ParallelPairwiseAligner aligner = new ParallelPairwiseAligner( 
    971                                         appData, from, to); 
    972                         executor.execute(aligner); 
    973                 } 
    974                 executor.shutdown(); 
    975                 try { 
    976                         executor.awaitTermination(2, TimeUnit.HOURS); 
    977                 } catch (InterruptedException e) { 
    978                         // TODO Auto-generated catch block 
    979                         e.printStackTrace(); 
    980                 } 
    981         } 
    982  
    983         /** 
    984      *  
    985      */ 
    986         private static class RuleApplicationData implements Serializable { 
    987  
    988                 /** 
    989                  *  
    990                  */ 
    991                 private static final long serialVersionUID = -7559657686755522960L; 
    992  
    993                 private HashMap<Integer, ITask> number2task; 
    994  
    995                 // TODO: We Actually just need number2task here, this structure can be 
    996                 // removed in the future. 
    997                 private HashSet<ITask> uniqueTasks; 
    998  
    999                 private ObjectDistanceSubstitionMatrix submat; 
    1000                  
    1001                 public HashMap<Integer, List<MatchOccurence>> replacedOccurences; 
    1002                  
    1003          
    1004                 public LinkedList<Match> matchseqs; 
    1005  
    1006                 private ArrayList<NumberSequence> numberseqs; 
    1007  
    1008                 private LinkedList<ITask> newTasks; 
    1009  
    1010                 /** 
    1011          *  
    1012          */ 
    1013                 private List<IUserSession> sessions; 
    1014  
    1015                 /** 
    1016          *  
    1017          */ 
    1018                 private boolean detectedAndReplacedTasks; 
    1019  
    1020                 /** 
    1021          *  
    1022          */ 
    1023                 private RuleApplicationResult result; 
    1024  
    1025                 /** 
    1026          *  
    1027          */ 
    1028                 private StopWatch stopWatch; 
    1029  
    1030                 /** 
    1031          *  
    1032          */ 
    1033                 private RuleApplicationData(List<IUserSession> sessions) { 
    1034                         this.sessions = sessions; 
    1035                         numberseqs = new ArrayList<NumberSequence>(); 
    1036                         uniqueTasks = new HashSet<ITask>(); 
    1037                         number2task = new HashMap<Integer, ITask>(); 
    1038                         stopWatch = new StopWatch(); 
    1039                         result = new RuleApplicationResult(); 
    1040                         submat = new ObjectDistanceSubstitionMatrix(6, -3, false); 
    1041                         newTasks = new LinkedList<ITask>(); 
    1042                         this.detectedAndReplacedTasks = true; 
    1043                 } 
    1044  
    1045                 public LinkedList<Match> getMatchseqs() { 
    1046                         return matchseqs; 
    1047                 } 
    1048  
    1049                 private ObjectDistanceSubstitionMatrix getSubmat() { 
    1050                         return submat; 
    1051                 } 
    1052  
    1053                 synchronized private void resetNewlyCreatedTasks() { 
    1054                         uniqueTasks.addAll(newTasks); 
    1055                         newTasks.clear(); 
    1056                 } 
    1057  
    1058                 private void newTaskCreated(ITask task) { 
    1059                         number2task.put(task.getId(), task); 
    1060                         newTasks.add(task); 
    1061                 } 
    1062  
    1063                 /** 
    1064                  * @return the UserSessions as List. 
    1065                  */ 
    1066                 private List<IUserSession> getSessions() { 
    1067                         return sessions; 
    1068                 } 
    1069                  
    1070  
    1071                 public HashMap<Integer, List<MatchOccurence>> getReplacedOccurences() { 
    1072                         return replacedOccurences; 
    1073                 } 
    1074  
    1075                 public void setReplacedOccurences( 
    1076                                 HashMap<Integer, List<MatchOccurence>> replacedOccurences) { 
    1077                         this.replacedOccurences = replacedOccurences; 
    1078                 } 
    1079  
    1080  
    1081                 private HashSet<ITask> getUniqueTasks() { 
    1082                         return uniqueTasks; 
    1083                 } 
    1084  
    1085                 private void setNumberSequences(ArrayList<NumberSequence> numberseqs) { 
    1086                         this.numberseqs = numberseqs; 
    1087                 } 
    1088  
    1089                 private ArrayList<NumberSequence> getNumberSequences() { 
    1090                         return numberseqs; 
    1091                 } 
    1092  
    1093                 private void updateSubstitutionMatrix() { 
    1094                         submat.update(getNewTasks()); 
    1095                         resetNewlyCreatedTasks(); 
    1096                 } 
    1097  
    1098                 /** 
    1099          * 
    1100          */ 
    1101                 private boolean detectedAndReplacedTasks() { 
    1102                         return detectedAndReplacedTasks; 
    1103                 } 
    1104  
    1105                 /** 
    1106                  * @return the result 
    1107                  */ 
    1108                 private RuleApplicationResult getResult() { 
    1109                         return result; 
    1110                 } 
    1111  
    1112                 public LinkedList<ITask> getNewTasks() { 
    1113                         return newTasks; 
    1114                 } 
    1115  
    1116                 /** 
    1117                  * @return the stopWatch 
    1118                  */ 
    1119                 private StopWatch getStopWatch() { 
    1120                         return stopWatch; 
    1121                 } 
    1122  
    1123                 private HashMap<Integer, ITask> getNumber2Task() { 
    1124                         return number2task; 
    1125                 } 
    1126  
     1152        /* 
     1153         * (non-Javadoc) 
     1154         *  
     1155         * @see java.lang.Object#toString() 
     1156         */ 
     1157        @Override 
     1158        public String toString() { 
     1159                return "SequenceForTaskDetectionRuleAlignment"; 
    11271160        } 
    11281161 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskHandlingStrategy.java

    r1551 r1733  
    2424 * <p> 
    2525 * concrete implementation of a symbol strategy required in the creation of a 
    26  * {@link de.ugoe.cs.autoquest.usageprofiles.Trie}. The strategy can be parameterized with a 
    27  * considered task equality. It uses task instance comparators to perform task comparison. 
    28  * It creates task specific symbol maps, which are {@link TaskSymbolIdentityMap} and 
    29  * {@link TaskSymbolBucketedMap} depending on the level of considered task equality. 
     26 * {@link de.ugoe.cs.autoquest.usageprofiles.Trie}. The strategy can be 
     27 * parameterized with a considered task equality. It uses task instance 
     28 * comparators to perform task comparison. It creates task specific symbol maps, 
     29 * which are {@link TaskSymbolIdentityMap} and {@link TaskSymbolBucketedMap} 
     30 * depending on the level of considered task equality. 
    3031 * </p> 
    3132 *  
     
    3334 */ 
    3435public class TaskHandlingStrategy implements SymbolStrategy<ITaskInstance> { 
    35      
    36     /**  */ 
    37     private static final long serialVersionUID = 1L; 
    3836 
    39     /** 
    40      * <p> 
    41      * the level of task equality considered in this task handling strategy 
    42      * </p> 
    43      */ 
    44     private TaskEquality consideredEquality; 
     37        /**  */ 
     38        private static final long serialVersionUID = 1L; 
    4539 
    46     /** 
    47     * <p> 
    48      * the comparator used for task comparisons 
    49     * </p> 
    50     */ 
    51     private TaskInstanceComparator comparator; 
     40        /** 
     41        * <p> 
     42         * the level of task equality considered in this task handling strategy 
     43        * </p> 
     44        */ 
     45        private final TaskEquality consideredEquality; 
    5246 
    53     /** 
    54      * <p> 
    55      * initializes this strategy with a task equality to be considered for task comparisons 
    56      * g</p> 
    57      * 
    58      * @param consideredEquality the task equality to be considered for task comparisons 
    59      */ 
    60     public TaskHandlingStrategy(TaskEquality consideredEquality) { 
    61         this.consideredEquality = consideredEquality; 
    62          
    63         if (this.consideredEquality == TaskEquality.IDENTICAL) { 
    64             comparator = new TaskIdentityComparator(); 
    65         } 
    66         else { 
    67             comparator = new TaskInstanceComparator(this.consideredEquality); 
    68         } 
    69     } 
     47        /** 
     48         * <p> 
     49         * the comparator used for task comparisons 
     50         * </p> 
     51         */ 
     52        private TaskInstanceComparator comparator; 
    7053 
    71     /* (non-Javadoc) 
    72      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#getSymbolComparator() 
    73      */ 
    74     @Override 
    75     public SymbolComparator<ITaskInstance> getSymbolComparator() { 
    76         return comparator; 
    77     } 
     54        /** 
     55         * <p> 
     56         * initializes this strategy with a task equality to be considered for task 
     57         * comparisons g 
     58         * </p> 
     59         * 
     60         * @param consideredEquality 
     61         *            the task equality to be considered for task comparisons 
     62         */ 
     63        public TaskHandlingStrategy(TaskEquality consideredEquality) { 
     64                this.consideredEquality = consideredEquality; 
    7865 
    79     /** 
    80      * <p> 
    81      * convenience method to have a correctly typed return value as alternative to 
    82      * {@link #getSymbolComparator()}; 
    83      * </p> 
    84      */ 
    85     public TaskInstanceComparator getTaskComparator() { 
    86         return comparator; 
    87     } 
     66                if (this.consideredEquality == TaskEquality.IDENTICAL) { 
     67                        comparator = new TaskIdentityComparator(); 
     68                } else { 
     69                        comparator = new TaskInstanceComparator(this.consideredEquality); 
     70                } 
     71        } 
    8872 
    89     /* (non-Javadoc) 
    90      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#createSymbolMap() 
    91      */ 
    92     @Override 
    93     public <V> SymbolMap<ITaskInstance, V> createSymbolMap() { 
    94         if (consideredEquality == TaskEquality.IDENTICAL) { 
    95             return new TaskSymbolIdentityMap<V>(); 
    96         } 
    97         else { 
    98             return new TaskSymbolBucketedMap<V>(comparator); 
    99         } 
    100     } 
     73        /* 
     74         * (non-Javadoc) 
     75         *  
     76         * @see 
     77         * de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#copySymbolMap(SymbolMap 
     78         * ) 
     79         */ 
     80        @Override 
     81        public <V> SymbolMap<ITaskInstance, V> copySymbolMap( 
     82                        SymbolMap<ITaskInstance, V> other) { 
     83                if (consideredEquality == TaskEquality.IDENTICAL) { 
     84                        return new TaskSymbolIdentityMap<V>(other); 
     85                } else { 
     86                        return new TaskSymbolBucketedMap<V>(comparator); 
     87                } 
     88        } 
    10189 
    102     /* (non-Javadoc) 
    103      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#copySymbolMap(SymbolMap) 
    104      */ 
    105     @Override 
    106     public <V> SymbolMap<ITaskInstance, V> copySymbolMap(SymbolMap<ITaskInstance, V> other) { 
    107         if (consideredEquality == TaskEquality.IDENTICAL) { 
    108             return new TaskSymbolIdentityMap<V>(other); 
    109         } 
    110         else { 
    111             return new TaskSymbolBucketedMap<V>(comparator); 
    112         } 
    113     } 
     90        /* 
     91         * (non-Javadoc) 
     92         *  
     93         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#createSymbolMap() 
     94         */ 
     95        @Override 
     96        public <V> SymbolMap<ITaskInstance, V> createSymbolMap() { 
     97                if (consideredEquality == TaskEquality.IDENTICAL) { 
     98                        return new TaskSymbolIdentityMap<V>(); 
     99                } else { 
     100                        return new TaskSymbolBucketedMap<V>(comparator); 
     101                } 
     102        } 
     103 
     104        /* 
     105         * (non-Javadoc) 
     106         *  
     107         * @see 
     108         * de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#getSymbolComparator() 
     109         */ 
     110        @Override 
     111        public SymbolComparator<ITaskInstance> getSymbolComparator() { 
     112                return comparator; 
     113        } 
     114 
     115        /** 
     116         * <p> 
     117         * convenience method to have a correctly typed return value as alternative 
     118         * to {@link #getSymbolComparator()}; 
     119         * </p> 
     120         */ 
     121        public TaskInstanceComparator getTaskComparator() { 
     122                return comparator; 
     123        } 
    114124 
    115125} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskIdentityComparator.java

    r1401 r1733  
    2020/** 
    2121 * <p> 
    22  * symbol comparator implementation for task instances considering to task instances as equal if 
    23  * they refer to the identical task object (comparison of object references). 
     22 * symbol comparator implementation for task instances considering to task 
     23 * instances as equal if they refer to the identical task object (comparison of 
     24 * object references). 
    2425 * </p> 
    2526 */ 
    2627class TaskIdentityComparator extends TaskInstanceComparator { 
    2728 
    28     /**  */ 
    29     private static final long serialVersionUID = 1L; 
    30      
    31     /** 
    32      * <p> 
    33      * initializes the parent class with the task equality {@link TaskEquality#IDENTICAL}. 
    34      * </p> 
    35      */ 
    36     public TaskIdentityComparator() { 
    37         super(TaskEquality.IDENTICAL); 
    38     } 
    39      
    40     /* (non-Javadoc) 
    41      * @see SymbolComparator#equals(Object, Object) 
    42      */ 
    43     @Override 
    44     public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) { 
    45         return taskInstance1.getTask() == taskInstance2.getTask(); 
    46     }         
     29        /**  */ 
     30        private static final long serialVersionUID = 1L; 
     31 
     32        /** 
     33         * <p> 
     34         * initializes the parent class with the task equality 
     35         * {@link TaskEquality#IDENTICAL}. 
     36         * </p> 
     37         */ 
     38        public TaskIdentityComparator() { 
     39                super(TaskEquality.IDENTICAL); 
     40        } 
     41 
     42        /* 
     43         * (non-Javadoc) 
     44         *  
     45         * @see SymbolComparator#equals(Object, Object) 
     46         */ 
     47        @Override 
     48        public boolean equals(ITaskInstance taskInstance1, 
     49                        ITaskInstance taskInstance2) { 
     50                return taskInstance1.getTask() == taskInstance2.getTask(); 
     51        } 
    4752 
    4853} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskInstanceComparator.java

    r1401 r1733  
    2727/** 
    2828 * <p> 
    29  * implementation of a symbol comparator for task instances. Internally, it uses comparison buffers 
    30  * to prevent comparing two tasks or task instances several times. It internally instantiates 
    31  * comparers being the implementation strategy of the comparisons required for a specific level 
    32  * of task equality. The comparers internally use the {@link TaskEqualityRuleManager} for 
    33  * performing comparisons. 
     29 * implementation of a symbol comparator for task instances. Internally, it uses 
     30 * comparison buffers to prevent comparing two tasks or task instances several 
     31 * times. It internally instantiates comparers being the implementation strategy 
     32 * of the comparisons required for a specific level of task equality. The 
     33 * comparers internally use the {@link TaskEqualityRuleManager} for performing 
     34 * comparisons. 
    3435 * </p> 
    3536 */ 
    3637public class TaskInstanceComparator implements SymbolComparator<ITaskInstance> { 
    37      
    38     /**  */ 
    39     private static final long serialVersionUID = 1L; 
    40      
    41     /** 
    42      * the maximum size of the internal buffer used for storing comparison results 
    43      */ 
    44     private static final int MAX_BUFFER_SIZE = 2 * 1024 * 1024; 
    45  
    46     /** 
    47      * the considered level of task equality 
    48      */ 
    49     private TaskEquality minimalTaskEquality; 
    50  
    51     /** 
    52      * the comparer used internally for comparing two tasks 
    53      */ 
    54     private transient Comparer comparer; 
    55  
    56     /** 
    57      * the comparer used for comparing two tasks on the lexical level 
    58      */ 
    59     private transient Comparer lexicalComparer; 
    60  
    61     /** 
    62      * internal buffer used for storing comparison results 
    63      */ 
    64     private transient HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>(); 
    65  
    66     /** 
    67      * internal buffer used for storing comparison results only for lexical comparisons 
    68      */ 
    69     private transient HashMap<Long, Boolean> lexicalEqualityBuffer; 
    70  
    71     /** 
    72      * <p> 
    73      * initializes the comparator with a considered task equality level 
    74      * </p> 
    75      *  
    76      * @param minimalTaskEquality the considered task equality level 
    77      */ 
    78     public TaskInstanceComparator(TaskEquality minimalTaskEquality) { 
    79         this.minimalTaskEquality = minimalTaskEquality; 
    80         init(); 
    81     } 
    82  
    83     /* (non-Javadoc) 
    84      * @see SymbolComparator#equals(Object, Object) 
    85      */ 
    86     @Override 
    87     public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) { 
    88         return equals(taskInstance1.getTask(), taskInstance2.getTask()); 
    89     }         
    90  
    91     /** 
    92      * <p> 
    93      * returns true, if this comparator considers the provided tasks as equal, false else 
    94      * </p> 
    95      *  
    96      * @param task1 the first task to compare 
    97      * @param task2 the second task to compare 
    98      *  
    99      * @return as described 
    100      */ 
    101     public boolean equals(ITask task1, ITask task2) { 
    102         Boolean result; 
    103          
    104         if (task1 != task2) { 
    105             //if ((task1 instanceof IEventTask) && (task2 instanceof IEventTask)) { 
    106                 long key = ((long) System.identityHashCode(task1)) << 32; 
    107                 key += System.identityHashCode(task2); 
    108              
    109                 result = equalityBuffer.get(key); 
    110              
    111                 if (result == null) { 
    112                     result = comparer.compare(task1, task2); 
    113                      
    114                     if (equalityBuffer.size() < MAX_BUFFER_SIZE) { 
    115                         equalityBuffer.put(key, result); 
    116                     } 
    117                 } 
    118             /*} 
    119             else { 
    120                 result = false; 
    121             }*/ 
    122         } 
    123         else { 
    124             result = true; 
    125         } 
    126          
    127         return result; 
    128     } 
    129  
    130     /** 
    131      * <p> 
    132      * returns true, if this comparator considers the provided tasks as lexically equal, false else 
    133      * </p> 
    134      *  
    135      * @param task1 the first task to compare 
    136      * @param task2 the second task to compare 
    137      *  
    138      * @return as described 
    139      */ 
    140     public boolean areLexicallyEqual(ITask task1, ITask task2) { 
    141         Boolean result; 
    142          
    143         if (task1 != task2) { 
    144             long key = ((long) System.identityHashCode(task1)) << 32; 
    145             key += System.identityHashCode(task2); 
    146              
    147             result = lexicalEqualityBuffer.get(key); 
    148              
    149             if (result == null) { 
    150                 result = lexicalComparer.compare(task1, task2); 
    151                 if (equalityBuffer.size() < MAX_BUFFER_SIZE) { 
    152                     lexicalEqualityBuffer.put(key, result); 
    153                 } 
    154             } 
    155         } 
    156         else { 
    157             result = true; 
    158         } 
    159          
    160         return result; 
    161     } 
    162      
    163     /** 
    164      * <p> 
    165      * can be called externally to clear the internal comparison buffers 
    166      * </p> 
    167      */ 
    168     public void clearBuffers() { 
    169         equalityBuffer.clear(); 
    170         init(); 
    171     } 
    172      
    173     /** 
    174      * <p> 
    175      * initializes the comparator with comparers depending on the different comparison levels as 
    176      * well as with the required comparison buffers. Comparers and buffers for lexical comparison 
    177      * may be reused if the considered equality level is also lexical. 
    178      * </p> 
    179      */ 
    180     private void init() { 
    181         if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) { 
    182             comparer = new LexicalComparer(); 
    183         } 
    184         else if (minimalTaskEquality == TaskEquality.SYNTACTICALLY_EQUAL) { 
    185             comparer = new SyntacticalComparer(); 
    186         } 
    187         else if (minimalTaskEquality == TaskEquality.SEMANTICALLY_EQUAL) { 
    188             comparer = new SemanticalComparer(); 
    189         } 
    190         else { 
    191             comparer = new DefaultComparer(this.minimalTaskEquality); 
    192         } 
    193          
    194         if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) { 
    195             lexicalComparer = comparer; 
    196             lexicalEqualityBuffer = equalityBuffer; 
    197         } 
    198         else { 
    199             lexicalComparer = new LexicalComparer(); 
    200             lexicalEqualityBuffer = new HashMap<Long, Boolean>(); 
    201         } 
    202     } 
    203      
    204     /** 
    205      * <p> 
    206      * deserialize this object and reinitialize the buffers 
    207      * </p> 
    208      */ 
    209     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 
    210         in.defaultReadObject(); 
    211         init(); 
    212     } 
    213  
    214  
    215     /** 
    216      * <p> 
    217      * interface for internally used comparers containing only a compare method 
    218      * </p> 
    219      */ 
    220     private static interface Comparer { 
    221          
    222         /** 
    223          * <p> 
    224          * returns true, if this comparator considers the provided tasks as equal, false else 
    225          * </p> 
    226          *  
    227          * @param task1 the first task to compare 
    228          * @param task2 the second task to compare 
    229          *  
    230          * @return as described 
    231          */ 
    232         boolean compare(ITask task1, ITask task2); 
    233     } 
    234  
    235     /** 
    236      * <p> 
    237      * comparer that performs comparisons only on the lexical level 
    238      * </p> 
    239      */ 
    240     private static class LexicalComparer implements Comparer { 
    241          
    242         /* (non-Javadoc) 
    243          * @see Comparer#compare(ITask, ITask) 
    244          */ 
    245         public boolean compare(ITask task1, ITask task2) { 
    246             return TaskEqualityRuleManager.getInstance().areLexicallyEqual(task1, task2); 
    247         } 
    248     } 
    249  
    250     /** 
    251      * <p> 
    252      * comparer that performs comparisons only on the syntactical level 
    253      * </p> 
    254      *  
    255      */ 
    256     private static class SyntacticalComparer implements Comparer { 
    257          
    258         /* (non-Javadoc) 
    259          * @see Comparer#compare(ITask, ITask) 
    260          */ 
    261         public boolean compare(ITask task1, ITask task2) { 
    262             return TaskEqualityRuleManager.getInstance().areSyntacticallyEqual(task1, task2); 
    263         } 
    264     } 
    265  
    266     /** 
    267      * <p> 
    268      * comparer that performs comparisons only on the semantical level 
    269      * </p> 
    270      */ 
    271     private static class SemanticalComparer implements Comparer { 
    272          
    273         /* (non-Javadoc) 
    274          * @see Comparer#compare(ITask, ITask) 
    275          */ 
    276         public boolean compare(ITask task1, ITask task2) { 
    277             return TaskEqualityRuleManager.getInstance().areSemanticallyEqual(task1, task2); 
    278         } 
    279     } 
    280  
    281     /** 
    282      * <p> 
    283      * comparer that performs comparisons only on the provided level 
    284      * </p> 
    285      */ 
    286     private static class DefaultComparer implements Comparer { 
    287          
    288         /** 
    289          * <p> 
    290          * the minimal task equality considered by this comparer 
    291          * </p> 
    292          */ 
    293         private TaskEquality minimalTaskEquality; 
    294          
    295         /** 
    296          * <p> 
    297          * initializes this comparer with the task equality to be considered 
    298          * </p> 
    299          */ 
    300         public DefaultComparer(TaskEquality minimalTaskEquality) { 
    301            this.minimalTaskEquality = minimalTaskEquality; 
    302         } 
    303          
    304         /* (non-Javadoc) 
    305          * @see Comparer#compare(ITask, ITask) 
    306          */ 
    307         public boolean compare(ITask task1, ITask task2) { 
    308             return TaskEqualityRuleManager.getInstance().areAtLeastEqual 
    309                 (task1, task2, minimalTaskEquality); 
    310         } 
    311     } 
     38 
     39        /** 
     40         * <p> 
     41         * interface for internally used comparers containing only a compare method 
     42         * </p> 
     43         */ 
     44        private static interface Comparer { 
     45 
     46                /** 
     47                 * <p> 
     48                 * returns true, if this comparator considers the provided tasks as 
     49                 * equal, false else 
     50                 * </p> 
     51                 *  
     52                 * @param task1 
     53                 *            the first task to compare 
     54                 * @param task2 
     55                 *            the second task to compare 
     56                 *  
     57                 * @return as described 
     58                 */ 
     59                boolean compare(ITask task1, ITask task2); 
     60        } 
     61 
     62        /** 
     63         * <p> 
     64         * comparer that performs comparisons only on the provided level 
     65         * </p> 
     66         */ 
     67        private static class DefaultComparer implements Comparer { 
     68 
     69                /** 
     70                 * <p> 
     71                 * the minimal task equality considered by this comparer 
     72                 * </p> 
     73                 */ 
     74                private final TaskEquality minimalTaskEquality; 
     75 
     76                /** 
     77                 * <p> 
     78                 * initializes this comparer with the task equality to be considered 
     79                 * </p> 
     80                 */ 
     81                public DefaultComparer(TaskEquality minimalTaskEquality) { 
     82                        this.minimalTaskEquality = minimalTaskEquality; 
     83                } 
     84 
     85                /* 
     86                 * (non-Javadoc) 
     87                 *  
     88                 * @see Comparer#compare(ITask, ITask) 
     89                 */ 
     90                @Override 
     91                public boolean compare(ITask task1, ITask task2) { 
     92                        return TaskEqualityRuleManager.getInstance().areAtLeastEqual(task1, 
     93                                        task2, minimalTaskEquality); 
     94                } 
     95        } 
     96 
     97        /** 
     98         * <p> 
     99         * comparer that performs comparisons only on the lexical level 
     100         * </p> 
     101         */ 
     102        private static class LexicalComparer implements Comparer { 
     103 
     104                /* 
     105                 * (non-Javadoc) 
     106                 *  
     107                 * @see Comparer#compare(ITask, ITask) 
     108                 */ 
     109                @Override 
     110                public boolean compare(ITask task1, ITask task2) { 
     111                        return TaskEqualityRuleManager.getInstance().areLexicallyEqual( 
     112                                        task1, task2); 
     113                } 
     114        } 
     115 
     116        /** 
     117         * <p> 
     118         * comparer that performs comparisons only on the semantical level 
     119         * </p> 
     120         */ 
     121        private static class SemanticalComparer implements Comparer { 
     122 
     123                /* 
     124                 * (non-Javadoc) 
     125                 *  
     126                 * @see Comparer#compare(ITask, ITask) 
     127                 */ 
     128                @Override 
     129                public boolean compare(ITask task1, ITask task2) { 
     130                        return TaskEqualityRuleManager.getInstance().areSemanticallyEqual( 
     131                                        task1, task2); 
     132                } 
     133        } 
     134 
     135        /** 
     136         * <p> 
     137         * comparer that performs comparisons only on the syntactical level 
     138         * </p> 
     139         *  
     140         */ 
     141        private static class SyntacticalComparer implements Comparer { 
     142 
     143                /* 
     144                 * (non-Javadoc) 
     145                 *  
     146                 * @see Comparer#compare(ITask, ITask) 
     147                 */ 
     148                @Override 
     149                public boolean compare(ITask task1, ITask task2) { 
     150                        return TaskEqualityRuleManager.getInstance().areSyntacticallyEqual( 
     151                                        task1, task2); 
     152                } 
     153        } 
     154 
     155        /**  */ 
     156        private static final long serialVersionUID = 1L; 
     157 
     158        /** 
     159         * the maximum size of the internal buffer used for storing comparison 
     160         * results 
     161         */ 
     162        private static final int MAX_BUFFER_SIZE = 2 * 1024 * 1024; 
     163 
     164        /** 
     165         * the considered level of task equality 
     166         */ 
     167        private final TaskEquality minimalTaskEquality; 
     168 
     169        /** 
     170         * the comparer used internally for comparing two tasks 
     171         */ 
     172        private transient Comparer comparer; 
     173 
     174        /** 
     175         * the comparer used for comparing two tasks on the lexical level 
     176         */ 
     177        private transient Comparer lexicalComparer; 
     178 
     179        /** 
     180         * internal buffer used for storing comparison results 
     181         */ 
     182        private transient HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>(); 
     183 
     184        /** 
     185         * internal buffer used for storing comparison results only for lexical 
     186         * comparisons 
     187         */ 
     188        private transient HashMap<Long, Boolean> lexicalEqualityBuffer; 
     189 
     190        /** 
     191         * <p> 
     192         * initializes the comparator with a considered task equality level 
     193         * </p> 
     194         *  
     195         * @param minimalTaskEquality 
     196         *            the considered task equality level 
     197         */ 
     198        public TaskInstanceComparator(TaskEquality minimalTaskEquality) { 
     199                this.minimalTaskEquality = minimalTaskEquality; 
     200                init(); 
     201        } 
     202 
     203        /** 
     204         * <p> 
     205         * returns true, if this comparator considers the provided tasks as 
     206         * lexically equal, false else 
     207         * </p> 
     208         *  
     209         * @param task1 
     210         *            the first task to compare 
     211         * @param task2 
     212         *            the second task to compare 
     213         *  
     214         * @return as described 
     215         */ 
     216        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     217                Boolean result; 
     218 
     219                if (task1 != task2) { 
     220                        long key = ((long) System.identityHashCode(task1)) << 32; 
     221                        key += System.identityHashCode(task2); 
     222 
     223                        result = lexicalEqualityBuffer.get(key); 
     224 
     225                        if (result == null) { 
     226                                result = lexicalComparer.compare(task1, task2); 
     227                                if (equalityBuffer.size() < MAX_BUFFER_SIZE) { 
     228                                        lexicalEqualityBuffer.put(key, result); 
     229                                } 
     230                        } 
     231                } else { 
     232                        result = true; 
     233                } 
     234 
     235                return result; 
     236        } 
     237 
     238        /** 
     239         * <p> 
     240         * can be called externally to clear the internal comparison buffers 
     241         * </p> 
     242         */ 
     243        public void clearBuffers() { 
     244                equalityBuffer.clear(); 
     245                init(); 
     246        } 
     247 
     248        /** 
     249         * <p> 
     250         * returns true, if this comparator considers the provided tasks as equal, 
     251         * false else 
     252         * </p> 
     253         *  
     254         * @param task1 
     255         *            the first task to compare 
     256         * @param task2 
     257         *            the second task to compare 
     258         *  
     259         * @return as described 
     260         */ 
     261        public boolean equals(ITask task1, ITask task2) { 
     262                Boolean result; 
     263 
     264                if (task1 != task2) { 
     265                        // if ((task1 instanceof IEventTask) && (task2 instanceof 
     266                        // IEventTask)) { 
     267                        long key = ((long) System.identityHashCode(task1)) << 32; 
     268                        key += System.identityHashCode(task2); 
     269 
     270                        result = equalityBuffer.get(key); 
     271 
     272                        if (result == null) { 
     273                                result = comparer.compare(task1, task2); 
     274 
     275                                if (equalityBuffer.size() < MAX_BUFFER_SIZE) { 
     276                                        equalityBuffer.put(key, result); 
     277                                } 
     278                        } 
     279                        /* 
     280                         * } else { result = false; } 
     281                         */ 
     282                } else { 
     283                        result = true; 
     284                } 
     285 
     286                return result; 
     287        } 
     288 
     289        /* 
     290         * (non-Javadoc) 
     291         *  
     292         * @see SymbolComparator#equals(Object, Object) 
     293         */ 
     294        @Override 
     295        public boolean equals(ITaskInstance taskInstance1, 
     296                        ITaskInstance taskInstance2) { 
     297                return equals(taskInstance1.getTask(), taskInstance2.getTask()); 
     298        } 
     299 
     300        /** 
     301         * <p> 
     302         * initializes the comparator with comparers depending on the different 
     303         * comparison levels as well as with the required comparison buffers. 
     304         * Comparers and buffers for lexical comparison may be reused if the 
     305         * considered equality level is also lexical. 
     306         * </p> 
     307         */ 
     308        private void init() { 
     309                if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) { 
     310                        comparer = new LexicalComparer(); 
     311                } else if (minimalTaskEquality == TaskEquality.SYNTACTICALLY_EQUAL) { 
     312                        comparer = new SyntacticalComparer(); 
     313                } else if (minimalTaskEquality == TaskEquality.SEMANTICALLY_EQUAL) { 
     314                        comparer = new SemanticalComparer(); 
     315                } else { 
     316                        comparer = new DefaultComparer(this.minimalTaskEquality); 
     317                } 
     318 
     319                if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) { 
     320                        lexicalComparer = comparer; 
     321                        lexicalEqualityBuffer = equalityBuffer; 
     322                } else { 
     323                        lexicalComparer = new LexicalComparer(); 
     324                        lexicalEqualityBuffer = new HashMap<Long, Boolean>(); 
     325                } 
     326        } 
     327 
     328        /** 
     329         * <p> 
     330         * deserialize this object and reinitialize the buffers 
     331         * </p> 
     332         */ 
     333        private void readObject(ObjectInputStream in) throws IOException, 
     334                        ClassNotFoundException { 
     335                in.defaultReadObject(); 
     336                init(); 
     337        } 
    312338 
    313339} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskInstanceTrie.java

    r1401 r1733  
    2929/** 
    3030 * <p> 
    31  * This trie implementation is a performance optimization for generating task trees. It does not 
    32  * create a full trie but adds only those subsequences having a chance of occurring most often. 
    33  * For this, it initially counts the number of occurrences of each task instance. Then, during 
    34  * training, it regularly determines the number of the currently most often occurring sequence. If 
    35  * this number is higher than the count of a task instance to be trained, the task instance is 
    36  * skipped the not added to the trie. 
     31 * This trie implementation is a performance optimization for generating task 
     32 * trees. It does not create a full trie but adds only those subsequences having 
     33 * a chance of occurring most often. For this, it initially counts the number of 
     34 * occurrences of each task instance. Then, during training, it regularly 
     35 * determines the number of the currently most often occurring sequence. If this 
     36 * number is higher than the count of a task instance to be trained, the task 
     37 * instance is skipped the not added to the trie. 
    3738 * </p> 
    3839 *  
     
    4142class TaskInstanceTrie extends Trie<ITaskInstance> { 
    4243 
    43     /**  */ 
    44     private static final long serialVersionUID = 1L; 
    45  
    46     /** 
    47      * <p> 
    48      * the task handling strategy to be used for comparing tasks 
    49      * </p> 
    50      */ 
    51     private TaskHandlingStrategy taskStrategy; 
    52      
    53     /** 
    54      * <p> 
    55      * instantiated the trie with the task handling strategy to be used 
    56      * </p> 
    57      * 
    58      * @param taskStrategy the task handling strategy to be used for comparing tasks 
    59      */ 
    60     public TaskInstanceTrie(TaskHandlingStrategy taskStrategy) { 
    61         super(taskStrategy); 
    62         this.taskStrategy = taskStrategy; 
    63     } 
    64  
    65     /** 
    66      * <p> 
    67      * trains this trie with the provided user sessions up to the provided maximum depth using 
    68      * the optimization described in the description of this class. 
    69      * </p> 
    70      *  
    71      * @param userSessions the sessions for which this trie is to be trained 
    72      * @param maxOrder     the depth of the trie 
    73      */ 
    74     public void trainSessions(List<IUserSession> userSessions, int maxOrder) { 
    75         if (maxOrder < 1) { 
    76             return; 
    77         } 
    78          
    79         SymbolMap<ITaskInstance, Counter> equalTaskInstancesMap = 
    80             taskStrategy.createSymbolMap(); 
    81          
    82         Map<ITask, Counter> instanceCountMap = new HashMap<ITask, Counter>(); 
    83          
    84         System.out.println("preparing training"); 
    85         int noOfTaskInstances = 0; 
    86         for (IUserSession session : userSessions) { 
    87             for (ITaskInstance taskInstance : session) { 
    88                 Counter counter = equalTaskInstancesMap.getValue(taskInstance); 
    89                  
    90                 if (counter == null) { 
    91                     counter = new Counter(); 
    92                     equalTaskInstancesMap.addSymbol(taskInstance, counter); 
    93                 } 
    94                  
    95                 counter.count++; 
    96                 instanceCountMap.put(taskInstance.getTask(), counter); 
    97                  
    98                 noOfTaskInstances++; 
    99             } 
    100         } 
    101          
    102         System.out.println("performing training of " + noOfTaskInstances + " task instances"); 
    103         Counter processedTaskInstances = new Counter(); 
    104         int counterRecheckAt = noOfTaskInstances / 10; // recheck the maximum count after each 
    105                                                        // 10% of processed task instances 
    106         for (IUserSession session : userSessions) { 
    107             train(session, maxOrder, instanceCountMap, processedTaskInstances, counterRecheckAt); 
    108         }       
    109          
    110         updateKnownSymbols(); 
    111     } 
    112      
    113     /* (non-Javadoc) 
    114      * @see de.ugoe.cs.autoquest.usageprofiles.Trie#equals(java.lang.Object) 
    115      */ 
    116     @Override 
    117     public boolean equals(Object other) { 
    118         if (this == other) { 
    119             return true; 
    120         } 
    121         else if (other instanceof TaskInstanceTrie) { 
    122             return super.equals(other); 
    123         } 
    124         else { 
    125             return false; 
    126         } 
    127     } 
    128  
    129     /* (non-Javadoc) 
    130      * @see de.ugoe.cs.autoquest.usageprofiles.Trie#hashCode() 
    131      */ 
    132     @Override 
    133     public int hashCode() { 
    134         return super.hashCode(); 
    135     } 
    136  
    137     /** 
    138      * <p> 
    139      * internally used convenience method for implementing the training optimization 
    140      * </p> 
    141      */ 
    142     private void train(IUserSession        userSession, 
    143                        int                 maxOrder, 
    144                        Map<ITask, Counter> taskInstanceCountMap, 
    145                        Counter             processedTaskInstances, 
    146                        int                 counterRecheckAt) 
    147     { 
    148         List<ITaskInstance> subsequence = new LinkedList<ITaskInstance>(); 
    149          
    150         int sequenceMaxCount = 0; 
    151          
    152         for (ITaskInstance currentTaskInstance : userSession) { 
    153              
    154             int occurrenceCount = taskInstanceCountMap.get(currentTaskInstance.getTask()).count; 
    155              
    156             if (processedTaskInstances.count >= counterRecheckAt) { 
    157                 sequenceMaxCount = getCurrentSequenceMaxCount(); 
    158                 processedTaskInstances.count = 0; 
    159             } 
    160              
    161             if (occurrenceCount < sequenceMaxCount) { 
    162                 // this task instance does not need to be considered, as it occurs not often enough 
    163                 // to be part of a sequence, that occurs most often. Therefore train all remaining 
    164                 // sequences so far and go on, until the next useful sequence is found. 
    165                  
    166                 while (subsequence.size() > 1) { 
    167                     add(subsequence); 
    168                     subsequence.remove(0); 
    169                 } 
    170                  
    171                 subsequence.clear(); 
    172             } 
    173             else { 
    174                 subsequence.add(currentTaskInstance); 
    175  
    176                 if (subsequence.size() == maxOrder) { 
    177                     add(subsequence); 
    178                     subsequence.remove(0); 
    179                 } 
    180             } 
    181              
    182             processedTaskInstances.count++; 
    183         } 
    184          
    185         // add shorter remaining subsequences, if any 
    186         while (subsequence.size() > 1) { 
    187             add(subsequence); 
    188             subsequence.remove(0); 
    189         } 
    190     } 
    191  
    192     /** 
    193      * <p> 
    194      * determines the current maximum count of sequences of a minimal length of two. Task instances 
    195      * occuring more seldom do not have to be considered anymore 
    196      * </p> 
    197      * 
    198      * @return the current maximum count of sequences of a minimal length of two 
    199      */ 
    200     private int getCurrentSequenceMaxCount() { 
    201         MaxSequenceCountFinder processor = new MaxSequenceCountFinder(); 
    202         super.process(processor); 
    203         return processor.getMaxCount(); 
    204     } 
    205  
    206     /** 
    207      * <p> 
    208      * trie processor identifying the current maximum count of sequences of a minimal length of two 
    209      * </p> 
    210      *  
    211      * @author Patrick Harms 
    212      */ 
    213     private static class MaxSequenceCountFinder implements TrieProcessor<ITaskInstance> { 
    214          
    215         /** 
    216          * <p> 
    217          * the current maximum count 
    218          * </p> 
    219          */ 
    220         private int currentCount = 0; 
    221          
    222         /* (non-Javadoc) 
    223          * @see de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, int) 
    224          */ 
    225         @Override 
    226         public TrieProcessor.Result process(List<ITaskInstance> foundTask, int count) { 
    227             if (foundTask.size() == 2) { 
    228                 this.currentCount = Math.max(this.currentCount, count); 
    229                  
    230                 // do not consider children 
    231                 return TrieProcessor.Result.SKIP_NODE; 
    232             } 
    233             else { 
    234                 return TrieProcessor.Result.CONTINUE; 
    235             } 
    236         } 
    237  
    238         /** 
    239          * <p> 
    240          * returns the current maximum count 
    241          * </p> 
    242          */ 
    243         private int getMaxCount() { 
    244             return currentCount; 
    245         } 
    246  
    247     } 
    248      
    249     /** 
    250      * <p> 
    251      * counter object to be able to call something by the counters reference 
    252      * </p> 
    253      *  
    254      * @author Patrick Harms 
    255      */ 
    256     private static class Counter { 
    257         int count = 0; 
    258     } 
    259          
     44        /** 
     45         * <p> 
     46         * counter object to be able to call something by the counters reference 
     47         * </p> 
     48         *  
     49         * @author Patrick Harms 
     50         */ 
     51        private static class Counter { 
     52                int count = 0; 
     53        } 
     54 
     55        /** 
     56         * <p> 
     57         * trie processor identifying the current maximum count of sequences of a 
     58         * minimal length of two 
     59         * </p> 
     60         *  
     61         * @author Patrick Harms 
     62         */ 
     63        private static class MaxSequenceCountFinder implements 
     64                        TrieProcessor<ITaskInstance> { 
     65 
     66                /** 
     67                 * <p> 
     68                 * the current maximum count 
     69                 * </p> 
     70                 */ 
     71                private int currentCount = 0; 
     72 
     73                /** 
     74                 * <p> 
     75                 * returns the current maximum count 
     76                 * </p> 
     77                 */ 
     78                private int getMaxCount() { 
     79                        return currentCount; 
     80                } 
     81 
     82                /* 
     83                 * (non-Javadoc) 
     84                 *  
     85                 * @see 
     86                 * de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util 
     87                 * .List, int) 
     88                 */ 
     89                @Override 
     90                public TrieProcessor.Result process(List<ITaskInstance> foundTask, 
     91                                int count) { 
     92                        if (foundTask.size() == 2) { 
     93                                this.currentCount = Math.max(this.currentCount, count); 
     94 
     95                                // do not consider children 
     96                                return TrieProcessor.Result.SKIP_NODE; 
     97                        } else { 
     98                                return TrieProcessor.Result.CONTINUE; 
     99                        } 
     100                } 
     101 
     102        } 
     103 
     104        /**  */ 
     105        private static final long serialVersionUID = 1L; 
     106 
     107        /** 
     108         * <p> 
     109         * the task handling strategy to be used for comparing tasks 
     110         * </p> 
     111         */ 
     112        private final TaskHandlingStrategy taskStrategy; 
     113 
     114        /** 
     115         * <p> 
     116         * instantiated the trie with the task handling strategy to be used 
     117         * </p> 
     118         * 
     119         * @param taskStrategy 
     120         *            the task handling strategy to be used for comparing tasks 
     121         */ 
     122        public TaskInstanceTrie(TaskHandlingStrategy taskStrategy) { 
     123                super(taskStrategy); 
     124                this.taskStrategy = taskStrategy; 
     125        } 
     126 
     127        /* 
     128         * (non-Javadoc) 
     129         *  
     130         * @see de.ugoe.cs.autoquest.usageprofiles.Trie#equals(java.lang.Object) 
     131         */ 
     132        @Override 
     133        public boolean equals(Object other) { 
     134                if (this == other) { 
     135                        return true; 
     136                } else if (other instanceof TaskInstanceTrie) { 
     137                        return super.equals(other); 
     138                } else { 
     139                        return false; 
     140                } 
     141        } 
     142 
     143        /** 
     144         * <p> 
     145         * determines the current maximum count of sequences of a minimal length of 
     146         * two. Task instances occuring more seldom do not have to be considered 
     147         * anymore 
     148         * </p> 
     149         * 
     150         * @return the current maximum count of sequences of a minimal length of two 
     151         */ 
     152        private int getCurrentSequenceMaxCount() { 
     153                final MaxSequenceCountFinder processor = new MaxSequenceCountFinder(); 
     154                super.process(processor); 
     155                return processor.getMaxCount(); 
     156        } 
     157 
     158        /* 
     159         * (non-Javadoc) 
     160         *  
     161         * @see de.ugoe.cs.autoquest.usageprofiles.Trie#hashCode() 
     162         */ 
     163        @Override 
     164        public int hashCode() { 
     165                return super.hashCode(); 
     166        } 
     167 
     168        /** 
     169         * <p> 
     170         * internally used convenience method for implementing the training 
     171         * optimization 
     172         * </p> 
     173         */ 
     174        private void train(IUserSession userSession, int maxOrder, 
     175                        Map<ITask, Counter> taskInstanceCountMap, 
     176                        Counter processedTaskInstances, int counterRecheckAt) { 
     177                final List<ITaskInstance> subsequence = new LinkedList<ITaskInstance>(); 
     178 
     179                int sequenceMaxCount = 0; 
     180 
     181                for (final ITaskInstance currentTaskInstance : userSession) { 
     182 
     183                        final int occurrenceCount = taskInstanceCountMap 
     184                                        .get(currentTaskInstance.getTask()).count; 
     185 
     186                        if (processedTaskInstances.count >= counterRecheckAt) { 
     187                                sequenceMaxCount = getCurrentSequenceMaxCount(); 
     188                                processedTaskInstances.count = 0; 
     189                        } 
     190 
     191                        if (occurrenceCount < sequenceMaxCount) { 
     192                                // this task instance does not need to be considered, as it 
     193                                // occurs not often enough 
     194                                // to be part of a sequence, that occurs most often. Therefore 
     195                                // train all remaining 
     196                                // sequences so far and go on, until the next useful sequence is 
     197                                // found. 
     198 
     199                                while (subsequence.size() > 1) { 
     200                                        add(subsequence); 
     201                                        subsequence.remove(0); 
     202                                } 
     203 
     204                                subsequence.clear(); 
     205                        } else { 
     206                                subsequence.add(currentTaskInstance); 
     207 
     208                                if (subsequence.size() == maxOrder) { 
     209                                        add(subsequence); 
     210                                        subsequence.remove(0); 
     211                                } 
     212                        } 
     213 
     214                        processedTaskInstances.count++; 
     215                } 
     216 
     217                // add shorter remaining subsequences, if any 
     218                while (subsequence.size() > 1) { 
     219                        add(subsequence); 
     220                        subsequence.remove(0); 
     221                } 
     222        } 
     223 
     224        /** 
     225         * <p> 
     226         * trains this trie with the provided user sessions up to the provided 
     227         * maximum depth using the optimization described in the description of this 
     228         * class. 
     229         * </p> 
     230         *  
     231         * @param userSessions 
     232         *            the sessions for which this trie is to be trained 
     233         * @param maxOrder 
     234         *            the depth of the trie 
     235         */ 
     236        public void trainSessions(List<IUserSession> userSessions, int maxOrder) { 
     237                if (maxOrder < 1) { 
     238                        return; 
     239                } 
     240 
     241                final SymbolMap<ITaskInstance, Counter> equalTaskInstancesMap = taskStrategy 
     242                                .createSymbolMap(); 
     243 
     244                final Map<ITask, Counter> instanceCountMap = new HashMap<ITask, Counter>(); 
     245 
     246                System.out.println("preparing training"); 
     247                int noOfTaskInstances = 0; 
     248                for (final IUserSession session : userSessions) { 
     249                        for (final ITaskInstance taskInstance : session) { 
     250                                Counter counter = equalTaskInstancesMap.getValue(taskInstance); 
     251 
     252                                if (counter == null) { 
     253                                        counter = new Counter(); 
     254                                        equalTaskInstancesMap.addSymbol(taskInstance, counter); 
     255                                } 
     256 
     257                                counter.count++; 
     258                                instanceCountMap.put(taskInstance.getTask(), counter); 
     259 
     260                                noOfTaskInstances++; 
     261                        } 
     262                } 
     263 
     264                System.out.println("performing training of " + noOfTaskInstances 
     265                                + " task instances"); 
     266                final Counter processedTaskInstances = new Counter(); 
     267                final int counterRecheckAt = noOfTaskInstances / 10; // recheck the 
     268                                                                                                                                // maximum count 
     269                                                                                                                                // after each 
     270                // 10% of processed task instances 
     271                for (final IUserSession session : userSessions) { 
     272                        train(session, maxOrder, instanceCountMap, processedTaskInstances, 
     273                                        counterRecheckAt); 
     274                } 
     275 
     276                updateKnownSymbols(); 
     277        } 
     278 
    260279} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskSymbolBucketedMap.java

    r1408 r1733  
    3636/** 
    3737 * <p> 
    38  * This class is a data structure for holding task instances in form of a symbol map. It is more 
    39  * efficient than a simple list. This data structure can be used with a comparator to adapt the 
    40  * effective list behavior and to define the equals strategy for comparing task instances. After a 
    41  * certain size ({@link #MAX_LIST_SIZE}), the map creates an index consisting of buckets of similar 
    42  * task instances. This allows searching for task instances in a more efficient order as the search 
    43  * can start in the most appropriate of the internal buckets. 
     38 * This class is a data structure for holding task instances in form of a symbol 
     39 * map. It is more efficient than a simple list. This data structure can be used 
     40 * with a comparator to adapt the effective list behavior and to define the 
     41 * equals strategy for comparing task instances. After a certain size ( 
     42 * {@link #MAX_LIST_SIZE}), the map creates an index consisting of buckets of 
     43 * similar task instances. This allows searching for task instances in a more 
     44 * efficient order as the search can start in the most appropriate of the 
     45 * internal buckets. 
    4446 * </p> 
    4547 * <p> 
    46  * The class is called a map, although it is not. It may contain the same task instances as 
    47  * separate keys. This implementation is done for performance improvements. If it is required to 
    48  * really assure, that a key exists only once, then each call to the 
    49  * {@link #addSymbol(Object, Object)} method should be done only, if the 
    50  * {@link #containsSymbol(Object)} method for the same symbol returns false. 
     48 * The class is called a map, although it is not. It may contain the same task 
     49 * instances as separate keys. This implementation is done for performance 
     50 * improvements. If it is required to really assure, that a key exists only 
     51 * once, then each call to the {@link #addSymbol(Object, Object)} method should 
     52 * be done only, if the {@link #containsSymbol(Object)} method for the same 
     53 * symbol returns false. 
    5154 * </p> 
    5255 *  
     
    5659 * @param <V> 
    5760 */ 
    58 class TaskSymbolBucketedMap<V> implements SymbolMap<ITaskInstance, V>, Serializable { 
    59  
    60     /** 
    61      * <p> 
    62      * default serial version UID 
    63      * </p> 
    64      */ 
    65     private static final long serialVersionUID = 1L; 
    66  
    67     /** 
    68      * <p> 
    69      * the maximum number of task instances in this map which is still only treated as list 
    70      * instead of using buckets. 
    71      * </p> 
    72      */ 
    73     private static final int MAX_LIST_SIZE = 15; 
    74      
    75     /** 
    76      * <p> 
    77      * Comparator to be used for comparing the task instances with each other 
    78      * </p> 
    79      */ 
    80     private TaskInstanceComparator comparator; 
    81  
    82     /** 
    83      * <p> 
    84      * Internally maintained plain list of task instances and associated values 
    85      * </p> 
    86      */ 
    87     private List<Map.Entry<ITaskInstance, V>> symbolList; 
    88  
    89     /** 
    90      * <p> 
    91      * If the size of the map exceeds {@link #MAX_LIST_SIZE}, this is the index using buckets 
    92      * for optimizing the search order. 
    93      * </p> 
    94      */ 
    95     private Map<Integer, List<Map.Entry<ITaskInstance, V>>> symbolBuckets; 
    96      
    97     /** 
    98      * <p> 
    99      * When using buckets, not any task instance may be associated a correct bucket. Therefore, we 
    100      * set a default bucket for all such task instances. This may change if the same bucket for a 
    101      * specific symbol is selected. 
    102      * </p> 
    103      */ 
    104     private int defaultBucket = 0; 
    105      
    106     /** 
    107      * <p> 
    108      * Instantiates a task instance map with a comparator 
    109      * </p> 
    110      * 
    111      * @param comparator the comparator to use for comparing task instances 
    112      *  
    113      * @throws IllegalArgumentException if the provided comparator is null 
    114      */ 
    115     public TaskSymbolBucketedMap(TaskInstanceComparator comparator) { 
    116         if (comparator == null) { 
    117             throw new IllegalArgumentException("comparator must not be null"); 
    118         } 
    119          
    120         this.comparator = comparator; 
    121         this.symbolList = new ArrayList<Map.Entry<ITaskInstance, V>>(); 
    122     } 
    123  
    124     /** 
    125      * <p> 
    126      * Copy constructor 
    127      * </p> 
    128      *  
    129      * @param otherMap the other map to be copied including its comparator 
    130      *  
    131      * @throws IllegalArgumentException if the provided other map is null 
    132      */ 
    133     public TaskSymbolBucketedMap(TaskSymbolBucketedMap<V> otherMap) { 
    134         if (otherMap == null) { 
    135             throw new IllegalArgumentException("otherMap must not be null"); 
    136         } 
    137  
    138         this.comparator = otherMap.comparator; 
    139         this.symbolList = new ArrayList<Map.Entry<ITaskInstance, V>>(otherMap.symbolList); 
    140          
    141         if (this.symbolList.size() > MAX_LIST_SIZE) { 
    142             createSymbolBuckets(); 
    143         } 
    144     } 
    145  
    146     /** 
    147      * <p> 
    148      * Returns the size of the map, i.e. the number of task instance entries 
    149      * </p> 
    150      *  
    151      * @return as described 
    152      */ 
    153     public int size() { 
    154         return symbolList.size(); 
    155     } 
    156  
    157     /** 
    158      * <p> 
    159      * Returns true if this map is empty, i.e. if {@link #size()} returns 0 
    160      * </p> 
    161      *  
    162      * @return as described 
    163      */ 
    164     public boolean isEmpty() { 
    165         return symbolList.isEmpty(); 
    166     } 
    167  
    168     /** 
    169      * <p> 
    170      * Returns true if the provided task instance was stored in this map. 
    171      * </p> 
    172      *  
    173      * @param symbol the task instance to check if it was stored in this map 
    174      *  
    175      * @return as described 
    176      *  
    177      * @throws IllegalArgumentException if the provided task instance is null 
    178      */ 
    179     public boolean containsSymbol(ITaskInstance symbol) { 
    180         if (symbol == null) { 
    181             throw new IllegalArgumentException("symbol must not be null"); 
    182         } 
    183          
    184         return getEntry(symbol) != null; 
    185     } 
    186  
    187     /** 
    188      * <p> 
    189      * Returns the value associated to the provided task instance in this map. If there is no value 
    190      * associated to the given task instance or if the task instance is not stored in this map, 
    191      * the method returns null. 
    192      * </p> 
    193      *  
    194      * @param symbol the task instance to return the value for 
    195      *  
    196      * @return as described 
    197      *  
    198      * @throws IllegalArgumentException if the provided task instance is null 
    199      */ 
    200     public V getValue(ITaskInstance symbol) { 
    201         if (symbol == null) { 
    202             throw new IllegalArgumentException("symbol must not be null"); 
    203         } 
    204          
    205         Map.Entry<ITaskInstance, V> entry = getEntry(symbol); 
    206          
    207         if (entry != null) { 
    208             return entry.getValue(); 
    209         } 
    210         else { 
    211             return null; 
    212         } 
    213     } 
    214  
    215     /** 
    216      * <p> 
    217      * Adds a task instance and an associated value to the map. If the value is null, the task 
    218      * instance is added, anyway and {@link #containsSymbol(Object)} will return true for that 
    219      * task instance. Adding the same task instance twice will produce two entries. This is 
    220      * contradictory to typical map implementations. To prevent this, the 
    221      * {@link #containsSymbol(Object)} and {@link #removeSymbol(Object)} methods should be used to 
    222      * ensure map behavior. 
    223      * </p> 
    224      *  
    225      * @param symbol the task instance to add to the map 
    226      * @param value  the value to associate to the task instance in this map 
    227      *  
    228      * @return as described 
    229      *  
    230      * @throws IllegalArgumentException if the provided task instance is null 
    231      */ 
    232     public void addSymbol(ITaskInstance symbol, V value) { 
    233         if (symbol == null) { 
    234             throw new IllegalArgumentException("symbol must not be null"); 
    235         } 
    236          
    237         Map.Entry<ITaskInstance, V> entry = new SymbolMapEntry(symbol, value); 
    238          
    239         symbolList.add(entry); 
    240              
    241         if (symbolList.size() > MAX_LIST_SIZE) { 
    242             if (symbolBuckets == null) { 
    243                 createSymbolBuckets(); 
    244             } 
    245             else { 
    246                 addToSymbolBucket(entry); 
    247             } 
    248         } 
    249     } 
    250  
    251     /** 
    252      * <p> 
    253      * Removes a task instance and its associated value from the map. If the task instance is 
    254      * stored several times, only the first of its occurrences is removed.  
    255      * </p> 
    256      *  
    257      * @param symbol the task instance to be removed from the map 
    258      *  
    259      * @return as described 
    260      *  
    261      * @throws IllegalArgumentException if the provided task instance is null 
    262      */ 
    263     public V removeSymbol(ITaskInstance symbol) { 
    264         if (symbol == null) { 
    265             throw new IllegalArgumentException("symbol must not be null"); 
    266         } 
    267          
    268         for (int i = 0; i < symbolList.size(); i++) { 
    269             if (comparator.equals(symbolList.get(i).getKey(), symbol)) { 
    270                 // found the symbol. Remove it from the list, and if required, also from the map. 
    271                 V value = symbolList.remove(i).getValue(); 
    272                  
    273                 if (symbolList.size() > MAX_LIST_SIZE) { 
    274                     removeFromSymbolBuckets(symbol); 
    275                 } 
    276                  
    277                 return value; 
    278             } 
    279         } 
    280          
    281         return null; 
    282     } 
    283  
    284     /** 
    285      * <p> 
    286      * Returns a collection of all task instances in this map. 
    287      * </p> 
    288      * 
    289      * @return as described 
    290      */ 
    291     public Collection<ITaskInstance> getSymbols() { 
    292         return new ReadOnlyCollectionFacade<ITaskInstance>(symbolList, new SymbolFacade()); 
    293     } 
    294      
    295     /** 
    296      * <p> 
    297      * Returns a collection of all values associated to task instances in this map. May contain 
    298      * null values, if some of the task instances are mapped to null. The length of the returned 
    299      * collection is in any case the same as the size of the map. 
    300      * </p> 
    301      * 
    302      * @return as described 
    303      */ 
    304     public Collection<V> getValues() { 
    305         return new ReadOnlyCollectionFacade<V>(symbolList, new ValueFacade()); 
    306     } 
    307      
    308     /** 
    309      * <p> 
    310      * Removes all task instances and associated values from the map. 
    311      * </p> 
    312      */ 
    313     public void clear() { 
    314         symbolList.clear(); 
    315         symbolBuckets = null; 
    316     } 
    317  
    318     /* (non-Javadoc) 
    319      * @see java.lang.Object#hashCode() 
    320      */ 
    321     @Override 
    322     public int hashCode() { 
    323         return symbolList.size(); 
    324     } 
    325  
    326     /* (non-Javadoc) 
    327      * @see java.lang.Object#equals(java.lang.Object) 
    328      */ 
    329     @SuppressWarnings("unchecked") 
    330     @Override 
    331     public boolean equals(Object obj) { 
    332         if (this == obj) { 
    333             return true; 
    334         } 
    335         else if (this.getClass().isInstance(obj)) { 
    336             TaskSymbolBucketedMap<V> other = (TaskSymbolBucketedMap<V>) obj; 
    337              
    338             return (symbolList.size() == other.symbolList.size()) && 
    339                    (symbolList.containsAll(other.symbolList)); 
    340         } 
    341         else { 
    342             return false; 
    343         } 
    344     } 
    345  
    346     /** 
    347      * <p> 
    348      * Internally used to create task instance buckets in case the number of stored task instances 
    349      * increased above {@link #MAX_LIST_SIZE}. 
    350      * </p> 
    351      */ 
    352     private void createSymbolBuckets() { 
    353         //System.out.println("creating symbol buckets"); 
    354         symbolBuckets = new HashMap<Integer, List<Map.Entry<ITaskInstance, V>>>(); 
    355          
    356         for (Map.Entry<ITaskInstance, V> symbol : symbolList) { 
    357             addToSymbolBucket(symbol); 
    358         } 
    359     } 
    360  
    361     /** 
    362      * <p> 
    363      * Adds a task instance and its value to its corresponding bucket. The corresponding bucket is 
    364      * the first element of the array returned by the method 
    365      * {@link #getBucketSearchOrder(ITaskInstance)}. If no search order for a task instance is 
    366      * defined, the entry is added to the default bucket. If the bucket id identical to the default 
    367      * bucket id, the default bucket id is shifted to another value. 
    368      * </p> 
    369      */ 
    370     private void addToSymbolBucket(Map.Entry<ITaskInstance, V> symbolEntry) { 
    371         int bucketId = defaultBucket; 
    372         int[] bucketSearchOrder = getBucketSearchOrder(symbolEntry.getKey()); 
    373          
    374         if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) { 
    375             bucketId = bucketSearchOrder[0]; 
    376              
    377             if (bucketId == defaultBucket) { 
    378                 setNewDefaultBucketId(); 
    379             } 
    380         } 
    381          
    382         List<Map.Entry<ITaskInstance, V>> list = symbolBuckets.get(bucketId); 
    383          
    384         if (list == null) { 
    385             list = new LinkedList<Map.Entry<ITaskInstance, V>>(); 
    386             symbolBuckets.put(bucketId, list); 
    387         } 
    388          
    389         list.add(symbolEntry); 
    390     } 
    391      
    392     /** 
    393      * <p> 
    394      * returns the search order for a task instance which is different for event task instances, 
    395      * sequence instances, selection instances, and iteration instances 
    396      * </p> 
    397      */ 
    398     private int[] getBucketSearchOrder(ITaskInstance taskInstance) { 
    399         // 0 = sequence; 1 = selection; 2 = iteration; 3 = optional; 4 = event task in general; 
    400         // other = hashCode of name of event type 
    401          
    402         if (taskInstance instanceof IEventTaskInstance) { 
    403             // event tasks are most likely equal to those of the same type happening on the same 
    404             // target. Afterwards, they should be equal to those of the event type with the same 
    405             // name. Afterwards, they may be equal to iterations, optionals, other event tasks, 
    406             // selections, and finally the rest. 
    407             Event event = ((IEventTaskInstance) taskInstance).getEvent(); 
    408             return new int[] { event.getTarget().hashCode() + event.getType().getName().hashCode(), 
    409                                event.getType().getName().hashCode(), 2, 3, 4, 1 };                        
    410         } 
    411         else if (taskInstance instanceof ISequenceInstance) { 
    412             return new int[] { 0, 2, 3, 1 };                        
    413         } 
    414         else if (taskInstance instanceof ISelectionInstance) { 
    415             return new int[] { 1, 4, 2, 3 };                        
    416         } 
    417         else if (taskInstance instanceof IIterationInstance) { 
    418             return new int[] { 2, 1, 4 };                        
    419         } 
    420          
    421         return null; 
    422     } 
    423  
    424     /** 
    425      * <p> 
    426      * Removes the entry for a given task instance from the buckets. It uses the bucket search order 
    427      * defined to find the task instance as fast as possible. 
    428      * </p> 
    429      */ 
    430     private Map.Entry<ITaskInstance, V> removeFromSymbolBuckets(ITaskInstance symbol) { 
    431         int bucketId = defaultBucket; 
    432         int[] bucketSearchOrder = getBucketSearchOrder(symbol); 
    433          
    434         if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) { 
    435             bucketId = bucketSearchOrder[0]; 
    436         } 
    437          
    438         List<Map.Entry<ITaskInstance, V>> list = symbolBuckets.get(bucketId); 
    439         Map.Entry<ITaskInstance, V> result = null; 
    440          
    441         if (list != null) { 
    442             for (int i = 0; i < list.size(); i++) { 
    443                 if (comparator.equals(list.get(i).getKey(), symbol)) { 
    444                     result = list.remove(i); 
    445                     break; 
    446                 } 
    447             } 
    448              
    449             if (list.isEmpty()) { 
    450                 symbolBuckets.remove(bucketId); 
    451             } 
    452         } 
    453          
    454         return result; 
    455     } 
    456  
    457     /** 
    458      * <p> 
    459      * Updates the default bucket id to a new one 
    460      * </p> 
    461      */ 
    462     private void setNewDefaultBucketId() { 
    463         int oldDefaultBucket = defaultBucket; 
    464         do { 
    465             defaultBucket += 1; 
    466         } 
    467         while (symbolBuckets.containsKey(defaultBucket)); 
    468          
    469         symbolBuckets.put(defaultBucket, symbolBuckets.remove(oldDefaultBucket)); 
    470     } 
    471  
    472     /** 
    473      * <p> 
    474      * searches for the entry belonging to the given task instance. The method either uses the 
    475      * list if buckets are not used yet, or it uses the buckets and searches them in the order 
    476      * defined by the method {@link #getBucketSearchOrder(ITaskInstance)}. If the task instances 
    477      * isn't found and the bucket search order does not refer all buckets, then also the other 
    478      * buckets are searched for the task instance. 
    479      * </p> 
    480      */ 
    481     private Map.Entry<ITaskInstance, V> getEntry(ITaskInstance symbol) { 
    482         Map.Entry<ITaskInstance, V> entry = null; 
    483         if (symbolBuckets == null) { 
    484             entry = lookup(symbol, symbolList); 
    485         } 
    486         else { 
    487             int[] bucketSearchOrder = getBucketSearchOrder(symbol); 
    488             for (int bucketId : bucketSearchOrder) { 
    489                 List<Map.Entry<ITaskInstance, V>> list = symbolBuckets.get(bucketId); 
    490                 if (list != null) { 
    491                     entry = lookup(symbol, list); 
    492                     if (entry != null) { 
    493                         break; 
    494                     } 
    495                 } 
    496             } 
    497              
    498             // try to search the other buckets 
    499             if (entry == null) { 
    500                 Arrays.sort(bucketSearchOrder); 
    501                 for (Map.Entry<Integer, List<Map.Entry<ITaskInstance, V>>> bucket : symbolBuckets.entrySet()) { 
    502                     if (Arrays.binarySearch(bucketSearchOrder, bucket.getKey()) < 0) { 
    503                         List<Map.Entry<ITaskInstance, V>> list = bucket.getValue(); 
    504                         if (list != null) { 
    505                             entry = lookup(symbol, list); 
    506                             if (entry != null) { 
    507                                 break; 
    508                             } 
    509                         } 
    510                     } 
    511                 } 
    512             } 
    513         } 
    514          
    515         return entry; 
    516     } 
    517  
    518     /** 
    519      * <p> 
    520      * Convenience method to look up a symbol in a list of entries using the comparator. 
    521      * </p> 
    522      */ 
    523     private Map.Entry<ITaskInstance, V> lookup(ITaskInstance symbol, List<Map.Entry<ITaskInstance, V>> list) { 
    524         for (Map.Entry<ITaskInstance, V> candidate : list) { 
    525             if (comparator.equals(candidate.getKey(), symbol)) { 
    526                 return candidate; 
    527             } 
    528         } 
    529          
    530         return null; 
    531     } 
    532  
    533     /** 
    534      * <p> 
    535      * Internally used data structure for storing task instance - value pairs 
    536      * </p> 
    537      *  
    538      * @author Patrick Harms 
    539      */ 
    540     private class SymbolMapEntry implements Map.Entry<ITaskInstance, V> { 
    541          
    542         /** 
    543          * the task instance to map to a value 
    544          */ 
    545         private ITaskInstance symbol; 
    546          
    547         /** 
    548          * the value associated with the symbol 
    549          */ 
    550         private V value; 
    551  
    552         /** 
    553          * <p> 
    554          * Simple constructor for initializing the entry with a task instance and its associated 
    555          * value. 
    556          * </p> 
    557          */ 
    558         private SymbolMapEntry(ITaskInstance symbol, V value) { 
    559             super(); 
    560             this.symbol = symbol; 
    561             this.value = value; 
    562         } 
    563  
    564         /* (non-Javadoc) 
    565          * @see java.util.Map.Entry#getKey() 
    566          */ 
    567         @Override 
    568         public ITaskInstance getKey() { 
    569             return symbol; 
    570         } 
    571  
    572         /* (non-Javadoc) 
    573          * @see java.util.Map.Entry#getValue() 
    574          */ 
    575         @Override 
    576         public V getValue() { 
    577             return value; 
    578         } 
    579  
    580         /* (non-Javadoc) 
    581          * @see java.util.Map.Entry#setValue(java.lang.Object) 
    582          */ 
    583         @Override 
    584         public V setValue(V value) { 
    585             V oldValue = this.value; 
    586             this.value = value; 
    587             return oldValue; 
    588         } 
    589  
    590         /* (non-Javadoc) 
    591          * @see java.lang.Object#hashCode() 
    592          */ 
    593         @Override 
    594         public int hashCode() { 
    595             return symbol.hashCode(); 
    596         } 
    597  
    598         /* (non-Javadoc) 
    599          * @see java.lang.Object#equals(java.lang.Object) 
    600          */ 
    601         @SuppressWarnings("unchecked") 
    602         @Override 
    603         public boolean equals(Object obj) { 
    604             if (this == obj) { 
    605                 return true; 
    606             } 
    607             else if (this.getClass().isInstance(obj)) { 
    608                 SymbolMapEntry other = (SymbolMapEntry) obj; 
    609                 return (symbol.equals(other.symbol) && 
    610                         (value == null ? other.value == null : value.equals(other.value))); 
    611             } 
    612             else { 
    613                 return false; 
    614             } 
    615         } 
    616  
    617         /* (non-Javadoc) 
    618          * @see java.lang.Object#toString() 
    619          */ 
    620         @Override 
    621         public String toString() { 
    622             return symbol + "=" + value; 
    623         } 
    624  
    625     } 
    626  
    627     /** 
    628      * <p> 
    629      * Used to create an efficient facade for accessing the internal list of entries either only 
    630      * for the task instances or only for the values. It is a default implementation of the 
    631      * collection interface. The entry facade provided to the constructor decides, if either the 
    632      * list accesses only the task instances or only the values.  
    633      * </p> 
    634      *  
    635      * @author Patrick Harms 
    636      */ 
    637     private class ReadOnlyCollectionFacade<TYPE> implements Collection<TYPE> { 
    638          
    639         /** 
    640          * the list facaded by this facade 
    641          */ 
    642         private List<Map.Entry<ITaskInstance, V>> list; 
    643          
    644         /** 
    645          * the facade to be used for the entries 
    646          */ 
    647         private EntryFacade<TYPE> entryFacade; 
    648          
    649         /** 
    650          * <p> 
    651          * Initializes the facade with the facaded list and the facade to be used for the entries 
    652          * </p> 
    653          */ 
    654         private ReadOnlyCollectionFacade(List<Map.Entry<ITaskInstance, V>> list, 
    655                                          EntryFacade<TYPE>                 entryFacade) 
    656         { 
    657             this.list = list; 
    658             this.entryFacade = entryFacade; 
    659         } 
    660  
    661         /* (non-Javadoc) 
    662          * @see java.util.Collection#size() 
    663          */ 
    664         @Override 
    665         public int size() { 
    666             return list.size(); 
    667         } 
    668  
    669         /* (non-Javadoc) 
    670          * @see java.util.Collection#isEmpty() 
    671          */ 
    672         @Override 
    673         public boolean isEmpty() { 
    674             return list.isEmpty(); 
    675         } 
    676  
    677         /* (non-Javadoc) 
    678          * @see java.util.Collection#contains(java.lang.Object) 
    679          */ 
    680         @Override 
    681         public boolean contains(Object o) { 
    682             if (o == null) { 
    683                 for (Map.Entry<ITaskInstance, V> entry : list) { 
    684                     if (entryFacade.getFacadedElement(entry) == null) { 
    685                         return true; 
    686                     } 
    687                 } 
    688             } 
    689             else { 
    690                 for (Map.Entry<ITaskInstance, V> entry : list) { 
    691                     if (o.equals(entryFacade.getFacadedElement(entry))) { 
    692                         return true; 
    693                     } 
    694                 } 
    695             } 
    696              
    697             return false; 
    698         } 
    699  
    700         /* (non-Javadoc) 
    701          * @see java.util.Collection#toArray() 
    702          */ 
    703         @Override 
    704         public Object[] toArray() { 
    705             Object[] result = new Object[list.size()]; 
    706              
    707             for (int i = 0; i < list.size(); i++) { 
    708                 result[i] = entryFacade.getFacadedElement(list.get(i)); 
    709             } 
    710              
    711             return result; 
    712         } 
    713  
    714         /* (non-Javadoc) 
    715          * @see java.util.Collection#toArray(T[]) 
    716          */ 
    717         @SuppressWarnings("unchecked") 
    718         @Override 
    719         public <T> T[] toArray(T[] a) { 
    720             T[] result = a; 
    721              
    722             for (int i = 0; i < list.size(); i++) { 
    723                 result[i] = (T) entryFacade.getFacadedElement(list.get(i)); 
    724             } 
    725              
    726             return result; 
    727         } 
    728  
    729         /* (non-Javadoc) 
    730          * @see java.util.Collection#add(java.lang.Object) 
    731          */ 
    732         @Override 
    733         public boolean add(TYPE e) { 
    734             throw new UnsupportedOperationException("this collection is read only"); 
    735         } 
    736  
    737         /* (non-Javadoc) 
    738          * @see java.util.Collection#remove(java.lang.Object) 
    739          */ 
    740         @Override 
    741         public boolean remove(Object o) { 
    742             throw new UnsupportedOperationException("this collection is read only"); 
    743         } 
    744  
    745         /* (non-Javadoc) 
    746          * @see java.util.Collection#containsAll(java.util.Collection) 
    747          */ 
    748         @Override 
    749         public boolean containsAll(Collection<?> c) { 
    750             for (Object candidate : c) { 
    751                 if (!contains(candidate)) { 
    752                     return false; 
    753                 } 
    754             } 
    755              
    756             return true; 
    757         } 
    758  
    759         /* (non-Javadoc) 
    760          * @see java.util.Collection#addAll(java.util.Collection) 
    761          */ 
    762         @Override 
    763         public boolean addAll(Collection<? extends TYPE> c) { 
    764             throw new UnsupportedOperationException("this collection is read only"); 
    765         } 
    766  
    767         /* (non-Javadoc) 
    768          * @see java.util.Collection#removeAll(java.util.Collection) 
    769          */ 
    770         @Override 
    771         public boolean removeAll(Collection<?> c) { 
    772             throw new UnsupportedOperationException("this collection is read only"); 
    773         } 
    774  
    775         /* (non-Javadoc) 
    776          * @see java.util.Collection#retainAll(java.util.Collection) 
    777          */ 
    778         @Override 
    779         public boolean retainAll(Collection<?> c) { 
    780             throw new UnsupportedOperationException("this collection is read only"); 
    781         } 
    782  
    783         /* (non-Javadoc) 
    784          * @see java.util.Collection#clear() 
    785          */ 
    786         @Override 
    787         public void clear() { 
    788             throw new UnsupportedOperationException("this collection is read only"); 
    789         } 
    790  
    791         /* (non-Javadoc) 
    792          * @see java.util.Collection#iterator() 
    793          */ 
    794         @Override 
    795         public Iterator<TYPE> iterator() { 
    796             return new ReadOnlyCollectionIteratorFacade<TYPE>(list.iterator(), entryFacade); 
    797         } 
    798          
    799     } 
    800  
    801     /** 
    802      * <p> 
    803      * Implementation of an iterator to facade an iterator on the internal list of task instance 
    804      * entries. 
    805      * </p> 
    806      *  
    807      * @author Patrick Harms 
    808      */ 
    809     private class ReadOnlyCollectionIteratorFacade<TYPE> implements Iterator<TYPE> { 
    810          
    811         /** 
    812          * the facaded iterator 
    813          */ 
    814         private Iterator<Map.Entry<ITaskInstance, V>> iterator; 
    815          
    816         /** 
    817          * the facade for the entries provided by the facaded iterator 
    818          */ 
    819         private EntryFacade<TYPE> entryFacade; 
    820          
    821         /** 
    822          * <p> 
    823          * initialized this facade with the facaded iterator and the entry facade to be used for 
    824          * the entries. 
    825          * </p> 
    826          */ 
    827         private ReadOnlyCollectionIteratorFacade(Iterator<Map.Entry<ITaskInstance, V>> iterator, 
    828                                                  EntryFacade<TYPE>                     entryFacade) 
    829         { 
    830             this.iterator = iterator; 
    831             this.entryFacade = entryFacade; 
    832         } 
    833  
    834         /* (non-Javadoc) 
    835          * @see java.util.Iterator#hasNext() 
    836          */ 
    837         @Override 
    838         public boolean hasNext() { 
    839             return iterator.hasNext(); 
    840         } 
    841  
    842         /* (non-Javadoc) 
    843          * @see java.util.Iterator#next() 
    844          */ 
    845         @Override 
    846         public TYPE next() { 
    847             return entryFacade.getFacadedElement(iterator.next()); 
    848         } 
    849  
    850         /* (non-Javadoc) 
    851          * @see java.util.Iterator#remove() 
    852          */ 
    853         @Override 
    854         public void remove() { 
    855             throw new UnsupportedOperationException("this iterator is read only"); 
    856         } 
    857          
    858     } 
    859          
    860     /** 
    861      * <p> 
    862      * Used to facade task instance entries and to return only this part of an entry, that is 
    863      * relevant. 
    864      * </p> 
    865      *  
    866      * @author Patrick Harms 
    867      */ 
    868     private abstract class EntryFacade<T> { 
    869          
    870         /** 
    871          * <p> 
    872          * Returns only the part of an entry that is relevant or required. 
    873          * </p> 
    874          * 
    875          * @param entry of which the part shall be returned 
    876          *  
    877          * @return the part of the entry to be returned 
    878          */ 
    879         protected abstract T getFacadedElement(Entry<ITaskInstance, V> entry); 
    880          
    881     } 
    882      
    883     /** 
    884      * <p> 
    885      * Implementation of the entry facade returning the entries key, i.e. the symbol. 
    886      * </p> 
    887      *  
    888      * @author Patrick Harms 
    889      */ 
    890     private class SymbolFacade extends EntryFacade<ITaskInstance> { 
    891  
    892         /* (non-Javadoc) 
    893          * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry) 
    894          */ 
    895         @Override 
    896         protected ITaskInstance getFacadedElement(Entry<ITaskInstance, V> entry) { 
    897             return entry.getKey(); 
    898         } 
    899     } 
    900      
    901     /** 
    902      * <p> 
    903      * Implementation of the entry facade returning the entries value, i.e. the value associated to 
    904      * the symbol. 
    905      * </p> 
    906      *  
    907      * @author Patrick Harms 
    908      */ 
    909     private class ValueFacade extends EntryFacade<V> { 
    910  
    911         /* (non-Javadoc) 
    912          * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry) 
    913          */ 
    914         @Override 
    915         protected V getFacadedElement(Entry<ITaskInstance, V> entry) { 
    916             return entry.getValue(); 
    917         } 
    918     } 
     61class TaskSymbolBucketedMap<V> implements SymbolMap<ITaskInstance, V>, 
     62                Serializable { 
     63 
     64        /** 
     65         * <p> 
     66         * Used to facade task instance entries and to return only this part of an 
     67         * entry, that is relevant. 
     68         * </p> 
     69         *  
     70         * @author Patrick Harms 
     71         */ 
     72        private abstract class EntryFacade<T> { 
     73 
     74                /** 
     75                 * <p> 
     76                 * Returns only the part of an entry that is relevant or required. 
     77                 * </p> 
     78                 * 
     79                 * @param entry 
     80                 *            of which the part shall be returned 
     81                 *  
     82                 * @return the part of the entry to be returned 
     83                 */ 
     84                protected abstract T getFacadedElement(Entry<ITaskInstance, V> entry); 
     85 
     86        } 
     87 
     88        /** 
     89         * <p> 
     90         * Used to create an efficient facade for accessing the internal list of 
     91         * entries either only for the task instances or only for the values. It is 
     92         * a default implementation of the collection interface. The entry facade 
     93         * provided to the constructor decides, if either the list accesses only the 
     94         * task instances or only the values. 
     95         * </p> 
     96         *  
     97         * @author Patrick Harms 
     98         */ 
     99        private class ReadOnlyCollectionFacade<TYPE> implements Collection<TYPE> { 
     100 
     101                /** 
     102                 * the list facaded by this facade 
     103                 */ 
     104                private final List<Map.Entry<ITaskInstance, V>> list; 
     105 
     106                /** 
     107                 * the facade to be used for the entries 
     108                 */ 
     109                private final EntryFacade<TYPE> entryFacade; 
     110 
     111                /** 
     112                 * <p> 
     113                 * Initializes the facade with the facaded list and the facade to be 
     114                 * used for the entries 
     115                 * </p> 
     116                 */ 
     117                private ReadOnlyCollectionFacade( 
     118                                List<Map.Entry<ITaskInstance, V>> list, 
     119                                EntryFacade<TYPE> entryFacade) { 
     120                        this.list = list; 
     121                        this.entryFacade = entryFacade; 
     122                } 
     123 
     124                /* 
     125                 * (non-Javadoc) 
     126                 *  
     127                 * @see java.util.Collection#add(java.lang.Object) 
     128                 */ 
     129                @Override 
     130                public boolean add(TYPE e) { 
     131                        throw new UnsupportedOperationException( 
     132                                        "this collection is read only"); 
     133                } 
     134 
     135                /* 
     136                 * (non-Javadoc) 
     137                 *  
     138                 * @see java.util.Collection#addAll(java.util.Collection) 
     139                 */ 
     140                @Override 
     141                public boolean addAll(Collection<? extends TYPE> c) { 
     142                        throw new UnsupportedOperationException( 
     143                                        "this collection is read only"); 
     144                } 
     145 
     146                /* 
     147                 * (non-Javadoc) 
     148                 *  
     149                 * @see java.util.Collection#clear() 
     150                 */ 
     151                @Override 
     152                public void clear() { 
     153                        throw new UnsupportedOperationException( 
     154                                        "this collection is read only"); 
     155                } 
     156 
     157                /* 
     158                 * (non-Javadoc) 
     159                 *  
     160                 * @see java.util.Collection#contains(java.lang.Object) 
     161                 */ 
     162                @Override 
     163                public boolean contains(Object o) { 
     164                        if (o == null) { 
     165                                for (final Map.Entry<ITaskInstance, V> entry : list) { 
     166                                        if (entryFacade.getFacadedElement(entry) == null) { 
     167                                                return true; 
     168                                        } 
     169                                } 
     170                        } else { 
     171                                for (final Map.Entry<ITaskInstance, V> entry : list) { 
     172                                        if (o.equals(entryFacade.getFacadedElement(entry))) { 
     173                                                return true; 
     174                                        } 
     175                                } 
     176                        } 
     177 
     178                        return false; 
     179                } 
     180 
     181                /* 
     182                 * (non-Javadoc) 
     183                 *  
     184                 * @see java.util.Collection#containsAll(java.util.Collection) 
     185                 */ 
     186                @Override 
     187                public boolean containsAll(Collection<?> c) { 
     188                        for (final Object candidate : c) { 
     189                                if (!contains(candidate)) { 
     190                                        return false; 
     191                                } 
     192                        } 
     193 
     194                        return true; 
     195                } 
     196 
     197                /* 
     198                 * (non-Javadoc) 
     199                 *  
     200                 * @see java.util.Collection#isEmpty() 
     201                 */ 
     202                @Override 
     203                public boolean isEmpty() { 
     204                        return list.isEmpty(); 
     205                } 
     206 
     207                /* 
     208                 * (non-Javadoc) 
     209                 *  
     210                 * @see java.util.Collection#iterator() 
     211                 */ 
     212                @Override 
     213                public Iterator<TYPE> iterator() { 
     214                        return new ReadOnlyCollectionIteratorFacade<TYPE>(list.iterator(), 
     215                                        entryFacade); 
     216                } 
     217 
     218                /* 
     219                 * (non-Javadoc) 
     220                 *  
     221                 * @see java.util.Collection#remove(java.lang.Object) 
     222                 */ 
     223                @Override 
     224                public boolean remove(Object o) { 
     225                        throw new UnsupportedOperationException( 
     226                                        "this collection is read only"); 
     227                } 
     228 
     229                /* 
     230                 * (non-Javadoc) 
     231                 *  
     232                 * @see java.util.Collection#removeAll(java.util.Collection) 
     233                 */ 
     234                @Override 
     235                public boolean removeAll(Collection<?> c) { 
     236                        throw new UnsupportedOperationException( 
     237                                        "this collection is read only"); 
     238                } 
     239 
     240                /* 
     241                 * (non-Javadoc) 
     242                 *  
     243                 * @see java.util.Collection#retainAll(java.util.Collection) 
     244                 */ 
     245                @Override 
     246                public boolean retainAll(Collection<?> c) { 
     247                        throw new UnsupportedOperationException( 
     248                                        "this collection is read only"); 
     249                } 
     250 
     251                /* 
     252                 * (non-Javadoc) 
     253                 *  
     254                 * @see java.util.Collection#size() 
     255                 */ 
     256                @Override 
     257                public int size() { 
     258                        return list.size(); 
     259                } 
     260 
     261                /* 
     262                 * (non-Javadoc) 
     263                 *  
     264                 * @see java.util.Collection#toArray() 
     265                 */ 
     266                @Override 
     267                public Object[] toArray() { 
     268                        final Object[] result = new Object[list.size()]; 
     269 
     270                        for (int i = 0; i < list.size(); i++) { 
     271                                result[i] = entryFacade.getFacadedElement(list.get(i)); 
     272                        } 
     273 
     274                        return result; 
     275                } 
     276 
     277                /* 
     278                 * (non-Javadoc) 
     279                 *  
     280                 * @see java.util.Collection#toArray(T[]) 
     281                 */ 
     282                @SuppressWarnings("unchecked") 
     283                @Override 
     284                public <T> T[] toArray(T[] a) { 
     285                        final T[] result = a; 
     286 
     287                        for (int i = 0; i < list.size(); i++) { 
     288                                result[i] = (T) entryFacade.getFacadedElement(list.get(i)); 
     289                        } 
     290 
     291                        return result; 
     292                } 
     293 
     294        } 
     295 
     296        /** 
     297         * <p> 
     298         * Implementation of an iterator to facade an iterator on the internal list 
     299         * of task instance entries. 
     300         * </p> 
     301         *  
     302         * @author Patrick Harms 
     303         */ 
     304        private class ReadOnlyCollectionIteratorFacade<TYPE> implements 
     305                        Iterator<TYPE> { 
     306 
     307                /** 
     308                 * the facaded iterator 
     309                 */ 
     310                private final Iterator<Map.Entry<ITaskInstance, V>> iterator; 
     311 
     312                /** 
     313                 * the facade for the entries provided by the facaded iterator 
     314                 */ 
     315                private final EntryFacade<TYPE> entryFacade; 
     316 
     317                /** 
     318                 * <p> 
     319                 * initialized this facade with the facaded iterator and the entry 
     320                 * facade to be used for the entries. 
     321                 * </p> 
     322                 */ 
     323                private ReadOnlyCollectionIteratorFacade( 
     324                                Iterator<Map.Entry<ITaskInstance, V>> iterator, 
     325                                EntryFacade<TYPE> entryFacade) { 
     326                        this.iterator = iterator; 
     327                        this.entryFacade = entryFacade; 
     328                } 
     329 
     330                /* 
     331                 * (non-Javadoc) 
     332                 *  
     333                 * @see java.util.Iterator#hasNext() 
     334                 */ 
     335                @Override 
     336                public boolean hasNext() { 
     337                        return iterator.hasNext(); 
     338                } 
     339 
     340                /* 
     341                 * (non-Javadoc) 
     342                 *  
     343                 * @see java.util.Iterator#next() 
     344                 */ 
     345                @Override 
     346                public TYPE next() { 
     347                        return entryFacade.getFacadedElement(iterator.next()); 
     348                } 
     349 
     350                /* 
     351                 * (non-Javadoc) 
     352                 *  
     353                 * @see java.util.Iterator#remove() 
     354                 */ 
     355                @Override 
     356                public void remove() { 
     357                        throw new UnsupportedOperationException( 
     358                                        "this iterator is read only"); 
     359                } 
     360 
     361        } 
     362 
     363        /** 
     364         * <p> 
     365         * Implementation of the entry facade returning the entries key, i.e. the 
     366         * symbol. 
     367         * </p> 
     368         *  
     369         * @author Patrick Harms 
     370         */ 
     371        private class SymbolFacade extends EntryFacade<ITaskInstance> { 
     372 
     373                /* 
     374                 * (non-Javadoc) 
     375                 *  
     376                 * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry) 
     377                 */ 
     378                @Override 
     379                protected ITaskInstance getFacadedElement(Entry<ITaskInstance, V> entry) { 
     380                        return entry.getKey(); 
     381                } 
     382        } 
     383 
     384        /** 
     385         * <p> 
     386         * Internally used data structure for storing task instance - value pairs 
     387         * </p> 
     388         *  
     389         * @author Patrick Harms 
     390         */ 
     391        private class SymbolMapEntry implements Map.Entry<ITaskInstance, V> { 
     392 
     393                /** 
     394                 * the task instance to map to a value 
     395                 */ 
     396                private final ITaskInstance symbol; 
     397 
     398                /** 
     399                 * the value associated with the symbol 
     400                 */ 
     401                private V value; 
     402 
     403                /** 
     404                 * <p> 
     405                 * Simple constructor for initializing the entry with a task instance 
     406                 * and its associated value. 
     407                 * </p> 
     408                 */ 
     409                private SymbolMapEntry(ITaskInstance symbol, V value) { 
     410                        super(); 
     411                        this.symbol = symbol; 
     412                        this.value = value; 
     413                } 
     414 
     415                /* 
     416                 * (non-Javadoc) 
     417                 *  
     418                 * @see java.lang.Object#equals(java.lang.Object) 
     419                 */ 
     420                @SuppressWarnings("unchecked") 
     421                @Override 
     422                public boolean equals(Object obj) { 
     423                        if (this == obj) { 
     424                                return true; 
     425                        } else if (this.getClass().isInstance(obj)) { 
     426                                final SymbolMapEntry other = (SymbolMapEntry) obj; 
     427                                return (symbol.equals(other.symbol) && (value == null ? other.value == null 
     428                                                : value.equals(other.value))); 
     429                        } else { 
     430                                return false; 
     431                        } 
     432                } 
     433 
     434                /* 
     435                 * (non-Javadoc) 
     436                 *  
     437                 * @see java.util.Map.Entry#getKey() 
     438                 */ 
     439                @Override 
     440                public ITaskInstance getKey() { 
     441                        return symbol; 
     442                } 
     443 
     444                /* 
     445                 * (non-Javadoc) 
     446                 *  
     447                 * @see java.util.Map.Entry#getValue() 
     448                 */ 
     449                @Override 
     450                public V getValue() { 
     451                        return value; 
     452                } 
     453 
     454                /* 
     455                 * (non-Javadoc) 
     456                 *  
     457                 * @see java.lang.Object#hashCode() 
     458                 */ 
     459                @Override 
     460                public int hashCode() { 
     461                        return symbol.hashCode(); 
     462                } 
     463 
     464                /* 
     465                 * (non-Javadoc) 
     466                 *  
     467                 * @see java.util.Map.Entry#setValue(java.lang.Object) 
     468                 */ 
     469                @Override 
     470                public V setValue(V value) { 
     471                        final V oldValue = this.value; 
     472                        this.value = value; 
     473                        return oldValue; 
     474                } 
     475 
     476                /* 
     477                 * (non-Javadoc) 
     478                 *  
     479                 * @see java.lang.Object#toString() 
     480                 */ 
     481                @Override 
     482                public String toString() { 
     483                        return symbol + "=" + value; 
     484                } 
     485 
     486        } 
     487 
     488        /** 
     489         * <p> 
     490         * Implementation of the entry facade returning the entries value, i.e. the 
     491         * value associated to the symbol. 
     492         * </p> 
     493         *  
     494         * @author Patrick Harms 
     495         */ 
     496        private class ValueFacade extends EntryFacade<V> { 
     497 
     498                /* 
     499                 * (non-Javadoc) 
     500                 *  
     501                 * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry) 
     502                 */ 
     503                @Override 
     504                protected V getFacadedElement(Entry<ITaskInstance, V> entry) { 
     505                        return entry.getValue(); 
     506                } 
     507        } 
     508 
     509        /** 
     510         * <p> 
     511         * default serial version UID 
     512         * </p> 
     513         */ 
     514        private static final long serialVersionUID = 1L; 
     515 
     516        /** 
     517         * <p> 
     518         * the maximum number of task instances in this map which is still only 
     519         * treated as list instead of using buckets. 
     520         * </p> 
     521         */ 
     522        private static final int MAX_LIST_SIZE = 15; 
     523 
     524        /** 
     525         * <p> 
     526         * Comparator to be used for comparing the task instances with each other 
     527         * </p> 
     528         */ 
     529        private final TaskInstanceComparator comparator; 
     530 
     531        /** 
     532         * <p> 
     533         * Internally maintained plain list of task instances and associated values 
     534         * </p> 
     535         */ 
     536        private final List<Map.Entry<ITaskInstance, V>> symbolList; 
     537 
     538        /** 
     539         * <p> 
     540         * If the size of the map exceeds {@link #MAX_LIST_SIZE}, this is the index 
     541         * using buckets for optimizing the search order. 
     542         * </p> 
     543         */ 
     544        private Map<Integer, List<Map.Entry<ITaskInstance, V>>> symbolBuckets; 
     545 
     546        /** 
     547         * <p> 
     548         * When using buckets, not any task instance may be associated a correct 
     549         * bucket. Therefore, we set a default bucket for all such task instances. 
     550         * This may change if the same bucket for a specific symbol is selected. 
     551         * </p> 
     552         */ 
     553        private int defaultBucket = 0; 
     554 
     555        /** 
     556         * <p> 
     557         * Instantiates a task instance map with a comparator 
     558         * </p> 
     559         * 
     560         * @param comparator 
     561         *            the comparator to use for comparing task instances 
     562         *  
     563         * @throws IllegalArgumentException 
     564         *             if the provided comparator is null 
     565         */ 
     566        public TaskSymbolBucketedMap(TaskInstanceComparator comparator) { 
     567                if (comparator == null) { 
     568                        throw new IllegalArgumentException("comparator must not be null"); 
     569                } 
     570 
     571                this.comparator = comparator; 
     572                this.symbolList = new ArrayList<Map.Entry<ITaskInstance, V>>(); 
     573        } 
     574 
     575        /** 
     576         * <p> 
     577         * Copy constructor 
     578         * </p> 
     579         *  
     580         * @param otherMap 
     581         *            the other map to be copied including its comparator 
     582         *  
     583         * @throws IllegalArgumentException 
     584         *             if the provided other map is null 
     585         */ 
     586        public TaskSymbolBucketedMap(TaskSymbolBucketedMap<V> otherMap) { 
     587                if (otherMap == null) { 
     588                        throw new IllegalArgumentException("otherMap must not be null"); 
     589                } 
     590 
     591                this.comparator = otherMap.comparator; 
     592                this.symbolList = new ArrayList<Map.Entry<ITaskInstance, V>>( 
     593                                otherMap.symbolList); 
     594 
     595                if (this.symbolList.size() > MAX_LIST_SIZE) { 
     596                        createSymbolBuckets(); 
     597                } 
     598        } 
     599 
     600        /** 
     601         * <p> 
     602         * Adds a task instance and an associated value to the map. If the value is 
     603         * null, the task instance is added, anyway and 
     604         * {@link #containsSymbol(Object)} will return true for that task instance. 
     605         * Adding the same task instance twice will produce two entries. This is 
     606         * contradictory to typical map implementations. To prevent this, the 
     607         * {@link #containsSymbol(Object)} and {@link #removeSymbol(Object)} methods 
     608         * should be used to ensure map behavior. 
     609         * </p> 
     610         *  
     611         * @param symbol 
     612         *            the task instance to add to the map 
     613         * @param value 
     614         *            the value to associate to the task instance in this map 
     615         *  
     616         * @return as described 
     617         *  
     618         * @throws IllegalArgumentException 
     619         *             if the provided task instance is null 
     620         */ 
     621        @Override 
     622        public void addSymbol(ITaskInstance symbol, V value) { 
     623                if (symbol == null) { 
     624                        throw new IllegalArgumentException("symbol must not be null"); 
     625                } 
     626 
     627                final Map.Entry<ITaskInstance, V> entry = new SymbolMapEntry(symbol, 
     628                                value); 
     629 
     630                symbolList.add(entry); 
     631 
     632                if (symbolList.size() > MAX_LIST_SIZE) { 
     633                        if (symbolBuckets == null) { 
     634                                createSymbolBuckets(); 
     635                        } else { 
     636                                addToSymbolBucket(entry); 
     637                        } 
     638                } 
     639        } 
     640 
     641        /** 
     642         * <p> 
     643         * Adds a task instance and its value to its corresponding bucket. The 
     644         * corresponding bucket is the first element of the array returned by the 
     645         * method {@link #getBucketSearchOrder(ITaskInstance)}. If no search order 
     646         * for a task instance is defined, the entry is added to the default bucket. 
     647         * If the bucket id identical to the default bucket id, the default bucket 
     648         * id is shifted to another value. 
     649         * </p> 
     650         */ 
     651        private void addToSymbolBucket(Map.Entry<ITaskInstance, V> symbolEntry) { 
     652                int bucketId = defaultBucket; 
     653                final int[] bucketSearchOrder = getBucketSearchOrder(symbolEntry 
     654                                .getKey()); 
     655 
     656                if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) { 
     657                        bucketId = bucketSearchOrder[0]; 
     658 
     659                        if (bucketId == defaultBucket) { 
     660                                setNewDefaultBucketId(); 
     661                        } 
     662                } 
     663 
     664                List<Map.Entry<ITaskInstance, V>> list = symbolBuckets.get(bucketId); 
     665 
     666                if (list == null) { 
     667                        list = new LinkedList<Map.Entry<ITaskInstance, V>>(); 
     668                        symbolBuckets.put(bucketId, list); 
     669                } 
     670 
     671                list.add(symbolEntry); 
     672        } 
     673 
     674        /** 
     675         * <p> 
     676         * Removes all task instances and associated values from the map. 
     677         * </p> 
     678         */ 
     679        @Override 
     680        public void clear() { 
     681                symbolList.clear(); 
     682                symbolBuckets = null; 
     683        } 
     684 
     685        /** 
     686         * <p> 
     687         * Returns true if the provided task instance was stored in this map. 
     688         * </p> 
     689         *  
     690         * @param symbol 
     691         *            the task instance to check if it was stored in this map 
     692         *  
     693         * @return as described 
     694         *  
     695         * @throws IllegalArgumentException 
     696         *             if the provided task instance is null 
     697         */ 
     698        @Override 
     699        public boolean containsSymbol(ITaskInstance symbol) { 
     700                if (symbol == null) { 
     701                        throw new IllegalArgumentException("symbol must not be null"); 
     702                } 
     703 
     704                return getEntry(symbol) != null; 
     705        } 
     706 
     707        /** 
     708         * <p> 
     709         * Internally used to create task instance buckets in case the number of 
     710         * stored task instances increased above {@link #MAX_LIST_SIZE}. 
     711         * </p> 
     712         */ 
     713        private void createSymbolBuckets() { 
     714                // System.out.println("creating symbol buckets"); 
     715                symbolBuckets = new HashMap<Integer, List<Map.Entry<ITaskInstance, V>>>(); 
     716 
     717                for (final Map.Entry<ITaskInstance, V> symbol : symbolList) { 
     718                        addToSymbolBucket(symbol); 
     719                } 
     720        } 
     721 
     722        /* 
     723         * (non-Javadoc) 
     724         *  
     725         * @see java.lang.Object#equals(java.lang.Object) 
     726         */ 
     727        @SuppressWarnings("unchecked") 
     728        @Override 
     729        public boolean equals(Object obj) { 
     730                if (this == obj) { 
     731                        return true; 
     732                } else if (this.getClass().isInstance(obj)) { 
     733                        final TaskSymbolBucketedMap<V> other = (TaskSymbolBucketedMap<V>) obj; 
     734 
     735                        return (symbolList.size() == other.symbolList.size()) 
     736                                        && (symbolList.containsAll(other.symbolList)); 
     737                } else { 
     738                        return false; 
     739                } 
     740        } 
     741 
     742        /** 
     743         * <p> 
     744         * returns the search order for a task instance which is different for event 
     745         * task instances, sequence instances, selection instances, and iteration 
     746         * instances 
     747         * </p> 
     748         */ 
     749        private int[] getBucketSearchOrder(ITaskInstance taskInstance) { 
     750                // 0 = sequence; 1 = selection; 2 = iteration; 3 = optional; 4 = event 
     751                // task in general; 
     752                // other = hashCode of name of event type 
     753 
     754                if (taskInstance instanceof IEventTaskInstance) { 
     755                        // event tasks are most likely equal to those of the same type 
     756                        // happening on the same 
     757                        // target. Afterwards, they should be equal to those of the event 
     758                        // type with the same 
     759                        // name. Afterwards, they may be equal to iterations, optionals, 
     760                        // other event tasks, 
     761                        // selections, and finally the rest. 
     762                        final Event event = ((IEventTaskInstance) taskInstance).getEvent(); 
     763                        return new int[] { 
     764                                        event.getTarget().hashCode() 
     765                                                        + event.getType().getName().hashCode(), 
     766                                        event.getType().getName().hashCode(), 2, 3, 4, 1 }; 
     767                } else if (taskInstance instanceof ISequenceInstance) { 
     768                        return new int[] { 0, 2, 3, 1 }; 
     769                } else if (taskInstance instanceof ISelectionInstance) { 
     770                        return new int[] { 1, 4, 2, 3 }; 
     771                } else if (taskInstance instanceof IIterationInstance) { 
     772                        return new int[] { 2, 1, 4 }; 
     773                } 
     774 
     775                return null; 
     776        } 
     777 
     778        /** 
     779         * <p> 
     780         * searches for the entry belonging to the given task instance. The method 
     781         * either uses the list if buckets are not used yet, or it uses the buckets 
     782         * and searches them in the order defined by the method 
     783         * {@link #getBucketSearchOrder(ITaskInstance)}. If the task instances isn't 
     784         * found and the bucket search order does not refer all buckets, then also 
     785         * the other buckets are searched for the task instance. 
     786         * </p> 
     787         */ 
     788        private Map.Entry<ITaskInstance, V> getEntry(ITaskInstance symbol) { 
     789                Map.Entry<ITaskInstance, V> entry = null; 
     790                if (symbolBuckets == null) { 
     791                        entry = lookup(symbol, symbolList); 
     792                } else { 
     793                        final int[] bucketSearchOrder = getBucketSearchOrder(symbol); 
     794                        for (final int bucketId : bucketSearchOrder) { 
     795                                final List<Map.Entry<ITaskInstance, V>> list = symbolBuckets 
     796                                                .get(bucketId); 
     797                                if (list != null) { 
     798                                        entry = lookup(symbol, list); 
     799                                        if (entry != null) { 
     800                                                break; 
     801                                        } 
     802                                } 
     803                        } 
     804 
     805                        // try to search the other buckets 
     806                        if (entry == null) { 
     807                                Arrays.sort(bucketSearchOrder); 
     808                                for (final Map.Entry<Integer, List<Map.Entry<ITaskInstance, V>>> bucket : symbolBuckets 
     809                                                .entrySet()) { 
     810                                        if (Arrays.binarySearch(bucketSearchOrder, bucket.getKey()) < 0) { 
     811                                                final List<Map.Entry<ITaskInstance, V>> list = bucket 
     812                                                                .getValue(); 
     813                                                if (list != null) { 
     814                                                        entry = lookup(symbol, list); 
     815                                                        if (entry != null) { 
     816                                                                break; 
     817                                                        } 
     818                                                } 
     819                                        } 
     820                                } 
     821                        } 
     822                } 
     823 
     824                return entry; 
     825        } 
     826 
     827        /** 
     828         * <p> 
     829         * Returns a collection of all task instances in this map. 
     830         * </p> 
     831         * 
     832         * @return as described 
     833         */ 
     834        @Override 
     835        public Collection<ITaskInstance> getSymbols() { 
     836                return new ReadOnlyCollectionFacade<ITaskInstance>(symbolList, 
     837                                new SymbolFacade()); 
     838        } 
     839 
     840        /** 
     841         * <p> 
     842         * Returns the value associated to the provided task instance in this map. 
     843         * If there is no value associated to the given task instance or if the task 
     844         * instance is not stored in this map, the method returns null. 
     845         * </p> 
     846         *  
     847         * @param symbol 
     848         *            the task instance to return the value for 
     849         *  
     850         * @return as described 
     851         *  
     852         * @throws IllegalArgumentException 
     853         *             if the provided task instance is null 
     854         */ 
     855        @Override 
     856        public V getValue(ITaskInstance symbol) { 
     857                if (symbol == null) { 
     858                        throw new IllegalArgumentException("symbol must not be null"); 
     859                } 
     860 
     861                final Map.Entry<ITaskInstance, V> entry = getEntry(symbol); 
     862 
     863                if (entry != null) { 
     864                        return entry.getValue(); 
     865                } else { 
     866                        return null; 
     867                } 
     868        } 
     869 
     870        /** 
     871         * <p> 
     872         * Returns a collection of all values associated to task instances in this 
     873         * map. May contain null values, if some of the task instances are mapped to 
     874         * null. The length of the returned collection is in any case the same as 
     875         * the size of the map. 
     876         * </p> 
     877         * 
     878         * @return as described 
     879         */ 
     880        @Override 
     881        public Collection<V> getValues() { 
     882                return new ReadOnlyCollectionFacade<V>(symbolList, new ValueFacade()); 
     883        } 
     884 
     885        /* 
     886         * (non-Javadoc) 
     887         *  
     888         * @see java.lang.Object#hashCode() 
     889         */ 
     890        @Override 
     891        public int hashCode() { 
     892                return symbolList.size(); 
     893        } 
     894 
     895        /** 
     896         * <p> 
     897         * Returns true if this map is empty, i.e. if {@link #size()} returns 0 
     898         * </p> 
     899         *  
     900         * @return as described 
     901         */ 
     902        @Override 
     903        public boolean isEmpty() { 
     904                return symbolList.isEmpty(); 
     905        } 
     906 
     907        /** 
     908         * <p> 
     909         * Convenience method to look up a symbol in a list of entries using the 
     910         * comparator. 
     911         * </p> 
     912         */ 
     913        private Map.Entry<ITaskInstance, V> lookup(ITaskInstance symbol, 
     914                        List<Map.Entry<ITaskInstance, V>> list) { 
     915                for (final Map.Entry<ITaskInstance, V> candidate : list) { 
     916                        if (comparator.equals(candidate.getKey(), symbol)) { 
     917                                return candidate; 
     918                        } 
     919                } 
     920 
     921                return null; 
     922        } 
     923 
     924        /** 
     925         * <p> 
     926         * Removes the entry for a given task instance from the buckets. It uses the 
     927         * bucket search order defined to find the task instance as fast as 
     928         * possible. 
     929         * </p> 
     930         */ 
     931        private Map.Entry<ITaskInstance, V> removeFromSymbolBuckets( 
     932                        ITaskInstance symbol) { 
     933                int bucketId = defaultBucket; 
     934                final int[] bucketSearchOrder = getBucketSearchOrder(symbol); 
     935 
     936                if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) { 
     937                        bucketId = bucketSearchOrder[0]; 
     938                } 
     939 
     940                final List<Map.Entry<ITaskInstance, V>> list = symbolBuckets 
     941                                .get(bucketId); 
     942                Map.Entry<ITaskInstance, V> result = null; 
     943 
     944                if (list != null) { 
     945                        for (int i = 0; i < list.size(); i++) { 
     946                                if (comparator.equals(list.get(i).getKey(), symbol)) { 
     947                                        result = list.remove(i); 
     948                                        break; 
     949                                } 
     950                        } 
     951 
     952                        if (list.isEmpty()) { 
     953                                symbolBuckets.remove(bucketId); 
     954                        } 
     955                } 
     956 
     957                return result; 
     958        } 
     959 
     960        /** 
     961         * <p> 
     962         * Removes a task instance and its associated value from the map. If the 
     963         * task instance is stored several times, only the first of its occurrences 
     964         * is removed. 
     965         * </p> 
     966         *  
     967         * @param symbol 
     968         *            the task instance to be removed from the map 
     969         *  
     970         * @return as described 
     971         *  
     972         * @throws IllegalArgumentException 
     973         *             if the provided task instance is null 
     974         */ 
     975        @Override 
     976        public V removeSymbol(ITaskInstance symbol) { 
     977                if (symbol == null) { 
     978                        throw new IllegalArgumentException("symbol must not be null"); 
     979                } 
     980 
     981                for (int i = 0; i < symbolList.size(); i++) { 
     982                        if (comparator.equals(symbolList.get(i).getKey(), symbol)) { 
     983                                // found the symbol. Remove it from the list, and if required, 
     984                                // also from the map. 
     985                                final V value = symbolList.remove(i).getValue(); 
     986 
     987                                if (symbolList.size() > MAX_LIST_SIZE) { 
     988                                        removeFromSymbolBuckets(symbol); 
     989                                } 
     990 
     991                                return value; 
     992                        } 
     993                } 
     994 
     995                return null; 
     996        } 
     997 
     998        /** 
     999         * <p> 
     1000         * Updates the default bucket id to a new one 
     1001         * </p> 
     1002         */ 
     1003        private void setNewDefaultBucketId() { 
     1004                final int oldDefaultBucket = defaultBucket; 
     1005                do { 
     1006                        defaultBucket += 1; 
     1007                } while (symbolBuckets.containsKey(defaultBucket)); 
     1008 
     1009                symbolBuckets 
     1010                                .put(defaultBucket, symbolBuckets.remove(oldDefaultBucket)); 
     1011        } 
     1012 
     1013        /** 
     1014         * <p> 
     1015         * Returns the size of the map, i.e. the number of task instance entries 
     1016         * </p> 
     1017         *  
     1018         * @return as described 
     1019         */ 
     1020        @Override 
     1021        public int size() { 
     1022                return symbolList.size(); 
     1023        } 
    9191024 
    9201025} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskSymbolIdentityMap.java

    r1401 r1733  
    2525/** 
    2626 * <p> 
    27  * symbol map implementation for task instances considering two task instances as equal if their 
    28  * tasks are identical 
     27 * symbol map implementation for task instances considering two task instances 
     28 * as equal if their tasks are identical 
    2929 * </p> 
    3030 *  
     
    3333public class TaskSymbolIdentityMap<V> implements SymbolMap<ITaskInstance, V> { 
    3434 
    35     /**  */ 
    36     private static final long serialVersionUID = 1L; 
    37  
    38     /** 
    39      * <p> 
    40      * internally used map for implementing the symbol map interface 
    41      * </p> 
    42      */ 
    43     private Map<ITask, V> delegate; 
    44  
    45     /** 
    46      * <p> 
    47      * mapping between the tasks and the real symbols stored in the map, i.e. the task instances 
    48      * </p> 
    49      */ 
    50     private Map<ITask, ITaskInstance> symbols; 
    51  
    52     /** 
    53      * <p> 
    54      * initializes this map 
    55      * </p> 
    56      */ 
    57     public TaskSymbolIdentityMap() { 
    58         delegate = new HashMap<ITask, V>(); 
    59         symbols = new HashMap<ITask, ITaskInstance>(); 
    60     } 
    61  
    62     /** 
    63      * <p> 
    64      * copy constructor 
    65      * </p> 
    66      * 
    67      * @param other the map to be copied 
    68      */ 
    69     public TaskSymbolIdentityMap(SymbolMap<ITaskInstance, V> other) { 
    70         if (other == null) { 
    71             throw new IllegalArgumentException("other map must not be null"); 
    72         } 
    73          
    74         delegate = new HashMap<ITask, V>(); 
    75         symbols = new HashMap<ITask, ITaskInstance>(); 
    76          
    77         for (ITaskInstance symbol : other.getSymbols()) { 
    78             delegate.put(symbol.getTask(), other.getValue(symbol)); 
    79             symbols.put(symbol.getTask(), symbol); 
    80         } 
    81     } 
    82  
    83     /* (non-Javadoc) 
    84      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#size() 
    85      */ 
    86     @Override 
    87     public int size() { 
    88         return delegate.size(); 
    89     } 
    90  
    91     /* (non-Javadoc) 
    92      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#isEmpty() 
    93      */ 
    94     @Override 
    95     public boolean isEmpty() { 
    96         return delegate.isEmpty(); 
    97     } 
    98  
    99     /* (non-Javadoc) 
    100      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#containsSymbol(java.lang.Object) 
    101      */ 
    102     @Override 
    103     public boolean containsSymbol(ITaskInstance symbol) { 
    104         if (symbol == null) { 
    105             throw new IllegalArgumentException("symbol must not be null"); 
    106         } 
    107          
    108         return delegate.containsKey(symbol.getTask()); 
    109     } 
    110  
    111     /* (non-Javadoc) 
    112      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValue(java.lang.Object) 
    113      */ 
    114     @Override 
    115     public V getValue(ITaskInstance symbol) { 
    116         if (symbol == null) { 
    117             throw new IllegalArgumentException("symbol must not be null"); 
    118         } 
    119          
    120         return delegate.get(symbol.getTask()); 
    121     } 
    122  
    123     /* (non-Javadoc) 
    124      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#addSymbol(java.lang.Object, java.lang.Object) 
    125      */ 
    126     @Override 
    127     public void addSymbol(ITaskInstance symbol, V value) { 
    128         if (symbol == null) { 
    129             throw new IllegalArgumentException("symbol must not be null"); 
    130         } 
    131          
    132         delegate.put(symbol.getTask(), value); 
    133         symbols.put(symbol.getTask(), symbol); 
    134     } 
    135  
    136     /* (non-Javadoc) 
    137      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#removeSymbol(java.lang.Object) 
    138      */ 
    139     @Override 
    140     public V removeSymbol(ITaskInstance symbol) { 
    141         if (symbol == null) { 
    142             throw new IllegalArgumentException("symbol must not be null"); 
    143         } 
    144          
    145         symbols.remove(symbol.getTask()); 
    146         return delegate.remove(symbol.getTask()); 
    147     } 
    148  
    149     /* (non-Javadoc) 
    150      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getSymbols() 
    151      */ 
    152     @Override 
    153     public Collection<ITaskInstance> getSymbols() { 
    154         return symbols.values(); 
    155     } 
    156  
    157     /* (non-Javadoc) 
    158      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValues() 
    159      */ 
    160     @Override 
    161     public Collection<V> getValues() { 
    162         return delegate.values(); 
    163     } 
    164  
    165     /* (non-Javadoc) 
    166      * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#clear() 
    167      */ 
    168     @Override 
    169     public void clear() { 
    170         delegate.clear(); 
    171     } 
    172  
    173     /* (non-Javadoc) 
    174      * @see java.lang.Object#hashCode() 
    175      */ 
    176     @Override 
    177     public int hashCode() { 
    178         return delegate.hashCode(); 
    179     } 
    180          
    181     /* (non-Javadoc) 
    182      * @see java.lang.Object#equals(java.lang.Object) 
    183      */ 
    184     @SuppressWarnings("unchecked") 
    185     @Override 
    186     public boolean equals(Object obj) { 
    187         if (this == obj) { 
    188             return true; 
    189         } 
    190         else if (this.getClass().isInstance(obj)) { 
    191             return delegate.equals(((TaskSymbolIdentityMap<V>) obj).delegate); 
    192         } 
    193         else { 
    194             return false; 
    195         } 
    196     } 
     35        /**  */ 
     36        private static final long serialVersionUID = 1L; 
     37 
     38        /** 
     39         * <p> 
     40         * internally used map for implementing the symbol map interface 
     41         * </p> 
     42         */ 
     43        private final Map<ITask, V> delegate; 
     44 
     45        /** 
     46         * <p> 
     47         * mapping between the tasks and the real symbols stored in the map, i.e. 
     48         * the task instances 
     49         * </p> 
     50         */ 
     51        private final Map<ITask, ITaskInstance> symbols; 
     52 
     53        /** 
     54         * <p> 
     55         * initializes this map 
     56         * </p> 
     57         */ 
     58        public TaskSymbolIdentityMap() { 
     59                delegate = new HashMap<ITask, V>(); 
     60                symbols = new HashMap<ITask, ITaskInstance>(); 
     61        } 
     62 
     63        /** 
     64         * <p> 
     65         * copy constructor 
     66         * </p> 
     67         * 
     68         * @param other 
     69         *            the map to be copied 
     70         */ 
     71        public TaskSymbolIdentityMap(SymbolMap<ITaskInstance, V> other) { 
     72                if (other == null) { 
     73                        throw new IllegalArgumentException("other map must not be null"); 
     74                } 
     75 
     76                delegate = new HashMap<ITask, V>(); 
     77                symbols = new HashMap<ITask, ITaskInstance>(); 
     78 
     79                for (final ITaskInstance symbol : other.getSymbols()) { 
     80                        delegate.put(symbol.getTask(), other.getValue(symbol)); 
     81                        symbols.put(symbol.getTask(), symbol); 
     82                } 
     83        } 
     84 
     85        /* 
     86         * (non-Javadoc) 
     87         *  
     88         * @see 
     89         * de.ugoe.cs.autoquest.usageprofiles.SymbolMap#addSymbol(java.lang.Object, 
     90         * java.lang.Object) 
     91         */ 
     92        @Override 
     93        public void addSymbol(ITaskInstance symbol, V value) { 
     94                if (symbol == null) { 
     95                        throw new IllegalArgumentException("symbol must not be null"); 
     96                } 
     97 
     98                delegate.put(symbol.getTask(), value); 
     99                symbols.put(symbol.getTask(), symbol); 
     100        } 
     101 
     102        /* 
     103         * (non-Javadoc) 
     104         *  
     105         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#clear() 
     106         */ 
     107        @Override 
     108        public void clear() { 
     109                delegate.clear(); 
     110        } 
     111 
     112        /* 
     113         * (non-Javadoc) 
     114         *  
     115         * @see 
     116         * de.ugoe.cs.autoquest.usageprofiles.SymbolMap#containsSymbol(java.lang 
     117         * .Object) 
     118         */ 
     119        @Override 
     120        public boolean containsSymbol(ITaskInstance symbol) { 
     121                if (symbol == null) { 
     122                        throw new IllegalArgumentException("symbol must not be null"); 
     123                } 
     124 
     125                return delegate.containsKey(symbol.getTask()); 
     126        } 
     127 
     128        /* 
     129         * (non-Javadoc) 
     130         *  
     131         * @see java.lang.Object#equals(java.lang.Object) 
     132         */ 
     133        @SuppressWarnings("unchecked") 
     134        @Override 
     135        public boolean equals(Object obj) { 
     136                if (this == obj) { 
     137                        return true; 
     138                } else if (this.getClass().isInstance(obj)) { 
     139                        return delegate.equals(((TaskSymbolIdentityMap<V>) obj).delegate); 
     140                } else { 
     141                        return false; 
     142                } 
     143        } 
     144 
     145        /* 
     146         * (non-Javadoc) 
     147         *  
     148         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getSymbols() 
     149         */ 
     150        @Override 
     151        public Collection<ITaskInstance> getSymbols() { 
     152                return symbols.values(); 
     153        } 
     154 
     155        /* 
     156         * (non-Javadoc) 
     157         *  
     158         * @see 
     159         * de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValue(java.lang.Object) 
     160         */ 
     161        @Override 
     162        public V getValue(ITaskInstance symbol) { 
     163                if (symbol == null) { 
     164                        throw new IllegalArgumentException("symbol must not be null"); 
     165                } 
     166 
     167                return delegate.get(symbol.getTask()); 
     168        } 
     169 
     170        /* 
     171         * (non-Javadoc) 
     172         *  
     173         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValues() 
     174         */ 
     175        @Override 
     176        public Collection<V> getValues() { 
     177                return delegate.values(); 
     178        } 
     179 
     180        /* 
     181         * (non-Javadoc) 
     182         *  
     183         * @see java.lang.Object#hashCode() 
     184         */ 
     185        @Override 
     186        public int hashCode() { 
     187                return delegate.hashCode(); 
     188        } 
     189 
     190        /* 
     191         * (non-Javadoc) 
     192         *  
     193         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#isEmpty() 
     194         */ 
     195        @Override 
     196        public boolean isEmpty() { 
     197                return delegate.isEmpty(); 
     198        } 
     199 
     200        /* 
     201         * (non-Javadoc) 
     202         *  
     203         * @see 
     204         * de.ugoe.cs.autoquest.usageprofiles.SymbolMap#removeSymbol(java.lang.Object 
     205         * ) 
     206         */ 
     207        @Override 
     208        public V removeSymbol(ITaskInstance symbol) { 
     209                if (symbol == null) { 
     210                        throw new IllegalArgumentException("symbol must not be null"); 
     211                } 
     212 
     213                symbols.remove(symbol.getTask()); 
     214                return delegate.remove(symbol.getTask()); 
     215        } 
     216 
     217        /* 
     218         * (non-Javadoc) 
     219         *  
     220         * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#size() 
     221         */ 
     222        @Override 
     223        public int size() { 
     224                return delegate.size(); 
     225        } 
    197226 
    198227} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java

    r1552 r1733  
    3333 *  
    3434 * <p> 
    35  * This class is responsible for applying temporal relationship rules on a task tree. Through this, 
    36  * a flat task tree is restructured to have more depth but to include more temporal relationships 
    37  * between tasks which are not only a major sequence. I.e. through the application of the 
    38  * rules iterations and selections of tasks are detected. Which kind of temporal relations 
    39  * between tasks are detected depends on the {@link ITaskInstanceScopeRule}s known to 
     35 * This class is responsible for applying temporal relationship rules on a task 
     36 * tree. Through this, a flat task tree is restructured to have more depth but 
     37 * to include more temporal relationships between tasks which are not only a 
     38 * major sequence. I.e. through the application of the rules iterations and 
     39 * selections of tasks are detected. Which kind of temporal relations between 
     40 * tasks are detected depends on the {@link ITaskInstanceScopeRule}s known to 
    4041 * this class. 
    4142 * </p> 
    42  * <p>The class holds references to the appropriate {@link ITaskInstanceScopeRule}s and calls 
    43  * their {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    44  * method for each task in the task tree it is needed for. The general behavior of this class is 
    45  * the following: 
     43 * <p> 
     44 * The class holds references to the appropriate {@link ITaskInstanceScopeRule}s 
     45 * and calls their 
     46 * {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
     47 * method for each task in the task tree it is needed for. The general behavior 
     48 * of this class is the following: 
    4649 * <ol> 
    47  *   <li> 
    48  *     An instance of this class is created using the constructor and calling the 
    49  *     {@link #init()} method afterwards 
    50  *   </li> 
    51  *   <li> 
    52  *     then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    53  *     method is called for a so far unstructured task 
    54  *   </li> 
    55  *   <li> 
    56  *     the class iterates its internal list of rules and calls their 
    57  *     {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    58  *     method. 
    59  *   </li> 
    60  *   <li> 
    61  *     the class evaluates the rule application result 
    62  *     <ul> 
    63  *       <li> 
    64  *         if a rule returns a rule application result that is null, the next rule is tried 
    65  *       </li> 
    66  *       <li> 
    67  *         if a rule returns that it would be feasible if more data was available and the rule 
    68  *         application shall not be finalized (see finalize parameter of the applyRules method) 
    69  *         the rule application is broken up  
    70  *       </li> 
    71  *       <li> 
    72  *         if a rule returns, that it was applied, the same rule is applied again until it returns 
    73  *         null or feasible. For each newly created parent task provided in the rule application 
    74  *         result, the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    75  *         method is called. 
    76  *       </li> 
    77  *     </ul> 
    78  *   </li> 
     50 * <li> 
     51 * An instance of this class is created using the constructor and calling the 
     52 * {@link #init()} method afterwards</li> 
     53 * <li> 
     54 * then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} 
     55 * method is called for a so far unstructured task</li> 
     56 * <li> 
     57 * the class iterates its internal list of rules and calls their 
     58 * {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
     59 * method.</li> 
     60 * <li> 
     61 * the class evaluates the rule application result 
     62 * <ul> 
     63 * <li> 
     64 * if a rule returns a rule application result that is null, the next rule is 
     65 * tried</li> 
     66 * <li> 
     67 * if a rule returns that it would be feasible if more data was available and 
     68 * the rule application shall not be finalized (see finalize parameter of the 
     69 * applyRules method) the rule application is broken up</li> 
     70 * <li> 
     71 * if a rule returns, that it was applied, the same rule is applied again until 
     72 * it returns null or feasible. For each newly created parent task provided in 
     73 * the rule application result, the 
     74 * {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} method is 
     75 * called.</li> 
     76 * </ul> 
     77 * </li> 
    7978 * </ol> 
    80  * Through this, all rules are tried to be applied at least once to the provided parent task and 
    81  * all parent tasks created during the rule application. 
     79 * Through this, all rules are tried to be applied at least once to the provided 
     80 * parent task and all parent tasks created during the rule application. 
    8281 * </p> 
    8382 *  
     
    8584 */ 
    8685public class TemporalRelationshipRuleManager { 
    87      
    88     /** 
    89      * <p> 
    90      * the task factory to be used during rule application 
    91      * </p> 
    92      */ 
    93     private ITaskFactory taskFactory; 
    94  
    95     /** 
    96      * <p> 
    97      * the task builder to be used during rule application 
    98      * </p> 
    99      */ 
    100     private ITaskBuilder taskBuilder; 
    101  
    102     /** 
    103      * <p> 
    104      * the temporal relationship rules known to the manager that are executed on whole sessions. 
    105      * The rules are applied in the order they occur in this list. 
    106      * </p> 
    107      */ 
    108     private ISessionScopeRule[] sessionScopeRules; 
    109  
    110     /** 
    111      * <p> 
    112      * the temporal relationship rules known to the manager that are executed on whole sub trees. 
    113      * The rules are applied in the order they occur in this list. 
    114      * </p> 
    115      */ 
    116     private ITaskInstanceScopeRule[] taskScopeRules; 
    117  
    118     /** 
    119      * <p> 
    120      * initialize the manager 
    121      * </p> 
    122      *  
    123      * @param taskFactory             the task factory to be used for instantiating new task tree 
    124      *                                tasks during rule application 
    125      * @param taskBuilder             the task builder to be used for linking tasks 
    126      *                                with each other during rule application 
    127      */ 
    128     public TemporalRelationshipRuleManager(ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
    129         super(); 
    130         this.taskFactory = taskFactory; 
    131         this.taskBuilder = taskBuilder; 
    132     } 
    133  
    134     /** 
    135      * <p> 
    136      * initialized the temporal relationship rule manager by instantiating the known rules and 
    137      * providing them with a reference to the task equality manager or other information they need. 
    138      * </p> 
    139      */ 
    140     public void init() { 
    141         List<Class<? extends IGUIElement>> frameFilter = 
    142             new ArrayList<Class<? extends IGUIElement>>(); 
    143         frameFilter.add(IFrame.class); 
    144         frameFilter.add(IDialog.class); 
    145         //frameFilter.add(ICanvas.class); 
    146  
    147         sessionScopeRules = new ISessionScopeRule[] { 
    148             new SequenceForTaskDetectionRuleAlignment 
    149                 (TaskEquality.SEMANTICALLY_EQUAL, taskFactory, taskBuilder), 
    150             /*new DefaultTaskSequenceDetectionRule 
    151                 (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder), 
    152             new DefaultTaskSequenceDetectionRule 
    153                 (NodeEquality.LEXICALLY_EQUAL, taskFactory, taskTreeBuilder),*/ 
    154             /*new TreeScopeWrapperRule 
    155                 (new DefaultIterationDetectionRule 
    156                     (NodeEquality.LEXICALLY_EQUAL, taskFactory, taskTreeBuilder)), 
    157             new TreeScopeWrapperRule 
    158                 (new DefaultIterationDetectionRule 
    159                     (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder)), 
    160             new TreeScopeWrapperRule 
    161                 (new DefaultIterationDetectionRule 
    162                     (NodeEquality.SEMANTICALLY_EQUAL, taskFactory, taskTreeBuilder))*/ 
    163         }; 
    164          
    165         //treeScopeRules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter)); 
    166  
    167         taskScopeRules = new ITaskInstanceScopeRule[] { 
    168             //new SequenceOnGuiElementDetectionRule(taskFactory, taskTreeBuilder), 
    169             //new EventSequenceOnSameTargetDetectionRule(taskFactory, taskTreeBuilder), 
    170             //new TrackBarSelectionDetectionRule(taskFactory, taskBuilder), 
    171             //new DefaultGuiEventSequenceDetectionRule(taskFactory, taskTreeBuilder), 
    172         }; 
    173  
    174     } 
    175  
    176     /** 
    177      * <p> 
    178      * applies the known rules to the provided sessions. For the creation of further tasks, 
    179      * the provided builder and task factory are utilized. The method expects, that no more data 
    180      * is available and, therefore, finalizes the rule application. 
    181      * </p> 
    182      *  
    183      * @param taskFactory  the task factory to be used for instantiating new tasks. 
    184      */ 
    185     public void applyRules(List<IUserSession> sessions) { 
    186         applyRules(sessionScopeRules, sessions, ""); 
    187     } 
    188  
    189     /** 
    190      * <p> 
    191      * applies the known rules to the provided parent task. For the creation of further tasks, 
    192      * the provided builder and task factory are utilized. If the finalize parameter is true, the 
    193      * rule application is finalized as far as possible without waiting for further data. If it is 
    194      * false, the rule application is broken up at the first rule returning, that its application 
    195      * would be feasible. The method calls itself for each parent task created through the rule 
    196      * application. In this case, the finalize parameter is always true. 
    197      * </p> 
    198      *  
    199      * @param parent       the parent task to apply the rules on 
    200      * @param finalize     used to indicate, if the rule application shall break up if a rule would 
    201      *                     be feasible if further data was available, or not. 
    202      * @param logIndent    simply used for logging purposes to indent the log messages depending 
    203      *                     on the recursion depth of calling this method. 
    204      */ 
    205     private int applyRules(ISessionScopeRule[] rules, 
    206                            List<IUserSession>  sessions, 
    207                            String              logIndent) 
    208     { 
    209         Console.traceln 
    210             (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions"); 
    211  
    212         int noOfRuleApplications = 0; 
    213  
    214         for (ISessionScopeRule rule : rules) { 
    215             RuleApplicationResult result; 
    216             do { 
    217                 Console.traceln(Level.FINER, logIndent + "trying rule " + rule); 
    218                 result = rule.apply(sessions); 
    219  
    220                 if ((result != null) && 
    221                     (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) 
    222                 { 
    223                     Console.traceln(Level.FINE, logIndent + "applied rule " + rule); 
    224                     noOfRuleApplications++; 
    225                      
    226                     //dumpTask(parent, ""); 
    227  
    228                     for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) { 
    229                         noOfRuleApplications += 
    230                             applyRules(taskScopeRules, newParent, logIndent + "  "); 
    231                     } 
    232                 } 
    233             } 
    234             while ((result != null) && 
    235                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
    236  
    237         } 
    238  
    239         if (noOfRuleApplications <= 0) { 
    240             Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " + 
    241                             "relationship generated"); 
    242         } 
    243  
    244         return noOfRuleApplications; 
    245     } 
    246  
    247     /** 
    248      * <p> 
    249      * applies the known rules to the provided parent task. For the creation of further tasks, 
    250      * the provided builder and task factory are utilized. If the finalize parameter is true, the 
    251      * rule application is finalized as far as possible without waiting for further data. If it is 
    252      * false, the rule application is broken up at the first rule returning, that its application 
    253      * would be feasible. The method calls itself for each parent task created through the rule 
    254      * application. In this case, the finalize parameter is always true. 
    255      * </p> 
    256      *  
    257      * @param parent       the parent task to apply the rules on 
    258      * @param finalize     used to indicate, if the rule application shall break up if a rule would 
    259      *                     be feasible if further data was available, or not. 
    260      * @param logIndent    simply used for logging purposes to indent the log messages depending 
    261      *                     on the recursion depth of calling this method. 
    262      */ 
    263     private int applyRules(ITaskInstanceScopeRule[] rules, 
    264                            ITaskInstance                taskInstance, 
    265                            String                       logIndent) 
    266     { 
    267         Console.traceln(Level.FINER, logIndent + "applying rules on " + taskInstance); 
    268  
    269         int noOfRuleApplications = 0; 
    270  
    271         for (ITaskInstanceScopeRule rule : rules) { 
    272             RuleApplicationResult result; 
    273             do { 
    274                 Console.traceln 
    275                     (Level.FINER, logIndent + "trying rule " + rule + " on " + taskInstance); 
    276                 result = rule.apply(taskInstance); 
    277  
    278                 if ((result != null) && 
    279                     (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) 
    280                 { 
    281                     Console.traceln 
    282                         (Level.FINE, logIndent + "applied rule " + rule + " on " + taskInstance); 
    283                     noOfRuleApplications++; 
    284                      
    285                     //dumpTask(parent, ""); 
    286  
    287                     for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) { 
    288                         noOfRuleApplications += 
    289                             applyRules(taskScopeRules, newParent, logIndent + "  "); 
    290                     } 
    291                 } 
    292             } 
    293             while ((result != null) && 
    294                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
    295         } 
    296  
    297         if (noOfRuleApplications <= 0) { 
    298             Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " + 
    299                             "relationship generated"); 
    300         } 
    301  
    302         return noOfRuleApplications; 
    303     } 
    304  
    305     /** 
    306      * 
    307      */ 
    308     /*private void dumpTask(ITask task, String indent) { 
    309         StringBuffer message = new StringBuffer(); 
    310         message.append(indent); 
    311         message.append(task); 
    312         if (task.getDescription() != null) { 
    313             message.append('('); 
    314             message.append(task.getDescription()); 
    315             message.append(')'); 
    316         } 
    317          
    318         Console.traceln(Level.FINER, message.toString()); 
    319          
    320         if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { 
    321             for (ITask child : task.getChildren()) { 
    322                 dumpTask(child, indent + "  "); 
    323             } 
    324         } 
    325     }*/ 
     86 
     87        /** 
     88         * <p> 
     89         * the task factory to be used during rule application 
     90         * </p> 
     91         */ 
     92        private final ITaskFactory taskFactory; 
     93 
     94        /** 
     95         * <p> 
     96         * the task builder to be used during rule application 
     97         * </p> 
     98         */ 
     99        private final ITaskBuilder taskBuilder; 
     100 
     101        /** 
     102         * <p> 
     103         * the temporal relationship rules known to the manager that are executed on 
     104         * whole sessions. The rules are applied in the order they occur in this 
     105         * list. 
     106         * </p> 
     107         */ 
     108        private ISessionScopeRule[] sessionScopeRules; 
     109 
     110        /** 
     111         * <p> 
     112         * the temporal relationship rules known to the manager that are executed on 
     113         * whole sub trees. The rules are applied in the order they occur in this 
     114         * list. 
     115         * </p> 
     116         */ 
     117        private ITaskInstanceScopeRule[] taskScopeRules; 
     118 
     119        /** 
     120         * <p> 
     121         * initialize the manager 
     122         * </p> 
     123         *  
     124         * @param taskFactory 
     125         *            the task factory to be used for instantiating new task tree 
     126         *            tasks during rule application 
     127         * @param taskBuilder 
     128         *            the task builder to be used for linking tasks with each other 
     129         *            during rule application 
     130         */ 
     131        public TemporalRelationshipRuleManager(ITaskFactory taskFactory, 
     132                        ITaskBuilder taskBuilder) { 
     133                super(); 
     134                this.taskFactory = taskFactory; 
     135                this.taskBuilder = taskBuilder; 
     136        } 
     137 
     138        /** 
     139         * <p> 
     140         * applies the known rules to the provided parent task. For the creation of 
     141         * further tasks, the provided builder and task factory are utilized. If the 
     142         * finalize parameter is true, the rule application is finalized as far as 
     143         * possible without waiting for further data. If it is false, the rule 
     144         * application is broken up at the first rule returning, that its 
     145         * application would be feasible. The method calls itself for each parent 
     146         * task created through the rule application. In this case, the finalize 
     147         * parameter is always true. 
     148         * </p> 
     149         *  
     150         * @param parent 
     151         *            the parent task to apply the rules on 
     152         * @param finalize 
     153         *            used to indicate, if the rule application shall break up if a 
     154         *            rule would be feasible if further data was available, or not. 
     155         * @param logIndent 
     156         *            simply used for logging purposes to indent the log messages 
     157         *            depending on the recursion depth of calling this method. 
     158         */ 
     159        private int applyRules(ISessionScopeRule[] rules, 
     160                        List<IUserSession> sessions, String logIndent) { 
     161                Console.traceln(Level.FINER, logIndent + "applying rules for " 
     162                                + sessions.size() + " sessions"); 
     163 
     164                int noOfRuleApplications = 0; 
     165 
     166                for (final ISessionScopeRule rule : rules) { 
     167                        RuleApplicationResult result; 
     168                        do { 
     169                                Console.traceln(Level.FINER, logIndent + "trying rule " + rule); 
     170                                result = rule.apply(sessions); 
     171 
     172                                if ((result != null) 
     173                                                && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) { 
     174                                        Console.traceln(Level.FINE, logIndent + "applied rule " 
     175                                                        + rule); 
     176                                        noOfRuleApplications++; 
     177 
     178                                        // dumpTask(parent, ""); 
     179 
     180                                        for (final ITaskInstance newParent : result 
     181                                                        .getNewlyCreatedTaskInstances()) { 
     182                                                noOfRuleApplications += applyRules(taskScopeRules, 
     183                                                                newParent, logIndent + "  "); 
     184                                        } 
     185                                } 
     186                        } while ((result != null) 
     187                                        && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
     188 
     189                } 
     190 
     191                if (noOfRuleApplications <= 0) { 
     192                        Console.traceln(Level.FINE, logIndent 
     193                                        + "no rules applied --> no temporal " 
     194                                        + "relationship generated"); 
     195                } 
     196 
     197                return noOfRuleApplications; 
     198        } 
     199 
     200        /** 
     201         * <p> 
     202         * applies the known rules to the provided parent task. For the creation of 
     203         * further tasks, the provided builder and task factory are utilized. If the 
     204         * finalize parameter is true, the rule application is finalized as far as 
     205         * possible without waiting for further data. If it is false, the rule 
     206         * application is broken up at the first rule returning, that its 
     207         * application would be feasible. The method calls itself for each parent 
     208         * task created through the rule application. In this case, the finalize 
     209         * parameter is always true. 
     210         * </p> 
     211         *  
     212         * @param parent 
     213         *            the parent task to apply the rules on 
     214         * @param finalize 
     215         *            used to indicate, if the rule application shall break up if a 
     216         *            rule would be feasible if further data was available, or not. 
     217         * @param logIndent 
     218         *            simply used for logging purposes to indent the log messages 
     219         *            depending on the recursion depth of calling this method. 
     220         */ 
     221        private int applyRules(ITaskInstanceScopeRule[] rules, 
     222                        ITaskInstance taskInstance, String logIndent) { 
     223                Console.traceln(Level.FINER, logIndent + "applying rules on " 
     224                                + taskInstance); 
     225 
     226                int noOfRuleApplications = 0; 
     227 
     228                for (final ITaskInstanceScopeRule rule : rules) { 
     229                        RuleApplicationResult result; 
     230                        do { 
     231                                Console.traceln(Level.FINER, logIndent + "trying rule " + rule 
     232                                                + " on " + taskInstance); 
     233                                result = rule.apply(taskInstance); 
     234 
     235                                if ((result != null) 
     236                                                && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) { 
     237                                        Console.traceln(Level.FINE, logIndent + "applied rule " 
     238                                                        + rule + " on " + taskInstance); 
     239                                        noOfRuleApplications++; 
     240 
     241                                        // dumpTask(parent, ""); 
     242 
     243                                        for (final ITaskInstance newParent : result 
     244                                                        .getNewlyCreatedTaskInstances()) { 
     245                                                noOfRuleApplications += applyRules(taskScopeRules, 
     246                                                                newParent, logIndent + "  "); 
     247                                        } 
     248                                } 
     249                        } while ((result != null) 
     250                                        && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
     251                } 
     252 
     253                if (noOfRuleApplications <= 0) { 
     254                        Console.traceln(Level.FINE, logIndent 
     255                                        + "no rules applied --> no temporal " 
     256                                        + "relationship generated"); 
     257                } 
     258 
     259                return noOfRuleApplications; 
     260        } 
     261 
     262        /** 
     263         * <p> 
     264         * applies the known rules to the provided sessions. For the creation of 
     265         * further tasks, the provided builder and task factory are utilized. The 
     266         * method expects, that no more data is available and, therefore, finalizes 
     267         * the rule application. 
     268         * </p> 
     269         *  
     270         * @param taskFactory 
     271         *            the task factory to be used for instantiating new tasks. 
     272         */ 
     273        public void applyRules(List<IUserSession> sessions) { 
     274                applyRules(sessionScopeRules, sessions, ""); 
     275        } 
     276 
     277        /** 
     278         * <p> 
     279         * initialized the temporal relationship rule manager by instantiating the 
     280         * known rules and providing them with a reference to the task equality 
     281         * manager or other information they need. 
     282         * </p> 
     283         */ 
     284        public void init() { 
     285                final List<Class<? extends IGUIElement>> frameFilter = new ArrayList<Class<? extends IGUIElement>>(); 
     286                frameFilter.add(IFrame.class); 
     287                frameFilter.add(IDialog.class); 
     288                // frameFilter.add(ICanvas.class); 
     289 
     290                sessionScopeRules = new ISessionScopeRule[] { new SequenceForTaskDetectionRuleAlignment( 
     291                                TaskEquality.SEMANTICALLY_EQUAL, taskFactory, taskBuilder), 
     292                /* 
     293                 * new DefaultTaskSequenceDetectionRule 
     294                 * (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder), new 
     295                 * DefaultTaskSequenceDetectionRule (NodeEquality.LEXICALLY_EQUAL, 
     296                 * taskFactory, taskTreeBuilder), 
     297                 */ 
     298                /* 
     299                 * new TreeScopeWrapperRule (new DefaultIterationDetectionRule 
     300                 * (NodeEquality.LEXICALLY_EQUAL, taskFactory, taskTreeBuilder)), new 
     301                 * TreeScopeWrapperRule (new DefaultIterationDetectionRule 
     302                 * (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder)), 
     303                 * new TreeScopeWrapperRule (new DefaultIterationDetectionRule 
     304                 * (NodeEquality.SEMANTICALLY_EQUAL, taskFactory, taskTreeBuilder)) 
     305                 */ 
     306                }; 
     307 
     308                // treeScopeRules.add(new 
     309                // DefaultGuiElementSequenceDetectionRule(frameFilter)); 
     310 
     311                taskScopeRules = new ITaskInstanceScopeRule[] { 
     312                // new SequenceOnGuiElementDetectionRule(taskFactory, taskTreeBuilder), 
     313                // new EventSequenceOnSameTargetDetectionRule(taskFactory, 
     314                // taskTreeBuilder), 
     315                // new TrackBarSelectionDetectionRule(taskFactory, taskBuilder), 
     316                // new DefaultGuiEventSequenceDetectionRule(taskFactory, 
     317                // taskTreeBuilder), 
     318                }; 
     319 
     320        } 
     321 
     322        /** 
     323         * 
     324         */ 
     325        /* 
     326         * private void dumpTask(ITask task, String indent) { StringBuffer message = 
     327         * new StringBuffer(); message.append(indent); message.append(task); if 
     328         * (task.getDescription() != null) { message.append('('); 
     329         * message.append(task.getDescription()); message.append(')'); } 
     330         *  
     331         * Console.traceln(Level.FINER, message.toString()); 
     332         *  
     333         * if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { 
     334         * for (ITask child : task.getChildren()) { dumpTask(child, indent + "  "); 
     335         * } } } 
     336         */ 
    326337 
    327338} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/DefaultTaskInstanceTraversingVisitor.java

    r1406 r1733  
    1717/** 
    1818 * <p> 
    19  * Default implementation for a task instance visitor performing a traversal of the instances 
     19 * Default implementation for a task instance visitor performing a traversal of 
     20 * the instances 
    2021 * </p> 
    2122 *  
    2223 * @author Patrick Harms 
    2324 */ 
    24 public class DefaultTaskInstanceTraversingVisitor implements ITaskInstanceVisitor { 
     25public class DefaultTaskInstanceTraversingVisitor implements 
     26                ITaskInstanceVisitor { 
    2527 
    26     /* (non-Javadoc) 
    27      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(IEventTaskInstance) 
    28      */ 
    29     @Override 
    30     public void visit(IEventTaskInstance eventTaskInstance) { 
    31         // do nothing 
    32     } 
     28        /* 
     29         * (non-Javadoc) 
     30         *  
     31         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     32         * IEventTaskInstance) 
     33         */ 
     34        @Override 
     35        public void visit(IEventTaskInstance eventTaskInstance) { 
     36                // do nothing 
     37        } 
    3338 
    34     /* (non-Javadoc) 
    35      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(IIterationInstance) 
    36      */ 
    37     @Override 
    38     public void visit(IIterationInstance iterationInstance) { 
    39         visit((ITaskInstanceList) iterationInstance); 
    40     } 
     39        /* 
     40         * (non-Javadoc) 
     41         *  
     42         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     43         * IIterationInstance) 
     44         */ 
     45        @Override 
     46        public void visit(IIterationInstance iterationInstance) { 
     47                visit((ITaskInstanceList) iterationInstance); 
     48        } 
    4149 
    42     /* (non-Javadoc) 
    43      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(IOptionalInstance) 
    44      */ 
    45     @Override 
    46     public void visit(IOptionalInstance optionalInstance) { 
    47         if (optionalInstance.getChild() != null) { 
    48             optionalInstance.getChild().accept(this); 
    49         } 
    50     } 
     50        /* 
     51         * (non-Javadoc) 
     52         *  
     53         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     54         * IOptionalInstance) 
     55         */ 
     56        @Override 
     57        public void visit(IOptionalInstance optionalInstance) { 
     58                if (optionalInstance.getChild() != null) { 
     59                        optionalInstance.getChild().accept(this); 
     60                } 
     61        } 
    5162 
    52     /* (non-Javadoc) 
    53      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(ISelectionInstance) 
    54      */ 
    55     @Override 
    56     public void visit(ISelectionInstance selectionInstance) { 
    57         selectionInstance.getChild().accept(this); 
    58     } 
     63        /* 
     64         * (non-Javadoc) 
     65         *  
     66         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     67         * ISelectionInstance) 
     68         */ 
     69        @Override 
     70        public void visit(ISelectionInstance selectionInstance) { 
     71                selectionInstance.getChild().accept(this); 
     72        } 
    5973 
    60     /* (non-Javadoc) 
    61      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(ISequenceInstance) 
    62      */ 
    63     @Override 
    64     public void visit(ISequenceInstance sequenceInstance) { 
    65         visit((ITaskInstanceList) sequenceInstance); 
    66     } 
     74        /* 
     75         * (non-Javadoc) 
     76         *  
     77         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     78         * ISequenceInstance) 
     79         */ 
     80        @Override 
     81        public void visit(ISequenceInstance sequenceInstance) { 
     82                visit((ITaskInstanceList) sequenceInstance); 
     83        } 
    6784 
    68     /* (non-Javadoc) 
    69      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit(ITaskInstance) 
    70      */ 
    71     @Override 
    72     public void visit(ITaskInstance taskInstance) { 
    73         if (taskInstance instanceof IEventTaskInstance) { 
    74             visit((IEventTaskInstance) taskInstance); 
    75         } 
    76         else if (taskInstance instanceof IIterationInstance) { 
    77             visit((IIterationInstance) taskInstance); 
    78         } 
    79         else if (taskInstance instanceof IOptionalInstance) { 
    80             visit((IOptionalInstance) taskInstance); 
    81         } 
    82         else if (taskInstance instanceof ISelectionInstance) { 
    83             visit((ISelectionInstance) taskInstance); 
    84         } 
    85         else if (taskInstance instanceof ISequenceInstance) { 
    86             visit((ISequenceInstance) taskInstance); 
    87         } 
    88     } 
     85        /* 
     86         * (non-Javadoc) 
     87         *  
     88         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceVisitor#visit( 
     89         * ITaskInstance) 
     90         */ 
     91        @Override 
     92        public void visit(ITaskInstance taskInstance) { 
     93                if (taskInstance instanceof IEventTaskInstance) { 
     94                        visit((IEventTaskInstance) taskInstance); 
     95                } else if (taskInstance instanceof IIterationInstance) { 
     96                        visit((IIterationInstance) taskInstance); 
     97                } else if (taskInstance instanceof IOptionalInstance) { 
     98                        visit((IOptionalInstance) taskInstance); 
     99                } else if (taskInstance instanceof ISelectionInstance) { 
     100                        visit((ISelectionInstance) taskInstance); 
     101                } else if (taskInstance instanceof ISequenceInstance) { 
     102                        visit((ISequenceInstance) taskInstance); 
     103                } 
     104        } 
    89105 
    90  
    91     /** 
    92      * <p> 
    93      * common implementation for traversing task instance lists. 
    94      * </p> 
    95      *  
    96      * @param taskInstanceList the task instance list to be traversed 
    97     */ 
    98     public void visit(ITaskInstanceList taskInstanceList) { 
    99         for (ITaskInstance child : taskInstanceList) { 
    100             child.accept(this); 
    101         } 
    102     } 
     106        /** 
     107         * <p> 
     108         * common implementation for traversing task instance lists. 
     109         * </p> 
     110         *  
     111         * @param taskInstanceList 
     112         *            the task instance list to be traversed 
     113        */ 
     114        public void visit(ITaskInstanceList taskInstanceList) { 
     115                for (final ITaskInstance child : taskInstanceList) { 
     116                        child.accept(this); 
     117                } 
     118        } 
    103119} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/DefaultTaskTraversingVisitor.java

    r1409 r1733  
    2424public class DefaultTaskTraversingVisitor implements ITaskVisitor { 
    2525 
    26     /* (non-Javadoc) 
    27      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IEventTask) 
    28      */ 
    29     @Override 
    30     public void visit(IEventTask eventTask) { 
    31         // do nothing 
    32     } 
     26        /* 
     27         * (non-Javadoc) 
     28         *  
     29         * @see 
     30         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IEventTask) 
     31         */ 
     32        @Override 
     33        public void visit(IEventTask eventTask) { 
     34                // do nothing 
     35        } 
    3336 
    34     /* (non-Javadoc) 
    35      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IIteration) 
    36      */ 
    37     @Override 
    38     public void visit(IIteration iteration) { 
    39         visit((IMarkingTemporalRelationship) iteration); 
    40     } 
     37        /* 
     38         * (non-Javadoc) 
     39         *  
     40         * @see 
     41         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IIteration) 
     42         */ 
     43        @Override 
     44        public void visit(IIteration iteration) { 
     45                visit((IMarkingTemporalRelationship) iteration); 
     46        } 
    4147 
    42     /* (non-Javadoc) 
    43      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IOptional) 
    44      */ 
    45     @Override 
    46     public void visit(IOptional optional) { 
    47         visit((IMarkingTemporalRelationship) optional); 
    48     } 
     48        /** 
     49         * <p> 
     50         * common implementation for traversing a marking temporal relationship 
     51         * </p> 
     52         *  
     53         * @param relationship 
     54         *            the marking temporal relationship to be traversed 
     55         */ 
     56        public void visit(IMarkingTemporalRelationship relationship) { 
     57                if (relationship.getMarkedTask() != null) { 
     58                        relationship.getMarkedTask().accept(this); 
     59                } 
     60        } 
    4961 
    50     /* (non-Javadoc) 
    51      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ISelection) 
    52      */ 
    53     @Override 
    54     public void visit(ISelection selection) { 
    55         visit((IStructuringTemporalRelationship) selection); 
    56     } 
     62        /* 
     63         * (non-Javadoc) 
     64         *  
     65         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(IOptional) 
     66         */ 
     67        @Override 
     68        public void visit(IOptional optional) { 
     69                visit((IMarkingTemporalRelationship) optional); 
     70        } 
    5771 
    58     /* (non-Javadoc) 
    59      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ISequence) 
    60      */ 
    61     @Override 
    62     public void visit(ISequence sequence) { 
    63         visit((IStructuringTemporalRelationship) sequence); 
    64     } 
     72        /* 
     73         * (non-Javadoc) 
     74         *  
     75         * @see 
     76         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ISelection) 
     77         */ 
     78        @Override 
     79        public void visit(ISelection selection) { 
     80                visit((IStructuringTemporalRelationship) selection); 
     81        } 
    6582 
    66     /* (non-Javadoc) 
    67      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ITask) 
    68      */ 
    69     @Override 
    70     public void visit(ITask task) { 
    71         if (task instanceof IEventTask) { 
    72             visit((IEventTask) task); 
    73         } 
    74         else if (task instanceof IIteration) { 
    75             visit((IIteration) task); 
    76         } 
    77         else if (task instanceof IOptional) { 
    78             visit((IOptional) task); 
    79         } 
    80         else if (task instanceof ISelection) { 
    81             visit((ISelection) task); 
    82         } 
    83         else if (task instanceof ISequence) { 
    84             visit((ISequence) task); 
    85         } 
    86     } 
     83        /* 
     84         * (non-Javadoc) 
     85         *  
     86         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ISequence) 
     87         */ 
     88        @Override 
     89        public void visit(ISequence sequence) { 
     90                visit((IStructuringTemporalRelationship) sequence); 
     91        } 
    8792 
    88     /** 
    89      * <p> 
    90      * common implementation for traversing a structuring temporal relationship  
    91      * </p> 
    92      *  
    93      * @param relationship the structuring temporal relationship to be traversed 
    94      */ 
    95     public void visit(IStructuringTemporalRelationship relationship) { 
    96         for (ITask child : relationship.getChildren()) { 
    97             child.accept(this); 
    98         } 
    99     } 
     93        /** 
     94         * <p> 
     95         * common implementation for traversing a structuring temporal relationship 
     96         * </p> 
     97         *  
     98         * @param relationship 
     99         *            the structuring temporal relationship to be traversed 
     100         */ 
     101        public void visit(IStructuringTemporalRelationship relationship) { 
     102                for (final ITask child : relationship.getChildren()) { 
     103                        child.accept(this); 
     104                } 
     105        } 
    100106 
    101     /** 
    102      * <p> 
    103      * common implementation for traversing a marking temporal relationship  
    104      * </p> 
    105      *  
    106      * @param relationship the marking temporal relationship to be traversed 
    107      */ 
    108     public void visit(IMarkingTemporalRelationship relationship) { 
    109         if (relationship.getMarkedTask() != null) { 
    110             relationship.getMarkedTask().accept(this); 
    111         } 
    112     } 
     107        /* 
     108         * (non-Javadoc) 
     109         *  
     110         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor#visit(ITask) 
     111         */ 
     112        @Override 
     113        public void visit(ITask task) { 
     114                if (task instanceof IEventTask) { 
     115                        visit((IEventTask) task); 
     116                } else if (task instanceof IIteration) { 
     117                        visit((IIteration) task); 
     118                } else if (task instanceof IOptional) { 
     119                        visit((IOptional) task); 
     120                } else if (task instanceof ISelection) { 
     121                        visit((ISelection) task); 
     122                } else if (task instanceof ISequence) { 
     123                        visit((ISequence) task); 
     124                } 
     125        } 
    113126} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IEventTask.java

    r1294 r1733  
    1717/** 
    1818 * <p> 
    19  * Event tasks represent single events. They have no children and are therefore the leaf nodes of 
    20  * a task model. They provide information about the event they represent as a String description. 
    21  * They do not refer to events, as they may represented several semantically equal but lexically 
    22  * different events. Their description carries as much information as required to show the 
    23  * level of distinction. 
     19 * Event tasks represent single events. They have no children and are therefore 
     20 * the leaf nodes of a task model. They provide information about the event they 
     21 * represent as a String description. They do not refer to events, as they may 
     22 * represented several semantically equal but lexically different events. Their 
     23 * description carries as much information as required to show the level of 
     24 * distinction. 
    2425 * </p> 
    2526 *  
     
    2728 */ 
    2829public interface IEventTask extends ITask { 
    29      
    30     /** 
    31      * <p> 
    32      * returns a clone of this task, i.e. another event task being identical to this. The event 
    33      * type and target are not cloned but reused. 
    34      * </p> 
    35      *  
    36      * @return as described 
    37      */ 
    38     public IEventTask clone(); 
     30 
     31        /** 
     32         * <p> 
     33         * returns a clone of this task, i.e. another event task being identical to 
     34         * this. The event type and target are not cloned but reused. 
     35         * </p> 
     36         *  
     37         * @return as described 
     38         */ 
     39        @Override 
     40        public IEventTask clone(); 
    3941 
    4042} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IEventTaskInstance.java

    r1398 r1733  
    1919/** 
    2020 * <p> 
    21  * the instance of an {@link IEventTask}. The instance refers to the concrete event it represents. 
     21 * the instance of an {@link IEventTask}. The instance refers to the concrete 
     22 * event it represents. 
    2223 * </p> 
    2324 *  
     
    2627public interface IEventTaskInstance extends ITaskInstance { 
    2728 
    28     /** 
    29      * <p> 
    30      * returns the event represented by this event task instance 
    31      * </p> 
    32      *  
    33      * @return as described 
    34      */ 
    35     public Event getEvent(); 
     29        /** 
     30         * <p> 
     31         * clones this task instance by creating exact clones of itself. The 
     32         * referred task and event stay untouched 
     33         * </p> 
     34         *  
     35         * @return a clone of the task instance 
     36         */ 
     37        @Override 
     38        public IEventTaskInstance clone(); 
    3639 
    37     /** 
    38     * <p> 
    39      * returns the task related to the instance, i.e. the event task. 
    40     * </p> 
    41     *  
    42     * @return as described 
    43     */ 
    44     public IEventTask getEventTask(); 
     40        /** 
     41        * <p> 
     42         * returns the event represented by this event task instance 
     43        * </p> 
     44        *  
     45        * @return as described 
     46        */ 
     47        public Event getEvent(); 
    4548 
    46     /** 
    47      * <p> 
    48      * clones this task instance by creating exact clones of itself. The referred task and event 
    49      * stay untouched 
    50      * </p> 
    51      *  
    52      * @return a clone of the task instance 
    53      */ 
    54     public IEventTaskInstance clone(); 
    55      
     49        /** 
     50         * <p> 
     51         * returns the task related to the instance, i.e. the event task. 
     52         * </p> 
     53         *  
     54         * @return as described 
     55         */ 
     56        public IEventTask getEventTask(); 
     57 
    5658} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IIteration.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * This temporal relationship defines that its single child may be executed zero or more times for 
    20  * fulfilling the task. This is most important for the parent node in the task model as this 
    21  * node may require that a specific subtask is executed several times. 
     19 * This temporal relationship defines that its single child may be executed zero 
     20 * or more times for fulfilling the task. This is most important for the parent 
     21 * node in the task model as this node may require that a specific subtask is 
     22 * executed several times. 
    2223 * </p> 
    2324 *  
     
    2627public interface IIteration extends IMarkingTemporalRelationship { 
    2728 
    28     /** 
    29      * <p> 
    30      * returns an exact copy of this temporal relationship. The clone has the same id. Its child 
    31      * is a clone of the child of the cloned task. A call on the method {@link #equals(ITask)} 
    32      * with the result of this method must return true. 
    33      * </p> 
    34      *  
    35      * @return as described 
    36      */ 
    37     public IIteration clone(); 
     29        /** 
     30         * <p> 
     31         * returns an exact copy of this temporal relationship. The clone has the 
     32         * same id. Its child is a clone of the child of the cloned task. A call on 
     33         * the method {@link #equals(ITask)} with the result of this method must 
     34         * return true. 
     35         * </p> 
     36         *  
     37         * @return as described 
     38         */ 
     39        @Override 
     40        public IIteration clone(); 
    3841 
    3942} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IIterationInstance.java

    r1398 r1733  
    1717/** 
    1818 * <p> 
    19  * the instance of an {@link IIteration}. The instance may have several children each being an 
    20  * instance of the task marked by the iteration of which this is an instance. 
     19 * the instance of an {@link IIteration}. The instance may have several children 
     20 * each being an instance of the task marked by the iteration of which this is 
     21 * an instance. 
    2122 * </p> 
    2223 *  
     
    2526public interface IIterationInstance extends ITaskInstance, ITaskInstanceList { 
    2627 
    27     /** 
    28      * <p> 
    29      * returns the task related to the instance, i.e. the iteration. 
    30      * </p> 
    31      *  
    32      * @return as described 
    33      */ 
    34     public IIteration getIteration(); 
     28        /** 
     29         * <p> 
     30         * clones this task instance by creating exact clones of each contained 
     31         * instance in their order 
     32         * </p> 
     33         *  
     34         * @return a clone of the task instance list 
     35         */ 
     36        @Override 
     37        public IIterationInstance clone(); 
    3538 
    36     /** 
    37      * <p> 
    38      * clones this task instance by creating exact clones of each contained instance in their 
    39      * order 
    40      * </p> 
    41      *  
    42      * @return a clone of the task instance list 
    43      */ 
    44     public IIterationInstance clone(); 
     39        /** 
     40         * <p> 
     41         * returns the task related to the instance, i.e. the iteration. 
     42         * </p> 
     43         *  
     44         * @return as described 
     45         */ 
     46        public IIteration getIteration(); 
    4547 
    4648} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IMarkingTemporalRelationship.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * A marking temporal relationship defines a temporal information for exactly one node in the task 
    20  * model. I.e., it has only one child for which it defines a special execution characteristic. 
     19 * A marking temporal relationship defines a temporal information for exactly 
     20 * one node in the task model. I.e., it has only one child for which it defines 
     21 * a special execution characteristic. 
    2122 * </p> 
    2223 *  
     
    2526public interface IMarkingTemporalRelationship extends ITemporalRelationship { 
    2627 
    27     /** 
    28      * <p> 
    29      * returns the task for which this relationship defines the execution characteristic. The 
    30      * task can be seen as the child node of this node. 
    31      * </p> 
    32      *  
    33      * @return as described 
    34      */ 
    35     public ITask getMarkedTask(); 
     28        /** 
     29         * <p> 
     30         * returns an exact copy of this temporal relationship. The clone has the 
     31         * same id. Its child is a clone of the child of the cloned task. A call on 
     32         * the method {@link #equals(ITask)} with the result of this method must 
     33         * return true. 
     34         * </p> 
     35         *  
     36         * @return as described 
     37         */ 
     38        @Override 
     39        public IMarkingTemporalRelationship clone(); 
    3640 
    37     /** 
    38      * <p> 
    39      * returns an exact copy of this temporal relationship. The clone has the same id. Its child 
    40      * is a clone of the child of the cloned task. A call on the method {@link #equals(ITask)} 
    41      * with the result of this method must return true. 
    42      * </p> 
    43      *  
    44      * @return as described 
    45      */ 
    46     public IMarkingTemporalRelationship clone(); 
     41        /** 
     42         * <p> 
     43         * returns the task for which this relationship defines the execution 
     44         * characteristic. The task can be seen as the child node of this node. 
     45         * </p> 
     46         *  
     47         * @return as described 
     48         */ 
     49        public ITask getMarkedTask(); 
    4750 
    4851} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IOptional.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * This temporal relationship defines that its single child may or may not be executed for 
    20  * fulfilling the task. This is most important for the parent node in the task model as this 
    21  * node may require that a specific subtask is optional. 
     19 * This temporal relationship defines that its single child may or may not be 
     20 * executed for fulfilling the task. This is most important for the parent node 
     21 * in the task model as this node may require that a specific subtask is 
     22 * optional. 
    2223 * </p> 
    2324 *  
     
    2627public interface IOptional extends IMarkingTemporalRelationship { 
    2728 
    28     /** 
    29      * <p> 
    30      * returns an exact copy of this temporal relationship. The clone has the same id. Its child 
    31      * is a clone of the child of the cloned task. A call on the method {@link #equals(ITask)} 
    32      * with the result of this method must return true. 
    33      * </p> 
    34      *  
    35      * @return as described 
    36      */ 
    37     public IOptional clone(); 
     29        /** 
     30         * <p> 
     31         * returns an exact copy of this temporal relationship. The clone has the 
     32         * same id. Its child is a clone of the child of the cloned task. A call on 
     33         * the method {@link #equals(ITask)} with the result of this method must 
     34         * return true. 
     35         * </p> 
     36         *  
     37         * @return as described 
     38         */ 
     39        @Override 
     40        public IOptional clone(); 
    3841 
    3942} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IOptionalInstance.java

    r1413 r1733  
    1818 * <p> 
    1919 * the instance of an {@link IOptional}. The instance may have a child being an 
    20  * instance of the task marked by the optional of which this is an instance. If this instance 
    21  * does not have a child, the optional child task was not executed. 
     20 * instance of the task marked by the optional of which this is an instance. If 
     21 * this instance does not have a child, the optional child task was not 
     22 * executed. 
    2223 * </p> 
    2324 *  
     
    2627public interface IOptionalInstance extends ITaskInstance { 
    2728 
    28     /** 
    29      * <p> 
    30      * returns the child of the optional of null if the optional was not executed 
    31      * </p> 
    32      *  
    33      * @return as described 
    34      */ 
    35     public ITaskInstance getChild(); 
     29        /** 
     30         * <p> 
     31         * clones this task instance by creating exact clones of each contained 
     32         * instance 
     33         * </p> 
     34         *  
     35         * @return a clone of the task instance 
     36         */ 
     37        @Override 
     38        public IOptionalInstance clone(); 
    3639 
    37     /** 
    38      * <p> 
    39      * returns the task related to the instance, i.e. the optional. 
    40      * </p> 
    41      *  
    42      * @return as described 
    43      */ 
    44     public IOptional getOptional(); 
     40        /** 
     41         * <p> 
     42         * returns the child of the optional of null if the optional was not 
     43         * executed 
     44         * </p> 
     45         *  
     46         * @return as described 
     47         */ 
     48        public ITaskInstance getChild(); 
    4549 
    46     /** 
    47     * <p> 
    48      * clones this task instance by creating exact clones of each contained instance 
    49     * </p> 
    50     *  
    51      * @return a clone of the task instance 
    52     */ 
    53     public IOptionalInstance clone(); 
     50        /** 
     51        * <p> 
     52         * returns the task related to the instance, i.e. the optional. 
     53        * </p> 
     54        *  
     55         * @return as described 
     56        */ 
     57        public IOptional getOptional(); 
    5458 
    5559} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISelection.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * This temporal relationship defines that only one of its children must be executed for 
    20  * fulfilling the represented task. 
     19 * This temporal relationship defines that only one of its children must be 
     20 * executed for fulfilling the represented task. 
    2121 * </p> 
    2222 *  
     
    2525public interface ISelection extends IStructuringTemporalRelationship { 
    2626 
    27     /** 
    28      * <p> 
    29      * returns an exact copy of this temporal relationship. The clone has the same id. Its children 
    30      * are clones of the children of the cloned task. A call on the method {@link #equals(ITask)} 
    31      * with the result of this method must return true. 
    32      * </p> 
    33      *  
    34      * @return as described 
    35      */ 
    36     public ISelection clone(); 
     27        /** 
     28         * <p> 
     29         * returns an exact copy of this temporal relationship. The clone has the 
     30         * same id. Its children are clones of the children of the cloned task. A 
     31         * call on the method {@link #equals(ITask)} with the result of this method 
     32         * must return true. 
     33         * </p> 
     34         *  
     35         * @return as described 
     36         */ 
     37        @Override 
     38        public ISelection clone(); 
    3739 
    3840} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISelectionInstance.java

    r1413 r1733  
    1717/** 
    1818 * <p> 
    19  * the instance of an {@link ISelection}. The instance has a child being an instance of the child 
    20  * task of the selection that was selected for execution. 
     19 * the instance of an {@link ISelection}. The instance has a child being an 
     20 * instance of the child task of the selection that was selected for execution. 
    2121 * </p> 
    2222 *  
     
    2525public interface ISelectionInstance extends ITaskInstance { 
    2626 
    27     /** 
    28      * <p> 
    29      * returns the selected child of the selection 
    30      * </p> 
    31      *  
    32      * @return as described 
    33      */ 
    34     public ITaskInstance getChild(); 
     27        /** 
     28         * <p> 
     29         * clones this task instance by creating exact clones of the contained 
     30         * instance 
     31         * </p> 
     32         *  
     33         * @return a clone of the task instance 
     34         */ 
     35        @Override 
     36        public ISelectionInstance clone(); 
    3537 
    36     /** 
    37     * <p> 
    38      * returns the task related to the instance, i.e. the selection. 
    39     * </p> 
    40     *  
    41     * @return as described 
    42     */ 
    43     public ISelection getSelection(); 
     38        /** 
     39        * <p> 
     40         * returns the selected child of the selection 
     41        * </p> 
     42        *  
     43        * @return as described 
     44        */ 
     45        public ITaskInstance getChild(); 
    4446 
    45     /** 
    46     * <p> 
    47      * clones this task instance by creating exact clones of the contained instance 
    48     * </p> 
    49     *  
    50      * @return a clone of the task instance 
    51     */ 
    52     public ISelectionInstance clone(); 
     47        /** 
     48        * <p> 
     49         * returns the task related to the instance, i.e. the selection. 
     50        * </p> 
     51        *  
     52         * @return as described 
     53        */ 
     54        public ISelection getSelection(); 
    5355 
    5456} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISequence.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * This temporal relationship defines that its children must be executed in the order they are 
    20  * listed for fulfilling the represented task. 
     19 * This temporal relationship defines that its children must be executed in the 
     20 * order they are listed for fulfilling the represented task. 
    2121 * </p> 
    2222 *  
     
    2525public interface ISequence extends IStructuringTemporalRelationship { 
    2626 
    27     /** 
    28      * <p> 
    29      * returns an exact copy of this temporal relationship. The clone has the same id. Its children 
    30      * are clones of the children of the cloned task. A call on the method {@link #equals(ITask)} 
    31      * with the result of this method must return true. 
    32      * </p> 
    33      *  
    34      * @return as described 
    35      */ 
    36     public ISequence clone(); 
     27        /** 
     28         * <p> 
     29         * returns an exact copy of this temporal relationship. The clone has the 
     30         * same id. Its children are clones of the children of the cloned task. A 
     31         * call on the method {@link #equals(ITask)} with the result of this method 
     32         * must return true. 
     33         * </p> 
     34         *  
     35         * @return as described 
     36         */ 
     37        @Override 
     38        public ISequence clone(); 
    3739 
    3840} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISequenceInstance.java

    r1413 r1733  
    1717/** 
    1818 * <p> 
    19  * the instance of an {@link ISequence}. The instance has the same number of children as the 
    20  * sequence it represents. 
     19 * the instance of an {@link ISequence}. The instance has the same number of 
     20 * children as the sequence it represents. 
    2121 * </p> 
    2222 *  
     
    2525public interface ISequenceInstance extends ITaskInstance, ITaskInstanceList { 
    2626 
    27     /** 
    28      * <p> 
    29      * returns the task related to the instance, i.e. the sequence. 
    30      * </p> 
    31      *  
    32      * @return as described 
    33      */ 
    34     public ISequence getSequence(); 
     27        /** 
     28         * <p> 
     29         * clones this task instance by creating exact clones of each contained 
     30         * instance in their order 
     31         * </p> 
     32         *  
     33         * @return a clone of the task instance 
     34         */ 
     35        @Override 
     36        public ISequenceInstance clone(); 
    3537 
    36     /** 
    37      * <p> 
    38      * clones this task instance by creating exact clones of each contained instance in their 
    39      * order 
    40      * </p> 
    41      *  
    42      * @return a clone of the task instance 
    43      */ 
    44     public ISequenceInstance clone(); 
    45    
     38        /** 
     39         * <p> 
     40         * returns the task related to the instance, i.e. the sequence. 
     41         * </p> 
     42         *  
     43         * @return as described 
     44         */ 
     45        public ISequence getSequence(); 
     46 
    4647} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IStructuringTemporalRelationship.java

    r1180 r1733  
    1919/** 
    2020 * <p> 
    21  * A structuring temporal relationship defines a temporal information for several nodes in the task 
    22  * model. I.e., it has several children and defines an execution order for them. 
     21 * A structuring temporal relationship defines a temporal information for 
     22 * several nodes in the task model. I.e., it has several children and defines an 
     23 * execution order for them. 
    2324 * </p> 
    2425 *  
     
    2728public interface IStructuringTemporalRelationship extends ITemporalRelationship { 
    2829 
    29     /** 
    30      * <p> 
    31      * returns the children of this temporal relationship. 
    32      * </p> 
    33      *  
    34      * @return as described 
    35      */ 
    36     public List<ITask> getChildren(); 
     30        /** 
     31         * <p> 
     32         * returns an exact copy of this temporal relationship. The clone has the 
     33         * same id. Its children are clones of the children of the cloned task. A 
     34         * call on the method {@link #equals(ITask)} with the result of this method 
     35         * must return true. 
     36         * </p> 
     37         *  
     38         * @return as described 
     39         */ 
     40        @Override 
     41        public IStructuringTemporalRelationship clone(); 
    3742 
    38     /** 
    39      * <p> 
    40      * returns an exact copy of this temporal relationship. The clone has the same id. Its children 
    41      * are clones of the children of the cloned task. A call on the method {@link #equals(ITask)} 
    42      * with the result of this method must return true. 
    43      * </p> 
    44      *  
    45      * @return as described 
    46      */ 
    47     public IStructuringTemporalRelationship clone(); 
     43        /** 
     44         * <p> 
     45         * returns the children of this temporal relationship. 
     46         * </p> 
     47         *  
     48         * @return as described 
     49         */ 
     50        public List<ITask> getChildren(); 
    4851 
    4952} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java

    r1400 r1733  
    2020/** 
    2121 * <p> 
    22  * A task represents a model for events that occur if the user interacts with a software for 
    23  * achieving a specific goal. A task can be a single event or a complex structure of events 
    24  * and temporal relationships defining the event order. Tasks may especially refer to other tasks 
    25  * to create task structures similar to trees. These structures fully define in which ways the 
    26  * events that form the task can occur. However, the structure of a task is not necessarily a 
    27  * tree as task structures may be reused several times in larger scale task structures. 
     22 * A task represents a model for events that occur if the user interacts with a 
     23 * software for achieving a specific goal. A task can be a single event or a 
     24 * complex structure of events and temporal relationships defining the event 
     25 * order. Tasks may especially refer to other tasks to create task structures 
     26 * similar to trees. These structures fully define in which ways the events that 
     27 * form the task can occur. However, the structure of a task is not necessarily 
     28 * a tree as task structures may be reused several times in larger scale task 
     29 * structures. 
    2830 * </p> 
    2931 *  
     
    3234public interface ITask extends Cloneable, Serializable { 
    3335 
    34     /** 
    35      * <p> 
    36      * every task is assigned a unique id which is returned by this method. The id is unique for 
    37      * the current runtime. 
    38      * </p> 
    39      *  
    40      * @return as described 
    41      */ 
    42     public int getId(); 
     36        /** 
     37         * <p> 
     38         * implements the visitor pattern to be able to process tasks and their 
     39         * children. 
     40         * </p> 
     41         *  
     42         * @param visitor 
     43         *            the visitor used to process the task 
     44         */ 
     45        public void accept(ITaskVisitor visitor); 
    4346 
    44     /** 
    45      * <p> 
    46      * returns a human readable type for the task.  
    47      * </p> 
    48      *  
    49      * @return as described 
    50      */ 
    51     public String getType(); 
     47        /** 
     48         * <p> 
     49         * returns an exact copy of this task. The clone has the same id. If the 
     50         * task has children, they are cloned as well. A call on the method 
     51         * {@link #equals(ITask)} with the result of this method must return true. 
     52         * </p> 
     53         *  
     54         * @return as described 
     55         */ 
     56        public ITask clone(); 
    5257 
    53     /** 
    54      * <p> 
    55      * returns a human readable description for the task.  
    56      * </p> 
    57      *  
    58      * @return as described 
    59      */ 
    60     public String getDescription(); 
     58        /** 
     59         * <p> 
     60         * checks whether this task is equal to another one. Task equality is only 
     61         * given, if two tasks have the same id. This means, that this method must 
     62         * only return true if the other task is either the same object or a clone 
     63         * of it. 
     64         * </p> 
     65         *  
     66         * @return as described 
     67         */ 
     68        public boolean equals(ITask task); 
    6169 
    62     /** 
    63     * <p> 
    64      * returns a collection of all observed instances of this task 
    65     * </p> 
    66     *  
    67     * @return as described 
    68     */ 
    69     public Collection<ITaskInstance> getInstances(); 
     70        /** 
     71        * <p> 
     72         * returns a human readable description for the task. 
     73        * </p> 
     74        *  
     75        * @return as described 
     76        */ 
     77        public String getDescription(); 
    7078 
    71     /** 
    72      * <p> 
    73      * returns a collection of collections of all different execution variants of this task. This 
    74      * is a grouping of all instances where each group contains structurally identical instances. 
    75      * </p> 
    76      *  
    77      * @return as described 
    78      */ 
    79     public Collection<Collection<ITaskInstance>> getExecutionVariants(); 
     79        /** 
     80         * <p> 
     81         * returns a collection of collections of all different execution variants 
     82         * of this task. This is a grouping of all instances where each group 
     83         * contains structurally identical instances. 
     84         * </p> 
     85         *  
     86         * @return as described 
     87         */ 
     88        public Collection<Collection<ITaskInstance>> getExecutionVariants(); 
    8089 
    81     /** 
    82      * <p> 
    83      * checks whether this task is equal to another one. Task equality is only given, if two 
    84      * tasks have the same id. This means, that this method must only return true if the other 
    85      * task is either the same object or a clone of it.  
    86      * </p> 
    87      *  
    88      * @return as described 
    89      */ 
    90     public boolean equals(ITask task); 
     90        /** 
     91         * <p> 
     92         * every task is assigned a unique id which is returned by this method. The 
     93         * id is unique for the current runtime. 
     94         * </p> 
     95         *  
     96         * @return as described 
     97         */ 
     98        public int getId(); 
    9199 
    92     /** 
    93     * <p> 
    94      * returns a hash code for the task, which is usually the id returned by {@link #getId()}. 
    95     * </p> 
    96     *  
    97     * @return as described 
    98     */ 
    99     public int hashCode(); 
     100        /** 
     101        * <p> 
     102         * returns a collection of all observed instances of this task 
     103        * </p> 
     104        *  
     105        * @return as described 
     106        */ 
     107        public Collection<ITaskInstance> getInstances(); 
    100108 
    101     /** 
    102     * <p> 
    103      * returns an exact copy of this task. The clone has the same id. If the task has 
    104      * children, they are cloned as well. A call on the method {@link #equals(ITask)} with the 
    105      * result of this method must return true. 
    106      * </p> 
    107      *  
    108      * @return as described 
    109      */ 
    110     public ITask clone(); 
    111      
    112     /** 
    113      * <p> 
    114      * implements the visitor pattern to be able to process tasks and their children. 
    115      * </p> 
    116      *  
    117      * @param visitor the visitor used to process the task 
    118      */ 
    119     public void accept(ITaskVisitor visitor); 
    120      
     109        /** 
     110        * <p> 
     111         * returns a human readable type for the task. 
     112         * </p> 
     113         *  
     114         * @return as described 
     115         */ 
     116        public String getType(); 
     117 
     118        /** 
     119         * <p> 
     120         * returns a hash code for the task, which is usually the id returned by 
     121         * {@link #getId()}. 
     122         * </p> 
     123         *  
     124         * @return as described 
     125         */ 
     126        @Override 
     127        public int hashCode(); 
     128 
    121129} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskBuilder.java

    r1294 r1733  
    1717/** 
    1818 * <p> 
    19  * Builder for task models. Can be used to create and edit task models. May perform integrity 
    20  * checks, though they may be incomplete as the integrity of a task model can not be ensured during 
    21  * creation. 
     19 * Builder for task models. Can be used to create and edit task models. May 
     20 * perform integrity checks, though they may be incomplete as the integrity of a 
     21 * task model can not be ensured during creation. 
    2222 * </p> 
    2323 */ 
    2424public interface ITaskBuilder { 
    2525 
    26     /** 
    27      * <p> 
    28      * adds a child to a sequence instance. May ensure, that the child is a valid child considering 
    29      * the task model of the parent. In that case, an IllegalArgumentException is thrown. 
    30      * </p> 
    31      *  
    32      * @param instance the instance of add the child to 
    33      * @param child    the child to be added 
    34      *  
    35      * @throws IllegalArgumentException as described 
    36      */ 
    37     void addChild(ISequenceInstance instance, ITaskInstance child) throws IllegalArgumentException; 
    38  
    39     /** 
    40      * <p> 
    41      * adds a child to an iteration instance. May ensure, that the child is a valid child 
    42      * considering the task model of the parent. In that case, an IllegalArgumentException is 
    43      * thrown. 
    44      * </p> 
    45      *  
    46      * @param instance the instance of add the child to 
    47      * @param child    the child to be added 
    48      *  
    49      * @throws IllegalArgumentException as described 
    50      */ 
    51     void addChild(IIterationInstance instance, ITaskInstance child) throws IllegalArgumentException; 
    52  
    53     /** 
    54      * <p> 
    55      * sets the child of a selection instance. May ensure, that the child is a valid child 
    56      * considering the task model of the parent. In that case, an IllegalArgumentException is 
    57      * thrown. 
    58      * </p> 
    59      *  
    60      * @param instance the instance of add the child to 
    61      * @param child    the child to be added 
    62      *  
    63      * @throws IllegalArgumentException as described 
    64      */ 
    65     void setChild(ISelectionInstance instance, ITaskInstance child) throws IllegalArgumentException; 
    66  
    67     /** 
    68      * <p> 
    69      * sets the child of an optional instance. May ensure, that the child is a valid child 
    70      * considering the task model of the parent. In that case, an IllegalArgumentException is 
    71      * thrown. 
    72      * </p> 
    73      *  
    74      * @param instance the instance of add the child to 
    75      * @param child    the child to be added 
    76      *  
    77      * @throws IllegalArgumentException as described 
    78      */ 
    79     void setChild(IOptionalInstance instance, ITaskInstance child) throws IllegalArgumentException; 
    80  
    81     /** 
    82      * <p> 
    83      * adds a task instance to a user session 
    84      * </p> 
    85      * 
    86      * @param session      the session to add the task instance to 
    87      * @param taskInstance the task instance to add 
    88      */ 
    89     void addExecutedTask(IUserSession session, ITaskInstance taskInstance); 
    90  
    91     /** 
    92      * <p> 
    93      * adds a task instance to a task instance list 
    94      * </p> 
    95      *  
    96      * @param taskInstanceList the list to add the task instance to 
    97      * @param taskInstance     the task instance to add 
    98      */ 
    99     void addTaskInstance(ITaskInstanceList taskInstanceList, ITaskInstance taskInstance); 
    100  
    101     /** 
    102      * <p> 
    103      * adds a task instance to a task instance list at a specific position. Subsequent task 
    104      * instances will be moved one index forward 
    105      * </p> 
    106      *  
    107      * @param taskInstanceList the list to add the task instance to 
    108      * @param index            the index of the task instance to add 
    109      * @param taskInstance     the task instance to add 
    110      *  
    111      * @throws IndexOutOfBoundsException if the index is invalid 
    112      */ 
    113     void addTaskInstance(ITaskInstanceList taskInstanceList, int index, ITaskInstance taskInstance) 
    114         throws IndexOutOfBoundsException; 
    115  
    116     /** 
    117      * <p> 
    118      * sets a task instance in a task instance list at a specific position 
    119      * </p> 
    120      *  
    121      * @param taskInstanceList the list to set the task instance in 
    122      * @param index            the index of the task instance to replace 
    123      * @param taskInstance     the replacement for the task instance at the index 
    124      *  
    125      * @throws IndexOutOfBoundsException if the index is invalid 
    126      */ 
    127     void setTaskInstance(ITaskInstanceList taskInstanceList, int index, ITaskInstance taskInstance) 
    128         throws IndexOutOfBoundsException; 
    129  
    130     /** 
    131      * <p> 
    132      * sets the task model of a task instance 
    133      * </p> 
    134      *  
    135      * @param taskInstance the task instance to set the task model for 
    136      * @param task         the task model of the instance 
    137      */ 
    138     void setTask(ITaskInstance taskInstance, ITask task); 
    139  
    140     /** 
    141      * <p> 
    142      * adds a child task to the end of a sequence 
    143      * </p> 
    144      *  
    145      * @param parent the sequence to add the child to 
    146      * @param child  the child to be added 
    147      */ 
    148     void addChild(ISequence parent, ITask child); 
    149  
    150     /** 
    151      * <p> 
    152      * adds a child task to a specific index of a sequence 
    153      * </p> 
    154      *  
    155      * @param parent the sequence to add the child to 
    156      * @param index  the index to set the child at 
    157      * @param child  the child to be added 
    158      *  
    159      * @throws IndexOutOfBoundsException if the index is invalid 
    160      */ 
    161     void addChild(ISequence parent, int index, ITask child) 
    162         throws IndexOutOfBoundsException; 
    163  
    164     /** 
    165      * <p> 
    166      * replaces the child task of a sequence at a specific position 
    167      * </p> 
    168      *  
    169      * @param parent the sequence to replace the child in 
    170      * @param index  the index to replace the child at 
    171      * @param child  the child to be added 
    172      *  
    173      * @throws IndexOutOfBoundsException if the index is invalid 
    174      */ 
    175     void setChild(ISequence parent, int index, ITask child) 
    176         throws IndexOutOfBoundsException; 
    177  
    178     /** 
    179      * <p> 
    180      * adds a child task to a selection 
    181      * </p> 
    182      *  
    183      * @param parent the selection to add the child to 
    184      * @param child  the child to be added 
    185      */ 
    186     void addChild(ISelection parent, ITask child); 
    187  
    188     /** 
    189      * <p> 
    190      * sets the child task of an iteration 
    191      * </p> 
    192      *  
    193      * @param iteration the iteration to set the child of 
    194      * @param child     the child to be set 
    195      */ 
    196     void setMarkedTask(IIteration iteration, ITask child); 
    197  
    198     /** 
    199      * <p> 
    200      * sets the child task of an optional 
    201      * </p> 
    202      *  
    203      * @param optional the optional to set the child of 
    204      * @param child    the child to be set 
    205      */ 
    206     void setMarkedTask(IOptional optional, ITask child); 
    207  
    208     /** 
    209      * <p> 
    210      * removes the child of a sequence at a specific position 
    211      * </p> 
    212      *  
    213      * @param parent the sequence of which the child must be removed 
    214      * @param index  the index of the child to be removed 
    215      *  
    216      * @throws IndexOutOfBoundsException if the index is invalid 
    217      */ 
    218     void removeChild(ISequence parent, int index) 
    219         throws IndexOutOfBoundsException; 
    220  
    221     /** 
    222      * <p> 
    223      * removes a child of a selection. Ignores the call, if the child is not found 
    224      * (comparison using equals). 
    225      * </p> 
    226      *  
    227      * @param parent the selection of which the child must be removed 
    228      * @param child  the child to be removes 
    229      */ 
    230     void removeChild(ISelection parent, ITask child); 
    231  
    232     /** 
    233      * <p> 
    234      * removes the entry of a task instance list at a specific position 
    235      * </p> 
    236      *  
    237      * @param taskInstanceList the task instance list of which the entry must be removed 
    238      * @param index            the index of the entry to be removed 
    239      *  
    240      * @throws IndexOutOfBoundsException if the index is invalid 
    241      */ 
    242     void removeTaskInstance(ITaskInstanceList taskInstanceList, int index) 
    243         throws IndexOutOfBoundsException; 
    244  
    245     /** 
    246      * <p> 
    247      * replaces a child of a selection. Throws an IllegalArgumentException if the child is not 
    248      * found (comparison using equals). 
    249      * </p> 
    250      *  
    251      * @param parent   the selection of which the child must be replace 
    252      * @param oldChild the child to replace 
    253      * @param newChild the replacement for the child 
    254      *  
    255      * @throws as described 
    256      */ 
    257     void replaceChild(ISelection parent, ITask oldChild, ITask newChild); 
     26        /** 
     27         * <p> 
     28         * adds a child to an iteration instance. May ensure, that the child is a 
     29         * valid child considering the task model of the parent. In that case, an 
     30         * IllegalArgumentException is thrown. 
     31         * </p> 
     32         *  
     33         * @param instance 
     34         *            the instance of add the child to 
     35         * @param child 
     36         *            the child to be added 
     37         *  
     38         * @throws IllegalArgumentException 
     39         *             as described 
     40         */ 
     41        void addChild(IIterationInstance instance, ITaskInstance child) 
     42                        throws IllegalArgumentException; 
     43 
     44        /** 
     45         * <p> 
     46         * adds a child task to a selection 
     47         * </p> 
     48         *  
     49         * @param parent 
     50         *            the selection to add the child to 
     51         * @param child 
     52         *            the child to be added 
     53         */ 
     54        void addChild(ISelection parent, ITask child); 
     55 
     56        /** 
     57         * <p> 
     58         * adds a child task to a specific index of a sequence 
     59         * </p> 
     60         *  
     61         * @param parent 
     62         *            the sequence to add the child to 
     63         * @param index 
     64         *            the index to set the child at 
     65         * @param child 
     66         *            the child to be added 
     67         *  
     68         * @throws IndexOutOfBoundsException 
     69         *             if the index is invalid 
     70         */ 
     71        void addChild(ISequence parent, int index, ITask child) 
     72                        throws IndexOutOfBoundsException; 
     73 
     74        /** 
     75         * <p> 
     76         * adds a child task to the end of a sequence 
     77         * </p> 
     78         *  
     79         * @param parent 
     80         *            the sequence to add the child to 
     81         * @param child 
     82         *            the child to be added 
     83         */ 
     84        void addChild(ISequence parent, ITask child); 
     85 
     86        /** 
     87         * <p> 
     88         * adds a child to a sequence instance. May ensure, that the child is a 
     89         * valid child considering the task model of the parent. In that case, an 
     90         * IllegalArgumentException is thrown. 
     91         * </p> 
     92         *  
     93         * @param instance 
     94         *            the instance of add the child to 
     95         * @param child 
     96         *            the child to be added 
     97         *  
     98         * @throws IllegalArgumentException 
     99         *             as described 
     100         */ 
     101        void addChild(ISequenceInstance instance, ITaskInstance child) 
     102                        throws IllegalArgumentException; 
     103 
     104        /** 
     105         * <p> 
     106         * adds a task instance to a user session 
     107         * </p> 
     108         * 
     109         * @param session 
     110         *            the session to add the task instance to 
     111         * @param taskInstance 
     112         *            the task instance to add 
     113         */ 
     114        void addExecutedTask(IUserSession session, ITaskInstance taskInstance); 
     115 
     116        /** 
     117         * <p> 
     118         * adds a task instance to a task instance list at a specific position. 
     119         * Subsequent task instances will be moved one index forward 
     120         * </p> 
     121         *  
     122         * @param taskInstanceList 
     123         *            the list to add the task instance to 
     124         * @param index 
     125         *            the index of the task instance to add 
     126         * @param taskInstance 
     127         *            the task instance to add 
     128         *  
     129         * @throws IndexOutOfBoundsException 
     130         *             if the index is invalid 
     131         */ 
     132        void addTaskInstance(ITaskInstanceList taskInstanceList, int index, 
     133                        ITaskInstance taskInstance) throws IndexOutOfBoundsException; 
     134 
     135        /** 
     136         * <p> 
     137         * adds a task instance to a task instance list 
     138         * </p> 
     139         *  
     140         * @param taskInstanceList 
     141         *            the list to add the task instance to 
     142         * @param taskInstance 
     143         *            the task instance to add 
     144         */ 
     145        void addTaskInstance(ITaskInstanceList taskInstanceList, 
     146                        ITaskInstance taskInstance); 
     147 
     148        /** 
     149         * <p> 
     150         * removes a child of a selection. Ignores the call, if the child is not 
     151         * found (comparison using equals). 
     152         * </p> 
     153         *  
     154         * @param parent 
     155         *            the selection of which the child must be removed 
     156         * @param child 
     157         *            the child to be removes 
     158         */ 
     159        void removeChild(ISelection parent, ITask child); 
     160 
     161        /** 
     162         * <p> 
     163         * removes the child of a sequence at a specific position 
     164         * </p> 
     165         *  
     166         * @param parent 
     167         *            the sequence of which the child must be removed 
     168         * @param index 
     169         *            the index of the child to be removed 
     170         *  
     171         * @throws IndexOutOfBoundsException 
     172         *             if the index is invalid 
     173         */ 
     174        void removeChild(ISequence parent, int index) 
     175                        throws IndexOutOfBoundsException; 
     176 
     177        /** 
     178         * <p> 
     179         * removes the entry of a task instance list at a specific position 
     180         * </p> 
     181         *  
     182         * @param taskInstanceList 
     183         *            the task instance list of which the entry must be removed 
     184         * @param index 
     185         *            the index of the entry to be removed 
     186         *  
     187         * @throws IndexOutOfBoundsException 
     188         *             if the index is invalid 
     189         */ 
     190        void removeTaskInstance(ITaskInstanceList taskInstanceList, int index) 
     191                        throws IndexOutOfBoundsException; 
     192 
     193        /** 
     194         * <p> 
     195         * replaces a child of a selection. Throws an IllegalArgumentException if 
     196         * the child is not found (comparison using equals). 
     197         * </p> 
     198         *  
     199         * @param parent 
     200         *            the selection of which the child must be replace 
     201         * @param oldChild 
     202         *            the child to replace 
     203         * @param newChild 
     204         *            the replacement for the child 
     205         *  
     206         * @throws as 
     207         *             described 
     208         */ 
     209        void replaceChild(ISelection parent, ITask oldChild, ITask newChild); 
     210 
     211        /** 
     212         * <p> 
     213         * sets the child of an optional instance. May ensure, that the child is a 
     214         * valid child considering the task model of the parent. In that case, an 
     215         * IllegalArgumentException is thrown. 
     216         * </p> 
     217         *  
     218         * @param instance 
     219         *            the instance of add the child to 
     220         * @param child 
     221         *            the child to be added 
     222         *  
     223         * @throws IllegalArgumentException 
     224         *             as described 
     225         */ 
     226        void setChild(IOptionalInstance instance, ITaskInstance child) 
     227                        throws IllegalArgumentException; 
     228 
     229        /** 
     230         * <p> 
     231         * sets the child of a selection instance. May ensure, that the child is a 
     232         * valid child considering the task model of the parent. In that case, an 
     233         * IllegalArgumentException is thrown. 
     234         * </p> 
     235         *  
     236         * @param instance 
     237         *            the instance of add the child to 
     238         * @param child 
     239         *            the child to be added 
     240         *  
     241         * @throws IllegalArgumentException 
     242         *             as described 
     243         */ 
     244        void setChild(ISelectionInstance instance, ITaskInstance child) 
     245                        throws IllegalArgumentException; 
     246 
     247        /** 
     248         * <p> 
     249         * replaces the child task of a sequence at a specific position 
     250         * </p> 
     251         *  
     252         * @param parent 
     253         *            the sequence to replace the child in 
     254         * @param index 
     255         *            the index to replace the child at 
     256         * @param child 
     257         *            the child to be added 
     258         *  
     259         * @throws IndexOutOfBoundsException 
     260         *             if the index is invalid 
     261         */ 
     262        void setChild(ISequence parent, int index, ITask child) 
     263                        throws IndexOutOfBoundsException; 
     264 
     265        /** 
     266         * <p> 
     267         * sets the child task of an iteration 
     268         * </p> 
     269         *  
     270         * @param iteration 
     271         *            the iteration to set the child of 
     272         * @param child 
     273         *            the child to be set 
     274         */ 
     275        void setMarkedTask(IIteration iteration, ITask child); 
     276 
     277        /** 
     278         * <p> 
     279         * sets the child task of an optional 
     280         * </p> 
     281         *  
     282         * @param optional 
     283         *            the optional to set the child of 
     284         * @param child 
     285         *            the child to be set 
     286         */ 
     287        void setMarkedTask(IOptional optional, ITask child); 
     288 
     289        /** 
     290         * <p> 
     291         * sets the task model of a task instance 
     292         * </p> 
     293         *  
     294         * @param taskInstance 
     295         *            the task instance to set the task model for 
     296         * @param task 
     297         *            the task model of the instance 
     298         */ 
     299        void setTask(ITaskInstance taskInstance, ITask task); 
     300 
     301        /** 
     302         * <p> 
     303         * sets a task instance in a task instance list at a specific position 
     304         * </p> 
     305         *  
     306         * @param taskInstanceList 
     307         *            the list to set the task instance in 
     308         * @param index 
     309         *            the index of the task instance to replace 
     310         * @param taskInstance 
     311         *            the replacement for the task instance at the index 
     312         *  
     313         * @throws IndexOutOfBoundsException 
     314         *             if the index is invalid 
     315         */ 
     316        void setTaskInstance(ITaskInstanceList taskInstanceList, int index, 
     317                        ITaskInstance taskInstance) throws IndexOutOfBoundsException; 
    258318 
    259319} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskFactory.java

    r1294 r1733  
    2828public interface ITaskFactory { 
    2929 
    30     /** 
    31      * <p> 
    32      * creates a new event task with the given description 
    33      * </p> 
    34      *  
    35      * @param description the description for the represented events 
    36      *  
    37      * @return the event task 
    38      */ 
    39     IEventTask createNewEventTask(String description); 
     30        /** 
     31         * <p> 
     32         * creates a new event task with the given description 
     33         * </p> 
     34         *  
     35         * @param description 
     36         *            the description for the represented events 
     37         *  
     38         * @return the event task 
     39         */ 
     40        IEventTask createNewEventTask(String description); 
    4041 
    41     /** 
    42     * <p> 
    43      * creates a new empty sequence 
    44     * </p> 
    45     *  
    46      * @return the sequence 
    47     */ 
    48     ISequence createNewSequence(); 
     42        /** 
     43        * <p> 
     44         * creates a new empty iteration 
     45        * </p> 
     46        *  
     47         * @return the iteration 
     48        */ 
     49        IIteration createNewIteration(); 
    4950 
    50     /** 
    51     * <p> 
    52      * creates a new empty iteration 
    53     * </p> 
    54     *  
    55      * @return the iteration 
    56     */ 
    57     IIteration createNewIteration(); 
     51        /** 
     52        * <p> 
     53         * creates a new empty optional 
     54        * </p> 
     55        *  
     56         * @return the optional 
     57        */ 
     58        IOptional createNewOptional(); 
    5859 
    59     /** 
    60     * <p> 
    61      * creates a new empty optional 
    62     * </p> 
    63     *  
    64      * @return the optional 
    65     */ 
    66     IOptional createNewOptional(); 
     60        /** 
     61        * <p> 
     62         * creates a new empty selection 
     63        * </p> 
     64        *  
     65         * @return the selection 
     66        */ 
     67        ISelection createNewSelection(); 
    6768 
    68     /** 
    69     * <p> 
    70      * creates a new empty selection 
    71     * </p> 
    72     *  
    73      * @return the selection 
    74     */ 
    75     ISelection createNewSelection(); 
     69        /** 
     70        * <p> 
     71         * creates a new empty sequence 
     72        * </p> 
     73        *  
     74         * @return the sequence 
     75        */ 
     76        ISequence createNewSequence(); 
    7677 
    77     /** 
    78      * <p> 
    79      * creates a new task instance with the given task as its model representing the provided event 
    80      * </p> 
    81      *  
    82      * @param task  the model of the task instance to be created 
    83      * @param event the event represented by the task instance 
    84      *  
    85      * @return the task instance 
    86      */ 
    87     IEventTaskInstance createNewTaskInstance(IEventTask task, Event event); 
     78        /** 
     79         * <p> 
     80         * creates a new task instance with the given task as its model representing 
     81         * the provided event 
     82         * </p> 
     83         *  
     84         * @param task 
     85         *            the model of the task instance to be created 
     86         * @param event 
     87         *            the event represented by the task instance 
     88         *  
     89         * @return the task instance 
     90         */ 
     91        IEventTaskInstance createNewTaskInstance(IEventTask task, Event event); 
    8892 
    89     /** 
    90      * <p> 
    91      * creates a new task instance with the given sequence as its model 
    92      * </p> 
    93      *  
    94      * @param sequence the model of the task instance to be created 
    95      *  
    96      * @return the task instance 
    97      */ 
    98     ISequenceInstance createNewTaskInstance(ISequence sequence); 
     93        /** 
     94         * <p> 
     95         * creates a new task instance with the given iteration as its model 
     96         * </p> 
     97         *  
     98         * @param iteration 
     99         *            the model of the task instance to be created 
     100         *  
     101         * @return the task instance 
     102         */ 
     103        IIterationInstance createNewTaskInstance(IIteration iteration); 
    99104 
    100     /** 
    101      * <p> 
    102      * creates a new task instance with the given iteration as its model 
    103      * </p> 
    104      *  
    105      * @param iteration the model of the task instance to be created 
    106      *  
    107      * @return the task instance 
    108      */ 
    109     IIterationInstance createNewTaskInstance(IIteration iteration); 
     105        /** 
     106         * <p> 
     107         * creates a new task instance with the given optional as its model 
     108         * </p> 
     109         *  
     110         * @param optional 
     111         *            the model of the task instance to be created 
     112         *  
     113         * @return the task instance 
     114         */ 
     115        IOptionalInstance createNewTaskInstance(IOptional optional); 
    110116 
    111     /** 
    112      * <p> 
    113      * creates a new task instance with the given optional as its model 
    114      * </p> 
    115      *  
    116      * @param optional the model of the task instance to be created 
    117      *  
    118      * @return the task instance 
    119      */ 
    120     IOptionalInstance createNewTaskInstance(IOptional optional); 
     117        /** 
     118         * <p> 
     119         * creates a new task instance with the given selection as its model 
     120         * </p> 
     121         *  
     122         * @param selection 
     123         *            the model of the task instance to be created 
     124         *  
     125         * @return the task instance 
     126         */ 
     127        ISelectionInstance createNewTaskInstance(ISelection selection); 
    121128 
    122     /** 
    123      * <p> 
    124      * creates a new task instance with the given selection as its model 
    125      * </p> 
    126      *  
    127      * @param selection the model of the task instance to be created 
    128      *  
    129      * @return the task instance 
    130      */ 
    131     ISelectionInstance createNewTaskInstance(ISelection selection); 
     129        /** 
     130         * <p> 
     131         * creates a new task instance with the given sequence as its model 
     132         * </p> 
     133         *  
     134         * @param sequence 
     135         *            the model of the task instance to be created 
     136         *  
     137         * @return the task instance 
     138         */ 
     139        ISequenceInstance createNewTaskInstance(ISequence sequence); 
    132140 
    133     /** 
    134      * <p> 
    135      * creates a new empty user session 
    136      * </p> 
    137      *  
    138      * @return the user session 
    139      */ 
    140     IUserSession createUserSession(); 
     141        /** 
     142         * <p> 
     143         * creates a task model based on the provided user sessions 
     144         * </p> 
     145         *  
     146         * @param userSessions 
     147         *            the session based on which the task model shall be created 
     148         *  
     149         * @return the task model 
     150         */ 
     151        ITaskModel createTaskModel(List<IUserSession> userSessions); 
    141152 
    142     /** 
    143      * <p> 
    144      * creates a task model based on the provided user sessions 
    145      * </p> 
    146      *  
    147      * @param userSessions the session based on which the task model shall be created 
    148      *  
    149      * @return the task model 
    150      */ 
    151     ITaskModel createTaskModel(List<IUserSession> userSessions); 
     153        /** 
     154         * <p> 
     155         * creates a new empty user session 
     156         * </p> 
     157         *  
     158         * @return the user session 
     159         */ 
     160        IUserSession createUserSession(); 
    152161 
    153162} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInfo.java

    r1428 r1733  
    1717/** 
    1818 * <p> 
    19  * Provides extended information about a specific task, such as statistics about task occurrences, 
    20  * etc. It contains measures for different metrics determined for a task. 
     19 * Provides extended information about a specific task, such as statistics about 
     20 * task occurrences, etc. It contains measures for different metrics determined 
     21 * for a task. 
    2122 * </p> 
    2223 *  
     
    2526public interface ITaskInfo { 
    2627 
    27     /** 
    28     * <p> 
    29      * returns the task to which these infos belong 
    30     * </p> 
    31     *  
    32      * @return as described 
    33     */ 
    34     public ITask getTask(); 
     28        /** 
     29        * <p> 
     30         * represents a measure for a specific metric 
     31        * </p> 
     32        *  
     33         * @author Patrick Harms 
     34        */ 
     35        public interface IMeasure { 
    3536 
    36     /** 
    37     * <p> 
    38      * returns all available measures 
    39     * </p> 
    40     *  
    41     * @return as described 
    42     */ 
    43     public IMeasure[] getMeasures(); 
     37                /** 
     38                * <p> 
     39                 * returns the metric of the measure 
     40                * </p> 
     41                *  
     42                * @return as described 
     43                */ 
     44                public TaskMetric getMetric(); 
    4445 
    45     /** 
    46      * <p> 
    47      * returns the value of the measure identified through the given metric 
    48      * </p> 
    49      * 
    50      * @param metric the metric for which the value is to be returned 
    51      *  
    52      * @return as described 
    53      */ 
    54     public int getMeasureValue(TaskMetric metric); 
     46                /** 
     47                 * <p> 
     48                 * returns the value of the measure 
     49                 * </p> 
     50                 *  
     51                 * @return as described 
     52                 */ 
     53                public int getValue(); 
    5554 
    56     /** 
    57      * <p> 
    58      * returns the value of the measure identified through the given metric if the task is 
    59      * observed in the given context, i.e. parent task. The result is Integer.MIN_VALUE if there 
    60      * is no value for this measure in a context. 
    61      * </p> 
    62      * 
    63      * @param metric  the metric for which the value is to be returned 
    64      * @param context the context for which the measure value is to be returned 
    65      *  
    66      * @return as described 
    67      */ 
    68     public int getMeasureValue(TaskMetric metric, ITask context); 
     55                /** 
     56                 * <p> 
     57                 * returns the value of the measure if the task was observed in a 
     58                 * specific context, i.e. parent task 
     59                 * </p> 
     60                 *  
     61                 * @return as described 
     62                 */ 
     63                public int getValue(ITask context); 
    6964 
    70     /** 
    71      * <p> 
    72      * represents a measure for a specific metric 
    73      * </p> 
    74      *  
    75      * @author Patrick Harms 
    76      */ 
    77     public interface IMeasure { 
    78          
    79         /** 
    80          * <p> 
    81          * returns the metric of the measure 
    82          * </p> 
    83          *  
    84          * @return as described 
    85          */ 
    86         public TaskMetric getMetric(); 
    87          
    88         /** 
    89          * <p> 
    90          * returns the value of the measure 
    91          * </p> 
    92          *  
    93          * @return as described 
    94          */ 
    95         public int getValue(); 
    96          
    97         /** 
    98          * <p> 
    99          * returns the value of the measure if the task was observed in a specific context, i.e. 
    100          * parent task 
    101          * </p> 
    102          *  
    103          * @return as described 
    104          */ 
    105         public int getValue(ITask context); 
    106          
    107     } 
     65        } 
     66 
     67        /** 
     68         * <p> 
     69         * returns all available measures 
     70         * </p> 
     71         *  
     72         * @return as described 
     73         */ 
     74        public IMeasure[] getMeasures(); 
     75 
     76        /** 
     77         * <p> 
     78         * returns the value of the measure identified through the given metric 
     79         * </p> 
     80         * 
     81         * @param metric 
     82         *            the metric for which the value is to be returned 
     83         *  
     84         * @return as described 
     85         */ 
     86        public int getMeasureValue(TaskMetric metric); 
     87 
     88        /** 
     89         * <p> 
     90         * returns the value of the measure identified through the given metric if 
     91         * the task is observed in the given context, i.e. parent task. The result 
     92         * is Integer.MIN_VALUE if there is no value for this measure in a context. 
     93         * </p> 
     94         * 
     95         * @param metric 
     96         *            the metric for which the value is to be returned 
     97         * @param context 
     98         *            the context for which the measure value is to be returned 
     99         *  
     100         * @return as described 
     101         */ 
     102        public int getMeasureValue(TaskMetric metric, ITask context); 
     103 
     104        /** 
     105         * <p> 
     106         * returns the task to which these infos belong 
     107         * </p> 
     108         *  
     109         * @return as described 
     110         */ 
     111        public ITask getTask(); 
    108112 
    109113} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstance.java

    r1405 r1733  
    1919/** 
    2020 * <p> 
    21  * a task instance represents the execution of a specific task within a user session. A task 
    22  * instance is always related to the task that was executed. 
     21 * a task instance represents the execution of a specific task within a user 
     22 * session. A task instance is always related to the task that was executed. 
    2323 * </p> 
    2424 *  
     
    2727public interface ITaskInstance extends Serializable, Cloneable { 
    2828 
    29     /** 
    30      * <p> 
    31      * returns the task related to the instance. 
    32      * </p> 
    33      *  
    34      * @return as described 
    35      */ 
    36     public ITask getTask(); 
     29        /** 
     30         * <p> 
     31         * implements the visitor pattern to be able to process task instances and 
     32         * their children. 
     33         * </p> 
     34         *  
     35         * @param visitor 
     36         *            the visitor used to process the task 
     37         */ 
     38        public void accept(ITaskInstanceVisitor visitor); 
    3739 
    38     /** 
    39      * <p> 
    40      * compares an instance to another one. Returns true if both instances are the same, i.e. not 
    41      * only the related task is equal but also all children and further characteristics of the 
    42      * task instance   
    43      * </p> 
    44      *  
    45      * @param taskInstance the instance to compare to 
    46      *  
    47      * @return as described 
    48      */ 
    49     public boolean equals(ITaskInstance taskInstance); 
     40        /** 
     41         * <p> 
     42         * clones a task instance by creating exact clones of each contained child 
     43         * instance as well as the related task. Furthermore, all other non 
     44         * transient information of the task instance must be cloned. 
     45         * </p> 
     46         *  
     47         * @return a clone of the task instance 
     48         */ 
     49        public ITaskInstance clone(); 
    5050 
    51     /** 
    52      * <p> 
    53      * returns a hash code for the task instance to be able to put it into hash maps 
    54      * </p> 
    55      *  
    56      * @return as described 
    57      */ 
    58     public int hashCode(); 
     51        /** 
     52         * <p> 
     53         * compares an instance to another one. Returns true if both instances are 
     54         * the same, i.e. not only the related task is equal but also all children 
     55         * and further characteristics of the task instance 
     56         * </p> 
     57         *  
     58         * @param taskInstance 
     59         *            the instance to compare to 
     60         *  
     61         * @return as described 
     62         */ 
     63        public boolean equals(ITaskInstance taskInstance); 
    5964 
    60     /** 
    61      * <p> 
    62      * clones a task instance by creating exact clones of each contained child instance as well 
    63      * as the related task. Furthermore, all other non transient information of the task 
    64      * instance must be cloned. 
    65      * </p> 
    66      *  
    67      * @return a clone of the task instance 
    68      */ 
    69     public ITaskInstance clone(); 
     65        /** 
     66         * <p> 
     67         * returns the task related to the instance. 
     68         * </p> 
     69         *  
     70         * @return as described 
     71         */ 
     72        public ITask getTask(); 
    7073 
    71     /** 
    72      * <p> 
    73      * implements the visitor pattern to be able to process task instances and their children. 
    74      * </p> 
    75      *  
    76      * @param visitor the visitor used to process the task 
    77      */ 
    78     public void accept(ITaskInstanceVisitor visitor); 
    79      
     74        /** 
     75         * <p> 
     76         * returns a hash code for the task instance to be able to put it into hash 
     77         * maps 
     78         * </p> 
     79         *  
     80         * @return as described 
     81         */ 
     82        @Override 
     83        public int hashCode(); 
     84 
    8085} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstanceList.java

    r1350 r1733  
    1919/** 
    2020 * <p> 
    21  * represents a serializable and iterable representation of a read only list of task 
    22  * instances. The list is ordered. It does not provide methods for changing it. 
     21 * represents a serializable and iterable representation of a read only list of 
     22 * task instances. The list is ordered. It does not provide methods for changing 
     23 * it. 
    2324 * </p> 
    2425 *  
    2526 * @author Patrick Harms 
    2627 */ 
    27 public interface ITaskInstanceList extends Cloneable, Serializable, Iterable<ITaskInstance> { 
     28public interface ITaskInstanceList extends Cloneable, Serializable, 
     29                Iterable<ITaskInstance> { 
    2830 
    29     /** 
    30      * <p> 
    31      * returns the task instance at the position with the given index. May throw an exception 
    32      * if the index is invalid. 
    33      * </p> 
    34      *  
    35      * @param index the index of the task instance to be returned 
    36      *  
    37      * @return the task instance at the given index 
    38      */ 
    39     public ITaskInstance get(int index); 
     31        /** 
     32         * <p> 
     33         * returns the task instance at the position with the given index. May throw 
     34         * an exception if the index is invalid. 
     35         * </p> 
     36         *  
     37         * @param index 
     38         *            the index of the task instance to be returned 
     39         *  
     40         * @return the task instance at the given index 
     41         */ 
     42        public ITaskInstance get(int index); 
    4043 
    41     /** 
    42      * <p> 
    43      * returns the size of the list, i.e. the number of task instances in the list 
    44      * </p> 
    45      *  
    46      * @return as described 
    47      */ 
    48     public int size(); 
     44        /** 
     45         * <p> 
     46         * returns the size of the list, i.e. the number of task instances in the 
     47         * list 
     48         * </p> 
     49         *  
     50         * @return as described 
     51         */ 
     52        public int size(); 
    4953 
    5054} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstanceVisitor.java

    r1405 r1733  
    1515package de.ugoe.cs.autoquest.tasktrees.treeifc; 
    1616 
    17  
    1817/** 
    1918 * <p> 
    20  * This is an implementation of the visitor pattern. Through this, it is possible to effectively 
    21  * process a task instance tree.  
     19 * This is an implementation of the visitor pattern. Through this, it is 
     20 * possible to effectively process a task instance tree. 
    2221 * </p> 
    2322 *  
     
    2625public interface ITaskInstanceVisitor { 
    2726 
    28     /** 
    29      * <p> 
    30      * method called for each visited event task instance. 
    31      * </p> 
    32      *  
    33      * @param eventTaskInstance the event task instance to be processed 
    34      */ 
    35     public void visit(IEventTaskInstance eventTaskInstance); 
    36      
    37     /** 
    38      * <p> 
    39      * method called for each visited iteration instance. 
    40      * </p> 
    41      *  
    42      * @param iterationInstance the iteration instance to be processed 
    43      */ 
    44     public void visit(IIterationInstance iterationInstance); 
    45      
    46     /** 
    47      * <p> 
    48      * method called for each visited optional instance. 
    49      * </p> 
    50      *  
    51      * @param optionalInstance the optional instance to be processed 
    52      */ 
    53     public void visit(IOptionalInstance optionalInstance); 
    54      
    55     /** 
    56      * <p> 
    57      * method called for each visited selection instance. 
    58      * </p> 
    59      *  
    60      * @param selectionInstance the selection instance to be processed 
    61      */ 
    62     public void visit(ISelectionInstance selectionInstance); 
    63      
    64     /** 
    65      * <p> 
    66      * method called for each visited sequence instance. 
    67      * </p> 
    68      *  
    69      * @param sequenceInstance the sequence instance to be processed 
    70      */ 
    71     public void visit(ISequenceInstance sequenceInstance); 
     27        /** 
     28         * <p> 
     29         * method called for each visited event task instance. 
     30         * </p> 
     31         *  
     32         * @param eventTaskInstance 
     33         *            the event task instance to be processed 
     34         */ 
     35        public void visit(IEventTaskInstance eventTaskInstance); 
    7236 
    73     /** 
    74      * <p> 
    75      * method called for each other kind of visited task instance (implemented to support future 
    76      * versions). 
    77      * </p> 
    78      *  
    79      * @param taskInstance the task instance to be processed 
    80      */ 
    81     public void visit(ITaskInstance taskInstance); 
    82      
     37        /** 
     38         * <p> 
     39         * method called for each visited iteration instance. 
     40         * </p> 
     41         *  
     42         * @param iterationInstance 
     43         *            the iteration instance to be processed 
     44         */ 
     45        public void visit(IIterationInstance iterationInstance); 
     46 
     47        /** 
     48         * <p> 
     49         * method called for each visited optional instance. 
     50         * </p> 
     51         *  
     52         * @param optionalInstance 
     53         *            the optional instance to be processed 
     54         */ 
     55        public void visit(IOptionalInstance optionalInstance); 
     56 
     57        /** 
     58         * <p> 
     59         * method called for each visited selection instance. 
     60         * </p> 
     61         *  
     62         * @param selectionInstance 
     63         *            the selection instance to be processed 
     64         */ 
     65        public void visit(ISelectionInstance selectionInstance); 
     66 
     67        /** 
     68         * <p> 
     69         * method called for each visited sequence instance. 
     70         * </p> 
     71         *  
     72         * @param sequenceInstance 
     73         *            the sequence instance to be processed 
     74         */ 
     75        public void visit(ISequenceInstance sequenceInstance); 
     76 
     77        /** 
     78         * <p> 
     79         * method called for each other kind of visited task instance (implemented 
     80         * to support future versions). 
     81         * </p> 
     82         *  
     83         * @param taskInstance 
     84         *            the task instance to be processed 
     85         */ 
     86        public void visit(ITaskInstance taskInstance); 
     87 
    8388} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskModel.java

    r1423 r1733  
    2121/** 
    2222 * <p> 
    23  * This class represents a complete task model. A task model within AutoQUEST is usually generated 
    24  * based on user sessions. Therefore, the task model consists of the user sessions, the models 
    25  * of the identified tasks, as well as further information about the tasks (e.g. their 
    26  * occurrence count) for statistical processing. 
     23 * This class represents a complete task model. A task model within AutoQUEST is 
     24 * usually generated based on user sessions. Therefore, the task model consists 
     25 * of the user sessions, the models of the identified tasks, as well as further 
     26 * information about the tasks (e.g. their occurrence count) for statistical 
     27 * processing. 
    2728 * </p> 
    2829 *  
     
    3132public interface ITaskModel extends Cloneable, Serializable { 
    3233 
    33     /** 
    34      * <p> 
    35      * returns the user sessions belonging to the model. The return value may be null in the case 
    36      * no user sessions are associated the the tasks in the model. 
    37      * </p> 
    38      *  
    39      * @return as described 
    40      */ 
    41     public List<IUserSession> getUserSessions(); 
     34        /** 
     35         * <p> 
     36         * creates a deep clone of the model including all tasks and user sessions. 
     37         * </p> 
     38         *  
     39         * @return as described 
     40         */ 
     41        public ITaskModel clone(); 
    4242 
    43     /** 
    44     * <p> 
    45      * returns the tasks belonging to the model. The return value must not be null. However, 
    46      * it may be an empty list, if the model is an empty model. 
    47     * </p> 
    48      *  
    49     * @return as described 
    50     */ 
    51     public Collection<ITask> getTasks(); 
     43        /** 
     44        * <p> 
     45         * returns a list of all metrics calculated by this model for the tasks and 
     46         * stored in the respective task infos 
     47        * </p> 
     48         * 
     49        * @return as described 
     50        */ 
     51        public TaskMetric[] getAllMetrics(); 
    5252 
    53     /** 
    54     * <p> 
    55      * returns additional info for the provided task. The method returns null, if the provided 
    56      * task does not belong to the model. 
    57     * </p> 
    58     *  
    59     * @return as described 
    60     */ 
    61     public ITaskInfo getTaskInfo(ITask task); 
     53        /** 
     54        * <p> 
     55         * returns additional info for the provided task. The method returns null, 
     56         * if the provided task does not belong to the model. 
     57        * </p> 
     58        *  
     59        * @return as described 
     60        */ 
     61        public ITaskInfo getTaskInfo(ITask task); 
    6262 
    63     /** 
    64     * <p> 
    65      * returns a list of all metrics calculated by this model for the tasks and stored in the 
    66      * respective task infos 
    67     * </p> 
    68      * 
    69     * @return as described 
    70     */ 
    71     public TaskMetric[] getAllMetrics(); 
     63        /** 
     64        * <p> 
     65         * returns the tasks belonging to the model. The return value must not be 
     66         * null. However, it may be an empty list, if the model is an empty model. 
     67        * </p> 
     68         *  
     69        * @return as described 
     70        */ 
     71        public Collection<ITask> getTasks(); 
    7272 
    73     /** 
    74      * <p> 
    75      * creates a deep clone of the model including all tasks and user sessions. 
    76      * </p> 
    77      *  
    78      * @return as described 
    79      */ 
    80     public ITaskModel clone(); 
     73        /** 
     74         * <p> 
     75         * returns the user sessions belonging to the model. The return value may be 
     76         * null in the case no user sessions are associated the the tasks in the 
     77         * model. 
     78         * </p> 
     79         *  
     80         * @return as described 
     81         */ 
     82        public List<IUserSession> getUserSessions(); 
    8183 
    8284} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskVisitor.java

    r1213 r1733  
    1515package de.ugoe.cs.autoquest.tasktrees.treeifc; 
    1616 
    17  
    1817/** 
    1918 * <p> 
    20  * This is an implementation of the visitor pattern. Through this, it is possible to effectively 
    21  * process a task model.  
     19 * This is an implementation of the visitor pattern. Through this, it is 
     20 * possible to effectively process a task model. 
    2221 * </p> 
    2322 *  
     
    2625public interface ITaskVisitor { 
    2726 
    28     /** 
    29      * <p> 
    30      * method called for each visited event task. 
    31      * </p> 
    32      *  
    33      * @param eventTask the event task to be processed 
    34      */ 
    35     public void visit(IEventTask eventTask); 
    36      
    37     /** 
    38      * <p> 
    39      * method called for each visited iteration. 
    40      * </p> 
    41      *  
    42      * @param iteration the iteration to be processed 
    43      */ 
    44     public void visit(IIteration iteration); 
    45      
    46     /** 
    47      * <p> 
    48      * method called for each visited optional. 
    49      * </p> 
    50      *  
    51      * @param optional the optional to be processed 
    52      */ 
    53     public void visit(IOptional optional); 
    54      
    55     /** 
    56      * <p> 
    57      * method called for each visited selection. 
    58      * </p> 
    59      *  
    60      * @param selection the selection to be processed 
    61      */ 
    62     public void visit(ISelection selection); 
    63      
    64     /** 
    65      * <p> 
    66      * method called for each visited sequence. 
    67      * </p> 
    68      *  
    69      * @param sequence the sequence to be processed 
    70      */ 
    71     public void visit(ISequence sequence); 
     27        /** 
     28         * <p> 
     29         * method called for each visited event task. 
     30         * </p> 
     31         *  
     32         * @param eventTask 
     33         *            the event task to be processed 
     34         */ 
     35        public void visit(IEventTask eventTask); 
    7236 
    73     /** 
    74      * <p> 
    75      * method called for each other kind of visited task (implemented to support future versions). 
    76      * </p> 
    77      *  
    78      * @param task the task to be processed 
    79      */ 
    80     public void visit(ITask task); 
    81      
     37        /** 
     38         * <p> 
     39         * method called for each visited iteration. 
     40         * </p> 
     41         *  
     42         * @param iteration 
     43         *            the iteration to be processed 
     44         */ 
     45        public void visit(IIteration iteration); 
     46 
     47        /** 
     48         * <p> 
     49         * method called for each visited optional. 
     50         * </p> 
     51         *  
     52         * @param optional 
     53         *            the optional to be processed 
     54         */ 
     55        public void visit(IOptional optional); 
     56 
     57        /** 
     58         * <p> 
     59         * method called for each visited selection. 
     60         * </p> 
     61         *  
     62         * @param selection 
     63         *            the selection to be processed 
     64         */ 
     65        public void visit(ISelection selection); 
     66 
     67        /** 
     68         * <p> 
     69         * method called for each visited sequence. 
     70         * </p> 
     71         *  
     72         * @param sequence 
     73         *            the sequence to be processed 
     74         */ 
     75        public void visit(ISequence sequence); 
     76 
     77        /** 
     78         * <p> 
     79         * method called for each other kind of visited task (implemented to support 
     80         * future versions). 
     81         * </p> 
     82         *  
     83         * @param task 
     84         *            the task to be processed 
     85         */ 
     86        public void visit(ITask task); 
     87 
    8288} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITemporalRelationship.java

    r1180 r1733  
    1717/** 
    1818 * <p> 
    19  * A temporal relationship is a node in a task model which is no leaf node. They are used to 
    20  * structure the tasks in a task model into useful orders. A temporal relationship defines through 
    21  * its type how its children can be executed to fulfill the task they represent themselves. E.g., 
    22  * the task of filling out a form can be subdivided into several subtasks for filling out the 
    23  * different elements of the. The task itself will define the order, in which the fill out process 
    24  * can and must be done. 
     19 * A temporal relationship is a node in a task model which is no leaf node. They 
     20 * are used to structure the tasks in a task model into useful orders. A 
     21 * temporal relationship defines through its type how its children can be 
     22 * executed to fulfill the task they represent themselves. E.g., the task of 
     23 * filling out a form can be subdivided into several subtasks for filling out 
     24 * the different elements of the. The task itself will define the order, in 
     25 * which the fill out process can and must be done. 
    2526 * </p> 
    2627 *  
     
    2930public interface ITemporalRelationship extends ITask { 
    3031 
    31     /** 
    32      * <p> 
    33      * returns an exact copy of this temporal relationship. The clone has the same id. Its children 
    34      * are clones of the children of the cloned task. A call on the method {@link #equals(ITask)} 
    35      * with the result of this method must return true. 
    36      * </p> 
    37      *  
    38      * @return as described 
    39      */ 
    40     public ITemporalRelationship clone(); 
     32        /** 
     33         * <p> 
     34         * returns an exact copy of this temporal relationship. The clone has the 
     35         * same id. Its children are clones of the children of the cloned task. A 
     36         * call on the method {@link #equals(ITask)} with the result of this method 
     37         * must return true. 
     38         * </p> 
     39         *  
     40         * @return as described 
     41         */ 
     42        @Override 
     43        public ITemporalRelationship clone(); 
    4144 
    4245} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IUserSession.java

    r1177 r1733  
    1919/** 
    2020 * <p> 
    21  * A user session represents task executions, i.e. a task instances of a specific user that were 
    22  * executed in a coherent manner. Therefore, they are an ordered list of task instances where 
    23  * the order denotes the order of the task executions. 
     21 * A user session represents task executions, i.e. a task instances of a 
     22 * specific user that were executed in a coherent manner. Therefore, they are an 
     23 * ordered list of task instances where the order denotes the order of the task 
     24 * executions. 
    2425 * </p> 
    2526 *  
     
    2829public interface IUserSession extends ITaskInstanceList { 
    2930 
    30     /** 
    31      * <p> 
    32      * returns the list of task instances executed in the represented session. 
    33      * </p> 
    34      *  
    35      * @return as described 
    36      */ 
    37     public List<ITaskInstance> getExecutedTasks(); 
    38      
    39     /** 
    40      * <p> 
    41      * compares the user session with another one. Two user sessions are only equal, if they 
    42      * contain the same number of task instances and if each task instance at each position is 
    43      * equal to the respective other session.  
    44      * </p> 
    45      *  
    46      * @param userSession the session to compare the session to 
    47      *  
    48      * @return true if both sessions are equal, false else 
    49      */ 
    50     public boolean equals(IUserSession userSession); 
     31        /** 
     32         * <p> 
     33         * clones a user session by creating exact clones of each contained instance 
     34         * in their order 
     35         * </p> 
     36         *  
     37         * @return a clone of the session 
     38         */ 
     39        public IUserSession clone(); 
    5140 
    52     /** 
    53      * <p> 
    54      * returns a hash code for the session to be able to store the session in a hash map. 
    55      * </p> 
    56      *  
    57      * @return as described 
    58      */ 
    59     public int hashCode(); 
     41        /** 
     42         * <p> 
     43         * compares the user session with another one. Two user sessions are only 
     44         * equal, if they contain the same number of task instances and if each task 
     45         * instance at each position is equal to the respective other session. 
     46         * </p> 
     47         *  
     48         * @param userSession 
     49         *            the session to compare the session to 
     50         *  
     51         * @return true if both sessions are equal, false else 
     52         */ 
     53        public boolean equals(IUserSession userSession); 
    6054 
    61     /** 
    62      * <p> 
    63      * clones a user session by creating exact clones of each contained instance in their order 
    64      * </p> 
    65      *  
    66      * @return a clone of the session 
    67      */ 
    68     public IUserSession clone(); 
     55        /** 
     56         * <p> 
     57         * returns the list of task instances executed in the represented session. 
     58         * </p> 
     59         *  
     60         * @return as described 
     61         */ 
     62        public List<ITaskInstance> getExecutedTasks(); 
     63 
     64        /** 
     65         * <p> 
     66         * returns a hash code for the session to be able to store the session in a 
     67         * hash map. 
     68         * </p> 
     69         *  
     70         * @return as described 
     71         */ 
     72        @Override 
     73        public int hashCode(); 
    6974 
    7075} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/TaskMetric.java

    r1494 r1733  
    1919/** 
    2020 * <p> 
    21  * represents different metrics available or calculatable for tasks. Measure for the metrics 
    22  * are calculated by a task model and added to the task infos of a specific task. 
     21 * represents different metrics available or calculatable for tasks. Measure for 
     22 * the metrics are calculated by a task model and added to the task infos of a 
     23 * specific task. 
    2324 * </p> 
    2425 *  
     
    2728public enum TaskMetric { 
    2829 
    29     COUNT("count", "number of all occurrences of the task in the model"), 
    30     DEPTH("depth", 
    31           "the maximum depth of the task, i.e., the number of children levels including the " + 
    32           "level of the task itself"), 
    33     EVENT_COVERAGE("covered events", "number of all event task instances covered by the task"), 
    34     EVENT_COVERAGE_RATIO("event coverage ratio", 
    35                          "the ratio of events covered by this task in relation to all events " + 
    36                          "covered by all tasks in their instances in per mille", 0.1, "%"), 
    37     EVENT_COVERAGE_QUANTILE("event coverage ratio quantile", 
    38                             "the quantile of with respect to all event coverages begining with " + 
    39                             "the lowest", 0.1, "%"); 
    40      
    41     /** 
    42      * <p> 
    43      * the name of the metric 
    44      * </p> 
    45      */ 
    46     private String name; 
    47      
    48     /** 
    49      * <p> 
    50      * a human readable description of the metric 
    51      * </p> 
    52      */ 
    53     private String description; 
     30        COUNT("count", "number of all occurrences of the task in the model"), DEPTH( 
     31                        "depth", 
     32                        "the maximum depth of the task, i.e., the number of children levels including the " 
     33                                        + "level of the task itself"), EVENT_COVERAGE( 
     34                        "covered events", 
     35                        "number of all event task instances covered by the task"), EVENT_COVERAGE_RATIO( 
     36                        "event coverage ratio", 
     37                        "the ratio of events covered by this task in relation to all events " 
     38                                        + "covered by all tasks in their instances in per mille", 
     39                        0.1, "%"), EVENT_COVERAGE_QUANTILE("event coverage ratio quantile", 
     40                        "the quantile of with respect to all event coverages begining with " 
     41                                        + "the lowest", 0.1, "%"); 
    5442 
    55     /** 
    56      * <p> 
    57      * a scale applied for the metric when formatting the value 
    58      * </p> 
    59      */ 
    60     private double formatScale; 
    61      
    62     /** 
    63      * <p> 
    64      * the unit of the metric used when formatting the value 
    65      * </p> 
    66      */ 
    67     private String formatUnit; 
    68      
    69     /** 
    70      * <p> 
    71      * initializes the metric with a name and a description 
    72      * </p> 
    73      */ 
    74     private TaskMetric(String name, String description) { 
    75         this.name = name; 
    76         this.description = description; 
    77         this.formatScale = 1.0; 
    78         this.formatUnit = null; 
    79     } 
     43        /** 
     44         * <p> 
     45         * the name of the metric 
     46         * </p> 
     47         */ 
     48        private String name; 
    8049 
    81     /** 
    82      * <p> 
    83      * initializes the metric with a name and a description, as well as with a scale and a unit for 
    84      * formatting it. 
    85      * </p> 
    86      */ 
    87     private TaskMetric(String name, String description, double formatScale, String formatUnit) { 
    88         this.name = name; 
    89         this.description = description; 
    90         this.formatScale = formatScale; 
    91         this.formatUnit = formatUnit; 
    92     } 
     50        /** 
     51         * <p> 
     52         * a human readable description of the metric 
     53         * </p> 
     54         */ 
     55        private String description; 
    9356 
    94     /** 
    95      * <p> 
    96      * returns the name of the metric 
    97      * </p> 
    98      *  
    99      * @return the name of the metric 
    100      */ 
    101     public String getName() { 
    102         return name; 
    103     } 
     57        /** 
     58         * <p> 
     59         * a scale applied for the metric when formatting the value 
     60         * </p> 
     61         */ 
     62        private double formatScale; 
    10463 
    105     /** 
    106      * <p> 
    107      * returns the human readable description of the metric 
    108      * </p> 
    109      *  
    110      * @return the human readable description of the metric 
    111      */ 
    112     public String getDescription() { 
    113         return description; 
    114     } 
    115      
    116     /** 
    117      * <p> 
    118      * formats the provided value of a measure of the metric using the internal format scale and 
    119      * unit. 
    120      * </p> 
    121      *  
    122      * @return the formatted value depending on the scale and unit of the metric 
    123      */ 
    124     public String formatValue(int value) { 
    125         String formattedValue; 
    126          
    127         if (formatScale != 1.0) { 
    128             double effectiveValue = formatScale * value; 
    129             formattedValue = new DecimalFormat( "#,##0.0;(#)").format(effectiveValue); 
    130         } 
    131         else { 
    132             formattedValue = Integer.toString(value); 
    133         } 
    134          
    135         if (formatUnit != null) { 
    136             formattedValue += formatUnit; 
    137         } 
    138          
    139         return formattedValue; 
    140     } 
     64        /** 
     65         * <p> 
     66         * the unit of the metric used when formatting the value 
     67         * </p> 
     68         */ 
     69        private String formatUnit; 
     70 
     71        /** 
     72         * <p> 
     73         * initializes the metric with a name and a description 
     74         * </p> 
     75         */ 
     76        private TaskMetric(String name, String description) { 
     77                this.name = name; 
     78                this.description = description; 
     79                this.formatScale = 1.0; 
     80                this.formatUnit = null; 
     81        } 
     82 
     83        /** 
     84         * <p> 
     85         * initializes the metric with a name and a description, as well as with a 
     86         * scale and a unit for formatting it. 
     87         * </p> 
     88         */ 
     89        private TaskMetric(String name, String description, double formatScale, 
     90                        String formatUnit) { 
     91                this.name = name; 
     92                this.description = description; 
     93                this.formatScale = formatScale; 
     94                this.formatUnit = formatUnit; 
     95        } 
     96 
     97        /** 
     98         * <p> 
     99         * formats the provided value of a measure of the metric using the internal 
     100         * format scale and unit. 
     101         * </p> 
     102         *  
     103         * @return the formatted value depending on the scale and unit of the metric 
     104         */ 
     105        public String formatValue(int value) { 
     106                String formattedValue; 
     107 
     108                if (formatScale != 1.0) { 
     109                        final double effectiveValue = formatScale * value; 
     110                        formattedValue = new DecimalFormat("#,##0.0;(#)") 
     111                                        .format(effectiveValue); 
     112                } else { 
     113                        formattedValue = Integer.toString(value); 
     114                } 
     115 
     116                if (formatUnit != null) { 
     117                        formattedValue += formatUnit; 
     118                } 
     119 
     120                return formattedValue; 
     121        } 
     122 
     123        /** 
     124         * <p> 
     125         * returns the human readable description of the metric 
     126         * </p> 
     127         *  
     128         * @return the human readable description of the metric 
     129         */ 
     130        public String getDescription() { 
     131                return description; 
     132        } 
     133 
     134        /** 
     135         * <p> 
     136         * returns the name of the metric 
     137         * </p> 
     138         *  
     139         * @return the name of the metric 
     140         */ 
     141        public String getName() { 
     142                return name; 
     143        } 
    141144} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/EventTask.java

    r1410 r1733  
    2020/** 
    2121 * <p> 
    22  * this is the default implementation of the interface {@link IEventTask}. It does not do anything 
    23  * fancy except implementing the interface. 
    24  * </p>  
     22 * this is the default implementation of the interface {@link IEventTask}. It 
     23 * does not do anything fancy except implementing the interface. 
     24 * </p> 
    2525 * 
    2626 * @author Patrick Harms 
    2727 */ 
    2828class EventTask extends Task implements IEventTask { 
    29      
    30     /** 
    31      * <p> 
    32      * default serial version UID 
    33      * </p> 
    34      */ 
    35     private static final long serialVersionUID = 1L; 
    3629 
    37     /** 
    38      * <p> 
    39      * simple constructor initializing this task with a description for the represented events 
    40      * </p> 
    41      *  
    42      * @param type a type for the represented events 
    43      */ 
    44     EventTask(String type) { 
    45         super(type); 
    46     } 
     30        /** 
     31         * <p> 
     32         * default serial version UID 
     33         * </p> 
     34         */ 
     35        private static final long serialVersionUID = 1L; 
    4736 
    48     /* (non-Javadoc) 
    49      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
    50      */ 
    51     @Override 
    52     public EventTask clone() { 
    53         // Event type and target are unchangeable and do not need to be cloned 
    54         return (EventTask) super.clone(); 
    55     } 
     37        /** 
     38         * <p> 
     39         * simple constructor initializing this task with a description for the 
     40         * represented events 
     41         * </p> 
     42         *  
     43         * @param type 
     44         *            a type for the represented events 
     45         */ 
     46        EventTask(String type) { 
     47                super(type); 
     48        } 
    5649 
    57     /* (non-Javadoc) 
    58      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#accept(ITaskVisitor) 
    59      */ 
    60     @Override 
    61     public void accept(ITaskVisitor visitor) { 
    62         visitor.visit(this); 
    63     } 
     50        /* 
     51         * (non-Javadoc) 
     52         *  
     53         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#accept(ITaskVisitor) 
     54         */ 
     55        @Override 
     56        public void accept(ITaskVisitor visitor) { 
     57                visitor.visit(this); 
     58        } 
     59 
     60        /* 
     61         * (non-Javadoc) 
     62         *  
     63         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
     64         */ 
     65        @Override 
     66        public EventTask clone() { 
     67                // Event type and target are unchangeable and do not need to be cloned 
     68                return (EventTask) super.clone(); 
     69        } 
    6470 
    6571} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/EventTaskInstance.java

    r1414 r1733  
    2828class EventTaskInstance extends TaskInstance implements IEventTaskInstance { 
    2929 
    30     /** 
    31      * <p> 
    32      * default serial version UID 
    33      * </p> 
    34      */ 
    35     private static final long serialVersionUID = 1L; 
    36      
    37     /** 
    38      * <p> 
    39      * the event represented by this instance 
    40      * </p> 
    41      */ 
    42     private Event event; 
     30        /** 
     31         * <p> 
     32         * default serial version UID 
     33         * </p> 
     34         */ 
     35        private static final long serialVersionUID = 1L; 
    4336 
    44     /** 
    45      * <p> 
    46      * initializes this instance with the respective task model and the represented event 
    47      * </p> 
    48      * 
    49      * @param task  the task of which this is an instance 
    50      * @param event the event represented by this instance 
    51      */ 
    52     EventTaskInstance(IEventTask task, Event event) { 
    53         super(task); 
    54         this.event = event; 
    55     } 
     37        /** 
     38         * <p> 
     39         * the event represented by this instance 
     40         * </p> 
     41         */ 
     42        private final Event event; 
    5643 
    57     /* (non-Javadoc) 
    58      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance#getEvent() 
    59      */ 
    60     @Override 
    61     public Event getEvent() { 
    62         return event; 
    63     } 
     44        /** 
     45         * <p> 
     46         * initializes this instance with the respective task model and the 
     47         * represented event 
     48         * </p> 
     49         * 
     50         * @param task 
     51         *            the task of which this is an instance 
     52         * @param event 
     53         *            the event represented by this instance 
     54         */ 
     55        EventTaskInstance(IEventTask task, Event event) { 
     56                super(task); 
     57                this.event = event; 
     58        } 
    6459 
    65     /* (non-Javadoc) 
    66      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance#getEventTask() 
    67      */ 
    68     @Override 
    69     public IEventTask getEventTask() { 
    70         return (IEventTask) super.getTask(); 
    71     } 
     60        /* 
     61         * (non-Javadoc) 
     62         *  
     63         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.IEventTaskInstance#clone() 
     64         */ 
     65        @Override 
     66        public synchronized IEventTaskInstance clone() { 
     67                return (IEventTaskInstance) super.clone(); 
     68        } 
    7269 
    73     /* (non-Javadoc) 
    74      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.IEventTaskInstance#clone() 
    75      */ 
    76     @Override 
    77     public synchronized IEventTaskInstance clone() { 
    78         return (IEventTaskInstance) super.clone(); 
    79     } 
     70        /* 
     71         * (non-Javadoc) 
     72         *  
     73         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance#getEvent() 
     74         */ 
     75        @Override 
     76        public Event getEvent() { 
     77                return event; 
     78        } 
     79 
     80        /* 
     81         * (non-Javadoc) 
     82         *  
     83         * @see 
     84         * de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance#getEventTask() 
     85         */ 
     86        @Override 
     87        public IEventTask getEventTask() { 
     88                return (IEventTask) super.getTask(); 
     89        } 
    8090 
    8191} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Iteration.java

    r1215 r1733  
    2121/** 
    2222 * <p> 
    23  * this is the default implementation of the interface {@link IIteration}. It does not do anything 
    24  * fancy except implementing the interface. 
    25  * </p>  
     23 * this is the default implementation of the interface {@link IIteration}. It 
     24 * does not do anything fancy except implementing the interface. 
     25 * </p> 
    2626 * 
    2727 * @author Patrick Harms 
     
    2929class Iteration extends MarkingTemporalRelationship implements IIteration { 
    3030 
    31     /** 
    32     * <p> 
    33     * default serial version UID 
    34     * </p> 
    35     */ 
    36     private static final long serialVersionUID = 1L; 
     31        /** 
     32        * <p> 
     33        * default serial version UID 
     34        * </p> 
     35        */ 
     36        private static final long serialVersionUID = 1L; 
    3737 
    38     /** 
    39     * <p> 
    40      * simple constructor providing the base class with a human readable name of the type of this 
    41      * task 
    42     * </p> 
    43     */ 
    44     Iteration() { 
    45         super("iteration"); 
    46     } 
     38        /** 
     39        * <p> 
     40         * simple constructor providing the base class with a human readable name of 
     41         * the type of this task 
     42        * </p> 
     43        */ 
     44        Iteration() { 
     45                super("iteration"); 
     46        } 
    4747 
    48     /* (non-Javadoc) 
    49      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#setMarkedTask(ITask) 
    50      */ 
    51     @Override 
    52     protected void setMarkedTask(ITask markedTask) { 
    53         if (markedTask instanceof IIteration) { 
    54             throw new IllegalArgumentException 
    55                 ("the marked task of an iteration must not be an iteration"); 
    56         } 
    57         else if (markedTask instanceof IOptional) { 
    58             throw new IllegalArgumentException 
    59                 ("the marked task of an iteration must not be an optional"); 
    60         } 
    61          
    62         super.setMarkedTask(markedTask); 
    63     } 
     48        /* 
     49         * (non-Javadoc) 
     50         *  
     51         * @see 
     52         * de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#clone 
     53         * () 
     54         */ 
     55        @Override 
     56        public Iteration clone() { 
     57                return (Iteration) super.clone(); 
     58        } 
    6459 
    65     /* (non-Javadoc) 
    66      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#clone() 
    67      */ 
    68     @Override 
    69     public Iteration clone() { 
    70         return (Iteration) super.clone(); 
    71     } 
    72      
     60        /* 
     61         * (non-Javadoc) 
     62         *  
     63         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship# 
     64         * setMarkedTask(ITask) 
     65         */ 
     66        @Override 
     67        protected void setMarkedTask(ITask markedTask) { 
     68                if (markedTask instanceof IIteration) { 
     69                        throw new IllegalArgumentException( 
     70                                        "the marked task of an iteration must not be an iteration"); 
     71                } else if (markedTask instanceof IOptional) { 
     72                        throw new IllegalArgumentException( 
     73                                        "the marked task of an iteration must not be an optional"); 
     74                } 
     75 
     76                super.setMarkedTask(markedTask); 
     77        } 
     78 
    7379} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/IterationInstance.java

    r1414 r1733  
    3333class IterationInstance extends TaskInstance implements IIterationInstance { 
    3434 
    35     /** 
    36     * <p> 
    37     * default serial version UID 
    38     * </p> 
    39     */ 
    40     private static final long serialVersionUID = 1L; 
     35        /** 
     36        * <p> 
     37        * default serial version UID 
     38        * </p> 
     39        */ 
     40        private static final long serialVersionUID = 1L; 
    4141 
    42     /** 
    43     * <p> 
    44     * the children of this task instance which are task instances, as well 
    45     * </p> 
    46     */ 
    47     private List<ITaskInstance> children; 
     42        /** 
     43        * <p> 
     44        * the children of this task instance which are task instances, as well 
     45        * </p> 
     46        */ 
     47        private List<ITaskInstance> children; 
    4848 
    49     /** 
    50      * <p> 
    51      * initializes this instance with the respective task model 
    52      * </p> 
    53      * 
    54      * @param task  the task of which this is an instance 
    55      */ 
    56     IterationInstance(IIteration task) { 
    57         super(task); 
    58     } 
     49        /** 
     50         * <p> 
     51         * initializes this instance with the respective task model 
     52         * </p> 
     53         * 
     54         * @param task 
     55         *            the task of which this is an instance 
     56         */ 
     57        IterationInstance(IIteration task) { 
     58                super(task); 
     59        } 
    5960 
    60     /* (non-Javadoc) 
    61      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getChildren() 
    62      */ 
    63     public synchronized List<ITaskInstance> getChildren() { 
    64         if (children == null) { 
    65             children = new LinkedList<ITaskInstance>(); 
    66         } 
     61        /** 
     62         * <p> 
     63         * used to add a child to this task instance at a specific position 
     64         * </p> 
     65         *  
     66         * @param index 
     67         *            the position of the new child in the list of children 
     68         * @param child 
     69         *            the new child of this instance 
     70         */ 
     71        synchronized void addChild(int index, ITaskInstance child) { 
     72                if (children == null) { 
     73                        children = new LinkedList<ITaskInstance>(); 
     74                } 
    6775 
    68         return Collections.unmodifiableList(children); 
    69     } 
     76                children.add(index, child); 
     77        } 
    7078 
    71     /* (non-Javadoc) 
    72      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
    73      */ 
    74     @Override 
    75     public ITaskInstance get(int index) { 
    76         if (children == null) { 
    77             throw new IndexOutOfBoundsException(Integer.toString(index)); 
    78         } 
    79         else { 
    80             return children.get(index); 
    81         } 
    82     } 
     79        /** 
     80         * <p> 
     81         * used to add a child to this task instance 
     82         * </p> 
     83         *  
     84         * @param child 
     85         *            the new child of this instance 
     86         */ 
     87        synchronized void addChild(ITaskInstance child) { 
     88                if (children == null) { 
     89                        children = new LinkedList<ITaskInstance>(); 
     90                } 
    8391 
    84     /* (non-Javadoc) 
    85      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
    86      */ 
    87     @Override 
    88     public int size() { 
    89         if (children == null) { 
    90             return 0; 
    91         } 
    92         else { 
    93             return children.size(); 
    94         } 
    95     } 
     92                children.add(child); 
     93        } 
    9694 
    97     /* (non-Javadoc) 
    98      * @see java.lang.Iterable#iterator() 
    99      */ 
    100     @Override 
    101     public Iterator<ITaskInstance> iterator() { 
    102         return getChildren().iterator(); 
    103     } 
     95        /* 
     96         * (non-Javadoc) 
     97         *  
     98         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.IIterationInstance#clone() 
     99         */ 
     100        @Override 
     101        public synchronized IIterationInstance clone() { 
     102                final IterationInstance clone = (IterationInstance) super.clone(); 
    104103 
    105     /* (non-Javadoc) 
    106      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance#getIteration() 
    107      */ 
    108     @Override 
    109     public IIteration getIteration() { 
    110         return (IIteration) super.getTask(); 
    111     } 
     104                if (children != null) { 
     105                        clone.children = new LinkedList<ITaskInstance>(); 
    112106 
    113     /* (non-Javadoc) 
    114      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.IIterationInstance#clone() 
    115      */ 
    116     @Override 
    117     public synchronized IIterationInstance clone() { 
    118         IterationInstance clone = (IterationInstance) super.clone(); 
     107                        for (final ITaskInstance child : children) { 
     108                                clone.children.add(child.clone()); 
     109                        } 
     110                } 
    119111 
    120         if (children != null) { 
    121             clone.children = new LinkedList<ITaskInstance>(); 
     112                return clone; 
     113        } 
    122114 
    123             for (ITaskInstance child : children) { 
    124                 clone.children.add(child.clone()); 
    125             } 
    126         } 
     115        /* 
     116         * (non-Javadoc) 
     117         *  
     118         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
     119         */ 
     120        @Override 
     121        public ITaskInstance get(int index) { 
     122                if (children == null) { 
     123                        throw new IndexOutOfBoundsException(Integer.toString(index)); 
     124                } else { 
     125                        return children.get(index); 
     126                } 
     127        } 
    127128 
    128         return clone; 
    129     } 
     129        /* 
     130         * (non-Javadoc) 
     131         *  
     132         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getChildren() 
     133         */ 
     134        public synchronized List<ITaskInstance> getChildren() { 
     135                if (children == null) { 
     136                        children = new LinkedList<ITaskInstance>(); 
     137                } 
    130138 
    131     /** 
    132      * <p> 
    133      * used to add a child to this task instance 
    134      * </p> 
    135      *  
    136      * @param child the new child of this instance 
    137      */ 
    138     synchronized void addChild(ITaskInstance child) { 
    139         if (children == null) { 
    140             children = new LinkedList<ITaskInstance>(); 
    141         } 
     139                return Collections.unmodifiableList(children); 
     140        } 
    142141 
    143         children.add(child); 
    144     } 
     142        /* 
     143         * (non-Javadoc) 
     144         *  
     145         * @see 
     146         * de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance#getIteration() 
     147         */ 
     148        @Override 
     149        public IIteration getIteration() { 
     150                return (IIteration) super.getTask(); 
     151        } 
    145152 
    146     /** 
    147      * <p> 
    148      * used to add a child to this task instance at a specific position 
    149      * </p> 
    150      *  
    151      * @param index the position of the new child in the list of children 
    152      * @param child the new child of this instance 
    153      */ 
    154     synchronized void addChild(int index, ITaskInstance child) { 
    155         if (children == null) { 
    156             children = new LinkedList<ITaskInstance>(); 
    157         } 
     153        /* 
     154         * (non-Javadoc) 
     155         *  
     156         * @see java.lang.Iterable#iterator() 
     157         */ 
     158        @Override 
     159        public Iterator<ITaskInstance> iterator() { 
     160                return getChildren().iterator(); 
     161        } 
    158162 
    159         children.add(index, child); 
    160     } 
     163        /** 
     164         * <p> 
     165         * removes a child from this task instance at a specific position 
     166         * </p> 
     167         *  
     168         * @param index 
     169         *            the position of the child to be removed 
     170         *  
     171         * @return the child removed from the children of this instance 
     172         */ 
     173        synchronized ITaskInstance removeChild(int index) { 
     174                if (children != null) { 
     175                        return children.remove(index); 
     176                } else { 
     177                        throw new IllegalArgumentException( 
     178                                        "this task instance does not have children that can be removed"); 
     179                } 
     180        } 
    161181 
    162     /** 
    163      * <p> 
    164      * removes a child from this task instance at a specific position 
    165      * </p> 
    166      *  
    167      * @param index the position of the child to be removed 
    168      *  
    169      * @return the child removed from the children of this instance 
    170      */ 
    171     synchronized ITaskInstance removeChild(int index) { 
    172         if (children != null) { 
    173             return children.remove(index); 
    174         } 
    175         else { 
    176             throw new IllegalArgumentException 
    177                 ("this task instance does not have children that can be removed"); 
    178         } 
    179     } 
     182        /* 
     183         * (non-Javadoc) 
     184         *  
     185         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
     186         */ 
     187        @Override 
     188        public int size() { 
     189                if (children == null) { 
     190                        return 0; 
     191                } else { 
     192                        return children.size(); 
     193                } 
     194        } 
    180195 
    181196} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/MarkingTemporalRelationship.java

    r1357 r1733  
    2020/** 
    2121 * <p> 
    22  * this is the default implementation of the interface {@link IMarkingTemporalRelationship}. It 
    23  * does not do anything fancy except implementing the interface. 
     22 * this is the default implementation of the interface 
     23 * {@link IMarkingTemporalRelationship}. It does not do anything fancy except 
     24 * implementing the interface. 
    2425 * </p> 
    2526 *  
    2627 * @author Patrick Harms 
    2728 */ 
    28 abstract class MarkingTemporalRelationship extends Task 
    29     implements IMarkingTemporalRelationship 
    30 { 
     29abstract class MarkingTemporalRelationship extends Task implements 
     30                IMarkingTemporalRelationship { 
    3131 
    32     /** 
    33     * <p> 
    34     * default serial version UID 
    35     * </p> 
    36     */ 
    37     private static final long serialVersionUID = 1L; 
     32        /** 
     33        * <p> 
     34        * default serial version UID 
     35        * </p> 
     36        */ 
     37        private static final long serialVersionUID = 1L; 
    3838 
    39     /** 
    40      * <p> 
    41      * the task marked through this marking temporal relationship 
    42      * </p> 
    43      */ 
    44     private ITask markedTask; 
    45      
    46     /** 
    47      * <p> 
    48      * initializes this temporal relationship with a human readable name 
    49      * </p> 
    50      * 
    51      * @param relationshipType the human readable name of this temporal relationship 
    52      */ 
    53     MarkingTemporalRelationship(String relationshipType) { 
    54         super(relationshipType); 
    55          
    56         if ((relationshipType == null) || ("".equals(relationshipType))) { 
    57             throw new IllegalArgumentException 
    58                 ("the relationship type must be something meaningful"); 
    59         } 
    60     } 
     39        /** 
     40         * <p> 
     41         * the task marked through this marking temporal relationship 
     42         * </p> 
     43         */ 
     44        private ITask markedTask; 
    6145 
    62     /* (non-Javadoc) 
    63      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship#getMarkedTask() 
    64      */ 
    65     @Override 
    66     public ITask getMarkedTask() { 
    67         return markedTask; 
    68     } 
     46        /** 
     47         * <p> 
     48         * initializes this temporal relationship with a human readable name 
     49         * </p> 
     50         * 
     51         * @param relationshipType 
     52         *            the human readable name of this temporal relationship 
     53         */ 
     54        MarkingTemporalRelationship(String relationshipType) { 
     55                super(relationshipType); 
    6956 
    70     /* (non-Javadoc) 
    71      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
    72      */ 
    73     @Override 
    74     public synchronized MarkingTemporalRelationship clone() { 
    75         MarkingTemporalRelationship clone = null; 
    76         clone = (MarkingTemporalRelationship) super.clone(); 
    77              
    78         if (markedTask != null) { 
    79             clone.markedTask = markedTask.clone(); 
    80         } 
     57                if ((relationshipType == null) || ("".equals(relationshipType))) { 
     58                        throw new IllegalArgumentException( 
     59                                        "the relationship type must be something meaningful"); 
     60                } 
     61        } 
    8162 
    82         return clone; 
    83     } 
     63        /* 
     64         * (non-Javadoc) 
     65         *  
     66         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
     67         */ 
     68        @Override 
     69        public synchronized MarkingTemporalRelationship clone() { 
     70                MarkingTemporalRelationship clone = null; 
     71                clone = (MarkingTemporalRelationship) super.clone(); 
    8472 
    85     /** 
    86      * <p> 
    87      * used to set the marked task 
    88      * </p> 
    89      *  
    90      * @param markedTask the marked task to set 
    91      */ 
    92     protected void setMarkedTask(ITask markedTask) { 
    93         this.markedTask = markedTask; 
    94          
    95         super.setDescription(markedTask.toString()); 
    96     } 
     73                if (markedTask != null) { 
     74                        clone.markedTask = markedTask.clone(); 
     75                } 
     76 
     77                return clone; 
     78        } 
     79 
     80        /* 
     81         * (non-Javadoc) 
     82         *  
     83         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship# 
     84         * getMarkedTask() 
     85         */ 
     86        @Override 
     87        public ITask getMarkedTask() { 
     88                return markedTask; 
     89        } 
     90 
     91        /** 
     92         * <p> 
     93         * used to set the marked task 
     94         * </p> 
     95         *  
     96         * @param markedTask 
     97         *            the marked task to set 
     98         */ 
     99        protected void setMarkedTask(ITask markedTask) { 
     100                this.markedTask = markedTask; 
     101 
     102                super.setDescription(markedTask.toString()); 
     103        } 
    97104 
    98105} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Optional.java

    r1215 r1733  
    2020/** 
    2121 * <p> 
    22  * this is the default implementation of the interface {@link IOptional}. It does not do anything 
    23  * fancy except implementing the interface. 
    24  * </p>  
     22 * this is the default implementation of the interface {@link IOptional}. It 
     23 * does not do anything fancy except implementing the interface. 
     24 * </p> 
    2525 * 
    2626 * @author Patrick Harms 
     
    2828class Optional extends MarkingTemporalRelationship implements IOptional { 
    2929 
    30     /** 
    31     * <p> 
    32     * default serial version UID 
    33     * </p> 
    34     */ 
    35     private static final long serialVersionUID = 1L; 
     30        /** 
     31        * <p> 
     32        * default serial version UID 
     33        * </p> 
     34        */ 
     35        private static final long serialVersionUID = 1L; 
    3636 
    37     /** 
    38      * <p> 
    39      * simple constructor providing the base class with a human readable name of the type of this 
    40      * task 
    41      * </p> 
    42      */ 
    43     Optional() { 
    44         super("optionality"); 
    45     } 
    46      
    47     /* (non-Javadoc) 
    48      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#setMarkedTask(ITask) 
    49      */ 
    50     @Override 
    51     protected void setMarkedTask(ITask markedTask) { 
    52         if (markedTask instanceof IOptional) { 
    53             throw new IllegalArgumentException 
    54                 ("the marked task of an optional must not be an optional"); 
    55         } 
    56          
    57         super.setMarkedTask(markedTask); 
    58     } 
     37        /** 
     38         * <p> 
     39         * simple constructor providing the base class with a human readable name of 
     40         * the type of this task 
     41         * </p> 
     42         */ 
     43        Optional() { 
     44                super("optionality"); 
     45        } 
    5946 
    60     /* (non-Javadoc) 
    61      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#clone() 
    62      */ 
    63     @Override 
    64     public Optional clone() { 
    65         return (Optional) super.clone(); 
    66     } 
     47        /* 
     48         * (non-Javadoc) 
     49         *  
     50         * @see 
     51         * de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship#clone 
     52         * () 
     53         */ 
     54        @Override 
     55        public Optional clone() { 
     56                return (Optional) super.clone(); 
     57        } 
     58 
     59        /* 
     60         * (non-Javadoc) 
     61         *  
     62         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.MarkingTemporalRelationship# 
     63         * setMarkedTask(ITask) 
     64         */ 
     65        @Override 
     66        protected void setMarkedTask(ITask markedTask) { 
     67                if (markedTask instanceof IOptional) { 
     68                        throw new IllegalArgumentException( 
     69                                        "the marked task of an optional must not be an optional"); 
     70                } 
     71 
     72                super.setMarkedTask(markedTask); 
     73        } 
    6774 
    6875} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/OptionalInstance.java

    r1414 r1733  
    2929class OptionalInstance extends TaskInstance implements IOptionalInstance { 
    3030 
    31     /** 
    32     * <p> 
    33     * default serial version UID 
    34     * </p> 
    35     */ 
    36     private static final long serialVersionUID = 1L; 
     31        /** 
     32        * <p> 
     33        * default serial version UID 
     34        * </p> 
     35        */ 
     36        private static final long serialVersionUID = 1L; 
    3737 
    38     /** 
    39      * <p> 
    40      * the child of this task instance if any 
    41      * </p> 
    42      */ 
    43     private ITaskInstance child; 
    44      
    45     /** 
    46      * <p> 
    47      * initializes this instance with the respective task model 
    48      * </p> 
    49      * 
    50      * @param task  the task of which this is an instance 
    51      */ 
    52     OptionalInstance(ITask task) { 
    53         super(task); 
    54     } 
     38        /** 
     39         * <p> 
     40         * the child of this task instance if any 
     41         * </p> 
     42         */ 
     43        private ITaskInstance child; 
    5544 
    56     /* (non-Javadoc) 
    57      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance#getChild() 
    58      */ 
    59     @Override 
    60     public ITaskInstance getChild() { 
    61         return child; 
    62     } 
     45        /** 
     46         * <p> 
     47         * initializes this instance with the respective task model 
     48         * </p> 
     49         * 
     50         * @param task 
     51         *            the task of which this is an instance 
     52         */ 
     53        OptionalInstance(ITask task) { 
     54                super(task); 
     55        } 
    6356 
    64     /* (non-Javadoc) 
    65      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance#getOptional() 
    66      */ 
    67     @Override 
    68     public IOptional getOptional() { 
    69         return (IOptional) super.getTask(); 
    70     } 
     57        /* 
     58         * (non-Javadoc) 
     59         *  
     60         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
     61         */ 
     62        @Override 
     63        public synchronized IOptionalInstance clone() { 
     64                final OptionalInstance clone = (OptionalInstance) super.clone(); 
    7165 
    72     /* (non-Javadoc) 
    73      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
    74      */ 
    75     @Override 
    76     public synchronized IOptionalInstance clone() { 
    77         OptionalInstance clone = (OptionalInstance) super.clone(); 
     66                if (child != null) { 
     67                        clone.child = child.clone(); 
     68                } 
    7869 
    79         if (child != null) { 
    80             clone.child = child.clone(); 
    81         } 
     70                return clone; 
     71        } 
    8272 
    83         return clone; 
    84     } 
     73        /* 
     74         * (non-Javadoc) 
     75         *  
     76         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance#getChild() 
     77         */ 
     78        @Override 
     79        public ITaskInstance getChild() { 
     80                return child; 
     81        } 
    8582 
    86     /** 
    87      * <p> 
    88      * used to set the child of this task instance 
    89      * </p> 
    90      *  
    91      * @param child the new child of this instance 
    92      */ 
    93     void setChild(ITaskInstance child) { 
    94         if (child instanceof IOptionalInstance) { 
    95             throw new IllegalArgumentException("the child of an optional can not be an optional"); 
    96         } 
    97          
    98         this.child = child; 
    99     } 
     83        /* 
     84         * (non-Javadoc) 
     85         *  
     86         * @see 
     87         * de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance#getOptional() 
     88         */ 
     89        @Override 
     90        public IOptional getOptional() { 
     91                return (IOptional) super.getTask(); 
     92        } 
     93 
     94        /** 
     95         * <p> 
     96         * used to set the child of this task instance 
     97         * </p> 
     98         *  
     99         * @param child 
     100         *            the new child of this instance 
     101         */ 
     102        void setChild(ITaskInstance child) { 
     103                if (child instanceof IOptionalInstance) { 
     104                        throw new IllegalArgumentException( 
     105                                        "the child of an optional can not be an optional"); 
     106                } 
     107 
     108                this.child = child; 
     109        } 
    100110 
    101111} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Selection.java

    r1404 r1733  
    2020/** 
    2121 * <p> 
    22  * this is the default implementation of the interface {@link ISelection}. It does not do anything 
    23  * fancy except implementing the interface. 
    24  * </p>  
     22 * this is the default implementation of the interface {@link ISelection}. It 
     23 * does not do anything fancy except implementing the interface. 
     24 * </p> 
    2525 * 
    2626 * @author Patrick Harms 
     
    2828class Selection extends StructuringTemporalRelationship implements ISelection { 
    2929 
    30     /** 
    31     * <p> 
    32     * default serial version UID 
    33     * </p> 
    34     */ 
    35     private static final long serialVersionUID = 1L; 
     30        /** 
     31        * <p> 
     32        * default serial version UID 
     33        * </p> 
     34        */ 
     35        private static final long serialVersionUID = 1L; 
    3636 
    37     /** 
    38     * <p> 
    39      * simple constructor providing the base class with a human readable name of the type of this 
    40      * task 
    41     * </p> 
    42     */ 
    43     Selection() { 
    44         super("selection"); 
    45     } 
     37        /** 
     38        * <p> 
     39         * simple constructor providing the base class with a human readable name of 
     40         * the type of this task 
     41        * </p> 
     42        */ 
     43        Selection() { 
     44                super("selection"); 
     45        } 
    4646 
    47     /* (non-Javadoc) 
    48      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship#clone() 
    49      */ 
    50     @Override 
    51     public Selection clone() { 
    52         return (Selection) super.clone(); 
    53     } 
     47        /* 
     48         * (non-Javadoc) 
     49         *  
     50         * @see 
     51         * de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship 
     52         * #addChild(int,ITask) 
     53         */ 
     54        @Override 
     55        void addChild(int index, ITask newChild) { 
     56                super.addChild(index, newChild); 
     57        } 
    5458 
    55     /* (non-Javadoc) 
    56      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship#addChild(ITask) 
    57      */ 
    58     @Override 
    59     void addChild(ITask newChild) { 
    60         super.addChild(newChild); 
    61     } 
     59        /* 
     60         * (non-Javadoc) 
     61         *  
     62         * @see 
     63         * de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship 
     64         * #addChild(ITask) 
     65         */ 
     66        @Override 
     67        void addChild(ITask newChild) { 
     68                super.addChild(newChild); 
     69        } 
    6270 
    63     /* (non-Javadoc) 
    64      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship#addChild(int,ITask) 
    65      */ 
    66     @Override 
    67     void addChild(int index, ITask newChild) { 
    68         super.addChild(index, newChild); 
    69     } 
     71        /* 
     72         * (non-Javadoc) 
     73         *  
     74         * @see 
     75         * de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship 
     76         * #clone() 
     77         */ 
     78        @Override 
     79        public Selection clone() { 
     80                return (Selection) super.clone(); 
     81        } 
    7082 
    7183} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/SelectionInstance.java

    r1414 r1733  
    2929class SelectionInstance extends TaskInstance implements ISelectionInstance { 
    3030 
    31     /** 
    32     * <p> 
    33     * default serial version UID 
    34     * </p> 
    35     */ 
    36     private static final long serialVersionUID = 1L; 
     31        /** 
     32        * <p> 
     33        * default serial version UID 
     34        * </p> 
     35        */ 
     36        private static final long serialVersionUID = 1L; 
    3737 
    38     /** 
    39      * <p> 
    40      * the child of this task instance 
    41      * </p> 
    42      */ 
    43     private ITaskInstance child; 
    44      
    45     /** 
    46      * <p> 
    47      * initializes this instance with the respective task model 
    48      * </p> 
    49      * 
    50      * @param task  the task of which this is an instance 
    51      */ 
    52     SelectionInstance(ITask task) { 
    53         super(task); 
    54     } 
     38        /** 
     39         * <p> 
     40         * the child of this task instance 
     41         * </p> 
     42         */ 
     43        private ITaskInstance child; 
    5544 
    56     /* (non-Javadoc) 
    57      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance#getChild() 
    58      */ 
    59     @Override 
    60     public ITaskInstance getChild() { 
    61         return child; 
    62     } 
     45        /** 
     46         * <p> 
     47         * initializes this instance with the respective task model 
     48         * </p> 
     49         * 
     50         * @param task 
     51         *            the task of which this is an instance 
     52         */ 
     53        SelectionInstance(ITask task) { 
     54                super(task); 
     55        } 
    6356 
    64     /* (non-Javadoc) 
    65      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance#getSelection() 
    66      */ 
    67     @Override 
    68     public ISelection getSelection() { 
    69         return (ISelection) super.getTask(); 
    70     } 
     57        /* 
     58         * (non-Javadoc) 
     59         *  
     60         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
     61         */ 
     62        @Override 
     63        public synchronized ISelectionInstance clone() { 
     64                final SelectionInstance clone = (SelectionInstance) super.clone(); 
    7165 
    72     /* (non-Javadoc) 
    73      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
    74      */ 
    75     @Override 
    76     public synchronized ISelectionInstance clone() { 
    77         SelectionInstance clone = (SelectionInstance) super.clone(); 
     66                if (child != null) { 
     67                        clone.child = child.clone(); 
     68                } 
    7869 
    79         if (child != null) { 
    80             clone.child = child.clone(); 
    81         } 
     70                return clone; 
     71        } 
    8272 
    83         return clone; 
    84     } 
     73        /* 
     74         * (non-Javadoc) 
     75         *  
     76         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance#getChild() 
     77         */ 
     78        @Override 
     79        public ITaskInstance getChild() { 
     80                return child; 
     81        } 
    8582 
    86     /** 
    87      * <p> 
    88      * used to set the child of this task instance 
    89      * </p> 
    90      *  
    91      * @param child the new child of this instance 
    92      */ 
    93     void setChild(ITaskInstance child) { 
    94         if (child instanceof ISelectionInstance) { 
    95             throw new IllegalArgumentException("the child of a selection can not be a selection"); 
    96         } 
    97          
    98         this.child = child; 
    99     } 
     83        /* 
     84         * (non-Javadoc) 
     85         *  
     86         * @see 
     87         * de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance#getSelection() 
     88         */ 
     89        @Override 
     90        public ISelection getSelection() { 
     91                return (ISelection) super.getTask(); 
     92        } 
     93 
     94        /** 
     95         * <p> 
     96         * used to set the child of this task instance 
     97         * </p> 
     98         *  
     99         * @param child 
     100         *            the new child of this instance 
     101         */ 
     102        void setChild(ITaskInstance child) { 
     103                if (child instanceof ISelectionInstance) { 
     104                        throw new IllegalArgumentException( 
     105                                        "the child of a selection can not be a selection"); 
     106                } 
     107 
     108                this.child = child; 
     109        } 
    100110 
    101111} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Sequence.java

    r1215 r1733  
    1919/** 
    2020 * <p> 
    21  * this is the default implementation of the interface {@link ISequence}. It does not do anything 
    22  * fancy except implementing the interface. 
    23  * </p>  
     21 * this is the default implementation of the interface {@link ISequence}. It 
     22 * does not do anything fancy except implementing the interface. 
     23 * </p> 
    2424 * 
    2525 * @author Patrick Harms 
    2626 */ 
    2727class Sequence extends StructuringTemporalRelationship implements ISequence { 
    28      
    29     /** 
    30      * <p> 
    31      * default serial version UID 
    32      * </p> 
    33      */ 
    34     private static final long serialVersionUID = 1L; 
    3528 
    36     /** 
    37      * <p> 
    38      * simple constructor providing the base class with a human readable name of the type of this 
    39      * task 
    40      * </p> 
    41      */ 
    42     Sequence() { 
    43         super("sequence"); 
    44     } 
     29        /** 
     30         * <p> 
     31         * default serial version UID 
     32         * </p> 
     33         */ 
     34        private static final long serialVersionUID = 1L; 
    4535 
    46     /* (non-Javadoc) 
    47      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship#clone() 
    48      */ 
    49     @Override 
    50     public Sequence clone() { 
    51         return (Sequence) super.clone(); 
    52     } 
    53      
     36        /** 
     37         * <p> 
     38         * simple constructor providing the base class with a human readable name of 
     39         * the type of this task 
     40         * </p> 
     41         */ 
     42        Sequence() { 
     43                super("sequence"); 
     44        } 
     45 
     46        /* 
     47         * (non-Javadoc) 
     48         *  
     49         * @see 
     50         * de.ugoe.cs.autoquest.tasktrees.treeimpl.StructuringTemporalRelationship 
     51         * #clone() 
     52         */ 
     53        @Override 
     54        public Sequence clone() { 
     55                return (Sequence) super.clone(); 
     56        } 
     57 
    5458} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/SequenceInstance.java

    r1414 r1733  
    3434class SequenceInstance extends TaskInstance implements ISequenceInstance { 
    3535 
    36     /** 
    37     * <p> 
    38     * default serial version UID 
    39     * </p> 
    40     */ 
    41     private static final long serialVersionUID = 1L; 
     36        /** 
     37        * <p> 
     38        * default serial version UID 
     39        * </p> 
     40        */ 
     41        private static final long serialVersionUID = 1L; 
    4242 
    43     /** 
    44     * <p> 
    45     * the children of this task instance which are task instances, as well 
    46     * </p> 
    47     */ 
    48     private List<ITaskInstance> children; 
     43        /** 
     44        * <p> 
     45        * the children of this task instance which are task instances, as well 
     46        * </p> 
     47        */ 
     48        private List<ITaskInstance> children; 
    4949 
    50     /** 
    51      * <p> 
    52      * initializes this instance with the respective task model 
    53      * </p> 
    54      * 
    55      * @param task  the task of which this is an instance 
    56      */ 
    57     SequenceInstance(ISequence task) { 
    58         super(task); 
    59     } 
     50        /** 
     51         * <p> 
     52         * initializes this instance with the respective task model 
     53         * </p> 
     54         * 
     55         * @param task 
     56         *            the task of which this is an instance 
     57         */ 
     58        SequenceInstance(ISequence task) { 
     59                super(task); 
     60        } 
    6061 
    61     /* (non-Javadoc) 
    62      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getChildren() 
    63      */ 
    64     public synchronized List<ITaskInstance> getChildren() { 
    65         if (children == null) { 
    66             children = new LinkedList<ITaskInstance>(); 
    67         } 
     62        /** 
     63         * <p> 
     64         * used to add a child to this task instance at a specific position 
     65         * </p> 
     66         *  
     67         * @param index 
     68         *            the position of the new child in the list of children 
     69         * @param child 
     70         *            the new child of this instance 
     71         */ 
     72        synchronized void addChild(int index, ITaskInstance child) { 
     73                if (children == null) { 
     74                        children = new LinkedList<ITaskInstance>(); 
     75                } 
    6876 
    69         return Collections.unmodifiableList(children); 
    70     } 
     77                children.add(index, child); 
     78        } 
    7179 
    72     /* (non-Javadoc) 
    73      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
    74      */ 
    75     @Override 
    76     public ITaskInstance get(int index) { 
    77         if (children == null) { 
    78             throw new IndexOutOfBoundsException(Integer.toString(index)); 
    79         } 
    80         else { 
    81             return children.get(index); 
    82         } 
    83     } 
     80        /** 
     81         * <p> 
     82         * used to add a child to this task instance 
     83         * </p> 
     84         *  
     85         * @param child 
     86         *            the new child of this instance 
     87         */ 
     88        synchronized void addChild(ITaskInstance child) { 
     89                if (children == null) { 
     90                        children = new LinkedList<ITaskInstance>(); 
     91                } 
    8492 
    85     /* (non-Javadoc) 
    86      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
    87      */ 
    88     @Override 
    89     public int size() { 
    90         if (children == null) { 
    91             return 0; 
    92         } 
    93         else { 
    94             return children.size(); 
    95         } 
    96     } 
     93                children.add(child); 
     94        } 
    9795 
    98     /* (non-Javadoc) 
    99      * @see java.lang.Iterable#iterator() 
    100      */ 
    101     @Override 
    102     public Iterator<ITaskInstance> iterator() { 
    103         return getChildren().iterator(); 
    104     } 
     96        /* 
     97         * (non-Javadoc) 
     98         *  
     99         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
     100         */ 
     101        @Override 
     102        public synchronized ISequenceInstance clone() { 
     103                final SequenceInstance clone = (SequenceInstance) super.clone(); 
    105104 
    106     /* (non-Javadoc) 
    107      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance#getSequence() 
    108      */ 
    109     @Override 
    110     public ISequence getSequence() { 
    111         return (ISequence) super.getTask(); 
    112     } 
     105                if (children != null) { 
     106                        clone.children = new LinkedList<ITaskInstance>(); 
    113107 
    114     /* (non-Javadoc) 
    115      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.ISequenceInstance#clone() 
    116      */ 
    117     @Override 
    118     public synchronized ISequenceInstance clone() { 
    119         SequenceInstance clone = (SequenceInstance) super.clone(); 
     108                        for (final ITaskInstance child : children) { 
     109                                clone.children.add(child.clone()); 
     110                        } 
     111                } 
    120112 
    121         if (children != null) { 
    122             clone.children = new LinkedList<ITaskInstance>(); 
     113                return clone; 
     114        } 
    123115 
    124             for (ITaskInstance child : children) { 
    125                 clone.children.add(child.clone()); 
    126             } 
    127         } 
     116        /* 
     117         * (non-Javadoc) 
     118         *  
     119         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
     120         */ 
     121        @Override 
     122        public ITaskInstance get(int index) { 
     123                if (children == null) { 
     124                        throw new IndexOutOfBoundsException(Integer.toString(index)); 
     125                } else { 
     126                        return children.get(index); 
     127                } 
     128        } 
    128129 
    129         return clone; 
    130     } 
     130        /* 
     131         * (non-Javadoc) 
     132         *  
     133         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getChildren() 
     134         */ 
     135        public synchronized List<ITaskInstance> getChildren() { 
     136                if (children == null) { 
     137                        children = new LinkedList<ITaskInstance>(); 
     138                } 
    131139 
    132     /** 
    133      * <p> 
    134      * used to add a child to this task instance 
    135      * </p> 
    136      *  
    137      * @param child the new child of this instance 
    138      */ 
    139     synchronized void addChild(ITaskInstance child) { 
    140         if (children == null) { 
    141             children = new LinkedList<ITaskInstance>(); 
    142         } 
     140                return Collections.unmodifiableList(children); 
     141        } 
    143142 
    144         children.add(child); 
    145     } 
     143        /* 
     144         * (non-Javadoc) 
     145         *  
     146         * @see 
     147         * de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance#getSequence() 
     148         */ 
     149        @Override 
     150        public ISequence getSequence() { 
     151                return (ISequence) super.getTask(); 
     152        } 
    146153 
    147     /** 
    148      * <p> 
    149      * used to add a child to this task instance at a specific position 
    150      * </p> 
    151      *  
    152      * @param index the position of the new child in the list of children 
    153      * @param child the new child of this instance 
    154      */ 
    155     synchronized void addChild(int index, ITaskInstance child) { 
    156         if (children == null) { 
    157             children = new LinkedList<ITaskInstance>(); 
    158         } 
     154        /* 
     155         * (non-Javadoc) 
     156         *  
     157         * @see java.lang.Iterable#iterator() 
     158         */ 
     159        @Override 
     160        public Iterator<ITaskInstance> iterator() { 
     161                return getChildren().iterator(); 
     162        } 
    159163 
    160         children.add(index, child); 
    161     } 
     164        /** 
     165         * <p> 
     166         * removes a child from this task instance at a specific position 
     167         * </p> 
     168         *  
     169         * @param index 
     170         *            the position of the child to be removed 
     171         *  
     172         * @return the child removed from the children of this instance 
     173         */ 
     174        synchronized ITaskInstance removeChild(int index) { 
     175                if (children != null) { 
     176                        return children.remove(index); 
     177                } else { 
     178                        throw new IllegalArgumentException( 
     179                                        "this task instance does not have children that can be removed"); 
     180                } 
     181        } 
    162182 
    163     /** 
    164      * <p> 
    165      * removes a child from this task instance at a specific position 
    166      * </p> 
    167      *  
    168      * @param index the position of the child to be removed 
    169      *  
    170      * @return the child removed from the children of this instance 
    171      */ 
    172     synchronized ITaskInstance removeChild(int index) { 
    173         if (children != null) { 
    174             return children.remove(index); 
    175         } 
    176         else { 
    177             throw new IllegalArgumentException 
    178                 ("this task instance does not have children that can be removed"); 
    179         } 
    180     } 
     183        /* 
     184         * (non-Javadoc) 
     185         *  
     186         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
     187         */ 
     188        @Override 
     189        public int size() { 
     190                if (children == null) { 
     191                        return 0; 
     192                } else { 
     193                        return children.size(); 
     194                } 
     195        } 
    181196 
    182197} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/StructuringTemporalRelationship.java

    r1357 r1733  
    2323/** 
    2424 * <p> 
    25  * this is the default implementation of the interface {@link IStructuringTemporalRelationship}. It 
    26  * does not do anything fancy except implementing the interface. 
     25 * this is the default implementation of the interface 
     26 * {@link IStructuringTemporalRelationship}. It does not do anything fancy 
     27 * except implementing the interface. 
    2728 * </p> 
    2829 *  
    2930 * @author Patrick Harms 
    3031 */ 
    31 abstract class StructuringTemporalRelationship extends Task 
    32     implements IStructuringTemporalRelationship 
    33 { 
     32abstract class StructuringTemporalRelationship extends Task implements 
     33                IStructuringTemporalRelationship { 
    3434 
    35     /** 
    36      * <p> 
    37      * default serial version UID 
    38      * </p> 
    39      */ 
    40     private static final long serialVersionUID = 1L; 
    41      
    42     /** 
    43      * <p> 
    44      * the list of children of this temporal relationship 
    45      * </p> 
    46      */ 
    47     private List<ITask> children = new LinkedList<ITask>(); 
     35        /** 
     36         * <p> 
     37         * default serial version UID 
     38         * </p> 
     39         */ 
     40        private static final long serialVersionUID = 1L; 
    4841 
    49     /** 
    50      * <p> 
    51      * initializes this temporal relationship with a human readable name 
    52      * </p> 
    53      * 
    54      * @param relationshipType the human readable name of this temporal relationship 
    55      */ 
    56     StructuringTemporalRelationship(String relationshipType) { 
    57         super(relationshipType); 
    58          
    59         if ((relationshipType == null) || ("".equals(relationshipType))) { 
    60             throw new IllegalArgumentException 
    61                 ("the relationship type must be something meaningful"); 
    62         } 
    63     } 
     42        /** 
     43         * <p> 
     44         * the list of children of this temporal relationship 
     45         * </p> 
     46         */ 
     47        private List<ITask> children = new LinkedList<ITask>(); 
    6448 
    65     /* (non-Javadoc) 
    66      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship#getChildren() 
    67      */ 
    68     @Override 
    69     public List<ITask> getChildren() { 
    70         return children; 
    71     } 
     49        /** 
     50         * <p> 
     51         * initializes this temporal relationship with a human readable name 
     52         * </p> 
     53         * 
     54         * @param relationshipType 
     55         *            the human readable name of this temporal relationship 
     56         */ 
     57        StructuringTemporalRelationship(String relationshipType) { 
     58                super(relationshipType); 
    7259 
    73     /* (non-Javadoc) 
    74      * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
    75      */ 
    76     @Override 
    77     public synchronized StructuringTemporalRelationship clone() { 
    78         StructuringTemporalRelationship clone = null; 
    79         clone = (StructuringTemporalRelationship) super.clone(); 
    80              
    81         clone.children = new LinkedList<ITask>(); 
    82          
    83         for (ITask child : this.children) { 
    84             clone.children.add(child.clone()); 
    85         } 
     60                if ((relationshipType == null) || ("".equals(relationshipType))) { 
     61                        throw new IllegalArgumentException( 
     62                                        "the relationship type must be something meaningful"); 
     63                } 
     64        } 
    8665 
    87         return clone; 
    88     } 
     66        /** 
     67         * <p> 
     68         * used to add a new child to this temporal relationship at a specific 
     69         * position. 
     70         * </p> 
     71         * 
     72         * @param index 
     73         *            the index of the new child to be added. 
     74         * @param newChild 
     75         *            the new child to be added 
     76         */ 
     77        void addChild(int index, ITask newChild) { 
     78                children.add(index, newChild); 
     79        } 
    8980 
    90     /** 
    91      * <p> 
    92      * used to add a new child to this temporal relationship. 
    93      * </p> 
    94      * 
    95      * @param newChild the new child to be added 
    96      */ 
    97     void addChild(ITask newChild) { 
    98         children.add(newChild); 
    99     } 
     81        /** 
     82         * <p> 
     83         * used to add a new child to this temporal relationship. 
     84         * </p> 
     85         * 
     86         * @param newChild 
     87         *            the new child to be added 
     88         */ 
     89        void addChild(ITask newChild) { 
     90                children.add(newChild); 
     91        } 
    10092 
    101     /** 
    102      * <p> 
    103      * used to add a new child to this temporal relationship at a specific position. 
    104      * </p> 
    105      * 
    106      * @param index    the index of the new child to be added. 
    107      * @param newChild the new child to be added 
    108      */ 
    109     void addChild(int index, ITask newChild) { 
    110         children.add(index, newChild); 
    111     } 
    112      
    113     /** 
    114      * <p> 
    115      * removes a child from this temporal relationship at a specific position. 
    116      * </p> 
    117      * 
    118      * @param index the index of the child to be removed. 
    119      */ 
    120     void removeChild(int index) { 
    121         children.remove(index); 
    122     } 
     93        /* 
     94         * (non-Javadoc) 
     95         *  
     96         * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone() 
     97         */ 
     98        @Override 
     99        public synchronized StructuringTemporalRelationship clone() { 
     100                StructuringTemporalRelationship clone = null; 
     101                clone = (StructuringTemporalRelationship) super.clone(); 
     102 
     103                clone.children = new LinkedList<ITask>(); 
     104 
     105                for (final ITask child : this.children) { 
     106                        clone.children.add(child.clone()); 
     107                } 
     108 
     109                return clone; 
     110        } 
     111 
     112        /* 
     113         * (non-Javadoc) 
     114         *  
     115         * @see 
     116         * de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship 
     117         * #getChildren() 
     118         */ 
     119        @Override 
     120        public List<ITask> getChildren() { 
     121                return children; 
     122        } 
     123 
     124        /** 
     125         * <p> 
     126         * removes a child from this temporal relationship at a specific position. 
     127         * </p> 
     128         * 
     129         * @param index 
     130         *            the index of the child to be removed. 
     131         */ 
     132        void removeChild(int index) { 
     133                children.remove(index); 
     134        } 
    123135} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java

    r1400 r1733  
    3232/** 
    3333 * <p> 
    34  * this is the default implementation of the interface {@link ITask}. It 
    35  * does not do anything fancy except implementing the interface. 
     34 * this is the default implementation of the interface {@link ITask}. It does 
     35 * not do anything fancy except implementing the interface. 
    3636 * </p> 
    3737 *  
     
    4040abstract class Task implements ITask { 
    4141 
    42     /** 
    43      * <p> 
    44      * default serial version UID 
    45      * </p> 
    46      */ 
    47     private static final long serialVersionUID = 1L; 
    48  
    49     /** 
    50      * <p> 
    51      * used as a counter to generate new ids for each newly created task. May overflow. 
    52      * </p> 
    53      */ 
    54     private static int temporalId = 0; 
    55  
    56     /** 
    57      * <p> 
    58      * the id of the task (unique throughout the system as long as {@link #temporalId} does not 
    59      * overflow. 
    60      * </p> 
    61      */ 
    62     private int id; 
    63      
    64     /** 
    65      * <p> 
    66      * a human readable type of the task (used for visualization purposes) 
    67      * </p> 
    68      */ 
    69     private String type; 
    70  
    71     /** 
    72      * <p> 
    73      * a human readable description of the task 
    74      * </p> 
    75      */ 
    76     private String description; 
    77      
    78     /** 
    79      * <p> 
    80      * the instances of this task 
    81      * </p> 
    82      */ 
    83     private Collection<ITaskInstance> instances = new HashSet<ITaskInstance>(); 
    84      
    85     /** 
    86      * <p> 
    87      * the execution variants of this task 
    88      * </p> 
    89      */ 
    90     private Collection<Collection<ITaskInstance>> executionVariants; 
    91  
    92     /** 
    93      * <p> 
    94      * constructs a new task with a new id. The id is generated using the {@link #getNewId()} 
    95      * method 
    96      * </p> 
    97      *  
    98      * @param type the human readable type of the task 
    99      *  
    100      * @throws IllegalArgumentException in the case the provided type is null 
    101      */ 
    102     Task(String type) { 
    103         this.id = getNewId(); 
    104         this.type = type; 
    105          
    106         if (type == null) { 
    107             throw new IllegalArgumentException("type must not be null"); 
    108         } 
    109     } 
    110  
    111     /** 
    112      * <p> 
    113      * creates a new id for a task using {@link #temporalId} by incrementing it an returning its 
    114      * current value. Resets the counter if {@link Integer.MAX_VALUE} is reached. 
    115      * </p> 
    116      *  
    117      * @return a new unique id for a task as long as {@link #temporalId} does not overflow 
    118      */ 
    119     private static synchronized int getNewId() { 
    120         if (temporalId == Integer.MAX_VALUE) { 
    121             temporalId = 0; 
    122         } 
    123  
    124         return temporalId++; 
    125     } 
    126  
    127     /* (non-Javadoc) 
    128      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#geId() 
    129      */ 
    130     @Override 
    131     public int getId() { 
    132         return id; 
    133     } 
    134  
    135     /* (non-Javadoc) 
    136      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getType() 
    137      */ 
    138     @Override 
    139     public String getType() { 
    140         return type; 
    141     } 
    142  
    143     /* (non-Javadoc) 
    144      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getDescription() 
    145      */ 
    146     @Override 
    147     public String getDescription() { 
    148         return description; 
    149     } 
    150  
    151     /* (non-Javadoc) 
    152      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getInstances() 
    153      */ 
    154     @Override 
    155     public Collection<ITaskInstance> getInstances() { 
    156         return Collections.unmodifiableCollection(instances); 
    157     } 
    158  
    159     /* (non-Javadoc) 
    160      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getExecutionVariants() 
    161      */ 
    162     @Override 
    163     public synchronized Collection<Collection<ITaskInstance>> getExecutionVariants() { 
    164         if (executionVariants == null) { 
    165             executionVariants = new LinkedList<Collection<ITaskInstance>>(); 
    166             determineExecutionVariants(executionVariants); 
    167         } 
    168          
    169         return executionVariants; 
    170     } 
    171  
    172     /* (non-Javadoc) 
    173      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#equals(ITask) 
    174      */ 
    175     @Override 
    176     public final boolean equals(ITask task) { 
    177         // tasks are only equal if they are identical or if they have the same id 
    178         // (may happen, if they are cloned) 
    179         return (this == task) || (this.hashCode() == task.hashCode()); 
    180     } 
    181  
    182     /* (non-Javadoc) 
    183      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#hashCode() 
    184      */ 
    185     @Override 
    186     public synchronized int hashCode() { 
    187         return id; 
    188     } 
    189  
    190     /* (non-Javadoc) 
    191      * @see java.lang.Object#toString() 
    192      */ 
    193     @Override 
    194     public synchronized String toString() { 
    195         StringBuffer result = new StringBuffer(); 
    196         result.append(type); 
    197         result.append(" #"); 
    198         result.append(id); 
    199          
    200         if (description != null) { 
    201             result.append(" ("); 
    202             result.append(description); 
    203             result.append(')'); 
    204         } 
    205          
    206         return result.toString(); 
    207     } 
    208  
    209     /* (non-Javadoc) 
    210      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#clone() 
    211      */ 
    212     @Override 
    213     public synchronized ITask clone() { 
    214         Task clone = null; 
    215         try { 
    216             clone = (Task) super.clone(); 
    217         } 
    218         catch (CloneNotSupportedException e) { 
    219             // this should never happen. Therefore simply dump the exception 
    220             e.printStackTrace(); 
    221         } 
    222  
    223         return clone; 
    224     } 
    225  
    226     /** 
    227      * <p> 
    228      * internally used to set the human readable description of the task 
    229      * </p> 
    230      *  
    231      * @param description the new human readable description of the task 
    232      */ 
    233     void setDescription(String description) { 
    234         this.description = description; 
    235     } 
    236  
    237     /** 
    238      * <p> 
    239      * internally used to remove an instance from this task 
    240      * </p> 
    241      *  
    242      * @param instance the instance to be removed from this task 
    243      */ 
    244     synchronized void removeInstance(ITaskInstance instance) { 
    245         this.instances.remove(instance); 
    246         this.executionVariants = null; 
    247     } 
    248  
    249     /** 
    250      * <p> 
    251      * internally used to add an instance to this task 
    252      * </p> 
    253      *  
    254      * @param instance the instance belonging to this task 
    255      */ 
    256     synchronized void addInstance(ITaskInstance instance) { 
    257         this.instances.add(instance); 
    258         this.executionVariants = null; 
    259     } 
    260      
    261     /* (non-Javadoc) 
    262      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#accept(ITaskVisitor) 
    263      */ 
    264     @Override 
    265     public void accept(ITaskVisitor visitor) { 
    266         visitor.visit(this); 
    267     } 
    268  
    269     /** 
    270      * 
    271      */ 
    272     private void determineExecutionVariants(Collection<Collection<ITaskInstance>> executionVariants) 
    273     { 
    274         for (ITaskInstance instance : instances) { 
    275             boolean added = false; 
    276             for (Collection<ITaskInstance> variant : executionVariants) { 
    277                 if (!variant.isEmpty() && (isSameExecution(variant.iterator().next(), instance))) { 
    278                     variant.add(instance); 
    279                     added = true; 
    280                 } 
    281             } 
    282              
    283             if (!added) { 
    284                 Collection<ITaskInstance> variant = new HashSet<ITaskInstance>(); 
    285                 variant.add(instance); 
    286                 executionVariants.add(variant); 
    287             } 
    288         } 
    289     } 
    290  
    291     /** 
    292      * 
    293      */ 
    294     private boolean isSameExecution(ITaskInstance instance1, ITaskInstance instance2) { 
    295         if (instance1 instanceof IIterationInstance) { 
    296             if (!(instance2 instanceof IIterationInstance)) { 
    297                 return false; 
    298             } 
    299              
    300             ITaskInstanceList iteration1 = (ITaskInstanceList) instance1; 
    301             ITaskInstanceList iteration2 = (ITaskInstanceList) instance2; 
    302              
    303             return isSameExecutionList(iteration1, iteration2); 
    304         } 
    305         else if (instance1 instanceof ISequenceInstance) { 
    306             if (!(instance2 instanceof ISequenceInstance)) { 
    307                 return false; 
    308             } 
    309              
    310             ITaskInstanceList selection1 = (ITaskInstanceList) instance1; 
    311             ITaskInstanceList selection2 = (ITaskInstanceList) instance2; 
    312              
    313             return isSameExecutionList(selection1, selection2); 
    314         } 
    315         else if (instance1 instanceof ISelectionInstance) { 
    316             if (!(instance2 instanceof ISelectionInstance)) { 
    317                 return false; 
    318             } 
    319             else { 
    320                 return isSameExecution(((ISelectionInstance) instance1).getChild(), 
    321                                        ((ISelectionInstance) instance2).getChild()); 
    322             } 
    323         } 
    324         else if (instance1 instanceof IOptionalInstance) { 
    325             if (!(instance2 instanceof IOptionalInstance)) { 
    326                 return false; 
    327             } 
    328             else { 
    329                 return isSameExecution(((IOptionalInstance) instance1).getChild(), 
    330                                        ((IOptionalInstance) instance2).getChild()); 
    331             } 
    332         } 
    333         else if (instance1 instanceof IEventTaskInstance) { 
    334             if (!(instance2 instanceof IEventTaskInstance)) { 
    335                 return false; 
    336             } 
    337             else { 
    338                 return ((IEventTaskInstance) instance1).getTask().equals 
    339                     (((IEventTaskInstance) instance2).getTask()); 
    340             } 
    341         } 
    342         else if (instance1 == null) { 
    343             return instance2 == null; 
    344         } 
    345         else { 
    346             throw new IllegalArgumentException("unknown type of task instance: " + instance1); 
    347         } 
    348     } 
    349  
    350     /** 
    351      * 
    352      */ 
    353     private boolean isSameExecutionList(ITaskInstanceList list1, ITaskInstanceList list2) { 
    354         if (list1.size() == list2.size()) { 
    355             for (int i = 0; i < list1.size(); i++) { 
    356                 if (!isSameExecution(list1.get(i), list2.get(i))) { 
    357                     return false; 
    358                 } 
    359             } 
    360              
    361             return true; 
    362         } 
    363         else { 
    364             return false; 
    365         } 
    366     } 
     42        /** 
     43         * <p> 
     44         * creates a new id for a task using {@link #temporalId} by incrementing it 
     45         * an returning its current value. Resets the counter if 
     46         * {@link Integer.MAX_VALUE} is reached. 
     47         * </p> 
     48         *  
     49         * @return a new unique id for a task as long as {@link #temporalId} does 
     50         *         not overflow 
     51         */ 
     52        private static synchronized int getNewId() { 
     53                if (temporalId == Integer.MAX_VALUE) { 
     54                        temporalId = 0; 
     55                } 
     56 
     57                return temporalId++; 
     58        } 
     59 
     60        /** 
     61         * <p> 
     62         * default serial version UID 
     63         * </p> 
     64         */ 
     65        private static final long serialVersionUID = 1L; 
     66 
     67        /** 
     68         * <p> 
     69         * used as a counter to generate new ids for each newly created task. May 
     70         * overflow. 
     71         * </p> 
     72         */ 
     73        private static int temporalId = 0; 
     74 
     75        /** 
     76         * <p> 
     77         * the id of the task (unique throughout the system as long as 
     78         * {@link #temporalId} does not overflow. 
     79         * </p> 
     80         */ 
     81        private final int id; 
     82 
     83        /** 
     84         * <p> 
     85         * a human readable type of the task (used for visualization purposes) 
     86         * </p> 
     87         */ 
     88        private final String type; 
     89 
     90        /** 
     91         * <p> 
     92         * a human readable description of the task 
     93         * </p> 
     94         */ 
     95        private String description; 
     96 
     97        /** 
     98         * <p> 
     99         * the instances of this task 
     100         * </p> 
     101         */ 
     102        private final Collection<ITaskInstance> instances = new HashSet<ITaskInstance>(); 
     103 
     104        /** 
     105         * <p> 
     106         * the execution variants of this task 
     107         * </p> 
     108         */ 
     109        private Collection<Collection<ITaskInstance>> executionVariants; 
     110 
     111        /** 
     112         * <p> 
     113         * constructs a new task with a new id. The id is generated using the 
     114         * {@link #getNewId()} method 
     115         * </p> 
     116         *  
     117         * @param type 
     118         *            the human readable type of the task 
     119         *  
     120         * @throws IllegalArgumentException 
     121         *             in the case the provided type is null 
     122         */ 
     123        Task(String type) { 
     124                this.id = getNewId(); 
     125                this.type = type; 
     126 
     127                if (type == null) { 
     128                        throw new IllegalArgumentException("type must not be null"); 
     129                } 
     130        } 
     131 
     132        /* 
     133         * (non-Javadoc) 
     134         *  
     135         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#accept(ITaskVisitor) 
     136         */ 
     137        @Override 
     138        public void accept(ITaskVisitor visitor) { 
     139                visitor.visit(this); 
     140        } 
     141 
     142        /** 
     143         * <p> 
     144         * internally used to add an instance to this task 
     145         * </p> 
     146         *  
     147         * @param instance 
     148         *            the instance belonging to this task 
     149         */ 
     150        synchronized void addInstance(ITaskInstance instance) { 
     151                this.instances.add(instance); 
     152                this.executionVariants = null; 
     153        } 
     154 
     155        /* 
     156         * (non-Javadoc) 
     157         *  
     158         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#clone() 
     159         */ 
     160        @Override 
     161        public synchronized ITask clone() { 
     162                Task clone = null; 
     163                try { 
     164                        clone = (Task) super.clone(); 
     165                } catch (final CloneNotSupportedException e) { 
     166                        // this should never happen. Therefore simply dump the exception 
     167                        e.printStackTrace(); 
     168                } 
     169 
     170                return clone; 
     171        } 
     172 
     173        /** 
     174         * 
     175         */ 
     176        private void determineExecutionVariants( 
     177                        Collection<Collection<ITaskInstance>> executionVariants) { 
     178                for (final ITaskInstance instance : instances) { 
     179                        boolean added = false; 
     180                        for (final Collection<ITaskInstance> variant : executionVariants) { 
     181                                if (!variant.isEmpty() 
     182                                                && (isSameExecution(variant.iterator().next(), instance))) { 
     183                                        variant.add(instance); 
     184                                        added = true; 
     185                                } 
     186                        } 
     187 
     188                        if (!added) { 
     189                                final Collection<ITaskInstance> variant = new HashSet<ITaskInstance>(); 
     190                                variant.add(instance); 
     191                                executionVariants.add(variant); 
     192                        } 
     193                } 
     194        } 
     195 
     196        /* 
     197         * (non-Javadoc) 
     198         *  
     199         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#equals(ITask) 
     200         */ 
     201        @Override 
     202        public final boolean equals(ITask task) { 
     203                // tasks are only equal if they are identical or if they have the same 
     204                // id 
     205                // (may happen, if they are cloned) 
     206                return (this == task) || (this.hashCode() == task.hashCode()); 
     207        } 
     208 
     209        /* 
     210         * (non-Javadoc) 
     211         *  
     212         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getDescription() 
     213         */ 
     214        @Override 
     215        public String getDescription() { 
     216                return description; 
     217        } 
     218 
     219        /* 
     220         * (non-Javadoc) 
     221         *  
     222         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getExecutionVariants() 
     223         */ 
     224        @Override 
     225        public synchronized Collection<Collection<ITaskInstance>> getExecutionVariants() { 
     226                if (executionVariants == null) { 
     227                        executionVariants = new LinkedList<Collection<ITaskInstance>>(); 
     228                        determineExecutionVariants(executionVariants); 
     229                } 
     230 
     231                return executionVariants; 
     232        } 
     233 
     234        /* 
     235         * (non-Javadoc) 
     236         *  
     237         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#geId() 
     238         */ 
     239        @Override 
     240        public int getId() { 
     241                return id; 
     242        } 
     243 
     244        /* 
     245         * (non-Javadoc) 
     246         *  
     247         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getInstances() 
     248         */ 
     249        @Override 
     250        public Collection<ITaskInstance> getInstances() { 
     251                return Collections.unmodifiableCollection(instances); 
     252        } 
     253 
     254        /* 
     255         * (non-Javadoc) 
     256         *  
     257         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getType() 
     258         */ 
     259        @Override 
     260        public String getType() { 
     261                return type; 
     262        } 
     263 
     264        /* 
     265         * (non-Javadoc) 
     266         *  
     267         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#hashCode() 
     268         */ 
     269        @Override 
     270        public synchronized int hashCode() { 
     271                return id; 
     272        } 
     273 
     274        /** 
     275         * 
     276         */ 
     277        private boolean isSameExecution(ITaskInstance instance1, 
     278                        ITaskInstance instance2) { 
     279                if (instance1 instanceof IIterationInstance) { 
     280                        if (!(instance2 instanceof IIterationInstance)) { 
     281                                return false; 
     282                        } 
     283 
     284                        final ITaskInstanceList iteration1 = (ITaskInstanceList) instance1; 
     285                        final ITaskInstanceList iteration2 = (ITaskInstanceList) instance2; 
     286 
     287                        return isSameExecutionList(iteration1, iteration2); 
     288                } else if (instance1 instanceof ISequenceInstance) { 
     289                        if (!(instance2 instanceof ISequenceInstance)) { 
     290                                return false; 
     291                        } 
     292 
     293                        final ITaskInstanceList selection1 = (ITaskInstanceList) instance1; 
     294                        final ITaskInstanceList selection2 = (ITaskInstanceList) instance2; 
     295 
     296                        return isSameExecutionList(selection1, selection2); 
     297                } else if (instance1 instanceof ISelectionInstance) { 
     298                        if (!(instance2 instanceof ISelectionInstance)) { 
     299                                return false; 
     300                        } else { 
     301                                return isSameExecution( 
     302                                                ((ISelectionInstance) instance1).getChild(), 
     303                                                ((ISelectionInstance) instance2).getChild()); 
     304                        } 
     305                } else if (instance1 instanceof IOptionalInstance) { 
     306                        if (!(instance2 instanceof IOptionalInstance)) { 
     307                                return false; 
     308                        } else { 
     309                                return isSameExecution( 
     310                                                ((IOptionalInstance) instance1).getChild(), 
     311                                                ((IOptionalInstance) instance2).getChild()); 
     312                        } 
     313                } else if (instance1 instanceof IEventTaskInstance) { 
     314                        if (!(instance2 instanceof IEventTaskInstance)) { 
     315                                return false; 
     316                        } else { 
     317                                return ((IEventTaskInstance) instance1).getTask().equals( 
     318                                                ((IEventTaskInstance) instance2).getTask()); 
     319                        } 
     320                } else if (instance1 == null) { 
     321                        return instance2 == null; 
     322                } else { 
     323                        throw new IllegalArgumentException( 
     324                                        "unknown type of task instance: " + instance1); 
     325                } 
     326        } 
     327 
     328        /** 
     329         * 
     330         */ 
     331        private boolean isSameExecutionList(ITaskInstanceList list1, 
     332                        ITaskInstanceList list2) { 
     333                if (list1.size() == list2.size()) { 
     334                        for (int i = 0; i < list1.size(); i++) { 
     335                                if (!isSameExecution(list1.get(i), list2.get(i))) { 
     336                                        return false; 
     337                                } 
     338                        } 
     339 
     340                        return true; 
     341                } else { 
     342                        return false; 
     343                } 
     344        } 
     345 
     346        /** 
     347         * <p> 
     348         * internally used to remove an instance from this task 
     349         * </p> 
     350         *  
     351         * @param instance 
     352         *            the instance to be removed from this task 
     353         */ 
     354        synchronized void removeInstance(ITaskInstance instance) { 
     355                this.instances.remove(instance); 
     356                this.executionVariants = null; 
     357        } 
     358 
     359        /** 
     360         * <p> 
     361         * internally used to set the human readable description of the task 
     362         * </p> 
     363         *  
     364         * @param description 
     365         *            the new human readable description of the task 
     366         */ 
     367        void setDescription(String description) { 
     368                this.description = description; 
     369        } 
     370 
     371        /* 
     372         * (non-Javadoc) 
     373         *  
     374         * @see java.lang.Object#toString() 
     375         */ 
     376        @Override 
     377        public synchronized String toString() { 
     378                final StringBuffer result = new StringBuffer(); 
     379                result.append(type); 
     380                result.append(" #"); 
     381                result.append(id); 
     382 
     383                if (description != null) { 
     384                        result.append(" ("); 
     385                        result.append(description); 
     386                        result.append(')'); 
     387                } 
     388 
     389                return result.toString(); 
     390        } 
    367391} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskBuilder.java

    r1422 r1733  
    3636 * <p> 
    3737 * this is the default implementation of the interface {@link ITaskBuilder}. It 
    38  * does not do anything fancy except implementing the interface. In some situations, it performs 
    39  * a check if the model or instances to be created a valid. However, this can not be done 
    40  * in any situation of the creation process. 
     38 * does not do anything fancy except implementing the interface. In some 
     39 * situations, it performs a check if the model or instances to be created a 
     40 * valid. However, this can not be done in any situation of the creation 
     41 * process. 
    4142 * </p> 
    4243 *  
     
    4546public class TaskBuilder implements ITaskBuilder { 
    4647 
    47     /* (non-Javadoc) 
    48      * @see ITaskBuilder#addChild(ISequenceInstance, ITaskInstance) 
    49      */ 
    50     @Override 
    51     public void addChild(ISequenceInstance instance, ITaskInstance child) 
    52         throws IllegalArgumentException 
    53     { 
    54         if (!(instance instanceof SequenceInstance)) { 
    55             throw new IllegalArgumentException 
    56                 ("illegal type of sequence instance provided: " + instance.getClass()); 
    57         } 
    58  
    59         if (!(child instanceof TaskInstance)) { 
    60             throw new IllegalArgumentException 
    61                 ("illegal type of task instance provided: " + child.getClass()); 
    62         } 
    63          
    64         SequenceInstance seqInstance = (SequenceInstance) instance; 
    65          
    66         // check if new child instance matches the model, if this can be checked 
    67         IStructuringTemporalRelationship parentTask = 
    68             (IStructuringTemporalRelationship) instance.getTask(); 
    69          
    70         if (((parentTask.getChildren() != null) && (parentTask.getChildren().size() > 0)) && 
    71             ((parentTask.getChildren().size() <= seqInstance.size()) || 
    72              (!parentTask.getChildren().get(seqInstance.size()).equals(child.getTask())))) 
    73         { 
    74             throw new IllegalArgumentException 
    75                 ("the task of the child instance to be added does not belong to the children " + 
    76                  "of the task of the parent instance"); 
    77         } 
    78  
    79         seqInstance.addChild(child); 
    80     } 
    81  
    82     /* (non-Javadoc) 
    83      * @see ITaskBuilder#addChild(ISequenceInstance, int, ITaskInstance) 
    84      */ 
    85     public void addChild(ISequenceInstance instance, int index, ITaskInstance child) 
    86         throws IllegalArgumentException 
    87     { 
    88         if (!(instance instanceof SequenceInstance)) { 
    89             throw new IllegalArgumentException 
    90                 ("illegal type of sequence instance provided: " + instance.getClass()); 
    91         } 
    92  
    93         if (!(child instanceof TaskInstance)) { 
    94             throw new IllegalArgumentException 
    95                 ("illegal type of task instance provided: " + child.getClass()); 
    96         } 
    97          
    98         SequenceInstance seqInstance = (SequenceInstance) instance; 
    99          
    100         // check if new child instance matches the model, if this can be checked 
    101         IStructuringTemporalRelationship parentTask = 
    102             (IStructuringTemporalRelationship) instance.getTask(); 
    103          
    104         if (((parentTask.getChildren() != null) && (parentTask.getChildren().size() > 0)) && 
    105             ((parentTask.getChildren().size() <= index) || 
    106              (!parentTask.getChildren().get(index).equals(child.getTask())))) 
    107         { 
    108             throw new IllegalArgumentException 
    109                 ("the task of the child instance to be added does not belong to the children " + 
    110                  "of the task of the parent instance"); 
    111         } 
    112          
    113         seqInstance.addChild(index, child); 
    114     } 
    115  
    116     /* (non-Javadoc) 
    117      * @see ITaskBuilder#addChild(IIterationInstance, ITaskInstance) 
    118      */ 
    119     @Override 
    120     public void addChild(IIterationInstance instance, ITaskInstance child) 
    121         throws IllegalArgumentException 
    122     { 
    123         if (!(instance instanceof IterationInstance)) { 
    124             throw new IllegalArgumentException 
    125                 ("illegal type of iteration instance provided: " + instance.getClass()); 
    126         } 
    127  
    128         if (!(child instanceof TaskInstance)) { 
    129             throw new IllegalArgumentException 
    130                 ("illegal type of task instance provided: " + child.getClass()); 
    131         } 
    132          
    133         // check if new child instance matches the model, if this can be checked 
    134         IMarkingTemporalRelationship parentTask = 
    135             (IMarkingTemporalRelationship) instance.getTask(); 
    136                  
    137         boolean foundChildTask = parentTask.getMarkedTask() != null ? 
    138             parentTask.getMarkedTask().equals(child.getTask()) : true; 
    139                  
    140         if (!foundChildTask) { 
    141             throw new IllegalArgumentException 
    142                 ("the task of the child instance does not match the model of the task of the " + 
    143                  "iteration instance: " + parentTask.getMarkedTask() + " <> " + child.getTask()); 
    144         } 
    145  
    146         ((IterationInstance) instance).addChild(child); 
    147     } 
    148  
    149     /* (non-Javadoc) 
    150      * @see ITaskBuilder#addChild(IIterationInstance, int, ITaskInstance) 
    151      */ 
    152     public void addChild(IIterationInstance instance, int index, ITaskInstance child) 
    153         throws IllegalArgumentException 
    154     { 
    155         if (!(instance instanceof IterationInstance)) { 
    156             throw new IllegalArgumentException 
    157                 ("illegal type of iteration instance provided: " + instance.getClass()); 
    158         } 
    159  
    160         if (!(child instanceof TaskInstance)) { 
    161             throw new IllegalArgumentException 
    162                 ("illegal type of task instance provided: " + child.getClass()); 
    163         } 
    164          
    165         // check if new child instance matches the model, if this can be checked 
    166         IMarkingTemporalRelationship parentTask = 
    167             (IMarkingTemporalRelationship) instance.getTask(); 
    168                  
    169         boolean foundChildTask = parentTask.getMarkedTask() != null ? 
    170             parentTask.getMarkedTask().equals(child.getTask()) : true; 
    171                  
    172         if (!foundChildTask) { 
    173             throw new IllegalArgumentException 
    174                 ("the task of the child instance does not match the model of the task of the " + 
    175                  "iteration instance: " + parentTask.getMarkedTask() + " <> " + child.getTask()); 
    176         } 
    177  
    178         ((IterationInstance) instance).addChild(index, child); 
    179     } 
    180  
    181     /* (non-Javadoc) 
    182      * @see ITaskBuilder#setChild(ISelectionInstance, ITaskInstance) 
    183      */ 
    184     @Override 
    185     public void setChild(ISelectionInstance instance, ITaskInstance child) 
    186         throws IllegalArgumentException 
    187     { 
    188         if (!(instance instanceof SelectionInstance)) { 
    189             throw new IllegalArgumentException 
    190                 ("illegal type of selection instance provided: " + instance.getClass()); 
    191         } 
    192  
    193         if (!(child instanceof TaskInstance)) { 
    194             throw new IllegalArgumentException("illegal type of task instance provided: " + 
    195                                                (child == null ? null : child.getClass())); 
    196         } 
    197          
    198         // check if new child instance matches the model, if this can be checked 
    199         IStructuringTemporalRelationship parentTask = 
    200             (IStructuringTemporalRelationship) instance.getTask(); 
    201          
    202         boolean foundChildTask = false; 
    203         for (ITask parentTaskChild : parentTask.getChildren()) { 
    204             if (parentTaskChild.equals(child.getTask())) { 
    205                 foundChildTask = true; 
    206                 break; 
    207             } 
    208         } 
    209              
    210         if (!foundChildTask) { 
    211             throw new IllegalArgumentException 
    212                 ("the task of the child instance to be added does not belong to the children " + 
    213                  "of the selection task model of the parent instance"); 
    214         } 
    215  
    216         ((SelectionInstance) instance).setChild(child); 
    217     } 
    218  
    219     /* (non-Javadoc) 
    220      * @see ITaskBuilder#setChild(IOptionalInstance, ITaskInstance) 
    221      */ 
    222     @Override 
    223     public void setChild(IOptionalInstance instance, ITaskInstance child) 
    224         throws IllegalArgumentException 
    225     { 
    226         if (!(instance instanceof OptionalInstance)) { 
    227             throw new IllegalArgumentException 
    228                 ("illegal type of optional instance provided: " + instance.getClass()); 
    229         } 
    230  
    231         if (!(child instanceof TaskInstance)) { 
    232             throw new IllegalArgumentException 
    233                 ("illegal type of task instance provided: " + child.getClass()); 
    234         } 
    235          
    236         // check if new child instance matches the model, if this can be checked 
    237         IMarkingTemporalRelationship parentTask = 
    238             (IMarkingTemporalRelationship) instance.getTask(); 
    239              
    240         boolean foundChildTask = parentTask.getMarkedTask() != null ? 
    241             parentTask.getMarkedTask().equals(child.getTask()) : true; 
    242              
    243         if (!foundChildTask) { 
    244             throw new IllegalArgumentException 
    245                 ("the task of the child instance does not match the model of the task of the " + 
    246                  "optional instance: " + parentTask.getMarkedTask() + " <> " + child.getTask()); 
    247         } 
    248  
    249         ((OptionalInstance) instance).setChild(child); 
    250     } 
    251  
    252     /* (non-Javadoc) 
    253      * @see ITaskBuilder#addExecutedTask(IUserSession, ITaskInstance) 
    254      */ 
    255     @Override 
    256     public void addExecutedTask(IUserSession session, ITaskInstance taskInstance) { 
    257         if (!(session instanceof UserSession)) { 
    258             throw new IllegalArgumentException 
    259                 ("illegal type of session provided: " + session.getClass()); 
    260         } 
    261  
    262         if (!(taskInstance instanceof TaskInstance)) { 
    263             throw new IllegalArgumentException 
    264                 ("illegal type of task instance provided: " + taskInstance.getClass()); 
    265         } 
    266          
    267         ((UserSession) session).addExecutedTask(taskInstance); 
    268     } 
    269  
    270     /* (non-Javadoc) 
    271      * @see ITaskBuilder#addExecutedTask(IUserSession, int, ITaskInstance) 
    272      */ 
    273     public void addExecutedTask(IUserSession session, int index, ITaskInstance taskInstance) { 
    274         if (!(session instanceof UserSession)) { 
    275             throw new IllegalArgumentException 
    276                 ("illegal type of session provided: " + session.getClass()); 
    277         } 
    278  
    279         if (!(taskInstance instanceof TaskInstance)) { 
    280             throw new IllegalArgumentException 
    281                 ("illegal type of task instance provided: " + taskInstance.getClass()); 
    282         } 
    283          
    284         ((UserSession) session).addExecutedTask(index, taskInstance); 
    285     } 
    286  
    287     /* (non-Javadoc) 
    288      * @see ITaskBuilder#addTaskInstance(ITaskInstanceList, ITaskInstance) 
    289      */ 
    290     @Override 
    291     public void addTaskInstance(ITaskInstanceList taskInstanceList, ITaskInstance taskInstance) { 
    292         if (taskInstanceList instanceof SequenceInstance) { 
    293             addChild((SequenceInstance) taskInstanceList, taskInstance); 
    294         } 
    295         else if (taskInstanceList instanceof IterationInstance) { 
    296             addChild((IterationInstance) taskInstanceList, taskInstance); 
    297         } 
    298         else if (taskInstanceList instanceof UserSession) { 
    299             addExecutedTask((UserSession) taskInstanceList, taskInstance); 
    300         } 
    301         else { 
    302             throw new IllegalArgumentException 
    303                 ("illegal type of task instance list provided: " + taskInstanceList.getClass()); 
    304         } 
    305     } 
    306  
    307     /* (non-Javadoc) 
    308      * @see ITaskBuilder#addTaskInstance(ITaskInstanceList, int, ITaskInstance) 
    309      */ 
    310     @Override 
    311     public void addTaskInstance(ITaskInstanceList taskInstanceList, 
    312                                 int               index, 
    313                                 ITaskInstance     taskInstance) 
    314     { 
    315         if (taskInstanceList instanceof SequenceInstance) { 
    316             addChild((SequenceInstance) taskInstanceList, index, taskInstance); 
    317         } 
    318         else if (taskInstanceList instanceof IterationInstance) { 
    319             addChild((IterationInstance) taskInstanceList, index, taskInstance); 
    320         } 
    321         else if (taskInstanceList instanceof UserSession) { 
    322             addExecutedTask((UserSession) taskInstanceList, index, taskInstance); 
    323         } 
    324         else { 
    325             throw new IllegalArgumentException 
    326                 ("illegal type of task instance list provided: " + taskInstanceList.getClass()); 
    327         } 
    328     } 
    329  
    330     /* (non-Javadoc) 
    331      * @see ITaskBuilder#setTaskInstance(ITaskInstanceList, int, ITaskInstance) 
    332      */ 
    333     @Override 
    334     public void setTaskInstance(ITaskInstanceList taskInstanceList, 
    335                                 int               index, 
    336                                 ITaskInstance     taskInstance) 
    337     { 
    338         removeTaskInstance(taskInstanceList, index); 
    339         addTaskInstance(taskInstanceList, index, taskInstance); 
    340     } 
    341  
    342     /* (non-Javadoc) 
    343      * @see ITaskBuilder#setTask(ITaskInstance, ITask) 
    344      */ 
    345     @Override 
    346     public void setTask(ITaskInstance taskInstance, ITask task) { 
    347         if (!(taskInstance instanceof TaskInstance)) { 
    348             throw new IllegalArgumentException 
    349                 ("illegal type of task instance provided: " + taskInstance.getClass()); 
    350         } 
    351         if (!(task instanceof Task)) { 
    352             throw new IllegalArgumentException("illegal type of task provided: " + task.getClass()); 
    353         } 
    354          
    355         if (((TaskInstance) taskInstance).getTask() instanceof Task) { 
    356             ((Task) ((TaskInstance) taskInstance).getTask()).removeInstance(taskInstance); 
    357         } 
    358         ((TaskInstance) taskInstance).setTask(task); 
    359          
    360         ((Task) task).addInstance(taskInstance); 
    361     } 
    362  
    363     /* (non-Javadoc) 
    364      * @see ITaskBuilder#addChild(ISequence, ITask) 
    365      */ 
    366     @Override 
    367     public void addChild(ISequence parent, ITask child) { 
    368         if (!(parent instanceof Sequence)) { 
    369             throw new IllegalArgumentException 
    370                 ("illegal type of sequence provided: " + parent.getClass()); 
    371         } 
    372  
    373         addChildInternal((Sequence) parent, -1, child); 
    374     } 
    375  
    376     /* (non-Javadoc) 
    377      * @see ITaskBuilder#addChild(ISequence, int, ITask) 
    378      */ 
    379     @Override 
    380     public void addChild(ISequence parent, int index, ITask child) { 
    381         if (!(parent instanceof Sequence)) { 
    382             throw new IllegalArgumentException 
    383                 ("illegal type of sequence provided: " + parent.getClass()); 
    384         } 
    385  
    386         addChildInternal((Sequence) parent, index, child); 
    387     } 
    388  
    389     /* (non-Javadoc) 
    390      * @see ITaskBuilder#setChild(ISequence, int, ITask) 
    391      */ 
    392     @Override 
    393     public void setChild(ISequence parent, int index, ITask child) { 
    394         if (!(parent instanceof Sequence)) { 
    395             throw new IllegalArgumentException 
    396                 ("illegal type of sequence provided: " + parent.getClass()); 
    397         } 
    398  
    399         ((Sequence) parent).removeChild(index); 
    400         addChildInternal((Sequence) parent, index, child); 
    401     } 
    402  
    403     /* (non-Javadoc) 
    404      * @see ITaskBuilder#addChild(ISelection, ITask) 
    405      */ 
    406     @Override 
    407     public void addChild(ISelection parent, ITask child) { 
    408         if (!(parent instanceof Selection)) { 
    409             throw new IllegalArgumentException 
    410                 ("illegal type of selection provided: " + parent.getClass()); 
    411         } 
    412  
    413         addChildInternal((Selection) parent, -1, child); 
    414     } 
    415  
    416     /* (non-Javadoc) 
    417      * @see ITaskBuilder#setMarkedTask(IIteration, ITask) 
    418      */ 
    419     @Override 
    420     public void setMarkedTask(IIteration iteration, ITask newChild) { 
    421         if (!(iteration instanceof Iteration)) { 
    422             throw new IllegalArgumentException 
    423                 ("illegal type of iteration provided: " + iteration.getClass()); 
    424         } 
    425  
    426         if (!(newChild instanceof Task)) { 
    427             throw new IllegalArgumentException 
    428                 ("illegal type of task provided: " + newChild.getClass()); 
    429         } 
    430  
    431         ((Iteration) iteration).setMarkedTask(newChild); 
    432     } 
    433  
    434     /* (non-Javadoc) 
    435      * @see ITaskTreeBuilder#setChild(IOptional, ITaskTreeNode) 
    436      */ 
    437     @Override 
    438     public void setMarkedTask(IOptional optional, ITask newChild) { 
    439         if (!(optional instanceof Optional)) { 
    440             throw new IllegalArgumentException 
    441                 ("illegal type of optional provided: " + optional.getClass()); 
    442         } 
    443  
    444         if (!(newChild instanceof Task)) { 
    445             throw new IllegalArgumentException 
    446                 ("illegal type of task provided: " + newChild.getClass()); 
    447         } 
    448  
    449         ((Optional) optional).setMarkedTask(newChild); 
    450     } 
    451  
    452     /* (non-Javadoc) 
    453      * @see ITaskBuilder#removeChild(ISequence, int) 
    454      */ 
    455     @Override 
    456     public void removeChild(ISequence parent, int index) { 
    457         if (!(parent instanceof Sequence)) { 
    458             throw new IllegalArgumentException 
    459                 ("illegal type of sequence provided: " + parent.getClass()); 
    460         } 
    461  
    462         ((Sequence) parent).removeChild(index); 
    463     } 
    464  
    465     /* (non-Javadoc) 
    466      * @see ITaskBuilder#removeChild(ISelection, ITask) 
    467      */ 
    468     @Override 
    469     public void removeChild(ISelection parent, ITask child) { 
    470         if (!(parent instanceof Selection)) { 
    471             throw new IllegalArgumentException 
    472                 ("illegal type of selection provided: " + parent.getClass()); 
    473         } 
    474  
    475         List<ITask> children = parent.getChildren(); 
    476          
    477         for (int i = 0; i < children.size(); i++) { 
    478             if ((children.get(i) == child) || 
    479                 ((children.get(i) != null) && (children.get(i).equals(child)))) 
    480             { 
    481                 ((Selection) parent).removeChild(i); 
    482                 break; 
    483             } 
    484         } 
    485     } 
    486  
    487     /* (non-Javadoc) 
    488      * @see ITaskBuilder#removeTaskInstance(ITaskInstanceList, int) 
    489      */ 
    490     @Override 
    491     public void removeTaskInstance(ITaskInstanceList taskInstanceList, int index) { 
    492         if (taskInstanceList instanceof SequenceInstance) { 
    493             ((SequenceInstance) taskInstanceList).removeChild(index); 
    494         } 
    495         else if (taskInstanceList instanceof IterationInstance) { 
    496             ((IterationInstance) taskInstanceList).removeChild(index); 
    497         } 
    498         else if (taskInstanceList instanceof UserSession) { 
    499             ((UserSession) taskInstanceList).removeExecutedTask(index); 
    500         } 
    501         else { 
    502             throw new IllegalArgumentException 
    503                 ("illegal type of task instance list provided: " + taskInstanceList.getClass()); 
    504         } 
    505     } 
    506  
    507     /* (non-Javadoc) 
    508      * @see ITaskTreeBuilder#replaceChild(ISelection, ITaskTreeNode, ITaskTreeNode) 
    509      */ 
    510     @Override 
    511     public void replaceChild(ISelection parent, ITask oldChild, ITask newChild) { 
    512         if (!(parent instanceof Selection)) { 
    513             throw new IllegalArgumentException 
    514                 ("illegal type of selection provided: " + parent.getClass()); 
    515         } 
    516  
    517         List<ITask> children = parent.getChildren(); 
    518          
    519         for (int i = 0; i < children.size(); i++) { 
    520             if ((children.get(i) == oldChild) || 
    521                 ((children.get(i) != null) && (children.get(i).equals(oldChild)))) 
    522             { 
    523                 ((Selection) parent).removeChild(i); 
    524                 ((Selection) parent).addChild(i, newChild); 
    525                 break; 
    526             } 
    527         } 
    528     } 
    529  
    530     /** 
    531      * <p> 
    532      * internal convenience method for adding children to a structuring temporal relationship 
    533      * including a check for the child type. 
    534      * </p> 
    535      */ 
    536     private void addChildInternal(StructuringTemporalRelationship parent, int index, ITask child) { 
    537         if (!(child instanceof Task)) { 
    538             throw new IllegalArgumentException 
    539                 ("illegal type of task provided: " + child.getClass()); 
    540         } 
    541  
    542         if (index > -1) { 
    543             parent.addChild(index, child); 
    544         } 
    545         else { 
    546             parent.addChild(child); 
    547         } 
    548     } 
     48        /* 
     49         * (non-Javadoc) 
     50         *  
     51         * @see ITaskBuilder#addChild(IIterationInstance, int, ITaskInstance) 
     52         */ 
     53        public void addChild(IIterationInstance instance, int index, 
     54                        ITaskInstance child) throws IllegalArgumentException { 
     55                if (!(instance instanceof IterationInstance)) { 
     56                        throw new IllegalArgumentException( 
     57                                        "illegal type of iteration instance provided: " 
     58                                                        + instance.getClass()); 
     59                } 
     60 
     61                if (!(child instanceof TaskInstance)) { 
     62                        throw new IllegalArgumentException( 
     63                                        "illegal type of task instance provided: " 
     64                                                        + child.getClass()); 
     65                } 
     66 
     67                // check if new child instance matches the model, if this can be checked 
     68                final IMarkingTemporalRelationship parentTask = (IMarkingTemporalRelationship) instance 
     69                                .getTask(); 
     70 
     71                final boolean foundChildTask = parentTask.getMarkedTask() != null ? parentTask 
     72                                .getMarkedTask().equals(child.getTask()) : true; 
     73 
     74                if (!foundChildTask) { 
     75                        throw new IllegalArgumentException( 
     76                                        "the task of the child instance does not match the model of the task of the " 
     77                                                        + "iteration instance: " 
     78                                                        + parentTask.getMarkedTask() + " <> " 
     79                                                        + child.getTask()); 
     80                } 
     81 
     82                ((IterationInstance) instance).addChild(index, child); 
     83        } 
     84 
     85        /* 
     86         * (non-Javadoc) 
     87         *  
     88         * @see ITaskBuilder#addChild(IIterationInstance, ITaskInstance) 
     89         */ 
     90        @Override 
     91        public void addChild(IIterationInstance instance, ITaskInstance child) 
     92                        throws IllegalArgumentException { 
     93                if (!(instance instanceof IterationInstance)) { 
     94                        throw new IllegalArgumentException( 
     95                                        "illegal type of iteration instance provided: " 
     96                                                        + instance.getClass()); 
     97                } 
     98 
     99                if (!(child instanceof TaskInstance)) { 
     100                        throw new IllegalArgumentException( 
     101                                        "illegal type of task instance provided: " 
     102                                                        + child.getClass()); 
     103                } 
     104 
     105                // check if new child instance matches the model, if this can be checked 
     106                final IMarkingTemporalRelationship parentTask = (IMarkingTemporalRelationship) instance 
     107                                .getTask(); 
     108 
     109                final boolean foundChildTask = parentTask.getMarkedTask() != null ? parentTask 
     110                                .getMarkedTask().equals(child.getTask()) : true; 
     111 
     112                if (!foundChildTask) { 
     113                        throw new IllegalArgumentException( 
     114                                        "the task of the child instance does not match the model of the task of the " 
     115                                                        + "iteration instance: " 
     116                                                        + parentTask.getMarkedTask() + " <> " 
     117                                                        + child.getTask()); 
     118                } 
     119 
     120                ((IterationInstance) instance).addChild(child); 
     121        } 
     122 
     123        /* 
     124         * (non-Javadoc) 
     125         *  
     126         * @see ITaskBuilder#addChild(ISelection, ITask) 
     127         */ 
     128        @Override 
     129        public void addChild(ISelection parent, ITask child) { 
     130                if (!(parent instanceof Selection)) { 
     131                        throw new IllegalArgumentException( 
     132                                        "illegal type of selection provided: " + parent.getClass()); 
     133                } 
     134 
     135                addChildInternal((Selection) parent, -1, child); 
     136        } 
     137 
     138        /* 
     139         * (non-Javadoc) 
     140         *  
     141         * @see ITaskBuilder#addChild(ISequence, int, ITask) 
     142         */ 
     143        @Override 
     144        public void addChild(ISequence parent, int index, ITask child) { 
     145                if (!(parent instanceof Sequence)) { 
     146                        throw new IllegalArgumentException( 
     147                                        "illegal type of sequence provided: " + parent.getClass()); 
     148                } 
     149 
     150                addChildInternal((Sequence) parent, index, child); 
     151        } 
     152 
     153        /* 
     154         * (non-Javadoc) 
     155         *  
     156         * @see ITaskBuilder#addChild(ISequence, ITask) 
     157         */ 
     158        @Override 
     159        public void addChild(ISequence parent, ITask child) { 
     160                if (!(parent instanceof Sequence)) { 
     161                        throw new IllegalArgumentException( 
     162                                        "illegal type of sequence provided: " + parent.getClass()); 
     163                } 
     164 
     165                addChildInternal((Sequence) parent, -1, child); 
     166        } 
     167 
     168        /* 
     169         * (non-Javadoc) 
     170         *  
     171         * @see ITaskBuilder#addChild(ISequenceInstance, int, ITaskInstance) 
     172         */ 
     173        public void addChild(ISequenceInstance instance, int index, 
     174                        ITaskInstance child) throws IllegalArgumentException { 
     175                if (!(instance instanceof SequenceInstance)) { 
     176                        throw new IllegalArgumentException( 
     177                                        "illegal type of sequence instance provided: " 
     178                                                        + instance.getClass()); 
     179                } 
     180 
     181                if (!(child instanceof TaskInstance)) { 
     182                        throw new IllegalArgumentException( 
     183                                        "illegal type of task instance provided: " 
     184                                                        + child.getClass()); 
     185                } 
     186 
     187                final SequenceInstance seqInstance = (SequenceInstance) instance; 
     188 
     189                // check if new child instance matches the model, if this can be checked 
     190                final IStructuringTemporalRelationship parentTask = (IStructuringTemporalRelationship) instance 
     191                                .getTask(); 
     192 
     193                if (((parentTask.getChildren() != null) && (parentTask.getChildren() 
     194                                .size() > 0)) 
     195                                && ((parentTask.getChildren().size() <= index) || (!parentTask 
     196                                                .getChildren().get(index).equals(child.getTask())))) { 
     197                        throw new IllegalArgumentException( 
     198                                        "the task of the child instance to be added does not belong to the children " 
     199                                                        + "of the task of the parent instance"); 
     200                } 
     201 
     202                seqInstance.addChild(index, child); 
     203        } 
     204 
     205        /* 
     206         * (non-Javadoc) 
     207         *  
     208         * @see ITaskBuilder#addChild(ISequenceInstance, ITaskInstance) 
     209         */ 
     210        @Override 
     211        public void addChild(ISequenceInstance instance, ITaskInstance child) 
     212                        throws IllegalArgumentException { 
     213                if (!(instance instanceof SequenceInstance)) { 
     214                        throw new IllegalArgumentException( 
     215                                        "illegal type of sequence instance provided: " 
     216                                                        + instance.getClass()); 
     217                } 
     218 
     219                if (!(child instanceof TaskInstance)) { 
     220                        throw new IllegalArgumentException( 
     221                                        "illegal type of task instance provided: " 
     222                                                        + child.getClass()); 
     223                } 
     224 
     225                final SequenceInstance seqInstance = (SequenceInstance) instance; 
     226 
     227                // check if new child instance matches the model, if this can be checked 
     228                final IStructuringTemporalRelationship parentTask = (IStructuringTemporalRelationship) instance 
     229                                .getTask(); 
     230 
     231                if (((parentTask.getChildren() != null) && (parentTask.getChildren() 
     232                                .size() > 0)) 
     233                                && ((parentTask.getChildren().size() <= seqInstance.size()) || (!parentTask 
     234                                                .getChildren().get(seqInstance.size()) 
     235                                                .equals(child.getTask())))) { 
     236                        throw new IllegalArgumentException( 
     237                                        "the task of the child instance to be added does not belong to the children " 
     238                                                        + "of the task of the parent instance"); 
     239                } 
     240 
     241                seqInstance.addChild(child); 
     242        } 
     243 
     244        /** 
     245         * <p> 
     246         * internal convenience method for adding children to a structuring temporal 
     247         * relationship including a check for the child type. 
     248         * </p> 
     249         */ 
     250        private void addChildInternal(StructuringTemporalRelationship parent, 
     251                        int index, ITask child) { 
     252                if (!(child instanceof Task)) { 
     253                        throw new IllegalArgumentException( 
     254                                        "illegal type of task provided: " + child.getClass()); 
     255                } 
     256 
     257                if (index > -1) { 
     258                        parent.addChild(index, child); 
     259                } else { 
     260                        parent.addChild(child); 
     261                } 
     262        } 
     263 
     264        /* 
     265         * (non-Javadoc) 
     266         *  
     267         * @see ITaskBuilder#addExecutedTask(IUserSession, int, ITaskInstance) 
     268         */ 
     269        public void addExecutedTask(IUserSession session, int index, 
     270                        ITaskInstance taskInstance) { 
     271                if (!(session instanceof UserSession)) { 
     272                        throw new IllegalArgumentException( 
     273                                        "illegal type of session provided: " + session.getClass()); 
     274                } 
     275 
     276                if (!(taskInstance instanceof TaskInstance)) { 
     277                        throw new IllegalArgumentException( 
     278                                        "illegal type of task instance provided: " 
     279                                                        + taskInstance.getClass()); 
     280                } 
     281 
     282                ((UserSession) session).addExecutedTask(index, taskInstance); 
     283        } 
     284 
     285        /* 
     286         * (non-Javadoc) 
     287         *  
     288         * @see ITaskBuilder#addExecutedTask(IUserSession, ITaskInstance) 
     289         */ 
     290        @Override 
     291        public void addExecutedTask(IUserSession session, ITaskInstance taskInstance) { 
     292                if (!(session instanceof UserSession)) { 
     293                        throw new IllegalArgumentException( 
     294                                        "illegal type of session provided: " + session.getClass()); 
     295                } 
     296 
     297                if (!(taskInstance instanceof TaskInstance)) { 
     298                        throw new IllegalArgumentException( 
     299                                        "illegal type of task instance provided: " 
     300                                                        + taskInstance.getClass()); 
     301                } 
     302 
     303                ((UserSession) session).addExecutedTask(taskInstance); 
     304        } 
     305 
     306        /* 
     307         * (non-Javadoc) 
     308         *  
     309         * @see ITaskBuilder#addTaskInstance(ITaskInstanceList, int, ITaskInstance) 
     310         */ 
     311        @Override 
     312        public void addTaskInstance(ITaskInstanceList taskInstanceList, int index, 
     313                        ITaskInstance taskInstance) { 
     314                if (taskInstanceList instanceof SequenceInstance) { 
     315                        addChild((SequenceInstance) taskInstanceList, index, taskInstance); 
     316                } else if (taskInstanceList instanceof IterationInstance) { 
     317                        addChild((IterationInstance) taskInstanceList, index, taskInstance); 
     318                } else if (taskInstanceList instanceof UserSession) { 
     319                        addExecutedTask((UserSession) taskInstanceList, index, taskInstance); 
     320                } else { 
     321                        throw new IllegalArgumentException( 
     322                                        "illegal type of task instance list provided: " 
     323                                                        + taskInstanceList.getClass()); 
     324                } 
     325        } 
     326 
     327        /* 
     328         * (non-Javadoc) 
     329         *  
     330         * @see ITaskBuilder#addTaskInstance(ITaskInstanceList, ITaskInstance) 
     331         */ 
     332        @Override 
     333        public void addTaskInstance(ITaskInstanceList taskInstanceList, 
     334                        ITaskInstance taskInstance) { 
     335                if (taskInstanceList instanceof SequenceInstance) { 
     336                        addChild((SequenceInstance) taskInstanceList, taskInstance); 
     337                } else if (taskInstanceList instanceof IterationInstance) { 
     338                        addChild((IterationInstance) taskInstanceList, taskInstance); 
     339                } else if (taskInstanceList instanceof UserSession) { 
     340                        addExecutedTask((UserSession) taskInstanceList, taskInstance); 
     341                } else { 
     342                        throw new IllegalArgumentException( 
     343                                        "illegal type of task instance list provided: " 
     344                                                        + taskInstanceList.getClass()); 
     345                } 
     346        } 
     347 
     348        /* 
     349         * (non-Javadoc) 
     350         *  
     351         * @see ITaskBuilder#removeChild(ISelection, ITask) 
     352         */ 
     353        @Override 
     354        public void removeChild(ISelection parent, ITask child) { 
     355                if (!(parent instanceof Selection)) { 
     356                        throw new IllegalArgumentException( 
     357                                        "illegal type of selection provided: " + parent.getClass()); 
     358                } 
     359 
     360                final List<ITask> children = parent.getChildren(); 
     361 
     362                for (int i = 0; i < children.size(); i++) { 
     363                        if ((children.get(i) == child) 
     364                                        || ((children.get(i) != null) && (children.get(i) 
     365                                                        .equals(child)))) { 
     366                                ((Selection) parent).removeChild(i); 
     367                                break; 
     368                        } 
     369                } 
     370        } 
     371 
     372        /* 
     373         * (non-Javadoc) 
     374         *  
     375         * @see ITaskBuilder#removeChild(ISequence, int) 
     376         */ 
     377        @Override 
     378        public void removeChild(ISequence parent, int index) { 
     379                if (!(parent instanceof Sequence)) { 
     380                        throw new IllegalArgumentException( 
     381                                        "illegal type of sequence provided: " + parent.getClass()); 
     382                } 
     383 
     384                ((Sequence) parent).removeChild(index); 
     385        } 
     386 
     387        /* 
     388         * (non-Javadoc) 
     389         *  
     390         * @see ITaskBuilder#removeTaskInstance(ITaskInstanceList, int) 
     391         */ 
     392        @Override 
     393        public void removeTaskInstance(ITaskInstanceList taskInstanceList, int index) { 
     394                if (taskInstanceList instanceof SequenceInstance) { 
     395                        ((SequenceInstance) taskInstanceList).removeChild(index); 
     396                } else if (taskInstanceList instanceof IterationInstance) { 
     397                        ((IterationInstance) taskInstanceList).removeChild(index); 
     398                } else if (taskInstanceList instanceof UserSession) { 
     399                        ((UserSession) taskInstanceList).removeExecutedTask(index); 
     400                } else { 
     401                        throw new IllegalArgumentException( 
     402                                        "illegal type of task instance list provided: " 
     403                                                        + taskInstanceList.getClass()); 
     404                } 
     405        } 
     406 
     407        /* 
     408         * (non-Javadoc) 
     409         *  
     410         * @see ITaskTreeBuilder#replaceChild(ISelection, ITaskTreeNode, 
     411         * ITaskTreeNode) 
     412         */ 
     413        @Override 
     414        public void replaceChild(ISelection parent, ITask oldChild, ITask newChild) { 
     415                if (!(parent instanceof Selection)) { 
     416                        throw new IllegalArgumentException( 
     417                                        "illegal type of selection provided: " + parent.getClass()); 
     418                } 
     419 
     420                final List<ITask> children = parent.getChildren(); 
     421 
     422                for (int i = 0; i < children.size(); i++) { 
     423                        if ((children.get(i) == oldChild) 
     424                                        || ((children.get(i) != null) && (children.get(i) 
     425                                                        .equals(oldChild)))) { 
     426                                ((Selection) parent).removeChild(i); 
     427                                ((Selection) parent).addChild(i, newChild); 
     428                                break; 
     429                        } 
     430                } 
     431        } 
     432 
     433        /* 
     434         * (non-Javadoc) 
     435         *  
     436         * @see ITaskBuilder#setChild(IOptionalInstance, ITaskInstance) 
     437         */ 
     438        @Override 
     439        public void setChild(IOptionalInstance instance, ITaskInstance child) 
     440                        throws IllegalArgumentException { 
     441                if (!(instance instanceof OptionalInstance)) { 
     442                        throw new IllegalArgumentException( 
     443                                        "illegal type of optional instance provided: " 
     444                                                        + instance.getClass()); 
     445                } 
     446 
     447                if (!(child instanceof TaskInstance)) { 
     448                        throw new IllegalArgumentException( 
     449                                        "illegal type of task instance provided: " 
     450                                                        + child.getClass()); 
     451                } 
     452 
     453                // check if new child instance matches the model, if this can be checked 
     454                final IMarkingTemporalRelationship parentTask = (IMarkingTemporalRelationship) instance 
     455                                .getTask(); 
     456 
     457                final boolean foundChildTask = parentTask.getMarkedTask() != null ? parentTask 
     458                                .getMarkedTask().equals(child.getTask()) : true; 
     459 
     460                if (!foundChildTask) { 
     461                        throw new IllegalArgumentException( 
     462                                        "the task of the child instance does not match the model of the task of the " 
     463                                                        + "optional instance: " 
     464                                                        + parentTask.getMarkedTask() + " <> " 
     465                                                        + child.getTask()); 
     466                } 
     467 
     468                ((OptionalInstance) instance).setChild(child); 
     469        } 
     470 
     471        /* 
     472         * (non-Javadoc) 
     473         *  
     474         * @see ITaskBuilder#setChild(ISelectionInstance, ITaskInstance) 
     475         */ 
     476        @Override 
     477        public void setChild(ISelectionInstance instance, ITaskInstance child) 
     478                        throws IllegalArgumentException { 
     479                if (!(instance instanceof SelectionInstance)) { 
     480                        throw new IllegalArgumentException( 
     481                                        "illegal type of selection instance provided: " 
     482                                                        + instance.getClass()); 
     483                } 
     484 
     485                if (!(child instanceof TaskInstance)) { 
     486                        throw new IllegalArgumentException( 
     487                                        "illegal type of task instance provided: " 
     488                                                        + (child == null ? null : child.getClass())); 
     489                } 
     490 
     491                // check if new child instance matches the model, if this can be checked 
     492                final IStructuringTemporalRelationship parentTask = (IStructuringTemporalRelationship) instance 
     493                                .getTask(); 
     494 
     495                boolean foundChildTask = false; 
     496                for (final ITask parentTaskChild : parentTask.getChildren()) { 
     497                        if (parentTaskChild.equals(child.getTask())) { 
     498                                foundChildTask = true; 
     499                                break; 
     500                        } 
     501                } 
     502 
     503                if (!foundChildTask) { 
     504                        throw new IllegalArgumentException( 
     505                                        "the task of the child instance to be added does not belong to the children " 
     506                                                        + "of the selection task model of the parent instance"); 
     507                } 
     508 
     509                ((SelectionInstance) instance).setChild(child); 
     510        } 
     511 
     512        /* 
     513         * (non-Javadoc) 
     514         *  
     515         * @see ITaskBuilder#setChild(ISequence, int, ITask) 
     516         */ 
     517        @Override 
     518        public void setChild(ISequence parent, int index, ITask child) { 
     519                if (!(parent instanceof Sequence)) { 
     520                        throw new IllegalArgumentException( 
     521                                        "illegal type of sequence provided: " + parent.getClass()); 
     522                } 
     523 
     524                ((Sequence) parent).removeChild(index); 
     525                addChildInternal((Sequence) parent, index, child); 
     526        } 
     527 
     528        /* 
     529         * (non-Javadoc) 
     530         *  
     531         * @see ITaskBuilder#setMarkedTask(IIteration, ITask) 
     532         */ 
     533        @Override 
     534        public void setMarkedTask(IIteration iteration, ITask newChild) { 
     535                if (!(iteration instanceof Iteration)) { 
     536                        throw new IllegalArgumentException( 
     537                                        "illegal type of iteration provided: " 
     538                                                        + iteration.getClass()); 
     539                } 
     540 
     541                if (!(newChild instanceof Task)) { 
     542                        throw new IllegalArgumentException( 
     543                                        "illegal type of task provided: " + newChild.getClass()); 
     544                } 
     545 
     546                ((Iteration) iteration).setMarkedTask(newChild); 
     547        } 
     548 
     549        /* 
     550         * (non-Javadoc) 
     551         *  
     552         * @see ITaskTreeBuilder#setChild(IOptional, ITaskTreeNode) 
     553         */ 
     554        @Override 
     555        public void setMarkedTask(IOptional optional, ITask newChild) { 
     556                if (!(optional instanceof Optional)) { 
     557                        throw new IllegalArgumentException( 
     558                                        "illegal type of optional provided: " + optional.getClass()); 
     559                } 
     560 
     561                if (!(newChild instanceof Task)) { 
     562                        throw new IllegalArgumentException( 
     563                                        "illegal type of task provided: " + newChild.getClass()); 
     564                } 
     565 
     566                ((Optional) optional).setMarkedTask(newChild); 
     567        } 
     568 
     569        /* 
     570         * (non-Javadoc) 
     571         *  
     572         * @see ITaskBuilder#setTask(ITaskInstance, ITask) 
     573         */ 
     574        @Override 
     575        public void setTask(ITaskInstance taskInstance, ITask task) { 
     576                if (!(taskInstance instanceof TaskInstance)) { 
     577                        throw new IllegalArgumentException( 
     578                                        "illegal type of task instance provided: " 
     579                                                        + taskInstance.getClass()); 
     580                } 
     581                if (!(task instanceof Task)) { 
     582                        throw new IllegalArgumentException( 
     583                                        "illegal type of task provided: " + task.getClass()); 
     584                } 
     585 
     586                if (((TaskInstance) taskInstance).getTask() instanceof Task) { 
     587                        ((Task) ((TaskInstance) taskInstance).getTask()) 
     588                                        .removeInstance(taskInstance); 
     589                } 
     590                ((TaskInstance) taskInstance).setTask(task); 
     591 
     592                ((Task) task).addInstance(taskInstance); 
     593        } 
     594 
     595        /* 
     596         * (non-Javadoc) 
     597         *  
     598         * @see ITaskBuilder#setTaskInstance(ITaskInstanceList, int, ITaskInstance) 
     599         */ 
     600        @Override 
     601        public void setTaskInstance(ITaskInstanceList taskInstanceList, int index, 
     602                        ITaskInstance taskInstance) { 
     603                removeTaskInstance(taskInstanceList, index); 
     604                addTaskInstance(taskInstanceList, index, taskInstance); 
     605        } 
    549606 
    550607} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskFactory.java

    r1294 r1733  
    3535 * <p> 
    3636 * this is the default implementation of the interface {@link ITaskFactory}. It 
    37  * does not do anything fancy except implementing the interface. It instantiates the other 
    38  * implementations of the tree ifc in this package. 
     37 * does not do anything fancy except implementing the interface. It instantiates 
     38 * the other implementations of the tree ifc in this package. 
    3939 * </p> 
    4040 *  
     
    4343public class TaskFactory implements ITaskFactory { 
    4444 
    45     /* (non-Javadoc) 
    46      * @see ITaskFactory#createNewEventTask(String) 
    47      */ 
    48     @Override 
    49     public IEventTask createNewEventTask(String description) { 
    50         return new EventTask(description); 
    51     } 
    52  
    53     /* (non-Javadoc) 
    54      * @see ITaskFactory#createNewSequence() 
    55      */ 
    56     @Override 
    57     public ISequence createNewSequence() { 
    58         return new Sequence(); 
    59     } 
    60  
    61     /* (non-Javadoc) 
    62      * @see ITaskFactory#createNewIteration() 
    63      */ 
    64     @Override 
    65     public IIteration createNewIteration() { 
    66         return new Iteration(); 
    67     } 
    68  
    69     /* (non-Javadoc) 
    70      * @see ITaskFactory#createNewOptional() 
    71      */ 
    72     @Override 
    73     public IOptional createNewOptional() { 
    74         return new Optional(); 
    75     } 
    76  
    77     /* (non-Javadoc) 
    78      * @see ITaskFactory#createNewSelection() 
    79      */ 
    80     @Override 
    81     public ISelection createNewSelection() { 
    82         return new Selection(); 
    83     } 
    84  
    85     /* (non-Javadoc) 
    86      * @see ITaskFactory#createNewTaskInstance(IEventTask, Event) 
    87      */ 
    88     @Override 
    89     public IEventTaskInstance createNewTaskInstance(IEventTask task, Event event) { 
    90         if (!(task instanceof EventTask)) { 
    91             throw new IllegalArgumentException 
    92                 ("illegal type of event task provided: " + task.getClass()); 
    93         } 
    94          
    95         EventTaskInstance instance = new EventTaskInstance(task, event); 
    96         ((EventTask) task).addInstance(instance); 
    97          
    98         return instance; 
    99     } 
    100  
    101     /* (non-Javadoc) 
    102      * @see ITaskFactory#createNewTaskInstance(ISequence) 
    103      */ 
    104     @Override 
    105     public ISequenceInstance createNewTaskInstance(ISequence sequence) { 
    106         if (!(sequence instanceof Sequence)) { 
    107             throw new IllegalArgumentException 
    108                 ("illegal type of sequence provided: " + sequence.getClass()); 
    109         } 
    110          
    111         SequenceInstance instance = new SequenceInstance(sequence); 
    112         ((Sequence) sequence).addInstance(instance); 
    113          
    114         return instance; 
    115     } 
    116  
    117     /* (non-Javadoc) 
    118      * @see ITaskFactory#createNewTaskInstance(IIteration) 
    119      */ 
    120     @Override 
    121     public IIterationInstance createNewTaskInstance(IIteration iteration) { 
    122         if (!(iteration instanceof Iteration)) { 
    123             throw new IllegalArgumentException 
    124                 ("illegal type of iteration provided: " + iteration.getClass()); 
    125         } 
    126          
    127         IterationInstance instance = new IterationInstance(iteration); 
    128         ((Iteration) iteration).addInstance(instance); 
    129          
    130         return instance; 
    131     } 
    132  
    133     /* (non-Javadoc) 
    134      * @see ITaskFactory#createNewTaskInstance(IOptional) 
    135      */ 
    136     @Override 
    137     public IOptionalInstance createNewTaskInstance(IOptional optional) { 
    138         if (!(optional instanceof Optional)) { 
    139             throw new IllegalArgumentException 
    140                 ("illegal type of optional provided: " + optional.getClass()); 
    141         } 
    142          
    143         OptionalInstance instance = new OptionalInstance(optional); 
    144         ((Optional) optional).addInstance(instance); 
    145          
    146         return instance; 
    147     } 
    148  
    149     /* (non-Javadoc) 
    150      * @see ITaskFactory#createNewTaskInstance(ISelection) 
    151      */ 
    152     @Override 
    153     public ISelectionInstance createNewTaskInstance(ISelection selection) { 
    154         if (!(selection instanceof Selection)) { 
    155             throw new IllegalArgumentException 
    156                 ("illegal type of optional provided: " + selection.getClass()); 
    157         } 
    158          
    159         SelectionInstance instance = new SelectionInstance(selection); 
    160         ((Selection) selection).addInstance(instance); 
    161          
    162         return instance; 
    163     } 
    164  
    165     /* (non-Javadoc) 
    166      * @see ITaskFactory#createUserSession() 
    167      */ 
    168     @Override 
    169     public IUserSession createUserSession() { 
    170         return new UserSession(); 
    171     } 
    172  
    173     /* (non-Javadoc) 
    174      * @see ITaskFactory#createTaskModel(List<IUserSession>) 
    175      */ 
    176     @Override 
    177     public ITaskModel createTaskModel(List<IUserSession> userSessions) { 
    178         return new TaskModel(userSessions); 
    179     } 
     45        /* 
     46         * (non-Javadoc) 
     47         *  
     48         * @see ITaskFactory#createNewEventTask(String) 
     49         */ 
     50        @Override 
     51        public IEventTask createNewEventTask(String description) { 
     52                return new EventTask(description); 
     53        } 
     54 
     55        /* 
     56         * (non-Javadoc) 
     57         *  
     58         * @see ITaskFactory#createNewIteration() 
     59         */ 
     60        @Override 
     61        public IIteration createNewIteration() { 
     62                return new Iteration(); 
     63        } 
     64 
     65        /* 
     66         * (non-Javadoc) 
     67         *  
     68         * @see ITaskFactory#createNewOptional() 
     69         */ 
     70        @Override 
     71        public IOptional createNewOptional() { 
     72                return new Optional(); 
     73        } 
     74 
     75        /* 
     76         * (non-Javadoc) 
     77         *  
     78         * @see ITaskFactory#createNewSelection() 
     79         */ 
     80        @Override 
     81        public ISelection createNewSelection() { 
     82                return new Selection(); 
     83        } 
     84 
     85        /* 
     86         * (non-Javadoc) 
     87         *  
     88         * @see ITaskFactory#createNewSequence() 
     89         */ 
     90        @Override 
     91        public ISequence createNewSequence() { 
     92                return new Sequence(); 
     93        } 
     94 
     95        /* 
     96         * (non-Javadoc) 
     97         *  
     98         * @see ITaskFactory#createNewTaskInstance(IEventTask, Event) 
     99         */ 
     100        @Override 
     101        public IEventTaskInstance createNewTaskInstance(IEventTask task, Event event) { 
     102                if (!(task instanceof EventTask)) { 
     103                        throw new IllegalArgumentException( 
     104                                        "illegal type of event task provided: " + task.getClass()); 
     105                } 
     106 
     107                final EventTaskInstance instance = new EventTaskInstance(task, event); 
     108                ((EventTask) task).addInstance(instance); 
     109 
     110                return instance; 
     111        } 
     112 
     113        /* 
     114         * (non-Javadoc) 
     115         *  
     116         * @see ITaskFactory#createNewTaskInstance(IIteration) 
     117         */ 
     118        @Override 
     119        public IIterationInstance createNewTaskInstance(IIteration iteration) { 
     120                if (!(iteration instanceof Iteration)) { 
     121                        throw new IllegalArgumentException( 
     122                                        "illegal type of iteration provided: " 
     123                                                        + iteration.getClass()); 
     124                } 
     125 
     126                final IterationInstance instance = new IterationInstance(iteration); 
     127                ((Iteration) iteration).addInstance(instance); 
     128 
     129                return instance; 
     130        } 
     131 
     132        /* 
     133         * (non-Javadoc) 
     134         *  
     135         * @see ITaskFactory#createNewTaskInstance(IOptional) 
     136         */ 
     137        @Override 
     138        public IOptionalInstance createNewTaskInstance(IOptional optional) { 
     139                if (!(optional instanceof Optional)) { 
     140                        throw new IllegalArgumentException( 
     141                                        "illegal type of optional provided: " + optional.getClass()); 
     142                } 
     143 
     144                final OptionalInstance instance = new OptionalInstance(optional); 
     145                ((Optional) optional).addInstance(instance); 
     146 
     147                return instance; 
     148        } 
     149 
     150        /* 
     151         * (non-Javadoc) 
     152         *  
     153         * @see ITaskFactory#createNewTaskInstance(ISelection) 
     154         */ 
     155        @Override 
     156        public ISelectionInstance createNewTaskInstance(ISelection selection) { 
     157                if (!(selection instanceof Selection)) { 
     158                        throw new IllegalArgumentException( 
     159                                        "illegal type of optional provided: " 
     160                                                        + selection.getClass()); 
     161                } 
     162 
     163                final SelectionInstance instance = new SelectionInstance(selection); 
     164                ((Selection) selection).addInstance(instance); 
     165 
     166                return instance; 
     167        } 
     168 
     169        /* 
     170         * (non-Javadoc) 
     171         *  
     172         * @see ITaskFactory#createNewTaskInstance(ISequence) 
     173         */ 
     174        @Override 
     175        public ISequenceInstance createNewTaskInstance(ISequence sequence) { 
     176                if (!(sequence instanceof Sequence)) { 
     177                        throw new IllegalArgumentException( 
     178                                        "illegal type of sequence provided: " + sequence.getClass()); 
     179                } 
     180 
     181                final SequenceInstance instance = new SequenceInstance(sequence); 
     182                ((Sequence) sequence).addInstance(instance); 
     183 
     184                return instance; 
     185        } 
     186 
     187        /* 
     188         * (non-Javadoc) 
     189         *  
     190         * @see ITaskFactory#createTaskModel(List<IUserSession>) 
     191         */ 
     192        @Override 
     193        public ITaskModel createTaskModel(List<IUserSession> userSessions) { 
     194                return new TaskModel(userSessions); 
     195        } 
     196 
     197        /* 
     198         * (non-Javadoc) 
     199         *  
     200         * @see ITaskFactory#createUserSession() 
     201         */ 
     202        @Override 
     203        public IUserSession createUserSession() { 
     204                return new UserSession(); 
     205        } 
    180206 
    181207} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInfo.java

    r1428 r1733  
    3131 */ 
    3232public class TaskInfo implements ITaskInfo { 
    33      
    34     /** 
    35      * <p> 
    36      * the task to which the infos belong 
    37      * </p> 
    38      */ 
    39     private ITask task; 
    40      
    41     /** 
    42      * <p> 
    43      * all available measures for the task 
    44      * </p> 
    45      */ 
    46     private ArrayList<Measure> measures = new ArrayList<Measure>(); 
    47  
    48     /** 
    49      * <p> 
    50      * initialized the task infos with the task to which they belong. 
    51      * </p> 
    52      *  
    53      * @param task 
    54      */ 
    55     TaskInfo(ITask task) { 
    56         this.task = task; 
    57     } 
    58  
    59     /* (non-Javadoc) 
    60      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getTask() 
    61      */ 
    62     @Override 
    63     public ITask getTask() { 
    64         return task; 
    65     } 
    66  
    67     /* (non-Javadoc) 
    68      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasures() 
    69      */ 
    70     @Override 
    71     public IMeasure[] getMeasures() { 
    72         measures.trimToSize(); 
    73         return measures.toArray(new IMeasure[measures.size()]); 
    74     } 
    75  
    76     /* (non-Javadoc) 
    77      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java.lang.String) 
    78      */ 
    79     @Override 
    80     public int getMeasureValue(TaskMetric metric) { 
    81         Measure measure = getMeasure(metric); 
    82          
    83         if (measure == null) { 
    84             throw new IllegalArgumentException("unknown metric " + metric); 
    85         } 
    86          
    87         return measure.getValue(); 
    88     } 
    89  
    90     /* (non-Javadoc) 
    91      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java.lang.String, de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 
    92      */ 
    93     @Override 
    94     public int getMeasureValue(TaskMetric metric, ITask context) { 
    95         Measure measure = getMeasure(metric); 
    96          
    97         if (measure == null) { 
    98             throw new IllegalArgumentException("unknown metric " + metric); 
    99         } 
    100          
    101         return measure.getValue(context); 
    102     } 
    103  
    104     /* (non-Javadoc) 
    105      * @see java.lang.Object#toString() 
    106      */ 
    107     @Override 
    108     public synchronized String toString() { 
    109         return "TaskInfo(" + task + ")"; 
    110     } 
    111  
    112     /** 
    113      * <p> 
    114      * must be called to indicate that a new new measures for the provided metric are about to 
    115      * be calculated and added. 
    116      * </p> 
    117      * 
    118      * @param metric the metric for which measures are about to be provided 
    119      */ 
    120     void addMeasure(TaskMetric metric) { 
    121         Measure measure = getMeasure(metric); 
    122          
    123         if (measure != null) { 
    124             throw new IllegalArgumentException("measure for metric " + metric + " already exists."); 
    125         } 
    126          
    127         measure = new Measure(metric); 
    128         measures.add(measure); 
    129     } 
    130  
    131     /** 
    132      * <p> 
    133      * sets a specific value for a measure of a specific metric in the provided context of the task 
    134      * </p> 
    135      *  
    136      * @param metric  the metric to which the value belongs 
    137      * @param context the context of the task in which the measure was recorded 
    138      * @param value   the value of the measure 
    139      */ 
    140     void setCount(TaskMetric metric, ITask context, int value) { 
    141         Measure measure = getMeasure(metric); 
    142          
    143         if (measure == null) { 
    144             throw new IllegalArgumentException("unknown metric. Please create a measure " + 
    145                                                "for the metric before using it."); 
    146         } 
    147          
    148         measure.set(context, value); 
    149     } 
    150  
    151     /** 
    152      * <p> 
    153      * increases a specific value for a measure of a specific metric in the provided context of the 
    154      * task 
    155      * </p> 
    156      *  
    157      * @param metric    the metric to which the value belongs 
    158      * @param context   the context of the task in which the measure was recorded 
    159      * @param increment the increment to be added to the value of the measure 
    160      */ 
    161     void increaseCount(TaskMetric metric, ITask context, int increment) { 
    162         Measure measure = getMeasure(metric); 
    163          
    164         if (measure == null) { 
    165             throw new IllegalArgumentException("unknown metric. Please create a measure " + 
    166                                                "for the metric before using it."); 
    167         } 
    168          
    169         measure.increase(context, increment); 
    170     } 
    171  
    172     /** 
    173      * <p> 
    174      * convenience method to internally determine the measure for a specific metric 
    175      * </p> 
    176      */ 
    177     private Measure getMeasure(TaskMetric metric) { 
    178         for (Measure candidate : measures) { 
    179             if (candidate.getMetric().equals(metric)) { 
    180                 return candidate; 
    181             } 
    182         } 
    183          
    184         return null; 
    185     } 
    186  
    187     /** 
    188      * <p> 
    189      * implementation for the measure interface of the task info interface. Does nothing fancy 
    190      * except implementing the interface 
    191      * </p> 
    192      *  
    193      * @author Patrick Harms 
    194      */ 
    195     private static class Measure implements IMeasure { 
    196  
    197         /** 
    198          * <p> 
    199          * the metric to which the measure belongs 
    200          * </p> 
    201          */ 
    202         private TaskMetric metric; 
    203          
    204         /** 
    205          * <p> 
    206          * the observed values for the difference contexts of the task 
    207          * </p> 
    208          */ 
    209         private HashMap<ITask, Integer> values; 
    210          
    211         /** 
    212          * <p> 
    213          * the context free value of the measure independent of the task context 
    214          * </p> 
    215          */ 
    216         private int contextFreeValue = 0; 
    217          
    218         /** 
    219          * <p> 
    220          * initializes the measure with a specific metric 
    221          * </p> 
    222          */ 
    223         private Measure(TaskMetric metric) { 
    224             super(); 
    225             this.metric = metric; 
    226         } 
    227  
    228         /* (non-Javadoc) 
    229          * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getMetric() 
    230          */ 
    231         @Override 
    232         public TaskMetric getMetric() { 
    233             return metric; 
    234         } 
    235  
    236         /* (non-Javadoc) 
    237          * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue() 
    238          */ 
    239         @Override 
    240         public int getValue() { 
    241             return contextFreeValue; 
    242         } 
    243  
    244         /* (non-Javadoc) 
    245          * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue(de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 
    246          */ 
    247         @Override 
    248         public int getValue(ITask context) { 
    249             if ((context != null) && (values != null)) { 
    250                 Integer currentValue = values.get(context); 
    251                  
    252                 if (currentValue != null) { 
    253                     return currentValue; 
    254                 } 
    255             } 
    256              
    257             return Integer.MIN_VALUE; 
    258         } 
    259  
    260         /** 
    261          * <p> 
    262          * sets the value of the measure context free as well as specific to the provided context 
    263          * </p> 
    264          */ 
    265         private void set(ITask context, int value) { 
    266             contextFreeValue = value; 
    267              
    268             if (context != null) { 
    269                 if (values == null) { 
    270                     values = new HashMap<ITask, Integer>(); 
    271                 } 
    272                  
    273                 values.put(context, value); 
    274             } 
    275         } 
    276  
    277         /** 
    278          * <p> 
    279          * increases the value of the measure context free as well as specific to the provided 
    280          * context according to the provided increment 
    281          * </p> 
    282          */ 
    283         private void increase(ITask context, int increment) { 
    284             contextFreeValue += increment; 
    285              
    286             if (context != null) { 
    287                 if (values == null) { 
    288                     values = new HashMap<ITask, Integer>(); 
    289                 } 
    290                  
    291                 Integer currentValue = values.get(context); 
    292                  
    293                 if (currentValue == null) { 
    294                     currentValue = 0; 
    295                 } 
    296                  
    297                 values.put(context, currentValue + increment); 
    298             } 
    299         } 
    300  
    301     } 
     33 
     34        /** 
     35         * <p> 
     36         * implementation for the measure interface of the task info interface. Does 
     37         * nothing fancy except implementing the interface 
     38         * </p> 
     39         *  
     40         * @author Patrick Harms 
     41         */ 
     42        private static class Measure implements IMeasure { 
     43 
     44                /** 
     45                 * <p> 
     46                 * the metric to which the measure belongs 
     47                 * </p> 
     48                 */ 
     49                private final TaskMetric metric; 
     50 
     51                /** 
     52                 * <p> 
     53                 * the observed values for the difference contexts of the task 
     54                 * </p> 
     55                 */ 
     56                private HashMap<ITask, Integer> values; 
     57 
     58                /** 
     59                 * <p> 
     60                 * the context free value of the measure independent of the task context 
     61                 * </p> 
     62                 */ 
     63                private int contextFreeValue = 0; 
     64 
     65                /** 
     66                 * <p> 
     67                 * initializes the measure with a specific metric 
     68                 * </p> 
     69                 */ 
     70                private Measure(TaskMetric metric) { 
     71                        super(); 
     72                        this.metric = metric; 
     73                } 
     74 
     75                /* 
     76                 * (non-Javadoc) 
     77                 *  
     78                 * @see 
     79                 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getMetric() 
     80                 */ 
     81                @Override 
     82                public TaskMetric getMetric() { 
     83                        return metric; 
     84                } 
     85 
     86                /* 
     87                 * (non-Javadoc) 
     88                 *  
     89                 * @see 
     90                 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue() 
     91                 */ 
     92                @Override 
     93                public int getValue() { 
     94                        return contextFreeValue; 
     95                } 
     96 
     97                /* 
     98                 * (non-Javadoc) 
     99                 *  
     100                 * @see 
     101                 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue 
     102                 * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 
     103                 */ 
     104                @Override 
     105                public int getValue(ITask context) { 
     106                        if ((context != null) && (values != null)) { 
     107                                final Integer currentValue = values.get(context); 
     108 
     109                                if (currentValue != null) { 
     110                                        return currentValue; 
     111                                } 
     112                        } 
     113 
     114                        return Integer.MIN_VALUE; 
     115                } 
     116 
     117                /** 
     118                 * <p> 
     119                 * increases the value of the measure context free as well as specific 
     120                 * to the provided context according to the provided increment 
     121                 * </p> 
     122                 */ 
     123                private void increase(ITask context, int increment) { 
     124                        contextFreeValue += increment; 
     125 
     126                        if (context != null) { 
     127                                if (values == null) { 
     128                                        values = new HashMap<ITask, Integer>(); 
     129                                } 
     130 
     131                                Integer currentValue = values.get(context); 
     132 
     133                                if (currentValue == null) { 
     134                                        currentValue = 0; 
     135                                } 
     136 
     137                                values.put(context, currentValue + increment); 
     138                        } 
     139                } 
     140 
     141                /** 
     142                 * <p> 
     143                 * sets the value of the measure context free as well as specific to the 
     144                 * provided context 
     145                 * </p> 
     146                 */ 
     147                private void set(ITask context, int value) { 
     148                        contextFreeValue = value; 
     149 
     150                        if (context != null) { 
     151                                if (values == null) { 
     152                                        values = new HashMap<ITask, Integer>(); 
     153                                } 
     154 
     155                                values.put(context, value); 
     156                        } 
     157                } 
     158 
     159        } 
     160 
     161        /** 
     162         * <p> 
     163         * the task to which the infos belong 
     164         * </p> 
     165         */ 
     166        private final ITask task; 
     167 
     168        /** 
     169         * <p> 
     170         * all available measures for the task 
     171         * </p> 
     172         */ 
     173        private final ArrayList<Measure> measures = new ArrayList<Measure>(); 
     174 
     175        /** 
     176         * <p> 
     177         * initialized the task infos with the task to which they belong. 
     178         * </p> 
     179         *  
     180         * @param task 
     181         */ 
     182        TaskInfo(ITask task) { 
     183                this.task = task; 
     184        } 
     185 
     186        /** 
     187         * <p> 
     188         * must be called to indicate that a new new measures for the provided 
     189         * metric are about to be calculated and added. 
     190         * </p> 
     191         * 
     192         * @param metric 
     193         *            the metric for which measures are about to be provided 
     194         */ 
     195        void addMeasure(TaskMetric metric) { 
     196                Measure measure = getMeasure(metric); 
     197 
     198                if (measure != null) { 
     199                        throw new IllegalArgumentException("measure for metric " + metric 
     200                                        + " already exists."); 
     201                } 
     202 
     203                measure = new Measure(metric); 
     204                measures.add(measure); 
     205        } 
     206 
     207        /** 
     208         * <p> 
     209         * convenience method to internally determine the measure for a specific 
     210         * metric 
     211         * </p> 
     212         */ 
     213        private Measure getMeasure(TaskMetric metric) { 
     214                for (final Measure candidate : measures) { 
     215                        if (candidate.getMetric().equals(metric)) { 
     216                                return candidate; 
     217                        } 
     218                } 
     219 
     220                return null; 
     221        } 
     222 
     223        /* 
     224         * (non-Javadoc) 
     225         *  
     226         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasures() 
     227         */ 
     228        @Override 
     229        public IMeasure[] getMeasures() { 
     230                measures.trimToSize(); 
     231                return measures.toArray(new IMeasure[measures.size()]); 
     232        } 
     233 
     234        /* 
     235         * (non-Javadoc) 
     236         *  
     237         * @see 
     238         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java 
     239         * .lang.String) 
     240         */ 
     241        @Override 
     242        public int getMeasureValue(TaskMetric metric) { 
     243                final Measure measure = getMeasure(metric); 
     244 
     245                if (measure == null) { 
     246                        throw new IllegalArgumentException("unknown metric " + metric); 
     247                } 
     248 
     249                return measure.getValue(); 
     250        } 
     251 
     252        /* 
     253         * (non-Javadoc) 
     254         *  
     255         * @see 
     256         * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java 
     257         * .lang.String, de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 
     258         */ 
     259        @Override 
     260        public int getMeasureValue(TaskMetric metric, ITask context) { 
     261                final Measure measure = getMeasure(metric); 
     262 
     263                if (measure == null) { 
     264                        throw new IllegalArgumentException("unknown metric " + metric); 
     265                } 
     266 
     267                return measure.getValue(context); 
     268        } 
     269 
     270        /* 
     271         * (non-Javadoc) 
     272         *  
     273         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getTask() 
     274         */ 
     275        @Override 
     276        public ITask getTask() { 
     277                return task; 
     278        } 
     279 
     280        /** 
     281         * <p> 
     282         * increases a specific value for a measure of a specific metric in the 
     283         * provided context of the task 
     284         * </p> 
     285         *  
     286         * @param metric 
     287         *            the metric to which the value belongs 
     288         * @param context 
     289         *            the context of the task in which the measure was recorded 
     290         * @param increment 
     291         *            the increment to be added to the value of the measure 
     292         */ 
     293        void increaseCount(TaskMetric metric, ITask context, int increment) { 
     294                final Measure measure = getMeasure(metric); 
     295 
     296                if (measure == null) { 
     297                        throw new IllegalArgumentException( 
     298                                        "unknown metric. Please create a measure " 
     299                                                        + "for the metric before using it."); 
     300                } 
     301 
     302                measure.increase(context, increment); 
     303        } 
     304 
     305        /** 
     306         * <p> 
     307         * sets a specific value for a measure of a specific metric in the provided 
     308         * context of the task 
     309         * </p> 
     310         *  
     311         * @param metric 
     312         *            the metric to which the value belongs 
     313         * @param context 
     314         *            the context of the task in which the measure was recorded 
     315         * @param value 
     316         *            the value of the measure 
     317         */ 
     318        void setCount(TaskMetric metric, ITask context, int value) { 
     319                final Measure measure = getMeasure(metric); 
     320 
     321                if (measure == null) { 
     322                        throw new IllegalArgumentException( 
     323                                        "unknown metric. Please create a measure " 
     324                                                        + "for the metric before using it."); 
     325                } 
     326 
     327                measure.set(context, value); 
     328        } 
     329 
     330        /* 
     331         * (non-Javadoc) 
     332         *  
     333         * @see java.lang.Object#toString() 
     334         */ 
     335        @Override 
     336        public synchronized String toString() { 
     337                return "TaskInfo(" + task + ")"; 
     338        } 
    302339 
    303340} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInstance.java

    r1405 r1733  
    2828 */ 
    2929class TaskInstance implements ITaskInstance { 
    30      
    31     /** 
    32      * <p> 
    33      * default serial version UID 
    34      * </p> 
    35      */ 
    36     private static final long serialVersionUID = 1L; 
    3730 
    38     /** 
    39      * <p> 
    40      * used as a counter to generate new ids for each newly created task instance. May overflow. 
    41      * </p> 
    42      */ 
    43     private static int temporalId = 0; 
     31        /** 
     32         * <p> 
     33         * creates a new id for a task instance using {@link #temporalId} by 
     34         * incrementing it an returning its current value. Resets the counter if 
     35         * {@link Integer.MAX_VALUE} is reached. 
     36         * </p> 
     37         *  
     38         * @return a new unique id for a task instance as long as 
     39         *         {@link #temporalId} does not overflow 
     40         */ 
     41        private static synchronized int getNewId() { 
     42                if (temporalId == Integer.MAX_VALUE) { 
     43                        temporalId = 0; 
     44                } 
    4445 
    45     /** 
    46      * <p> 
    47      * the task instantiated by this task instance 
    48      * </p> 
    49      */ 
    50     private ITask task; 
    51      
    52     /** 
    53      * <p> 
    54      * the id of the task instance (unique throughout the system as long as {@link #temporalId} 
    55      * does not overflow. 
    56      * </p> 
    57      */ 
    58     private int id; 
     46                return temporalId++; 
     47        } 
    5948 
    60     /** 
    61      * <p> 
    62      * instantiated the task instance with the task that is instantiated by the instance. It also 
    63      * assigns a unique id to the instance using {@link #getNewId()}. 
    64      * </p> 
    65      */ 
    66     TaskInstance(ITask task) { 
    67         this.task = task; 
    68         id = getNewId(); 
    69     } 
     49        /** 
     50         * <p> 
     51         * default serial version UID 
     52         * </p> 
     53         */ 
     54        private static final long serialVersionUID = 1L; 
    7055 
    71     /** 
    72      * <p> 
    73      * creates a new id for a task instance using {@link #temporalId} by incrementing it an 
    74      * returning its current value. Resets the counter if {@link Integer.MAX_VALUE} is reached. 
    75      * </p> 
    76      *  
    77      * @return a new unique id for a task instance as long as {@link #temporalId} does not overflow 
    78      */ 
    79     private static synchronized int getNewId() { 
    80         if (temporalId == Integer.MAX_VALUE) { 
    81             temporalId = 0; 
    82         } 
     56        /** 
     57         * <p> 
     58         * used as a counter to generate new ids for each newly created task 
     59         * instance. May overflow. 
     60         * </p> 
     61         */ 
     62        private static int temporalId = 0; 
    8363 
    84         return temporalId++; 
    85     } 
     64        /** 
     65         * <p> 
     66         * the task instantiated by this task instance 
     67         * </p> 
     68         */ 
     69        private ITask task; 
    8670 
    87     /* (non-Javadoc) 
    88      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getTask() 
    89      */ 
    90     @Override 
    91     public ITask getTask() { 
    92         return task; 
    93     } 
     71        /** 
     72         * <p> 
     73         * the id of the task instance (unique throughout the system as long as 
     74         * {@link #temporalId} does not overflow. 
     75         * </p> 
     76         */ 
     77        private final int id; 
    9478 
    95     /* 
    96      * (non-Javadoc) 
    97      *  
    98      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode) 
    99      */ 
    100     @Override 
    101     public boolean equals(ITaskInstance taskInstance) { 
    102         // task instances are only equal if they are identical or if they have the same id 
    103         // (may happen, if they are cloned) 
    104         return (this == taskInstance) || (this.hashCode() == taskInstance.hashCode()); 
    105     } 
     79        /** 
     80         * <p> 
     81         * instantiated the task instance with the task that is instantiated by the 
     82         * instance. It also assigns a unique id to the instance using 
     83         * {@link #getNewId()}. 
     84         * </p> 
     85         */ 
     86        TaskInstance(ITask task) { 
     87                this.task = task; 
     88                id = getNewId(); 
     89        } 
    10690 
    107     /* (non-Javadoc) 
    108      * @see java.lang.Object#hashCode() 
    109      */ 
    110     @Override 
    111     public synchronized int hashCode() { 
    112         return id; 
    113     } 
     91        /* 
     92         * (non-Javadoc) 
     93         *  
     94         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#accept( 
     95         * ITaskInstanceVisitor) 
     96         */ 
     97        @Override 
     98        public void accept(ITaskInstanceVisitor visitor) { 
     99                visitor.visit(this); 
     100        } 
    114101 
    115     /* (non-Javadoc) 
    116      * @see java.lang.Object#toString() 
    117      */ 
    118     @Override 
    119     public synchronized String toString() { 
    120         StringBuffer result = new StringBuffer(); 
    121         result.append(task.getType()); 
    122         result.append(" #"); 
    123         result.append(task.getId()); 
    124          
    125         if (task.getDescription() != null) { 
    126             result.append(" ("); 
    127             result.append(task.getDescription()); 
    128             result.append(')'); 
    129         } 
    130          
    131         /*if (children != null) { 
    132             result.append(", "); 
    133             result.append(children.size()); 
    134             result.append(" children"); 
    135         }*/ 
    136          
    137         return result.toString(); 
    138     } 
     102        /* 
     103         * (non-Javadoc) 
     104         *  
     105         * @see java.lang.Object#clone() 
     106         */ 
     107        @Override 
     108        public synchronized ITaskInstance clone() { 
     109                TaskInstance clone = null; 
     110                try { 
     111                        clone = (TaskInstance) super.clone(); 
     112                } catch (final CloneNotSupportedException e) { 
     113                        // this should never happen. Therefore simply dump the exception 
     114                        e.printStackTrace(); 
     115                } 
    139116 
    140     /* (non-Javadoc) 
    141      * @see java.lang.Object#clone() 
    142      */ 
    143     @Override 
    144     public synchronized ITaskInstance clone() { 
    145         TaskInstance clone = null; 
    146         try { 
    147             clone = (TaskInstance) super.clone(); 
    148         } 
    149         catch (CloneNotSupportedException e) { 
    150             // this should never happen. Therefore simply dump the exception 
    151             e.printStackTrace(); 
    152         } 
     117                return clone; 
     118        } 
    153119 
    154         return clone; 
    155     } 
     120        /* 
     121         * (non-Javadoc) 
     122         *  
     123         * @see 
     124         * de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode) 
     125         */ 
     126        @Override 
     127        public boolean equals(ITaskInstance taskInstance) { 
     128                // task instances are only equal if they are identical or if they have 
     129                // the same id 
     130                // (may happen, if they are cloned) 
     131                return (this == taskInstance) 
     132                                || (this.hashCode() == taskInstance.hashCode()); 
     133        } 
    156134 
    157     /* (non-Javadoc) 
    158      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#accept(ITaskInstanceVisitor) 
    159      */ 
    160     @Override 
    161     public void accept(ITaskInstanceVisitor visitor) { 
    162         visitor.visit(this); 
    163     } 
     135        /* 
     136         * (non-Javadoc) 
     137         *  
     138         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getTask() 
     139         */ 
     140        @Override 
     141        public ITask getTask() { 
     142                return task; 
     143        } 
    164144 
    165     /** 
    166      * <p> 
    167      * used to update the task represented through this instance 
    168      * </p> 
    169      *  
    170      * @param task the task to set 
    171      */ 
    172     void setTask(ITask task) { 
    173         this.task = task; 
    174     } 
     145        /* 
     146         * (non-Javadoc) 
     147         *  
     148         * @see java.lang.Object#hashCode() 
     149         */ 
     150        @Override 
     151        public synchronized int hashCode() { 
     152                return id; 
     153        } 
     154 
     155        /** 
     156         * <p> 
     157         * used to update the task represented through this instance 
     158         * </p> 
     159         *  
     160         * @param task 
     161         *            the task to set 
     162         */ 
     163        void setTask(ITask task) { 
     164                this.task = task; 
     165        } 
     166 
     167        /* 
     168         * (non-Javadoc) 
     169         *  
     170         * @see java.lang.Object#toString() 
     171         */ 
     172        @Override 
     173        public synchronized String toString() { 
     174                final StringBuffer result = new StringBuffer(); 
     175                result.append(task.getType()); 
     176                result.append(" #"); 
     177                result.append(task.getId()); 
     178 
     179                if (task.getDescription() != null) { 
     180                        result.append(" ("); 
     181                        result.append(task.getDescription()); 
     182                        result.append(')'); 
     183                } 
     184 
     185                /* 
     186                 * if (children != null) { result.append(", "); 
     187                 * result.append(children.size()); result.append(" children"); } 
     188                 */ 
     189 
     190                return result.toString(); 
     191        } 
    175192 
    176193} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java

    r1494 r1733  
    4343 * <p> 
    4444 * this is the default implementation of the interface {@link ITaskModel}. It 
    45  * does not do anything fancy except implementing the interface. It also calculates on 
    46  * initialisations the measures for diverse metrics of the task belonging to the model 
     45 * does not do anything fancy except implementing the interface. It also 
     46 * calculates on initialisations the measures for diverse metrics of the task 
     47 * belonging to the model 
    4748 * </p> 
    4849 *  
     
    5051 */ 
    5152class TaskModel implements ITaskModel { 
    52      
    53     /** 
    54      * <p> 
    55      * default serial version UID 
    56      * </p> 
    57      */ 
    58     private static final long serialVersionUID = 1L; 
    59      
    60     /** 
    61      * <p> 
    62      * all metrics calculated by this type of task model 
    63      * </p> 
    64      */ 
    65     private static final TaskMetric[] taskMetrics = new TaskMetric[] 
    66         { TaskMetric.COUNT, 
    67           TaskMetric.DEPTH, 
    68           TaskMetric.EVENT_COVERAGE, 
    69           TaskMetric.EVENT_COVERAGE_RATIO, 
    70           TaskMetric.EVENT_COVERAGE_QUANTILE }; 
    71  
    72     /** 
    73      * <p> 
    74      * the user sessions belonging to the model 
    75      * </p> 
    76      */ 
    77     private List<IUserSession> userSessions; 
    78  
    79     /** 
    80      * <p> 
    81      * index for effectively accessing the model and calculating statistics about it 
    82      * </p> 
    83      */ 
    84     private transient TaskModelIndex index = null; 
    85      
    86     /** 
    87      * <p> 
    88      * initializes the task model with the user sessions out of which the tasks are extracted 
    89      * </p> 
    90      *  
    91      * @param userSessions as described 
    92      */ 
    93     TaskModel(List<IUserSession> userSessions) { 
    94         if ((userSessions == null) || (userSessions.size() == 0)) { 
    95             throw new IllegalArgumentException("user sessions must not be null"); 
    96         } 
    97          
    98         this.userSessions = userSessions; 
    99     } 
    100  
    101      
    102     /* (non-Javadoc) 
    103      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getUserSessions() 
    104      */ 
    105     @Override 
    106     public List<IUserSession> getUserSessions() { 
    107         ensureInitialized(); 
    108         return Collections.unmodifiableList(userSessions); 
    109     } 
    110  
    111  
    112     /* (non-Javadoc) 
    113      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTasks() 
    114      */ 
    115     @Override 
    116     public Collection<ITask> getTasks() { 
    117         ensureInitialized(); 
    118         return Collections.unmodifiableCollection(index.taskMap.keySet()); 
    119     } 
    120  
    121  
    122     /* (non-Javadoc) 
    123      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTaskInfo(ITask) 
    124      */ 
    125     @Override 
    126     public ITaskInfo getTaskInfo(ITask task) { 
    127         ensureInitialized(); 
    128         return index.taskMap.get(task); 
    129     } 
    130  
    131     /* (non-Javadoc) 
    132      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getAllMetrics() 
    133      */ 
    134     @Override 
    135     public TaskMetric[] getAllMetrics() { 
    136         return taskMetrics; 
    137     } 
    138  
    139  
    140     /* (non-Javadoc) 
    141      * @see java.lang.Object#clone() 
    142      */ 
    143     @Override 
    144     public TaskModel clone() { 
    145         return new TaskModel(userSessions); 
    146     } 
    147  
    148     /** 
    149      * <p> 
    150      * internal convenience method that initializes the internal index and calculates all measures 
    151      * for metrics available for the tasks 
    152      * </p> 
    153      */ 
    154     private synchronized void ensureInitialized() { 
    155         if (index == null) { 
    156             index = new TaskModelIndex(); 
    157              
    158             for (IUserSession session : this.userSessions) { 
    159                 for (ITaskInstance taskInstance : session) { 
    160                     index.handleTaskInstance(taskInstance, null); 
    161                 } 
    162             } 
    163              
    164             // count all events covered 
    165             int allEventsCovered = 0; 
    166             Collection<ITask> tasks = getTasks(); 
    167             for (ITask task : tasks) { 
    168                 if (task instanceof IEventTask) { 
    169                     allEventsCovered += task.getInstances().size(); 
    170                 } 
    171             } 
    172              
    173             int[] eventCoverageRatios = new int[tasks.size()]; 
    174             int i = 0; 
    175  
    176             // add some further measures 
    177             for (ITask task : tasks) { 
    178                 TaskInfo info = index.taskMap.get(task); 
    179                 info.addMeasure(TaskMetric.EVENT_COVERAGE_RATIO); 
    180                  
    181                 int coveredEvents = info.getMeasureValue(TaskMetric.EVENT_COVERAGE); 
    182                 int coverageRatio = 0; 
    183                  
    184                 if (allEventsCovered > 0) { 
    185                     coverageRatio = (coveredEvents * 1000) / allEventsCovered; 
    186                 } 
    187                  
    188                 eventCoverageRatios[i++] = coverageRatio; 
    189                 info.setCount(TaskMetric.EVENT_COVERAGE_RATIO, null, coverageRatio); 
    190             } 
    191              
    192             Arrays.sort(eventCoverageRatios); 
    193              
    194             // add some further measures 
    195             for (ITask task : tasks) { 
    196                 TaskInfo info = index.taskMap.get(task); 
    197                 info.addMeasure(TaskMetric.EVENT_COVERAGE_QUANTILE); 
    198                 int quantile = Arrays.binarySearch 
    199                     (eventCoverageRatios, info.getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 
    200                  
    201                 quantile = 1000 * quantile / eventCoverageRatios.length; 
    202                  
    203                 info.setCount(TaskMetric.EVENT_COVERAGE_QUANTILE, null, quantile); 
    204             } 
    205              
    206             //index.dumpToCSV(System.out); 
    207             /*try { 
    208                 OutputStream stream = new FileOutputStream(new File("tasks.csv")); 
    209                 index.dumpToCSV(new PrintStream(stream)); 
    210                 stream.close(); 
    211             } 
    212             catch (FileNotFoundException e) { 
    213                 e.printStackTrace(); 
    214             }*/ 
    215         } 
    216          
    217     } 
    218  
    219     /** 
    220      * <p> 
    221      * the index of task infos used internally. The index is created once and while that filled 
    222      * with task infos for each observed task containing all measures for metrics belonging 
    223      * to the tasks.  
    224      * </p> 
    225      *  
    226      * @author Patrick Harms 
    227      */ 
    228     private static class TaskModelIndex { 
    229  
    230         /** 
    231          * <p> 
    232          * the tasks contained in the user session belonging to the model as well as statistical 
    233          * infos about them 
    234          * </p> 
    235          */ 
    236         private Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 
    237  
    238         /** 
    239          * <p> 
    240          * called on initialization to fill the index with infos about the given task instance 
    241          * as well as to calculate the appropriate metrics 
    242          * </p> 
    243          */ 
    244         private int[] handleTaskInstance(ITaskInstance taskInstance, ITask context) { 
    245             int eventTaskInstancesCovered = 0; 
    246             int depth = 0; 
    247              
    248             if (taskInstance instanceof ITaskInstanceList) { 
    249                 for (ITaskInstance child : (ITaskInstanceList) taskInstance) { 
    250                     int[] measures = handleTaskInstance(child, taskInstance.getTask()); 
    251                     eventTaskInstancesCovered += measures[0]; 
    252                     depth = Math.max(depth, measures[1]); 
    253                 } 
    254                  
    255                 if ((((ITaskInstanceList) taskInstance).size() == 0) && 
    256                     (taskInstance instanceof IIterationInstance)) 
    257                 { 
    258                     // ensure also empty task infos for unselected variants 
    259                     ensureTaskInfo(((IIteration) taskInstance.getTask()).getMarkedTask(), context); 
    260                 } 
    261             } 
    262             else if (taskInstance instanceof ISelectionInstance) { 
    263                 ITaskInstance child = ((ISelectionInstance) taskInstance).getChild(); 
    264                 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 
    265                 eventTaskInstancesCovered += measures[0]; 
    266                 depth = Math.max(depth, measures[1]); 
    267                  
    268                 // ensure also empty task infos for unselected variants 
    269                 for (ITask otherChildTask : ((ISelection) taskInstance.getTask()).getChildren()) { 
    270                     ensureTaskInfo(otherChildTask, context); 
    271                 } 
    272             } 
    273             else if (taskInstance instanceof IOptionalInstance) { 
    274                 ITaskInstance child = ((IOptionalInstance) taskInstance).getChild(); 
    275                 if (child != null) { 
    276                     int[] measures = handleTaskInstance(child, taskInstance.getTask()); 
    277                     eventTaskInstancesCovered += measures[0]; 
    278                     depth = Math.max(depth, measures[1]); 
    279                 } 
    280                 else { 
    281                     // ensure also empty task infos for unselected variants 
    282                     ensureTaskInfo(((IOptional) taskInstance.getTask()).getMarkedTask(), context); 
    283                 } 
    284             } 
    285             else if (taskInstance instanceof IEventTaskInstance) { 
    286                 eventTaskInstancesCovered = 1; 
    287             } 
    288              
    289             depth++; 
    290              
    291             ensureTaskInfo(taskInstance.getTask(), context, eventTaskInstancesCovered, depth); 
    292              
    293             return new int[] { eventTaskInstancesCovered, depth }; 
    294         } 
    295          
    296         /** 
    297          * <p> 
    298          * internal convenience method to build the task model during initialization 
    299          * </p> 
    300          */ 
    301         private void ensureTaskInfo(ITask task, ITask context) { 
    302             ensureTaskInfo(task, context, 0, 0); 
    303              
    304             if (task instanceof IStructuringTemporalRelationship) { 
    305                 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 
    306                     ensureTaskInfo(child, task); 
    307                 } 
    308             } 
    309             else if (task instanceof IMarkingTemporalRelationship) { 
    310                 ensureTaskInfo(((IMarkingTemporalRelationship) task).getMarkedTask(), task); 
    311             } 
    312          
    313         } 
    314          
    315         /** 
    316          * <p> 
    317          * internal convenience method to build the task model during initialization. Adds a new 
    318          * task info object to the map for the provided task and fills it with measures. If there 
    319          * are already some task infos for the task, the contained measures are updated according 
    320          * to the parameters. 
    321          * </p> 
    322          */ 
    323         private void ensureTaskInfo(ITask task, 
    324                                     ITask context, 
    325                                     int   eventTaskInstancesCovered, 
    326                                     int   depth) 
    327         { 
    328             TaskInfo taskInfo = taskMap.get(task); 
    329  
    330             if (taskInfo == null) { 
    331                 taskInfo = new TaskInfo(task); 
    332                 taskInfo.addMeasure(TaskMetric.COUNT); 
    333                 taskInfo.addMeasure(TaskMetric.EVENT_COVERAGE); 
    334                 taskInfo.addMeasure(TaskMetric.DEPTH); 
    335                 taskMap.put(task, taskInfo); 
    336                  
    337                 taskInfo.setCount(TaskMetric.DEPTH, null, getDepth(task)); 
    338             } 
    339  
    340             taskInfo.increaseCount(TaskMetric.COUNT, context, 1); 
    341             taskInfo.increaseCount(TaskMetric.EVENT_COVERAGE, context, eventTaskInstancesCovered); 
    342  
    343             taskInfo.setCount(TaskMetric.DEPTH, context, depth); 
    344         } 
    345  
    346         /** 
    347          * <p> 
    348          * internal convenience method to calculate the maximum depth of a task 
    349          * </p> 
    350          */ 
    351         private int getDepth(ITask task) { 
    352             if (task instanceof IMarkingTemporalRelationship) { 
    353                 return getDepth(((IMarkingTemporalRelationship) task).getMarkedTask()) + 1; 
    354             } 
    355             else if (task instanceof IStructuringTemporalRelationship) { 
    356                 int maxDepth = 0; 
    357                  
    358                 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 
    359                     maxDepth = Math.max(maxDepth, getDepth(child)); 
    360                 } 
    361                  
    362                 return maxDepth + 1; 
    363             } 
    364             else { 
    365                 // event tasks 
    366                 return 1; 
    367             } 
    368         } 
    369  
    370         /** 
    371          * 
    372          */ 
    373         /*private void dumpToCSV(PrintStream out) { 
    374             out.println("taskid;depth;count;eventcoverage;eventcoverageratio"); 
    375              
    376             for (Map.Entry<ITask, TaskInfo> entry : taskMap.entrySet()) { 
    377                 out.print(entry.getKey().getId()); 
    378                 out.print(';'); 
    379                 out.print(entry.getValue().getMeasureValue(TaskMetric.DEPTH)); 
    380                 out.print(';'); 
    381                 out.print(entry.getValue().getMeasureValue(TaskMetric.COUNT)); 
    382                 out.print(';'); 
    383                 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE)); 
    384                 out.print(';'); 
    385                 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 
    386                 out.println(); 
    387             } 
    388         }*/ 
    389  
    390     } 
    391  
     53 
     54        /** 
     55         * <p> 
     56         * the index of task infos used internally. The index is created once and 
     57         * while that filled with task infos for each observed task containing all 
     58         * measures for metrics belonging to the tasks. 
     59         * </p> 
     60         *  
     61         * @author Patrick Harms 
     62         */ 
     63        private static class TaskModelIndex { 
     64 
     65                /** 
     66                 * <p> 
     67                 * the tasks contained in the user session belonging to the model as 
     68                 * well as statistical infos about them 
     69                 * </p> 
     70                 */ 
     71                private final Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 
     72 
     73                /** 
     74                 * <p> 
     75                 * internal convenience method to build the task model during 
     76                 * initialization 
     77                 * </p> 
     78                 */ 
     79                private void ensureTaskInfo(ITask task, ITask context) { 
     80                        ensureTaskInfo(task, context, 0, 0); 
     81 
     82                        if (task instanceof IStructuringTemporalRelationship) { 
     83                                for (final ITask child : ((IStructuringTemporalRelationship) task) 
     84                                                .getChildren()) { 
     85                                        ensureTaskInfo(child, task); 
     86                                } 
     87                        } else if (task instanceof IMarkingTemporalRelationship) { 
     88                                ensureTaskInfo( 
     89                                                ((IMarkingTemporalRelationship) task).getMarkedTask(), 
     90                                                task); 
     91                        } 
     92 
     93                } 
     94 
     95                /** 
     96                 * <p> 
     97                 * internal convenience method to build the task model during 
     98                 * initialization. Adds a new task info object to the map for the 
     99                 * provided task and fills it with measures. If there are already some 
     100                 * task infos for the task, the contained measures are updated according 
     101                 * to the parameters. 
     102                 * </p> 
     103                 */ 
     104                private void ensureTaskInfo(ITask task, ITask context, 
     105                                int eventTaskInstancesCovered, int depth) { 
     106                        TaskInfo taskInfo = taskMap.get(task); 
     107 
     108                        if (taskInfo == null) { 
     109                                taskInfo = new TaskInfo(task); 
     110                                taskInfo.addMeasure(TaskMetric.COUNT); 
     111                                taskInfo.addMeasure(TaskMetric.EVENT_COVERAGE); 
     112                                taskInfo.addMeasure(TaskMetric.DEPTH); 
     113                                taskMap.put(task, taskInfo); 
     114 
     115                                taskInfo.setCount(TaskMetric.DEPTH, null, getDepth(task)); 
     116                        } 
     117 
     118                        taskInfo.increaseCount(TaskMetric.COUNT, context, 1); 
     119                        taskInfo.increaseCount(TaskMetric.EVENT_COVERAGE, context, 
     120                                        eventTaskInstancesCovered); 
     121 
     122                        taskInfo.setCount(TaskMetric.DEPTH, context, depth); 
     123                } 
     124 
     125                /** 
     126                 * <p> 
     127                 * internal convenience method to calculate the maximum depth of a task 
     128                 * </p> 
     129                 */ 
     130                private int getDepth(ITask task) { 
     131                        if (task instanceof IMarkingTemporalRelationship) { 
     132                                return getDepth(((IMarkingTemporalRelationship) task) 
     133                                                .getMarkedTask()) + 1; 
     134                        } else if (task instanceof IStructuringTemporalRelationship) { 
     135                                int maxDepth = 0; 
     136 
     137                                for (final ITask child : ((IStructuringTemporalRelationship) task) 
     138                                                .getChildren()) { 
     139                                        maxDepth = Math.max(maxDepth, getDepth(child)); 
     140                                } 
     141 
     142                                return maxDepth + 1; 
     143                        } else { 
     144                                // event tasks 
     145                                return 1; 
     146                        } 
     147                } 
     148 
     149                /** 
     150                 * <p> 
     151                 * called on initialization to fill the index with infos about the given 
     152                 * task instance as well as to calculate the appropriate metrics 
     153                 * </p> 
     154                 */ 
     155                private int[] handleTaskInstance(ITaskInstance taskInstance, 
     156                                ITask context) { 
     157                        int eventTaskInstancesCovered = 0; 
     158                        int depth = 0; 
     159 
     160                        if (taskInstance instanceof ITaskInstanceList) { 
     161                                for (final ITaskInstance child : (ITaskInstanceList) taskInstance) { 
     162                                        final int[] measures = handleTaskInstance(child, 
     163                                                        taskInstance.getTask()); 
     164                                        eventTaskInstancesCovered += measures[0]; 
     165                                        depth = Math.max(depth, measures[1]); 
     166                                } 
     167 
     168                                if ((((ITaskInstanceList) taskInstance).size() == 0) 
     169                                                && (taskInstance instanceof IIterationInstance)) { 
     170                                        // ensure also empty task infos for unselected variants 
     171                                        ensureTaskInfo( 
     172                                                        ((IIteration) taskInstance.getTask()) 
     173                                                                        .getMarkedTask(), 
     174                                                        context); 
     175                                } 
     176                        } else if (taskInstance instanceof ISelectionInstance) { 
     177                                final ITaskInstance child = ((ISelectionInstance) taskInstance) 
     178                                                .getChild(); 
     179                                final int[] measures = handleTaskInstance(child, 
     180                                                taskInstance.getTask()); 
     181                                eventTaskInstancesCovered += measures[0]; 
     182                                depth = Math.max(depth, measures[1]); 
     183 
     184                                // ensure also empty task infos for unselected variants 
     185                                for (final ITask otherChildTask : ((ISelection) taskInstance 
     186                                                .getTask()).getChildren()) { 
     187                                        ensureTaskInfo(otherChildTask, context); 
     188                                } 
     189                        } else if (taskInstance instanceof IOptionalInstance) { 
     190                                final ITaskInstance child = ((IOptionalInstance) taskInstance) 
     191                                                .getChild(); 
     192                                if (child != null) { 
     193                                        final int[] measures = handleTaskInstance(child, 
     194                                                        taskInstance.getTask()); 
     195                                        eventTaskInstancesCovered += measures[0]; 
     196                                        depth = Math.max(depth, measures[1]); 
     197                                } else { 
     198                                        // ensure also empty task infos for unselected variants 
     199                                        ensureTaskInfo( 
     200                                                        ((IOptional) taskInstance.getTask()) 
     201                                                                        .getMarkedTask(), 
     202                                                        context); 
     203                                } 
     204                        } else if (taskInstance instanceof IEventTaskInstance) { 
     205                                eventTaskInstancesCovered = 1; 
     206                        } 
     207 
     208                        depth++; 
     209 
     210                        ensureTaskInfo(taskInstance.getTask(), context, 
     211                                        eventTaskInstancesCovered, depth); 
     212 
     213                        return new int[] { eventTaskInstancesCovered, depth }; 
     214                } 
     215 
     216                /** 
     217                 * 
     218                 */ 
     219                /* 
     220                 * private void dumpToCSV(PrintStream out) { 
     221                 * out.println("taskid;depth;count;eventcoverage;eventcoverageratio"); 
     222                 *  
     223                 * for (Map.Entry<ITask, TaskInfo> entry : taskMap.entrySet()) { 
     224                 * out.print(entry.getKey().getId()); out.print(';'); 
     225                 * out.print(entry.getValue().getMeasureValue(TaskMetric.DEPTH)); 
     226                 * out.print(';'); 
     227                 * out.print(entry.getValue().getMeasureValue(TaskMetric.COUNT)); 
     228                 * out.print(';'); 
     229                 * out.print(entry.getValue().getMeasureValue(TaskMetric. 
     230                 * EVENT_COVERAGE)); out.print(';'); 
     231                 * out.print(entry.getValue().getMeasureValue 
     232                 * (TaskMetric.EVENT_COVERAGE_RATIO)); out.println(); } } 
     233                 */ 
     234 
     235        } 
     236 
     237        /** 
     238         * <p> 
     239         * default serial version UID 
     240         * </p> 
     241         */ 
     242        private static final long serialVersionUID = 1L; 
     243 
     244        /** 
     245         * <p> 
     246         * all metrics calculated by this type of task model 
     247         * </p> 
     248         */ 
     249        private static final TaskMetric[] taskMetrics = new TaskMetric[] { 
     250                        TaskMetric.COUNT, TaskMetric.DEPTH, TaskMetric.EVENT_COVERAGE, 
     251                        TaskMetric.EVENT_COVERAGE_RATIO, TaskMetric.EVENT_COVERAGE_QUANTILE }; 
     252 
     253        /** 
     254         * <p> 
     255         * the user sessions belonging to the model 
     256         * </p> 
     257         */ 
     258        private final List<IUserSession> userSessions; 
     259 
     260        /** 
     261         * <p> 
     262         * index for effectively accessing the model and calculating statistics 
     263         * about it 
     264         * </p> 
     265         */ 
     266        private transient TaskModelIndex index = null; 
     267 
     268        /** 
     269         * <p> 
     270         * initializes the task model with the user sessions out of which the tasks 
     271         * are extracted 
     272         * </p> 
     273         *  
     274         * @param userSessions 
     275         *            as described 
     276         */ 
     277        TaskModel(List<IUserSession> userSessions) { 
     278                if ((userSessions == null) || (userSessions.size() == 0)) { 
     279                        throw new IllegalArgumentException("user sessions must not be null"); 
     280                } 
     281 
     282                this.userSessions = userSessions; 
     283        } 
     284 
     285        /* 
     286         * (non-Javadoc) 
     287         *  
     288         * @see java.lang.Object#clone() 
     289         */ 
     290        @Override 
     291        public TaskModel clone() { 
     292                return new TaskModel(userSessions); 
     293        } 
     294 
     295        /** 
     296         * <p> 
     297         * internal convenience method that initializes the internal index and 
     298         * calculates all measures for metrics available for the tasks 
     299         * </p> 
     300         */ 
     301        private synchronized void ensureInitialized() { 
     302                if (index == null) { 
     303                        index = new TaskModelIndex(); 
     304 
     305                        for (final IUserSession session : this.userSessions) { 
     306                                for (final ITaskInstance taskInstance : session) { 
     307                                        index.handleTaskInstance(taskInstance, null); 
     308                                } 
     309                        } 
     310 
     311                        // count all events covered 
     312                        int allEventsCovered = 0; 
     313                        final Collection<ITask> tasks = getTasks(); 
     314                        for (final ITask task : tasks) { 
     315                                if (task instanceof IEventTask) { 
     316                                        allEventsCovered += task.getInstances().size(); 
     317                                } 
     318                        } 
     319 
     320                        final int[] eventCoverageRatios = new int[tasks.size()]; 
     321                        int i = 0; 
     322 
     323                        // add some further measures 
     324                        for (final ITask task : tasks) { 
     325                                final TaskInfo info = index.taskMap.get(task); 
     326                                info.addMeasure(TaskMetric.EVENT_COVERAGE_RATIO); 
     327 
     328                                final int coveredEvents = info 
     329                                                .getMeasureValue(TaskMetric.EVENT_COVERAGE); 
     330                                int coverageRatio = 0; 
     331 
     332                                if (allEventsCovered > 0) { 
     333                                        coverageRatio = (coveredEvents * 1000) / allEventsCovered; 
     334                                } 
     335 
     336                                eventCoverageRatios[i++] = coverageRatio; 
     337                                info.setCount(TaskMetric.EVENT_COVERAGE_RATIO, null, 
     338                                                coverageRatio); 
     339                        } 
     340 
     341                        Arrays.sort(eventCoverageRatios); 
     342 
     343                        // add some further measures 
     344                        for (final ITask task : tasks) { 
     345                                final TaskInfo info = index.taskMap.get(task); 
     346                                info.addMeasure(TaskMetric.EVENT_COVERAGE_QUANTILE); 
     347                                int quantile = Arrays.binarySearch(eventCoverageRatios, 
     348                                                info.getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 
     349 
     350                                quantile = (1000 * quantile) / eventCoverageRatios.length; 
     351 
     352                                info.setCount(TaskMetric.EVENT_COVERAGE_QUANTILE, null, 
     353                                                quantile); 
     354                        } 
     355 
     356                        // index.dumpToCSV(System.out); 
     357                        /* 
     358                         * try { OutputStream stream = new FileOutputStream(new 
     359                         * File("tasks.csv")); index.dumpToCSV(new PrintStream(stream)); 
     360                         * stream.close(); } catch (FileNotFoundException e) { 
     361                         * e.printStackTrace(); } 
     362                         */ 
     363                } 
     364 
     365        } 
     366 
     367        /* 
     368         * (non-Javadoc) 
     369         *  
     370         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getAllMetrics() 
     371         */ 
     372        @Override 
     373        public TaskMetric[] getAllMetrics() { 
     374                return taskMetrics; 
     375        } 
     376 
     377        /* 
     378         * (non-Javadoc) 
     379         *  
     380         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTaskInfo(ITask) 
     381         */ 
     382        @Override 
     383        public ITaskInfo getTaskInfo(ITask task) { 
     384                ensureInitialized(); 
     385                return index.taskMap.get(task); 
     386        } 
     387 
     388        /* 
     389         * (non-Javadoc) 
     390         *  
     391         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTasks() 
     392         */ 
     393        @Override 
     394        public Collection<ITask> getTasks() { 
     395                ensureInitialized(); 
     396                return Collections.unmodifiableCollection(index.taskMap.keySet()); 
     397        } 
     398 
     399        /* 
     400         * (non-Javadoc) 
     401         *  
     402         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getUserSessions() 
     403         */ 
     404        @Override 
     405        public List<IUserSession> getUserSessions() { 
     406                ensureInitialized(); 
     407                return Collections.unmodifiableList(userSessions); 
     408        } 
    392409 
    393410} 
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/UserSession.java

    r1407 r1733  
    3333 */ 
    3434class UserSession implements IUserSession { 
    35      
    36     /** 
    37      * <p> 
    38      * default serial version UID 
    39      * </p> 
    40      */ 
    41     private static final long serialVersionUID = 1L; 
    42      
    43     /** 
    44      * <p> 
    45      * the task instances belonging to the user session 
    46      * </p> 
    47      */ 
    48     private List<ITaskInstance> executedTasks = new ArrayList<ITaskInstance>(); 
    4935 
    50     /* (non-Javadoc) 
    51      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
    52      */ 
    53     @Override 
    54     public ITaskInstance get(int index) { 
    55         return executedTasks.get(index); 
    56     } 
     36        /** 
     37         * <p> 
     38         * default serial version UID 
     39         * </p> 
     40         */ 
     41        private static final long serialVersionUID = 1L; 
    5742 
    58     /* (non-Javadoc) 
    59      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
    60      */ 
    61     @Override 
    62     public int size() { 
    63         return executedTasks.size(); 
    64     } 
     43        /** 
     44         * <p> 
     45         * the task instances belonging to the user session 
     46         * </p> 
     47         */ 
     48        private List<ITaskInstance> executedTasks = new ArrayList<ITaskInstance>(); 
    6549 
    66     /* (non-Javadoc) 
    67      * @see java.lang.Iterable#iterator() 
    68      */ 
    69     @Override 
    70     public Iterator<ITaskInstance> iterator() { 
    71         return executedTasks.iterator(); 
    72     } 
     50        /** 
     51         * <p> 
     52         * used internally to add a task instance to the user session at a specific 
     53         * position 
     54         * </p> 
     55         *  
     56         * @param index 
     57         *            the index the task instance shall be added to 
     58         * @param taskInstance 
     59         *            the task instance to be added 
     60         */ 
     61        void addExecutedTask(int index, ITaskInstance taskInstance) { 
     62                executedTasks.add(index, taskInstance); 
     63        } 
    7364 
    74     /* (non-Javadoc) 
    75      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession#getExecutedTasks() 
    76      */ 
    77     @Override 
    78     public List<ITaskInstance> getExecutedTasks() { 
    79         return Collections.unmodifiableList(executedTasks); 
    80     } 
     65        /** 
     66         * <p> 
     67         * used internally to add a task instance to the user session 
     68         * </p> 
     69         *  
     70         * @param taskInstance 
     71         *            the task instance to be added 
     72         */ 
     73        void addExecutedTask(ITaskInstance taskInstance) { 
     74                executedTasks.add(taskInstance); 
     75        } 
    8176 
    82     /* (non-Javadoc) 
    83      * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession#equals(IUserSession) 
    84      */ 
    85     @Override 
    86     public boolean equals(IUserSession userSession) { 
    87         // task instances are only equal if they are identical or if they have the same id 
    88         // (may happen, if they are cloned) 
    89         return (this == userSession) || (this.hashCode() == userSession.hashCode()); 
    90     } 
     77        /* 
     78         * (non-Javadoc) 
     79         *  
     80         * @see java.lang.Object#clone() 
     81         */ 
     82        @Override 
     83        public synchronized IUserSession clone() { 
     84                UserSession clone = null; 
     85                try { 
     86                        clone = (UserSession) super.clone(); 
    9187 
    92     /* (non-Javadoc) 
    93      * @see java.lang.Object#hashCode() 
    94      */ 
    95     @Override 
    96     public synchronized int hashCode() { 
    97         return super.hashCode(); 
    98     } 
     88                        clone.executedTasks = new LinkedList<ITaskInstance>(); 
    9989 
    100     /* (non-Javadoc) 
    101      * @see java.lang.Object#toString() 
    102      */ 
    103     @Override 
    104     public synchronized String toString() { 
    105         return "session (" + executedTasks.size() + " task instances)"; 
    106     } 
     90                        for (final ITaskInstance child : executedTasks) { 
     91                                clone.executedTasks.add(child.clone()); 
     92                        } 
    10793 
    108     /* (non-Javadoc) 
    109      * @see java.lang.Object#clone() 
    110      */ 
    111     @Override 
    112     public synchronized IUserSession clone() { 
    113         UserSession clone = null; 
    114         try { 
    115             clone = (UserSession) super.clone(); 
     94                } catch (final CloneNotSupportedException e) { 
     95                        // this should never happen. Therefore simply dump the exception 
     96                        e.printStackTrace(); 
     97                } 
    11698 
    117             clone.executedTasks = new LinkedList<ITaskInstance>(); 
    118              
    119             for (ITaskInstance child : executedTasks) { 
    120                 clone.executedTasks.add(child.clone()); 
    121             } 
     99                return clone; 
     100        } 
    122101 
    123         } 
    124         catch (CloneNotSupportedException e) { 
    125             // this should never happen. Therefore simply dump the exception 
    126             e.printStackTrace(); 
    127         } 
     102        /* 
     103         * (non-Javadoc) 
     104         *  
     105         * @see 
     106         * de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession#equals(IUserSession) 
     107         */ 
     108        @Override 
     109        public boolean equals(IUserSession userSession) { 
     110                // task instances are only equal if they are identical or if they have 
     111                // the same id 
     112                // (may happen, if they are cloned) 
     113                return (this == userSession) 
     114                                || (this.hashCode() == userSession.hashCode()); 
     115        } 
    128116 
    129         return clone; 
    130     } 
     117        /* 
     118         * (non-Javadoc) 
     119         *  
     120         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int) 
     121         */ 
     122        @Override 
     123        public ITaskInstance get(int index) { 
     124                return executedTasks.get(index); 
     125        } 
    131126 
    132     /** 
    133      * <p> 
    134      * used internally to add a task instance to the user session 
    135      * </p> 
    136      *  
    137      * @param taskInstance the task instance to be added 
    138      */ 
    139     void addExecutedTask(ITaskInstance taskInstance) { 
    140         executedTasks.add(taskInstance); 
    141     } 
     127        /* 
     128         * (non-Javadoc) 
     129         *  
     130         * @see 
     131         * de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession#getExecutedTasks() 
     132         */ 
     133        @Override 
     134        public List<ITaskInstance> getExecutedTasks() { 
     135                return Collections.unmodifiableList(executedTasks); 
     136        } 
    142137 
    143     /** 
    144      * <p> 
    145      * used internally to add a task instance to the user session at a specific position 
    146      * </p> 
    147      *  
    148      * @param index        the index the task instance shall be added to 
    149      * @param taskInstance the task instance to be added 
    150      */ 
    151     void addExecutedTask(int index, ITaskInstance taskInstance) { 
    152         executedTasks.add(index, taskInstance); 
    153     } 
     138        /* 
     139         * (non-Javadoc) 
     140         *  
     141         * @see java.lang.Object#hashCode() 
     142         */ 
     143        @Override 
     144        public synchronized int hashCode() { 
     145                return super.hashCode(); 
     146        } 
    154147 
    155     /** 
    156      * <p> 
    157      * used internally to remove a task instance from the user session 
    158      * </p> 
    159      *  
    160      * @param index the index of the task instance to be removed 
    161      */ 
    162     void removeExecutedTask(int index) { 
    163         executedTasks.remove(index); 
    164     } 
     148        /* 
     149         * (non-Javadoc) 
     150         *  
     151         * @see java.lang.Iterable#iterator() 
     152         */ 
     153        @Override 
     154        public Iterator<ITaskInstance> iterator() { 
     155                return executedTasks.iterator(); 
     156        } 
     157 
     158        /** 
     159         * <p> 
     160         * used internally to remove a task instance from the user session 
     161         * </p> 
     162         *  
     163         * @param index 
     164         *            the index of the task instance to be removed 
     165         */ 
     166        void removeExecutedTask(int index) { 
     167                executedTasks.remove(index); 
     168        } 
     169 
     170        /* 
     171         * (non-Javadoc) 
     172         *  
     173         * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size() 
     174         */ 
     175        @Override 
     176        public int size() { 
     177                return executedTasks.size(); 
     178        } 
     179 
     180        /* 
     181         * (non-Javadoc) 
     182         *  
     183         * @see java.lang.Object#toString() 
     184         */ 
     185        @Override 
     186        public synchronized String toString() { 
     187                return "session (" + executedTasks.size() + " task instances)"; 
     188        } 
    165189 
    166190} 
Note: See TracChangeset for help on using the changeset viewer.