KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > internal > TokenComparator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.compare.internal;
12
13 import org.eclipse.jface.util.Assert;
14
15 import org.eclipse.compare.rangedifferencer.IRangeComparator;
16 import org.eclipse.compare.contentmergeviewer.ITokenComparator;
17
18 /**
19  * Implements the <code>ITokenComparator</code> interface for words (or tokens)
20  * in a string.
21  * A <code>TokenComparator</code> is used as the input for the <code>RangeDifferencer</code>
22  * engine to perform a token oriented compare on strings.
23  */

24 public class TokenComparator implements ITokenComparator {
25
26     private boolean fShouldEscape= true;
27     private String JavaDoc fText;
28     private int fCount;
29     private int[] fStarts;
30     private int[] fLengths;
31
32     /**
33      * Creates a <code>TokenComparator</code> for the given string.
34      *
35      * @param text the string that is split into token
36      */

37     public TokenComparator(String JavaDoc text) {
38         
39         Assert.isNotNull(text);
40
41         fText= text;
42         
43         int length= fText.length();
44         fStarts= new int[length]; // pessimistic assumption!
45
fLengths= new int[length];
46         fCount= 0;
47         
48         char lastCategory= 0; // 0: no category
49
for (int i= 0; i < length; i++) {
50             char c= fText.charAt(i);
51             
52             char category= '?'; // unspecified category
53
if (Character.isWhitespace(c))
54                 category= ' '; // white space category
55
else if (Character.isDigit(c))
56                 category= '0'; // digits
57
else if (Character.isLetter(c))
58                 category= 'a'; // letters
59

60             if (category != lastCategory) {
61                 // start a new token
62
fStarts[fCount++]= i;
63                 lastCategory= category;
64             }
65             fLengths[fCount-1]++;
66         }
67     }
68     
69     /**
70      * Creates a <code>TokenComparator</code> for the given string.
71      *
72      * @param text the string that is split into token
73      * @param shouldEscape
74      */

75     public TokenComparator(String JavaDoc text, boolean shouldEscape) {
76         this(text);
77         fShouldEscape= shouldEscape;
78     }
79
80     /**
81      * Returns the number of token in the string.
82      *
83      * @return number of token in the string
84      */

85     public int getRangeCount() {
86         return fCount;
87     }
88
89     /* (non Javadoc)
90      * see ITokenComparator.getTokenStart
91      */

92     public int getTokenStart(int index) {
93         if (index < fCount)
94             return fStarts[index];
95         return fText.length();
96     }
97
98     /* (non Javadoc)
99      * see ITokenComparator.getTokenLength
100      */

101     public int getTokenLength(int index) {
102         if (index < fCount)
103             return fLengths[index];
104         return 0;
105     }
106         
107     /**
108      * Returns <code>true</code> if a token given by the first index
109      * matches a token specified by the other <code>IRangeComparator</code> and index.
110      *
111      * @param thisIndex the number of the token within this range comparator
112      * @param other the range comparator to compare this with
113      * @param otherIndex the number of the token within the other comparator
114      * @return <code>true</code> if the token are equal
115      */

116     public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) {
117         if (other != null && getClass() == other.getClass()) {
118             TokenComparator tc= (TokenComparator) other;
119             int thisLen= getTokenLength(thisIndex);
120             int otherLen= tc.getTokenLength(otherIndex);
121             if (thisLen == otherLen)
122                 return fText.regionMatches(false, getTokenStart(thisIndex), tc.fText, tc.getTokenStart(otherIndex), thisLen);
123         }
124         return false;
125     }
126
127     /*
128      * Aborts the comparison if the number of tokens is too large.
129      * @return <code>true</code> to abort a token comparison
130      */

131     public boolean skipRangeComparison(int length, int max, IRangeComparator other) {
132
133         if (!fShouldEscape)
134             return false;
135
136         if (getRangeCount() < 50 || other.getRangeCount() < 50)
137             return false;
138
139         if (max < 100)
140             return false;
141
142         if (length < 100)
143             return false;
144
145         if (max > 800)
146             return true;
147
148         if (length < max / 4)
149             return false;
150
151         return true;
152     }
153         
154 // public static void main(String args[]) {
155
// //String in= "private static boolean isWhitespace(char c) {";
156
// //String in= "for (int j= 0; j < l-1; j++) {";
157
// String in= "for do i= 123; i++";
158
// TokenComparator tc= new TokenComparator(in, false);
159
//
160
// System.out.println("n: " + tc.getRangeCount());
161
// System.out.println(in);
162
//
163
// int p= 0;
164
// for (int i= 0; i < tc.getRangeCount(); i++) {
165
// int l= tc.getTokenLength(i);
166
// System.out.print("<");
167
//
168
// for (int j= 0; j < l-1; j++)
169
// System.out.print(" ");
170
// }
171
// System.out.println();
172
//
173
// //System.out.println("extract: <" + tc.extract(16, 1) + ">");
174
// }
175
}
176
Popular Tags