KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > myfaces > util > StringUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.myfaces.util;
17
18 import java.util.ArrayList JavaDoc;
19
20
21 /**
22  * Implements utility functions for the String class
23  *
24  * <p>
25  * Emphasis on performance and reduced memory allocation/garbage collection
26  * in exchange for longer more complex code.
27  * </p>
28  *
29  * @author Anton Koinov (latest modification by $Author: matze $)
30  * @version $Revision: 1.4 $ $Date: 2004/10/13 11:51:01 $
31  *
32  * $Log: StringUtils.java,v $
33  * Revision 1.4 2004/10/13 11:51:01 matze
34  * renamed packages to org.apache
35  *
36  * Revision 1.3 2004/08/23 05:15:32 dave0000
37  * be user friendly, do not return null
38  *
39  * Revision 1.2 2004/08/20 07:16:09 manolito
40  * moved StringUtils to share source tree
41  *
42  * Revision 1.1 2004/08/19 16:18:54 manolito
43  * moved to share dir
44  *
45  *
46  * old cvs log (myfaces dir):
47  *
48  * Revision 1.9 2004/07/01 22:05:15 mwessendorf
49  * ASF switch
50  *
51  * Revision 1.8 2004/06/17 03:51:22 dave0000
52  * Use EMPTY_STRING_ARRAY from ArrayUtils
53  *
54  * Revision 1.7 2004/03/30 07:42:53 dave0000
55  * minIndex()
56  *
57  */

58 public class StringUtils
59 {
60     private StringUtils()
61     {
62         // utility class, no instantiation
63
}
64     
65     //~ Methods ------------------------------------------------------------------------------------
66

67     /**
68      * Checks that the string represents a floating point number that CANNOT be
69      * in exponential notation
70      *
71      * @param str the string to check
72      *
73      * @return boolean
74      */

75     public static boolean isFloatNoExponent(String JavaDoc str)
76     {
77         int len = str.length();
78         if (len == 0)
79         {
80             return false;
81         }
82
83         // skip first char if sign char
84
char c = str.charAt(0);
85         int i = ((c == '-') || (c == '+')) ? 1 : 0;
86
87         // is it only a sign?
88
if (i >= len)
89         {
90             return false;
91         }
92
93         boolean decimalPointFound = false;
94
95         do
96         {
97             c = str.charAt(i);
98             if (c == '.')
99             {
100                 // is this a second dot?
101
if (decimalPointFound)
102                 {
103                     return false;
104                 }
105
106                 decimalPointFound = true;
107             }
108             else if (!Character.isDigit(c))
109             {
110                 return false;
111             }
112
113             i++;
114         }
115         while (i < len);
116
117         return true;
118     }
119
120     public static boolean isFloatWithOptionalExponent(String JavaDoc str)
121     {
122         int len = str.length();
123         if (len == 0)
124         {
125             return false;
126         }
127
128         // skip first char if sign char
129
char c = str.charAt(0);
130         int i = ((c == '-') || (c == '+')) ? 1 : 0;
131
132         // is it only a sign?
133
if (i >= len)
134         {
135             return false;
136         }
137
138         boolean exponentFound = false;
139         boolean decimalPointFound = false;
140
141         do
142         {
143             c = str.charAt(i);
144             switch (c)
145             {
146                 case '.':
147
148                     // is this a second one, are we in the exponent?
149
if (decimalPointFound || exponentFound)
150                     {
151                         return false;
152                     }
153                     decimalPointFound = true;
154
155                     break;
156
157                 case 'e':
158                 case 'E':
159
160                     // is this a second one?
161
if (exponentFound)
162                     {
163                         return false;
164                     }
165                     exponentFound = true;
166
167                     // check for exponent sign
168
c = str.charAt(i + 1);
169
170                     if ((c == '-') || (c == '+'))
171                     {
172                         i++;
173                     }
174
175                     break;
176
177                 default:
178                     if (!Character.isDigit(c))
179                     {
180                         return false;
181                     }
182             }
183
184             i++;
185         }
186         while (i < len);
187
188         return true;
189     }
190
191     public static boolean isInteger(String JavaDoc str)
192     {
193         int len = str.length();
194         if (len == 0)
195         {
196             return false;
197         }
198
199         // skip first char if sign char
200
char c = str.charAt(0);
201         int i = ((c == '-') || (c == '+')) ? 1 : 0;
202
203         // is it only a sign?
204
if (i >= len)
205         {
206             return false;
207         }
208
209         do
210         {
211             if (!Character.isDigit(str.charAt(i)))
212             {
213                 return false;
214             }
215             i++;
216         }
217         while (i < len);
218
219         return true;
220     }
221
222     public static boolean isUnsignedInteger(String JavaDoc str)
223     {
224         int len = str.length();
225         if (len == 0)
226         {
227             return false;
228         }
229
230         for (int i = 0; i < len; i++)
231         {
232             if (!Character.isDigit(str.charAt(i)))
233             {
234                 return false;
235             }
236         }
237
238         return true;
239     }
240
241     /**
242      * Undoubles the quotes inside the string <br> Example:<br>
243      * <pre>
244      * hello""world becomes hello"world
245      * </pre>
246      *
247      * @param str input string to dequote
248      * @param quote the quoting char
249      *
250      * @return dequoted string
251      */

252     public static String JavaDoc dequote(String JavaDoc str, char quote)
253     {
254         // Is there anything to dequote?
255
if (str == null)
256         {
257             return null;
258         }
259
260         return dequote(str, 0, str.length(), quote);
261     }
262
263     /**
264      * Undoubles the quotes inside a substring <br> Example:<br>
265      * <pre>
266      * hello""world becomes hello"world
267      * </pre>
268      * WARNING: scan for quote may continue to the end of the string, make sure
269      * that either <code>charAt(end + 1) == quote</code> or <code>end =
270      * str.lentgth()</code>. If in doubt call
271      * <code>dequote(str.substring(begin, end), quote)</code>
272      *
273      * @param str input string from which to get the substring, must not be
274      * null
275      * @param begin begin index for substring
276      * @param end end index for substring
277      * @param quote the quoting char
278      *
279      * @return dequoted string
280      *
281      * @throws IllegalArgumentException if string is incorrectly quoted
282      */

283     public static String JavaDoc dequote(String JavaDoc str, int begin, int end, char quote)
284     {
285         // Is there anything to dequote?
286
if (begin == end)
287         {
288             return "";
289         }
290
291         int end_ = str.indexOf(quote, begin);
292
293         // If no quotes, return the original string
294
// and save StringBuffer allocation/char copying
295
if (end_ < 0)
296         {
297             return str.substring(begin, end);
298         }
299
300         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(end - begin);
301         int begin_ = begin; // need begin later
302
for (; (end_ >= 0) && (end_ < end);
303             end_ = str.indexOf(quote, begin_ = end_ + 2))
304         {
305             if (((end_ + 1) >= end) || (str.charAt(end_ + 1) != quote))
306             {
307                 throw new IllegalArgumentException JavaDoc(
308                     "Internal quote not doubled in string '"
309                     + str.substring(begin, end) + "'");
310             }
311
312             sb.append(substring(str, begin_, end_)).append(quote);
313         }
314
315         return sb.append(substring(str, begin_, end)).toString();
316     }
317
318     /**
319      * Removes the surrounding quote and any double quote inside the string <br>
320      * Example:<br>
321      * <pre>
322      * "hello""world" becomes hello"world
323      * </pre>
324      *
325      * @param str input string to dequote
326      * @param quote the quoting char
327      *
328      * @return dequoted String
329      */

330     public static String JavaDoc dequoteFull(String JavaDoc str, char quote)
331     {
332         if (str == null)
333         {
334             return null;
335         }
336
337         return dequoteFull(str, 0, str.length(), quote);
338     }
339
340     public static String JavaDoc dequoteFull(String JavaDoc str, int begin, int end, char quote)
341     {
342         // If empty substring, return empty string
343
if (begin == end)
344         {
345             return "";
346         }
347
348         // If not quoted, return string
349
if (str.charAt(begin) != quote)
350         {
351             return str.substring(begin, end);
352         }
353
354         int _end = end - 1;
355         if ((str.length() < 2) || (str.charAt(_end) != quote))
356         {
357             throw new IllegalArgumentException JavaDoc(
358                 "Closing quote missing in string '"
359                 + substring(str, begin, end) + "'");
360         }
361
362         return dequote(str, begin + 1, _end, quote);
363     }
364
365     public static String JavaDoc replace(String JavaDoc str, String JavaDoc repl, String JavaDoc with)
366     {
367         int lastindex = 0;
368         int pos = str.indexOf(repl);
369
370         // If no replacement needed, return the original string
371
// and save StringBuffer allocation/char copying
372
if (pos < 0)
373         {
374             return str;
375         }
376
377         int len = repl.length();
378         int lendiff = with.length() - repl.length();
379         StringBuffer JavaDoc out =
380             new StringBuffer JavaDoc((lendiff <= 0) ? str.length()
381                 : (str.length() + (10 * lendiff)));
382         for (; pos >= 0; pos = str.indexOf(repl, lastindex = pos + len))
383         {
384             out.append(substring(str, lastindex, pos)).append(with);
385         }
386
387         return out.append(substring(str, lastindex, str.length())).toString();
388     }
389
390     public static String JavaDoc replace(String JavaDoc str, char repl, String JavaDoc with)
391     {
392         int pos = str.indexOf(repl);
393
394         // If no replacement needed, return the original string
395
// and save StringBuffer allocation/char copying
396
if (pos < 0)
397         {
398             return str;
399         }
400
401         int len = str.length();
402         int lendiff = with.length() - 1;
403         StringBuffer JavaDoc out =
404             new StringBuffer JavaDoc((lendiff <= 0) ? str.length()
405                 : (str.length() + (10 * lendiff)));
406         int lastindex = 0;
407         for (; pos >= 0; pos = str.indexOf(repl, lastindex = pos + 1))
408         {
409             out.append(substring(str, lastindex, pos)).append(with);
410         }
411
412         return out.append(substring(str, lastindex, len)).toString();
413     }
414
415     public static StringBuffer JavaDoc replace(
416         StringBuffer JavaDoc out, String JavaDoc s, String JavaDoc repl, String JavaDoc with)
417     {
418         int lastindex = 0;
419         int len = repl.length();
420         for (int index = s.indexOf(repl); index >= 0;
421                     index = s.indexOf(repl, lastindex = index + len))
422         {
423             // we have search string at position index
424
out.append(substring(s, lastindex, index)).append(with);
425         }
426
427         return out.append(substring(s, lastindex, len));
428     }
429
430     /**
431      * Split a string into an array of strings arround a character separator.
432      * This function will be efficient for longer strings
433      *
434      * @param str the string to be split
435      * @param separator the separator character
436      *
437      * @return array of string subparts
438      */

439     public static String JavaDoc[] splitLongString(String JavaDoc str, char separator)
440     {
441         int len;
442         if (str == null || (len = str.length()) == 0)
443         {
444             return ArrayUtils.EMPTY_STRING_ARRAY;
445         }
446
447         int oldPos = 0;
448         ArrayList JavaDoc list = new ArrayList JavaDoc();
449         for (
450             int pos = str.indexOf(separator); pos >= 0;
451                     pos = str.indexOf(separator, (oldPos = (pos + 1))))
452         {
453             list.add(substring(str, oldPos, pos));
454         }
455
456         list.add(substring(str, oldPos, len));
457
458         return (String JavaDoc[]) list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
459     }
460
461     /**
462      * Split a string into an array of strings arround a character separator.
463      * Each element can be optionally quoted by the quote character.<br>
464      * This function will be efficient for long strings
465      *
466      * @param str the string to be split
467      * @param separator the separator character
468      * @param quote the quote character
469      *
470      * @return array of string subparts
471      *
472      * @throws IllegalArgumentException DOCUMENT ME!
473      */

474     public static String JavaDoc[] splitLongString(
475         String JavaDoc str, char separator, char quote)
476     {
477         int len;
478         if (str == null || (len = str.length()) == 0)
479         {
480             return ArrayUtils.EMPTY_STRING_ARRAY;
481         }
482
483         int oldPos = 0;
484         ArrayList JavaDoc list = new ArrayList JavaDoc();
485         for (int pos = 0; pos < len; oldPos = ++pos)
486         {
487             // Skip quoted text, if any
488
while ((pos < len) && (str.charAt(pos) == quote))
489             {
490                 pos = str.indexOf(quote, pos + 1) + 1;
491
492                 if (pos == 0)
493                 {
494                     throw new IllegalArgumentException JavaDoc(
495                         "Closing quote missing in string '" + str + "'");
496                 }
497             }
498
499             boolean quoted;
500
501             if (pos != oldPos)
502             {
503                 quoted = true;
504
505                 if ((pos < len) && (str.charAt(pos) != separator))
506                 {
507                     throw new IllegalArgumentException JavaDoc(
508                         "Separator must follow closing quote in string '"
509                         + str + "'");
510                 }
511             }
512             else
513             {
514                 quoted = false;
515                 pos = str.indexOf(separator, pos);
516                 if (pos < 0)
517                 {
518                     pos = len;
519                 }
520             }
521
522             list.add(
523                 quoted ? dequote(str, oldPos + 1, pos - 1, quote)
524                     : substring(str, oldPos, pos));
525         }
526
527         return (String JavaDoc[]) list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
528     }
529
530     /**
531      * Split a string into an array of strings arround a character separator.
532      * This function will be efficient for short strings, for longer strings,
533      * another approach may be better
534      *
535      * @param str the string to be split
536      * @param separator the separator character
537      *
538      * @return array of string subparts
539      */

540     public static String JavaDoc[] splitShortString(String JavaDoc str, char separator)
541     {
542         int len;
543         if (str == null || (len = str.length()) == 0)
544         {
545             return ArrayUtils.EMPTY_STRING_ARRAY;
546         }
547
548         int lastTokenIndex = 0;
549
550         // Step 1: how many substrings?
551
// We exchange double scan time for less memory allocation
552
for (int pos = str.indexOf(separator);
553             pos >= 0; pos = str.indexOf(separator, pos + 1))
554         {
555             lastTokenIndex++;
556         }
557
558         // Step 2: allocate exact size array
559
String JavaDoc[] list = new String JavaDoc[lastTokenIndex + 1];
560
561         int oldPos = 0;
562
563         // Step 3: retrieve substrings
564
for (
565             int pos = str.indexOf(separator), i = 0; pos >= 0;
566                     pos = str.indexOf(separator, (oldPos = (pos + 1))))
567         {
568             list[i++] = substring(str, oldPos, pos);
569         }
570
571         list[lastTokenIndex] = substring(str, oldPos, len);
572
573         return list;
574     }
575
576     /**
577      * Split a string into an array of strings arround a character separator.
578      * Each element can be optionally quoted by the quote character.<br>
579      * This function will be efficient for short strings, for longer strings,
580      * another approach may be better
581      *
582      * @param str the string to be split
583      * @param separator the separator character
584      * @param quote the quote character
585      *
586      * @return array of string subparts
587      *
588      * @throws IllegalArgumentException DOCUMENT ME!
589      */

590     public static String JavaDoc[] splitShortString(
591         String JavaDoc str, char separator, char quote)
592     {
593         int len;
594         if (str == null || (len = str.length()) == 0)
595         {
596             return ArrayUtils.EMPTY_STRING_ARRAY;
597         }
598
599         // Step 1: how many substrings?
600
// We exchange double scan time for less memory allocation
601
int tokenCount = 0;
602         for (int pos = 0; pos < len; pos++)
603         {
604             tokenCount++;
605
606             int oldPos = pos;
607
608             // Skip quoted text, if any
609
while ((pos < len) && (str.charAt(pos) == quote))
610             {
611                 pos = str.indexOf(quote, pos + 1) + 1;
612
613                 // pos == 0 is not found (-1 returned by indexOf + 1)
614
if (pos == 0)
615                 {
616                     throw new IllegalArgumentException JavaDoc(
617                         "Closing quote missing in string '" + str + "'");
618                 }
619             }
620
621             if (pos != oldPos)
622             {
623                 if ((pos < len) && (str.charAt(pos) != separator))
624                 {
625                     throw new IllegalArgumentException JavaDoc(
626                         "Separator must follow closing quote in strng '"
627                         + str + "'");
628                 }
629             }
630             else
631             {
632                 pos = str.indexOf(separator, pos);
633                 if (pos < 0)
634                 {
635                     break;
636                 }
637             }
638         }
639
640         // Main loop will finish one substring short when last char is separator
641
if (str.charAt(len - 1) == separator)
642         {
643             tokenCount++;
644         }
645
646         // Step 2: allocate exact size array
647
String JavaDoc[] list = new String JavaDoc[tokenCount];
648
649         // Step 3: retrieve substrings
650
// Note: on this pass we do not check for correctness,
651
// since we have already done so
652
tokenCount--; // we want to stop one token short
653

654         int oldPos = 0;
655         for (int pos = 0, i = 0; i < tokenCount; i++, oldPos = ++pos)
656         {
657             boolean quoted;
658
659             // Skip quoted text, if any
660
while (str.charAt(pos) == quote)
661             {
662                 pos = str.indexOf(quote, pos + 1) + 1;
663             }
664
665             if (pos != oldPos)
666             {
667                 quoted = true;
668
669                 if (str.charAt(pos) != separator)
670                 {
671                     throw new IllegalArgumentException JavaDoc(
672                         "Separator must follow closing quote in strng '"
673                         + str + "'");
674                 }
675             }
676             else
677             {
678                 quoted = false;
679                 pos = str.indexOf(separator, pos);
680             }
681
682             list[i] =
683                 quoted ? dequote(str, oldPos + 1, pos - 1, quote)
684                     : substring(str, oldPos, pos);
685         }
686
687         list[tokenCount] = dequoteFull(str, oldPos, len, quote);
688
689         return list;
690     }
691
692     public static String JavaDoc substring(String JavaDoc str, int begin, int end)
693     {
694         if (begin == end)
695         {
696             return "";
697         }
698
699         return str.substring(begin, end);
700     }
701
702     public static String JavaDoc[] trim(String JavaDoc[] strings)
703     {
704         if (strings == null)
705         {
706             return null;
707         }
708
709         for (int i = 0, len = strings.length; i < len; i++)
710         {
711             strings[i] = strings[i].trim();
712         }
713
714         return strings;
715     }
716     
717     /**
718      * Returns the minimum index >= 0, if any
719      *
720      * <p>
721      * Use to find the first of two characters in a string:<br>
722      * <code>minIndex(s.indexOf('/'), indexOf('\'))</code>
723      * </p>
724      *
725      */

726     public static int minIndex(int a, int b)
727     {
728         return (a < 0) ? b
729             : (b < 0) ? a
730                 : (a < b) ? a : b;
731     }
732 }
733
Popular Tags