KickJava   Java API By Example, From Geeks To Geeks.

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


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.text.*;
14 import org.eclipse.compare.contentmergeviewer.ITokenComparator;
15 import org.eclipse.compare.rangedifferencer.IRangeComparator;
16
17 /**
18  * Implements the <code>IRangeComparator</code> interface for lines in a document.
19  * A <code>DocLineComparator</code> is used as the input for the <code>RangeDifferencer</code>
20  * engine to perform a line oriented compare on documents.
21  * <p>
22  * A <code>DocLineComparator</code> doesn't know anything about line separators because
23  * its notion of lines is solely defined in the underlying <code>IDocument</code>.
24  */

25 public class DocLineComparator implements ITokenComparator {
26
27     private IDocument fDocument;
28     private int fLineOffset;
29     private int fLineCount;
30     private int fLength;
31     private boolean fIgnoreWhiteSpace;
32
33     /**
34      * Creates a <code>DocLineComparator</code> for the given document range.
35      * ignoreWhiteSpace controls whether comparing lines (in method
36      * <code>rangesEqual<code>) should ignore whitespace.
37      *
38      * @param document the document from which the lines are taken
39      * @param region if non-<code>null</code> only lines within this range are taken
40      * @param ignoreWhiteSpace if <code>true</code> white space is ignored when comparing lines
41      */

42     public DocLineComparator(IDocument document, IRegion region, boolean ignoreWhiteSpace) {
43
44         fDocument= document;
45         fIgnoreWhiteSpace= ignoreWhiteSpace;
46
47         fLineOffset= 0;
48         if (region != null) {
49             fLength= region.getLength();
50             int start= region.getOffset();
51             try {
52                 fLineOffset= fDocument.getLineOfOffset(start);
53             } catch (BadLocationException ex) {
54                 // silently ignored
55
}
56
57             if (fLength == 0)
58                 fLineCount= 0;
59             else {
60                 int endLine= fDocument.getNumberOfLines();
61                 try {
62                     endLine= fDocument.getLineOfOffset(start + fLength);
63                 } catch (BadLocationException ex) {
64                     // silently ignored
65
}
66                 fLineCount= endLine - fLineOffset + 1;
67             }
68
69         } else {
70             fLength= document.getLength();
71             fLineCount= fDocument.getNumberOfLines();
72         }
73     }
74
75     /**
76      * Returns the number of lines in the document.
77      *
78      * @return number of lines
79      */

80     public int getRangeCount() {
81         return fLineCount;
82     }
83
84     /* (non Javadoc)
85      * see ITokenComparator.getTokenStart
86      */

87     public int getTokenStart(int line) {
88         try {
89             IRegion r= fDocument.getLineInformation(fLineOffset + line);
90             return r.getOffset();
91         } catch (BadLocationException ex) {
92             return fDocument.getLength();
93         }
94     }
95
96     /* (non Javadoc)
97      * Returns the length of the given line.
98      * see ITokenComparator.getTokenLength
99      */

100     public int getTokenLength(int line) {
101         return getTokenStart(line+1) - getTokenStart(line);
102     }
103
104     /**
105      * Returns <code>true</code> if a line given by the first index
106      * matches a line specified by the other <code>IRangeComparator</code> and index.
107      *
108      * @param thisIndex the number of the line within this range comparator
109      * @param otherComparator the range comparator to compare this with
110      * @param otherIndex the number of the line within the other comparator
111      * @return <code>true</code> if the lines are equal
112      */

113     public boolean rangesEqual(int thisIndex, IRangeComparator otherComparator, int otherIndex) {
114
115         if (otherComparator != null && otherComparator.getClass() == getClass()) {
116             DocLineComparator other= (DocLineComparator) otherComparator;
117
118             if (fIgnoreWhiteSpace) {
119                 String JavaDoc s1= extract(thisIndex);
120                 String JavaDoc s2= other.extract(otherIndex);
121                 //return s1.trim().equals(s2.trim());
122
return compare(s1, s2);
123             }
124
125             int tlen= getTokenLength(thisIndex);
126             int olen= other.getTokenLength(otherIndex);
127             if (tlen == olen) {
128                 String JavaDoc s1= extract(thisIndex);
129                 String JavaDoc s2= other.extract(otherIndex);
130                 return s1.equals(s2);
131             }
132         }
133         return false;
134     }
135
136     /**
137      * Aborts the comparison if the number of tokens is too large.
138      *
139      * @param length a number on which to base the decision whether to return
140      * <code>true</code> or <code>false</code>
141      * @param maxLength another number on which to base the decision whether to return
142      * <code>true</code> or <code>false</code>
143      * @param other the other <code>IRangeComparator</code> to compare with
144      * @return <code>true</code> to avoid a too lengthy range comparison
145      */

146     public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) {
147         return false;
148     }
149         
150     //---- private methods
151

152     /**
153      * Extract a single line from the underlying document without the line separator.
154      *
155      * @param line the number of the line to extract
156      * @return the contents of the line as a String
157      */

158     private String JavaDoc extract(int line) {
159         if (line < fLineCount) {
160             try {
161                 IRegion r= fDocument.getLineInformation(fLineOffset + line);
162                 return fDocument.get(r.getOffset(), r.getLength());
163             } catch(BadLocationException e) {
164                 // silently ignored
165
}
166         }
167         return ""; //$NON-NLS-1$
168
}
169     
170     private boolean compare(String JavaDoc s1, String JavaDoc s2) {
171         int l1= s1.length();
172         int l2= s2.length();
173         int c1= 0, c2= 0;
174         int i1= 0, i2= 0;
175         
176         while (c1 != -1) {
177             
178             c1= -1;
179             while (i1 < l1) {
180                 char c= s1.charAt(i1++);
181                 if (! Character.isWhitespace(c)) {
182                     c1= c;
183                     break;
184                 }
185             }
186             
187             c2= -1;
188             while (i2 < l2) {
189                 char c= s2.charAt(i2++);
190                 if (! Character.isWhitespace(c)) {
191                     c2= c;
192                     break;
193                 }
194             }
195                 
196             if (c1 != c2)
197                 return false;
198         }
199         return true;
200     }
201 }
202
203
Popular Tags