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 }