1d70768f027fd1402e909e3309351a7c1f77f9e3
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / JavaWordIterator.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text;
12
13 import java.text.BreakIterator;
14 import java.text.CharacterIterator;
15
16 //incastrix
17 //import org.eclipse.jface.text.Assert;
18 import org.eclipse.core.runtime.Assert;
19
20 /**
21  * Breaks java text into word starts, also stops at line start and end. No
22  * direction dependency.
23  * 
24  * @since 3.0
25  */
26 public class JavaWordIterator extends BreakIterator {
27
28         /**
29          * The underlying java break iterator. It returns all breaks, including
30          * before and after every whitespace.
31          */
32         private JavaBreakIterator fIterator;
33
34         /** The current index for the stateful operations. */
35         private int fIndex;
36
37         /**
38          * Creates a new word iterator.
39          */
40         public JavaWordIterator() {
41                 fIterator = new JavaBreakIterator();
42                 first();
43         }
44
45         /*
46          * @see java.text.BreakIterator#first()
47          */
48         public int first() {
49                 fIndex = fIterator.first();
50                 return fIndex;
51         }
52
53         /*
54          * @see java.text.BreakIterator#last()
55          */
56         public int last() {
57                 fIndex = fIterator.last();
58                 return fIndex;
59         }
60
61         /*
62          * @see java.text.BreakIterator#next(int)
63          */
64         public int next(int n) {
65                 int next = 0;
66                 while (--n > 0 && next != DONE) {
67                         next = next();
68                 }
69                 return next;
70         }
71
72         /*
73          * @see java.text.BreakIterator#next()
74          */
75         public int next() {
76                 fIndex = following(fIndex);
77                 return fIndex;
78         }
79
80         /*
81          * @see java.text.BreakIterator#previous()
82          */
83         public int previous() {
84                 fIndex = preceding(fIndex);
85                 return fIndex;
86         }
87
88         /*
89          * @see java.text.BreakIterator#preceding(int)
90          */
91         public int preceding(int offset) {
92                 int first = fIterator.preceding(offset);
93                 if (isWhitespace(first, offset)) {
94                         int second = fIterator.preceding(first);
95                         if (second != DONE && !isDelimiter(second, first))
96                                 return second;
97                 }
98                 return first;
99         }
100
101         /*
102          * @see java.text.BreakIterator#following(int)
103          */
104         public int following(int offset) {
105                 int first = fIterator.following(offset);
106                 if (eatFollowingWhitespace(offset, first)) {
107                         int second = fIterator.following(first);
108                         if (isWhitespace(first, second))
109                                 return second;
110                 }
111                 return first;
112         }
113
114         private boolean eatFollowingWhitespace(int offset, int exclusiveEnd) {
115                 if (exclusiveEnd == DONE || offset == DONE)
116                         return false;
117
118                 if (isWhitespace(offset, exclusiveEnd))
119                         return false;
120                 if (isDelimiter(offset, exclusiveEnd))
121                         return false;
122
123                 return true;
124         }
125
126         /**
127          * Returns <code>true</code> if the given sequence into the underlying
128          * text represents a delimiter, <code>false</code> otherwise.
129          * 
130          * @param offset
131          *            the offset
132          * @param exclusiveEnd
133          *            the end offset
134          * @return <code>true</code> if the given range is a delimiter
135          */
136         private boolean isDelimiter(int offset, int exclusiveEnd) {
137                 if (exclusiveEnd == DONE || offset == DONE)
138                         return false;
139
140                 Assert.isTrue(offset >= 0);
141                 Assert.isTrue(exclusiveEnd <= getText().getEndIndex());
142                 Assert.isTrue(exclusiveEnd > offset);
143
144                 CharSequence seq = fIterator.fText;
145
146                 while (offset < exclusiveEnd) {
147                         char ch = seq.charAt(offset);
148                         if (ch != '\n' && ch != '\r')
149                                 return false;
150                         offset++;
151                 }
152
153                 return true;
154         }
155
156         /**
157          * Returns <code>true</code> if the given sequence into the underlying
158          * text represents whitespace, but not a delimiter, <code>false</code>
159          * otherwise.
160          * 
161          * @param offset
162          *            the offset
163          * @param exclusiveEnd
164          *            the end offset
165          * @return <code>true</code> if the given range is whitespace
166          */
167         private boolean isWhitespace(int offset, int exclusiveEnd) {
168                 if (exclusiveEnd == DONE || offset == DONE)
169                         return false;
170
171                 Assert.isTrue(offset >= 0);
172                 Assert.isTrue(exclusiveEnd <= getText().getEndIndex());
173                 Assert.isTrue(exclusiveEnd > offset);
174
175                 CharSequence seq = fIterator.fText;
176
177                 while (offset < exclusiveEnd) {
178                         char ch = seq.charAt(offset);
179                         if (!Character.isWhitespace(ch))
180                                 return false;
181                         if (ch == '\n' || ch == '\r')
182                                 return false;
183                         offset++;
184                 }
185
186                 return true;
187         }
188
189         /*
190          * @see java.text.BreakIterator#current()
191          */
192         public int current() {
193                 return fIndex;
194         }
195
196         /*
197          * @see java.text.BreakIterator#getText()
198          */
199         public CharacterIterator getText() {
200                 return fIterator.getText();
201         }
202
203         /**
204          * Sets the text as <code>CharSequence</code>.
205          * 
206          * @param newText
207          *            the new text
208          */
209         public void setText(CharSequence newText) {
210                 fIterator.setText(newText);
211                 first();
212         }
213
214         /*
215          * @see java.text.BreakIterator#setText(java.text.CharacterIterator)
216          */
217         public void setText(CharacterIterator newText) {
218                 fIterator.setText(newText);
219                 first();
220         }
221
222         /*
223          * @see java.text.BreakIterator#setText(java.lang.String)
224          */
225         public void setText(String newText) {
226                 setText((CharSequence) newText);
227         }
228
229 }