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 }