001: package org.acm.seguin.pmd.cpd;
002:
003: public class TokenEntry implements Comparable {
004:
005: public static final TokenEntry EOF = new TokenEntry();
006: private char[] chars;
007: private int hash;
008: private String image;
009: private int index;
010: private String tokenSrcID;
011: private int beginLine;
012:
013: private int sortCode;
014:
015: private TokenEntry() {
016: this .image = "EOF";
017: this .chars = image.toCharArray();
018: this .tokenSrcID = "EOFMarker";
019: }
020:
021: public TokenEntry(String image, int index, String tokenSrcID,
022: int beginLine) {
023: this .image = image;
024: this .index = index;
025: this .tokenSrcID = tokenSrcID;
026: this .beginLine = beginLine;
027: this .chars = image.toCharArray();
028: }
029:
030: public int getIndex() {
031: return index;
032: }
033:
034: public String getTokenSrcID() {
035: return tokenSrcID;
036: }
037:
038: public int getBeginLine() {
039: return beginLine;
040: }
041:
042: public void setSortCode(int code) {
043: this .sortCode = code;
044: }
045:
046: public boolean equals(Object o) {
047: if (o instanceof TokenEntry) {
048: TokenEntry token = (TokenEntry) o;
049: if (this == EOF) {
050: return token == EOF;
051: }
052: if (token.image.length() != image.length()) {
053: return false;
054: }
055: for (int i = 0; i < image.length(); i++) {
056: if (this .chars[i] != token.chars[i]) {
057: return false;
058: }
059: }
060: return true;
061: }
062: return false;
063: }
064:
065: // calculate a hash, as done in Effective Programming in Java.
066: public int hashCode() {
067: int h = hash;
068: if (h == 0) {
069: if (this == EOF) {
070: h = -1;
071: } else {
072: for (int i = 0; i < image.length(); i++) {
073: h = (37 * h + this .chars[i]);
074: }
075: }
076: hash = h; // single assignment = thread safe hashcode.
077: }
078: return h;
079: }
080:
081: public int compareTo(Object o) {
082: TokenEntry token = (TokenEntry) o;
083: // try to use sort codes if available.
084: if (this == EOF) {
085: if (token == EOF) {
086: return 0;
087: }
088: return -1;
089: }
090: if (this .sortCode > 0 && token.sortCode > 0) {
091: return this .sortCode - token.sortCode;
092: }
093: // otherwise sort lexicographically
094: if (image.length() == token.image.length()) {
095: for (int i = 0; i < image.length()
096: && i < token.image.length(); i++) {
097: char c1 = this .chars[i];
098: char c2 = token.chars[i];
099: if (c1 != c2) {
100: return c1 - c2;
101: }
102: }
103: return 0;
104: }
105: for (int i = 0; i < image.length() && i < token.image.length(); i++) {
106: char c1 = this .chars[i];
107: char c2 = token.chars[i];
108: if (c1 != c2) {
109: return c1 - c2;
110: }
111: }
112: return image.length() - token.image.length();
113: }
114: }
|