01: package org.acm.seguin.pmd.cpd;
02:
03: import java.util.ArrayList;
04: import java.util.Collections;
05: import java.util.Iterator;
06: import java.util.List;
07: import java.util.Map;
08: import java.util.TreeMap;
09:
10: public class MatchAlgorithm {
11:
12: private Map pool = new TreeMap();
13: private List code = new ArrayList();
14: private List marks = new ArrayList();
15: private List matches;
16: private Map source;
17: private Tokens tokens;
18: private CPDListener cpdListener;
19:
20: public MatchAlgorithm(Map sourceCode, Tokens tokens) {
21: this .source = sourceCode;
22: this .tokens = tokens;
23: for (Iterator i = tokens.iterator(); i.hasNext();) {
24: add((TokenEntry) i.next());
25: }
26: }
27:
28: public void setListener(CPDListener listener) {
29: this .cpdListener = listener;
30: }
31:
32: public void add(TokenEntry token) {
33: if (!pool.containsKey(token)) {
34: pool.put(token, token);
35: }
36: code.add(pool.get(token));
37: if (!(token.equals(TokenEntry.EOF))) {
38: marks.add(new Mark(code.size(), token.getTokenSrcID(),
39: token.getIndex(), token.getBeginLine()));
40: }
41: }
42:
43: public void findMatches(int min) {
44: /*
45: Assign sort codes to all the pooled code. This should speed
46: up sorting them.
47: */
48: int count = 1;
49: for (Iterator iter = pool.keySet().iterator(); iter.hasNext();) {
50: TokenEntry token = (TokenEntry) iter.next();
51: token.setSortCode(count++);
52: }
53:
54: MarkComparator mc = new MarkComparator(cpdListener, code);
55: Collections.sort(marks, mc);
56:
57: MatchCollector coll = new MatchCollector(marks, mc);
58: matches = coll.collect(min);
59: Collections.sort(matches);
60:
61: for (Iterator i = matches(); i.hasNext();) {
62: Match match = (Match) i.next();
63: for (Iterator occurrences = match.iterator(); occurrences
64: .hasNext();) {
65: Mark mark = (Mark) occurrences.next();
66: match.setLineCount(tokens.getLineCount(mark, match));
67: if (!occurrences.hasNext()) {
68: int start = mark.getBeginLine();
69: int end = start + match.getLineCount() - 1;
70: SourceCode sourceCode = (SourceCode) source
71: .get(mark.getTokenSrcID());
72: match.setSourceCodeSlice(sourceCode.getSlice(start,
73: end));
74: }
75: }
76: }
77: }
78:
79: public Iterator matches() {
80: return matches.iterator();
81: }
82: }
|