001    /**
002     * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003     */
004    package org.sonar.duplications.cpd;
005    
006    import java.util.Comparator;
007    import java.util.Iterator;
008    import java.util.Set;
009    import java.util.TreeSet;
010    
011    import net.sourceforge.pmd.cpd.TokenEntry;
012    
013    public class Match implements Comparable<Match> {
014    
015      public static final String EOL = System.getProperty("line.separator", "\n");
016    
017      private int tokenCount;
018      private int lineCount;
019      private Set<TokenEntry> markSet = new TreeSet<TokenEntry>();
020      private TokenEntry[] marks = new TokenEntry[2];
021      private String code;
022      private MatchCode mc;
023      private String label;
024    
025      public static final Comparator<Match> MatchesComparator = new Comparator<Match>() {
026    
027        public int compare(Match ma, Match mb) {
028          return mb.getMarkCount() - ma.getMarkCount();
029        }
030      };
031    
032      public static final Comparator<Match> LinesComparator = new Comparator<Match>() {
033    
034        public int compare(Match ma, Match mb) {
035          return mb.getLineCount() - ma.getLineCount();
036        }
037      };
038    
039      public static final Comparator<Match> LabelComparator = new Comparator<Match>() {
040    
041        public int compare(Match ma, Match mb) {
042          if (ma.getLabel() == null)
043            return 1;
044          if (mb.getLabel() == null)
045            return -1;
046          return mb.getLabel().compareTo(ma.getLabel());
047        }
048      };
049    
050      public static final Comparator<Match> LengthComparator = new Comparator<Match>() {
051    
052        public int compare(Match ma, Match mb) {
053          return mb.getLineCount() - ma.getLineCount();
054        }
055      };
056    
057      public static class MatchCode {
058    
059        private int first;
060        private int second;
061    
062        public MatchCode() {
063        }
064    
065        public MatchCode(TokenEntry m1, TokenEntry m2) {
066          first = m1.getIndex();
067          second = m2.getIndex();
068        }
069    
070        public int hashCode() {
071          return first + 37 * second;
072        }
073    
074        public boolean equals(Object other) {
075          MatchCode mc = (MatchCode) other;
076          return mc.first == first && mc.second == second;
077        }
078    
079        public void setFirst(int first) {
080          this.first = first;
081        }
082    
083        public void setSecond(int second) {
084          this.second = second;
085        }
086    
087      }
088    
089      public Match(int tokenCount, TokenEntry first, TokenEntry second) {
090        markSet.add(first);
091        markSet.add(second);
092        marks[0] = first;
093        marks[1] = second;
094        this.tokenCount = tokenCount;
095      }
096    
097      public int getMarkCount() {
098        return markSet.size();
099      }
100    
101      public void setLineCount(int lineCount) {
102        this.lineCount = lineCount;
103      }
104    
105      public int getLineCount() {
106        return this.lineCount;
107      }
108    
109      public int getTokenCount() {
110        return this.tokenCount;
111      }
112    
113      public String getSourceCodeSlice() {
114        return this.code;
115      }
116    
117      public void setSourceCodeSlice(String code) {
118        this.code = code;
119      }
120    
121      public Iterator<TokenEntry> iterator() {
122        return markSet.iterator();
123      }
124    
125      public int compareTo(Match other) {
126        int diff = other.getTokenCount() - getTokenCount();
127        if (diff != 0) {
128          return diff;
129        }
130        return other.getFirstMark().getIndex() - getFirstMark().getIndex();
131      }
132    
133      public TokenEntry getFirstMark() {
134        return marks[0];
135      }
136    
137      public TokenEntry getSecondMark() {
138        return marks[1];
139      }
140    
141      public String toString() {
142        return "Match: " + EOL + "tokenCount = " + tokenCount + EOL + "marks = " + markSet.size();
143      }
144    
145      public Set<TokenEntry> getMarkSet() {
146        return markSet;
147      }
148    
149      public MatchCode getMatchCode() {
150        if (mc == null) {
151          mc = new MatchCode(marks[0], marks[1]);
152        }
153        return mc;
154      }
155    
156      public int getEndIndex() {
157        return marks[1].getIndex() + getTokenCount() - 1;
158      }
159    
160      public void setMarkSet(Set<TokenEntry> markSet) {
161        this.markSet = markSet;
162      }
163    
164      public void setLabel(String aLabel) {
165        label = aLabel;
166      }
167    
168      public String getLabel() {
169        return label;
170      }
171    }