1
2
3
4 package net.sourceforge.pmd.cpd;
5
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.concurrent.atomic.AtomicInteger;
11
12 public class TokenEntry implements Comparable<TokenEntry> {
13
14 public static final TokenEntry EOF = new TokenEntry();
15
16 private String tokenSrcID;
17 private int beginLine;
18 private int index;
19 private int identifier;
20 private int hashCode;
21
22 private static ThreadLocal<Map<String, Integer>> TOKENS = new ThreadLocal<Map<String, Integer>>(){
23 @Override
24 protected Map<String, Integer> initialValue() {
25 return new HashMap<String, Integer>();
26 }
27 };
28 private static ThreadLocal<AtomicInteger> tokenCount = new ThreadLocal<AtomicInteger>(){
29 @Override
30 protected AtomicInteger initialValue() {
31 return new AtomicInteger(0);
32 }
33 };
34
35 private TokenEntry() {
36 this.identifier = 0;
37 this.tokenSrcID = "EOFMarker";
38 }
39
40 public TokenEntry(String image, String tokenSrcID, int beginLine) {
41 Integer i = TOKENS.get().get(image);
42 if (i == null) {
43 i = TOKENS.get().size() + 1;
44 TOKENS.get().put(image, i);
45 }
46 this.identifier = i.intValue();
47 this.tokenSrcID = tokenSrcID;
48 this.beginLine = beginLine;
49 this.index = tokenCount.get().getAndIncrement();
50 }
51
52 public static TokenEntry getEOF() {
53 tokenCount.get().getAndIncrement();
54 return EOF;
55 }
56
57 public static void clearImages() {
58 TOKENS.get().clear();
59 TOKENS.remove();
60 tokenCount.remove();
61 }
62
63
64
65
66 public static class State {
67 private int tokenCount;
68 private Map<String, Integer> tokens;
69 private List<TokenEntry> entries;
70 public State(List<TokenEntry> entries) {
71 this.tokenCount = TokenEntry.tokenCount.get().intValue();
72 this.tokens = new HashMap<String, Integer>(TokenEntry.TOKENS.get());
73 this.entries = new ArrayList<TokenEntry>(entries);
74 }
75 public List<TokenEntry> restore() {
76 TokenEntry.tokenCount.get().set(tokenCount);
77 TOKENS.get().clear();
78 TOKENS.get().putAll(tokens);
79 return entries;
80 }
81 }
82
83 public String getTokenSrcID() {
84 return tokenSrcID;
85 }
86
87 public int getBeginLine() {
88 return beginLine;
89 }
90
91 public int getIdentifier() {
92 return this.identifier;
93 }
94
95 public int getIndex() {
96 return this.index;
97 }
98
99 public int hashCode() {
100 return hashCode;
101 }
102
103 public void setHashCode(int hashCode) {
104 this.hashCode = hashCode;
105 }
106
107 public boolean equals(Object o) {
108 if (!(o instanceof TokenEntry)) {
109 return false;
110 }
111 TokenEntry other = (TokenEntry) o;
112 return other.hashCode == hashCode;
113 }
114
115 public int compareTo(TokenEntry other) {
116 return getIndex() - other.getIndex();
117 }
118
119 @Override
120 public String toString() {
121 if (this == EOF) {
122 return "EOF";
123 }
124 for (Map.Entry<String, Integer> e : TOKENS.get().entrySet()) {
125 if (e.getValue().intValue() == identifier) {
126 return e.getKey();
127 }
128 }
129 return "--unkown--";
130 }
131 }