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 }