001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2011 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020
021 /**
022 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
023 */
024 package org.sonar.duplications.cpd;
025
026 import java.util.Comparator;
027 import java.util.Iterator;
028 import java.util.Set;
029 import java.util.TreeSet;
030
031 import net.sourceforge.pmd.cpd.TokenEntry;
032
033 public class Match implements Comparable<Match> {
034
035 public static final String EOL = System.getProperty("line.separator", "\n");
036
037 private int tokenCount;
038 private int lineCount;
039 private Set<TokenEntry> markSet = new TreeSet<TokenEntry>();
040 private TokenEntry[] marks = new TokenEntry[2];
041 private String code;
042 private MatchCode mc;
043 private String label;
044
045 public static final Comparator<Match> MatchesComparator = new Comparator<Match>() {
046
047 public int compare(Match ma, Match mb) {
048 return mb.getMarkCount() - ma.getMarkCount();
049 }
050 };
051
052 public static final Comparator<Match> LinesComparator = new Comparator<Match>() {
053
054 public int compare(Match ma, Match mb) {
055 return mb.getLineCount() - ma.getLineCount();
056 }
057 };
058
059 public static final Comparator<Match> LabelComparator = new Comparator<Match>() {
060
061 public int compare(Match ma, Match mb) {
062 if (ma.getLabel() == null)
063 return 1;
064 if (mb.getLabel() == null)
065 return -1;
066 return mb.getLabel().compareTo(ma.getLabel());
067 }
068 };
069
070 public static final Comparator<Match> LengthComparator = new Comparator<Match>() {
071
072 public int compare(Match ma, Match mb) {
073 return mb.getLineCount() - ma.getLineCount();
074 }
075 };
076
077 public static class MatchCode {
078
079 private int first;
080 private int second;
081
082 public MatchCode() {
083 }
084
085 public MatchCode(TokenEntry m1, TokenEntry m2) {
086 first = m1.getIndex();
087 second = m2.getIndex();
088 }
089
090 public int hashCode() {
091 return first + 37 * second;
092 }
093
094 public boolean equals(Object other) {
095 MatchCode mc = (MatchCode) other;
096 return mc.first == first && mc.second == second;
097 }
098
099 public void setFirst(int first) {
100 this.first = first;
101 }
102
103 public void setSecond(int second) {
104 this.second = second;
105 }
106
107 }
108
109 public Match(int tokenCount, TokenEntry first, TokenEntry second) {
110 markSet.add(first);
111 markSet.add(second);
112 marks[0] = first;
113 marks[1] = second;
114 this.tokenCount = tokenCount;
115 }
116
117 public int getMarkCount() {
118 return markSet.size();
119 }
120
121 public void setLineCount(int lineCount) {
122 this.lineCount = lineCount;
123 }
124
125 public int getLineCount() {
126 return this.lineCount;
127 }
128
129 public int getTokenCount() {
130 return this.tokenCount;
131 }
132
133 public String getSourceCodeSlice() {
134 return this.code;
135 }
136
137 public void setSourceCodeSlice(String code) {
138 this.code = code;
139 }
140
141 public Iterator<TokenEntry> iterator() {
142 return markSet.iterator();
143 }
144
145 public int compareTo(Match other) {
146 int diff = other.getTokenCount() - getTokenCount();
147 if (diff != 0) {
148 return diff;
149 }
150 return other.getFirstMark().getIndex() - getFirstMark().getIndex();
151 }
152
153 public TokenEntry getFirstMark() {
154 return marks[0];
155 }
156
157 public TokenEntry getSecondMark() {
158 return marks[1];
159 }
160
161 public String toString() {
162 return "Match: " + EOL + "tokenCount = " + tokenCount + EOL + "marks = " + markSet.size();
163 }
164
165 public Set<TokenEntry> getMarkSet() {
166 return markSet;
167 }
168
169 public MatchCode getMatchCode() {
170 if (mc == null) {
171 mc = new MatchCode(marks[0], marks[1]);
172 }
173 return mc;
174 }
175
176 public int getEndIndex() {
177 return marks[1].getIndex() + getTokenCount() - 1;
178 }
179
180 public void setMarkSet(Set<TokenEntry> markSet) {
181 this.markSet = markSet;
182 }
183
184 public void setLabel(String aLabel) {
185 label = aLabel;
186 }
187
188 public String getLabel() {
189 return label;
190 }
191 }