KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > editor > util > CharSequenceUtilities


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.editor.util;
21
22 /**
23  * Utility methods related to character sequences.
24  *
25  * @author Miloslav Metelka
26  * @version 1.00
27  */

28
29 public final class CharSequenceUtilities {
30
31     private CharSequenceUtilities() {
32         // no instances
33
}
34
35     /**
36      * Compute {@link String}-like hashcode over given {@link CharSequence}.
37      *
38      * @param text character sequence for which the hashcode is being computed.
39      * @return hashcode of the given character sequence.
40      */

41     public static int stringLikeHashCode(CharSequence JavaDoc text) {
42         int len = text.length();
43
44         int h = 0;
45         for (int i = 0; i < len; i++) {
46             h = 31 * h + text.charAt(i);
47         }
48         return h;
49     }
50
51     /**
52      * Method that compares a given character sequence to another object.
53      * The match is successful if the other object is a character sequence as well
54      * and both character sequences contain the same characters.
55      *
56      * @param text character sequence being compared to the given object.
57      * It must not be <code>null</code>.
58      * @param o object to be compared to the character sequence.
59      * It can be <code>null</code>.
60      * @return true if both parameters are non-null
61      * and they are equal in String-like manner.
62      */

63     public static boolean equals(CharSequence JavaDoc text, Object JavaDoc o) {
64         if (text == o) {
65             return true;
66         }
67
68         if (o instanceof CharSequence JavaDoc) { // both non-null
69
CharSequence JavaDoc text2 = (CharSequence JavaDoc)o;
70             int len = text.length();
71             if (len == text2.length()) {
72                 for (int i = len - 1; i >= 0; i--) {
73                     if (text.charAt(i) != text2.charAt(i)) {
74                         return false;
75                     }
76                 }
77                 return true;
78             }
79         }
80         return false;
81     }
82     
83     /**
84      * Test whether whether the given character sequences
85      * represent the same text.
86      * <br>
87      * The match is successful if the contained characters
88      * of the two character sequences are the same.
89      *
90      * @param text1 first character sequence being compared.
91      * It must not be <code>null</code>.
92      * @param text2 second character sequence being compared.
93      * It must not be <code>null</code>.
94      * @return true if both parameters are equal in String-like manner.
95      */

96     public static boolean textEquals(CharSequence JavaDoc text1, CharSequence JavaDoc text2) {
97         if (text1 == text2) {
98             return true;
99         }
100         int len = text1.length();
101         if (len == text2.length()) {
102             for (int i = len - 1; i >= 0; i--) {
103                 if (text1.charAt(i) != text2.charAt(i)) {
104                     return false;
105                 }
106             }
107             return true;
108         }
109         return false;
110     }
111     
112     /**
113      * Create a string from the given character sequence by first creating
114      * a <code>StringBuilder</code> and appending the whole character sequence
115      * to it.
116      * <br>
117      * The method does not call <code>toString()</code> on the given character
118      * sequence.
119      *
120      * @param text character sequence for which the <code>String</code> form
121      * should be created.
122      * @return string representation of the character sequence.
123      */

124     public static String JavaDoc toString(CharSequence JavaDoc text) {
125         StringBuilder JavaDoc sb = new StringBuilder JavaDoc(text.length());
126         sb.append(text);
127         return sb.toString();
128     }
129
130     /**
131      * Create string for the given portion of the character sequence.
132      *
133      * @param text non-null text.
134      * @param start >=0 and <text.length() index of the first character
135      * to be present in the returned string.
136      * @param end >=start and <text.length() index after the last character
137      * to be present in the returned string.
138      */

139     public static String JavaDoc toString(CharSequence JavaDoc text, int start, int end) {
140         checkIndexesValid(text, start, end);
141         StringBuilder JavaDoc sb = new StringBuilder JavaDoc(end - start);
142         sb.append(text, start, end);
143         return sb.toString();
144     }
145     
146     /**
147      * Append character sequence to the given string buffer.
148      * <br/>
149      * This method is no longer needed in JDK 1.5 where the implementation
150      * does not create an extra java.lang.String instance.
151      */

152     public static void append(StringBuffer JavaDoc sb, CharSequence JavaDoc text) {
153         sb.append(text); // Only assume to run on 1.5
154
}
155     
156     /**
157      * Append part of the character sequence to the given string buffer.
158      * <br/>
159      * This method is no longer needed in JDK 1.5 where the implementation
160      * of the same functionality is available in the StringBuffer directly.
161      */

162     public static void append(StringBuffer JavaDoc sb, CharSequence JavaDoc text, int start, int end) {
163         checkIndexesValid(text, start, end);
164         while (start < end) {
165             sb.append(text.charAt(start++));
166         }
167     }
168
169     /**
170      * Implementation of {@link String#indexOf(int)} for character sequences.
171      */

172     public static int indexOf(CharSequence JavaDoc text, int ch) {
173     return indexOf(text, ch, 0);
174     }
175
176     /**
177      * Implementation of {@link String#indexOf(int,int)} for character sequences.
178      */

179     public static int indexOf(CharSequence JavaDoc text, int ch, int fromIndex) {
180     int length = text.length();
181     while (fromIndex < length) {
182         if (text.charAt(fromIndex) == ch) {
183         return fromIndex;
184         }
185             fromIndex++;
186     }
187     return -1;
188     }
189     
190     /**
191      * Implementation of {@link String#indexOf(String)} for character sequences.
192      */

193     public static int indexOf(CharSequence JavaDoc text, CharSequence JavaDoc seq) {
194         return indexOf(text, seq, 0);
195     }
196     
197     /**
198      * Implementation of {@link String#indexOf(String,int)} for character sequences.
199      */

200     public static int indexOf(CharSequence JavaDoc text, CharSequence JavaDoc seq, int fromIndex) {
201         int textLength = text.length();
202         int seqLength = seq.length();
203     if (fromIndex >= textLength) {
204             return (seqLength == 0 ? textLength : -1);
205     }
206         if (fromIndex < 0) {
207             fromIndex = 0;
208         }
209     if (seqLength == 0) {
210         return fromIndex;
211     }
212
213         char first = seq.charAt(0);
214         int max = textLength - seqLength;
215
216         for (int i = fromIndex; i <= max; i++) {
217             // look for first character
218
if (text.charAt(i) != first) {
219                 while (++i <= max && text.charAt(i) != first);
220             }
221
222             // found first character, now look at the rest of seq
223
if (i <= max) {
224                 int j = i + 1;
225                 int end = j + seqLength - 1;
226                 for (int k = 1; j < end && text.charAt(j) == seq.charAt(k); j++, k++);
227                 if (j == end) {
228                     // found whole sequence
229
return i;
230                 }
231             }
232         }
233         return -1;
234     }
235     
236     /**
237      * Implementation of {@link String#lastIndexOf(String)} for character sequences.
238      */

239     public static int lastIndexOf(CharSequence JavaDoc text, CharSequence JavaDoc seq) {
240         return lastIndexOf(text, seq, text.length());
241     }
242     
243     /**
244      * Implementation of {@link String#lastIndexOf(String,int)} for character sequences.
245      */

246     public static int lastIndexOf(CharSequence JavaDoc text, CharSequence JavaDoc seq, int fromIndex) {
247         int textLength = text.length();
248         int seqLength = seq.length();
249         int rightIndex = textLength - seqLength;
250     if (fromIndex < 0) {
251         return -1;
252     }
253     if (fromIndex > rightIndex) {
254         fromIndex = rightIndex;
255     }
256     // empty string always matches
257
if (seqLength == 0) {
258         return fromIndex;
259     }
260
261         int strLastIndex = seqLength - 1;
262     char strLastChar = seq.charAt(strLastIndex);
263     int min = seqLength - 1;
264     int i = min + fromIndex;
265
266     startSearchForLastChar:
267     while (true) {
268         while (i >= min && text.charAt(i) != strLastChar) {
269         i--;
270         }
271             
272         if (i < min) {
273         return -1;
274         }
275         int j = i - 1;
276         int start = j - (seqLength - 1);
277         int k = strLastIndex - 1;
278
279         while (j > start) {
280             if (text.charAt(j--) != seq.charAt(k--)) {
281             i--;
282             continue startSearchForLastChar;
283         }
284         }
285         return start + 1;
286     }
287     }
288     
289     /**
290      * Implementation of {@link String#lastIndexOf(int)} for character sequences.
291      */

292     public static int lastIndexOf(CharSequence JavaDoc text, int ch) {
293     return lastIndexOf(text, ch, text.length() - 1);
294     }
295
296     /**
297      * Implementation of {@link String#lastIndexOf(int,int)} for character sequences.
298      */

299     public static int lastIndexOf(CharSequence JavaDoc text, int ch, int fromIndex) {
300         if (fromIndex > text.length() - 1) {
301             fromIndex = text.length() - 1;
302         }
303     while (fromIndex >= 0) {
304         if (text.charAt(fromIndex) == ch) {
305         return fromIndex;
306         }
307             fromIndex--;
308     }
309     return -1;
310     }
311
312     /**
313      * Implementation of {@link String#startsWith(String)} for character sequences.
314      */

315     public static boolean startsWith(CharSequence JavaDoc text, CharSequence JavaDoc prefix) {
316         int p_length = prefix.length();
317         if (p_length > text.length()) {
318             return false;
319         }
320         for (int x = 0; x < p_length; x++) {
321             if (text.charAt(x) != prefix.charAt(x))
322                 return false;
323         }
324         return true;
325     }
326     
327     /**
328      * Implementation of {@link String#endsWith(String)} for character sequences.
329      */

330     public static boolean endsWith(CharSequence JavaDoc text, CharSequence JavaDoc suffix) {
331         int s_length = suffix.length();
332         int text_length = text.length();
333         if (s_length > text_length) {
334             return false;
335         }
336         for (int x = 0; x < s_length; x++) {
337             if (text.charAt(text_length - s_length + x) != suffix.charAt(x))
338                 return false;
339         }
340         return true;
341     }
342     
343     /**
344      * Implementation of {@link String#trim()} for character sequences.
345      */

346     public static CharSequence JavaDoc trim(CharSequence JavaDoc text) {
347         int length = text.length();
348         if (length == 0)
349             return text;
350         int start = 0;
351         int end = length - 1;
352         while (start < length && text.charAt(start) <= ' ') {
353             start++;
354         }
355         if (start == length)
356             return text.subSequence(0, 0);
357         while (end > start && text.charAt(end) <= ' ') {
358             end--;
359         }
360         return text.subSequence(start, end + 1);
361     }
362
363     /**
364      * Append the character description to the given string buffer
365      * translating the special characters (and '\') into escape sequences.
366      *
367      * @param sb non-null string buffer to append to.
368      * @param ch character to be debugged.
369      */

370     public static void debugChar(StringBuffer JavaDoc sb, char ch) {
371         switch (ch) {
372             case '\n':
373                 sb.append("\\n");
374                 break;
375             case '\r':
376                 sb.append("\\r");
377                 break;
378             case '\t':
379                 sb.append("\\t");
380                 break;
381             case '\b':
382                 sb.append("\\b");
383                 break;
384             case '\f':
385                 sb.append("\\f");
386                 break;
387             case '\\':
388                 sb.append("\\\\");
389                 break;
390             default:
391                 sb.append(ch);
392                 break;
393         }
394     }
395     
396     /**
397      * Append the character description to the given string builder
398      * translating the special characters (and '\') into escape sequences.
399      *
400      * @param sb non-null string buffer to append to.
401      * @param ch character to be debugged.
402      */

403     public static void debugChar(StringBuilder JavaDoc sb, char ch) {
404         switch (ch) {
405             case '\n':
406                 sb.append("\\n");
407                 break;
408             case '\r':
409                 sb.append("\\r");
410                 break;
411             case '\t':
412                 sb.append("\\t");
413                 break;
414             case '\b':
415                 sb.append("\\b");
416                 break;
417             case '\f':
418                 sb.append("\\f");
419                 break;
420             case '\\':
421                 sb.append("\\\\");
422                 break;
423             default:
424                 sb.append(ch);
425                 break;
426         }
427     }
428     
429     /**
430      * Return the text description of the given character
431      * translating the special characters (and '\') into escape sequences.
432      *
433      * @param ch char to debug.
434      * @return non-null debug text.
435      */

436     public static String JavaDoc debugChar(char ch) {
437         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
438         debugChar(sb, ch);
439         return sb.toString();
440     }
441     
442     /**
443      * Append the text description to the given string buffer
444      * translating the special characters (and '\') into escape sequences.
445      *
446      * @param sb non-null string buffer to append to.
447      * @param text non-null text to be debugged.
448      */

449     public static void debugText(StringBuffer JavaDoc sb, CharSequence JavaDoc text) {
450         for (int i = 0; i < text.length(); i++) {
451             debugChar(sb, text.charAt(i));
452         }
453     }
454     
455     /**
456      * Append the text description to the given string builder
457      * translating the special characters (and '\') into escape sequences.
458      *
459      * @param sb non-null string builder to append to.
460      * @param text non-null text to be debugged.
461      */

462     public static void debugText(StringBuilder JavaDoc sb, CharSequence JavaDoc text) {
463         for (int i = 0; i < text.length(); i++) {
464             debugChar(sb, text.charAt(i));
465         }
466     }
467     
468     /**
469      * Create text description as String
470      * translating the special characters (and '\') into escape sequences.
471      *
472      * @param text non-null text to be debugged.
473      * @return non-null string containing the debug text.
474      */

475     public static String JavaDoc debugText(CharSequence JavaDoc text) {
476         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
477         debugText(sb, text);
478         return sb.toString();
479     }
480     
481     /**
482      * Ensure that the given index is &gt;=0 and lower than the given length.
483      * @throws IndexOutOfBoundsException if the index is not within bounds.
484      */

485     public static void checkIndexNonNegative(int index) {
486         if (index < 0) {
487             throw new IndexOutOfBoundsException JavaDoc("index=" + index + " < 0");
488         }
489     }
490
491     /**
492      * Ensure that the given index is &gt;=0 and lower than the given length.
493      * @throws IndexOutOfBoundsException if the index is not within bounds.
494      */

495     public static void checkIndexValid(int index, int length) {
496         checkIndexNonNegative(index);
497         if (index >= length) {
498             throw new IndexOutOfBoundsException JavaDoc("index=" + index
499                 + " >= length()=" + length);
500         }
501     }
502
503     /**
504      * Ensure that the given start and end parameters are valid indices
505      * of the given text.
506      * @throws IndexOutOfBoundsException if the start or end are not within bounds
507      * of the given text.
508      */

509     public static void checkIndexesValid(CharSequence JavaDoc text, int start, int end) {
510         if (start < 0) {
511             throw new IndexOutOfBoundsException JavaDoc("start=" + start + " < 0");
512         }
513         if (end < start) {
514             throw new IndexOutOfBoundsException JavaDoc("end=" + end + " < start=" + start);
515         }
516         if (end > text.length()) {
517             throw new IndexOutOfBoundsException JavaDoc("end=" + end
518             + " > text.length()=" + text.length());
519         }
520     }
521     
522
523 }
524
Popular Tags