001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 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 net.sourceforge.pmd.cpd.TokenEntry;
027    
028    import java.util.Comparator;
029    import java.util.Iterator;
030    import java.util.Set;
031    import java.util.TreeSet;
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          }
065          if (mb.getLabel() == null) {
066            return -1;
067          }
068          return mb.getLabel().compareTo(ma.getLabel());
069        }
070      };
071    
072      public static final Comparator<Match> LengthComparator = new Comparator<Match>() {
073    
074        public int compare(Match ma, Match mb) {
075          return mb.getLineCount() - ma.getLineCount();
076        }
077      };
078    
079      public static class MatchCode {
080    
081        private int first;
082        private int second;
083    
084        public MatchCode() {
085        }
086    
087        public MatchCode(TokenEntry m1, TokenEntry m2) {
088          first = m1.getIndex();
089          second = m2.getIndex();
090        }
091    
092        @Override
093        public int hashCode() {
094          return first + 37 * second;
095        }
096    
097        @Override
098        public boolean equals(Object other) {
099          if (!(other instanceof MatchCode)) {
100            return false;
101          }
102          MatchCode mc = (MatchCode) other;
103          return mc.first == first && mc.second == second;
104        }
105    
106        public void setFirst(int first) {
107          this.first = first;
108        }
109    
110        public void setSecond(int second) {
111          this.second = second;
112        }
113    
114      }
115    
116      public Match(int tokenCount, TokenEntry first, TokenEntry second) {
117        markSet.add(first);
118        markSet.add(second);
119        marks[0] = first;
120        marks[1] = second;
121        this.tokenCount = tokenCount;
122      }
123    
124      public int getMarkCount() {
125        return markSet.size();
126      }
127    
128      public void setLineCount(int lineCount) {
129        this.lineCount = lineCount;
130      }
131    
132      public int getLineCount() {
133        return this.lineCount;
134      }
135    
136      public int getTokenCount() {
137        return this.tokenCount;
138      }
139    
140      public String getSourceCodeSlice() {
141        return this.code;
142      }
143    
144      public void setSourceCodeSlice(String code) {
145        this.code = code;
146      }
147    
148      public Iterator<TokenEntry> iterator() {
149        return markSet.iterator();
150      }
151    
152      public int compareTo(Match other) {
153        int diff = other.getTokenCount() - getTokenCount(); // NOSONAR Bad practice - Class defines compareTo(...) and uses Object.equals()
154        if (diff != 0) {
155          return diff;
156        }
157        return other.getFirstMark().getIndex() - getFirstMark().getIndex();
158      }
159    
160      public TokenEntry getFirstMark() {
161        return marks[0];
162      }
163    
164      public TokenEntry getSecondMark() {
165        return marks[1];
166      }
167    
168      @Override
169      public String toString() {
170        return "Match: " + EOL + "tokenCount = " + tokenCount + EOL + "marks = " + markSet.size();
171      }
172    
173      public Set<TokenEntry> getMarkSet() {
174        return markSet;
175      }
176    
177      public MatchCode getMatchCode() {
178        if (mc == null) {
179          mc = new MatchCode(marks[0], marks[1]);
180        }
181        return mc;
182      }
183    
184      public int getEndIndex() {
185        return marks[1].getIndex() + getTokenCount() - 1;
186      }
187    
188      public void setMarkSet(Set<TokenEntry> markSet) {
189        this.markSet = markSet;
190      }
191    
192      public void setLabel(String aLabel) {
193        label = aLabel;
194      }
195    
196      public String getLabel() {
197        return label;
198      }
199    }