KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > util > StringOps


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2006 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  *END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.util;
35
36 import edu.rice.cs.plt.tuple.Pair;
37 import java.io.StringWriter JavaDoc;
38 import java.io.PrintWriter JavaDoc;
39 import java.text.DecimalFormat JavaDoc;
40
41 /**
42  * A class to provide some convenient String operations as static methods.
43  * It's abstract to prevent (useless) instantiation, though it can be subclassed
44  * to provide convenient namespace importation of its methods.
45  * @version $Id: StringOps.java 4057 2007-01-16 00:06:10Z dlsmith $
46  */

47
48 public abstract class StringOps {
49   /**
50    * Takes theString fullString and replaces all instances of toReplace with
51    * replacement
52    */

53   public static String JavaDoc replace (String JavaDoc fullString, String JavaDoc toReplace, String JavaDoc replacement) {
54     int index = 0;
55     int pos;
56     int fullStringLength = fullString.length();
57     int toReplaceLength = toReplace.length();
58     if (toReplaceLength > 0) {
59       int replacementLength = replacement.length();
60       StringBuilder JavaDoc buff;
61       while (index < fullStringLength &&
62              ((pos = fullString.indexOf(toReplace, index)) >= 0)) {
63         buff = new StringBuilder JavaDoc(fullString.substring(0, pos));
64         buff.append(replacement);
65         buff.append(fullString.substring(pos + toReplaceLength, fullStringLength));
66         index = pos + replacementLength;
67         fullString = buff.toString();
68         fullStringLength = fullString.length();
69       }
70     }
71     return fullString;
72   }
73   
74   /**
75    * Converts the given string to a valid Java string literal.
76    * All back slashes, quotes, new-lines, and tabs are converted
77    * to their escap character form, and the sourounding quotes
78    * are added.
79    * @param s the normal string to turn into a string literal
80    * @return the valid Java string literal
81    */

82   public static String JavaDoc convertToLiteral(String JavaDoc s) {
83     String JavaDoc output = s;
84     output = replace(output, "\\", "\\\\"); // convert \ to \\
85
output = replace(output, "\"", "\\\""); // convert " to \"
86
output = replace(output, "\t", "\\t"); // convert [tab] to \t
87
output = replace(output, "\n", "\\n"); // convert [newline] to \n
88
return "\"" + output + "\"";
89   }
90   
91   /**
92    * Verifies that (startRow, startCol) occurs before (endRow, endCol).
93    * @throws IllegalArgumentException if end is before start
94    */

95   private static void _ensureStartBeforeEnd(int startRow, int startCol,
96                                             int endRow, int endCol) {
97     if (startRow > endRow) {
98       throw new IllegalArgumentException JavaDoc("end row before start row: " +
99                                          startRow + " > " + endRow);
100     }
101     else if (startRow == endRow && startCol > endCol) {
102       throw new IllegalArgumentException JavaDoc("end before start: (" +
103                                          startRow + ", " + startCol +
104                                          ") > (" + endRow + ", " + endCol + ")");
105     }
106   }
107
108   /**
109    * Verifies that the given column position is within the row at rowStartIndex
110    * in the given String.
111    * @param fullString the string in which to check the column
112    * @param col the column index that should be within the row
113    * @param rowStartIndex the first index of the row within fullString that col should be in
114    * @throws IllegalArgumentException if col is after the end of the given row
115    */

116   private static void _ensureColInRow(String JavaDoc fullString, int col, int rowStartIndex) {
117     int endOfLine = fullString.indexOf("\n",rowStartIndex);
118     if (endOfLine == -1) {
119       endOfLine = fullString.length();
120     }
121     if (col > (endOfLine - rowStartIndex)) {
122       throw new IllegalArgumentException JavaDoc("the given column is past the end of its row");
123     }
124   }
125
126   /**
127    * Gets the offset and length equivalent to the given pairs start and end row-col.
128    * @param fullString the string in which to compute the offset/length
129    * @param startRow the row on which the error starts, starting at one for the first row
130    * @param startCol the col on which the error starts, starting at one for the first column
131    * @param endRow the row on which the error ends. Equals the startRow for one-line errors
132    * @param endCol the character position on which the error ends.
133    * Equals the startCol for one-character errors
134    * @return a Pair of which the first is the offset, the second is the length
135    */

136   public static Pair<Integer JavaDoc,Integer JavaDoc> getOffsetAndLength(String JavaDoc fullString, int startRow,
137                                                          int startCol, int endRow, int endCol) {
138     _ensureStartBeforeEnd(startRow, startCol, endRow, endCol);
139
140     // find the offset
141
int currentChar = 0;
142     int linesSeen = 1;
143     while (startRow > linesSeen) {
144       currentChar = fullString.indexOf("\n",currentChar);
145       if (currentChar == -1) {
146         throw new IllegalArgumentException JavaDoc("startRow is beyond the end of the string");
147       }
148       // Must move past the newline
149
currentChar++;
150       linesSeen++;
151     }
152     
153     _ensureColInRow(fullString, startCol, currentChar);
154     int offset = currentChar + startCol - 1; // offset is zero-based
155

156     // find the length
157
while (endRow > linesSeen) {
158       currentChar = fullString.indexOf("\n",currentChar);
159       if (currentChar == -1) {
160         throw new IllegalArgumentException JavaDoc("endRow is beyond the end of the string");
161       }
162       currentChar++;
163       linesSeen++;
164     }
165
166     _ensureColInRow(fullString, endCol, currentChar);
167     int length = currentChar + endCol - offset;
168
169     // ensure the length is in bounds
170
if (offset + length > fullString.length()) {
171       throw new IllegalArgumentException JavaDoc("Given positions beyond the end of the string");
172     }
173     return new Pair<Integer JavaDoc,Integer JavaDoc>(new Integer JavaDoc(offset), new Integer JavaDoc(length));
174   }
175
176   /**
177    * Gets the stack trace of the given Throwable as a String.
178    * @param t the throwable object for which to get the stack trace
179    * @return the stack trace of the given Throwable
180    */

181   public static String JavaDoc getStackTrace(Throwable JavaDoc t) {
182     StringWriter JavaDoc sw = new StringWriter JavaDoc();
183     PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
184     t.printStackTrace(pw);
185     return sw.toString();
186   }
187   
188   /**
189    * Gets the stack trace of the current code. Does not include this method.
190    * @return the stack trace for the current code
191    */

192   public static String JavaDoc getStackTrace() {
193     try { throw new Exception JavaDoc(); } // Thread.getStackTrace() might be more efficient, but is new in Java 5.0
194
catch (Exception JavaDoc e) {
195       StringWriter JavaDoc sw = new StringWriter JavaDoc();
196       PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
197       StackTraceElement JavaDoc[] stes = e.getStackTrace();
198       int skip = 1;
199       for(StackTraceElement JavaDoc ste: stes) {
200         if (skip>0) { --skip; } else { pw.print("at "); pw.println(ste); }
201       }
202       return sw.toString();
203     }
204   }
205   
206   /**
207    * Character.isDigit answers <tt>true</tt> to some non-ascii
208    * digits. This one does not.
209    */

210   public static boolean isAsciiDigit(char c) {
211     return '0' <= c && c <= '9';
212   }
213   
214   /**
215    * Returns true if the class is an anonymous inner class.
216    * This works just like Class.isAnonymousClass() in Java 5.0 but is not version-specific.
217    * @param c class to check
218    * @return true if anonymous inner class
219    */

220   public static boolean isAnonymousClass(Class JavaDoc c) {
221     String JavaDoc simpleName = c.getName();
222     int idx = simpleName.lastIndexOf('$');
223     if (idx >= 0) {
224       // see if we have just numbers after the $
225
for (int pos=idx+1; pos < simpleName.length(); ++pos) {
226         if (!isAsciiDigit(simpleName.charAt(pos))) {
227           return false;
228         }
229       }
230       return true;
231     }
232     return false;
233   }
234   
235   /**
236    * Returns true if the class is a member class.
237    * This works just like Class.isMemberClass() in Java 5.0 but is not version-specific.
238    * @param c class to check
239    * @return true if member class
240    */

241   public static boolean isMemberClass(Class JavaDoc c) {
242     String JavaDoc simpleName = c.getName();
243     int idx = simpleName.lastIndexOf('$');
244     if (idx == -1) {
245       return false;
246     }
247     return !isAnonymousClass(c);
248   }
249   
250   /**
251    * Returns the simple class name.
252    * This works just like Class.getSimpleName() in Java 5.0 but is not version-specific.
253    * @param c class for which to get the simple name
254    * @return simple name
255    */

256   public static String JavaDoc getSimpleName(Class JavaDoc c) {
257     if (c.isArray())
258       return getSimpleName(c.getComponentType())+"[]";
259
260     if (isAnonymousClass(c)) {
261       return "";
262     }
263     
264     String JavaDoc simpleName = c.getName();
265     int idx = Math.max(simpleName.lastIndexOf('.'),
266                        simpleName.lastIndexOf('$'));
267     return simpleName.substring(idx + 1); // strip the package name
268
}
269   
270   /**
271    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
272    */

273   public static String JavaDoc toString(long[] a) {
274     if (a == null)
275       return "null";
276     if (a.length == 0)
277       return "[]";
278     
279     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
280     buf.append('[');
281     buf.append(a[0]);
282     
283     for (int i = 1; i < a.length; i++) {
284       buf.append(", ");
285       buf.append(a[i]);
286     }
287     
288     buf.append("]");
289     return buf.toString();
290   }
291   
292   /**
293    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
294    */

295   public static String JavaDoc toString(int[] a) {
296     if (a == null)
297       return "null";
298     if (a.length == 0)
299       return "[]";
300     
301     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
302     buf.append('[');
303     buf.append(a[0]);
304     
305     for (int i = 1; i < a.length; i++) {
306       buf.append(", ");
307       buf.append(a[i]);
308     }
309     
310     buf.append("]");
311     return buf.toString();
312   }
313   
314   /**
315    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
316    */

317   public static String JavaDoc toString(short[] a) {
318     if (a == null)
319       return "null";
320     if (a.length == 0)
321       return "[]";
322     
323     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
324     buf.append('[');
325     buf.append(a[0]);
326     
327     for (int i = 1; i < a.length; i++) {
328       buf.append(", ");
329       buf.append(a[i]);
330     }
331     
332     buf.append("]");
333     return buf.toString();
334   }
335   
336   /**
337    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
338    */

339   public static String JavaDoc toString(char[] a) {
340     if (a == null)
341       return "null";
342     if (a.length == 0)
343       return "[]";
344     
345     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
346     buf.append('[');
347     buf.append(a[0]);
348     
349     for (int i = 1; i < a.length; i++) {
350       buf.append(", ");
351       buf.append(a[i]);
352     }
353     
354     buf.append("]");
355     return buf.toString();
356   }
357   
358   /**
359    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
360    */

361   public static String JavaDoc toString(byte[] a) {
362     if (a == null)
363       return "null";
364     if (a.length == 0)
365       return "[]";
366     
367     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
368     buf.append('[');
369     buf.append(a[0]);
370     
371     for (int i = 1; i < a.length; i++) {
372       buf.append(", ");
373       buf.append(a[i]);
374     }
375     
376     buf.append("]");
377     return buf.toString();
378   }
379   
380   /**
381    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
382    */

383   public static String JavaDoc toString(boolean[] a) {
384     if (a == null)
385       return "null";
386     if (a.length == 0)
387       return "[]";
388     
389     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
390     buf.append('[');
391     buf.append(a[0]);
392     
393     for (int i = 1; i < a.length; i++) {
394       buf.append(", ");
395       buf.append(a[i]);
396     }
397     
398     buf.append("]");
399     return buf.toString();
400   }
401   
402   /**
403    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
404    */

405   public static String JavaDoc toString(float[] a) {
406     if (a == null)
407       return "null";
408     if (a.length == 0)
409       return "[]";
410     
411     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
412     buf.append('[');
413     buf.append(a[0]);
414     
415     for (int i = 1; i < a.length; i++) {
416       buf.append(", ");
417       buf.append(a[i]);
418     }
419     
420     buf.append("]");
421     return buf.toString();
422   }
423   
424   /**
425    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
426    */

427   public static String JavaDoc toString(double[] a) {
428     if (a == null)
429       return "null";
430     if (a.length == 0)
431       return "[]";
432     
433     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
434     buf.append('[');
435     buf.append(a[0]);
436     
437     for (int i = 1; i < a.length; i++) {
438       buf.append(", ");
439       buf.append(a[i]);
440     }
441     
442     buf.append("]");
443     return buf.toString();
444   }
445   
446   /**
447    * This works just like java.util.Arrays.toString in Java 5.0 but is not version-specific.
448    */

449   public static String JavaDoc toString(Object JavaDoc[] a) {
450     if (a == null)
451       return "null";
452     if (a.length == 0)
453       return "[]";
454     
455     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
456     
457     for (int i = 0; i < a.length; i++) {
458       if (i == 0)
459         buf.append('[');
460       else
461         buf.append(", ");
462       
463       buf.append(String.valueOf(a[i]));
464     }
465     
466     buf.append("]");
467     return buf.toString();
468   }
469
470   /**
471    * Encode &, <, > and newlines as HTML entities.
472    * @param s string to encode
473    * @return encoded string
474    */

475   public static String JavaDoc encodeHTML(String JavaDoc s) {
476     s = StringOps.replace(s, "&", "&amp;");
477     s = StringOps.replace(s, "<", "&lt;");
478     s = StringOps.replace(s, ">", "&gt;");
479     s = StringOps.replace(s, System.getProperty("line.separator"),"<br>");
480     s = StringOps.replace(s, "\n","<br>");
481     return s;
482   }
483
484   /**
485    * Return a string representing the approximate amount of memory specified in bytes.
486    * @param l memory in bytes
487    * @return string approximating the amount of memory
488    */

489   public static String JavaDoc memSizeToString(long l) {
490     String JavaDoc[] sizes = new String JavaDoc[] { "byte", "kilobyte", "megabyte", "gigabyte" };
491     double d = l;
492     int i = 0;
493     while((d >= 1024) && (i<sizes.length)) {
494       ++i;
495       d /= 1024;
496     }
497     if (i>=sizes.length) { i = sizes.length-1; }
498     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
499     long whole = (long)d;
500     if (whole==d) {
501       if (whole==1) {
502         sb.append(whole);
503         sb.append(' ');
504         sb.append(sizes[i]);
505       }
506       else {
507         sb.append(whole);
508         sb.append(' ');
509         sb.append(sizes[i]);
510         sb.append('s');
511       }
512     }
513     else {
514       // two decimal digits
515
DecimalFormat JavaDoc df = new DecimalFormat JavaDoc("#.00");
516       sb.append(df.format(d));
517       sb.append(' ');
518       sb.append(sizes[i]);
519       sb.append('s');
520     }
521     return sb.toString();
522   }
523 }
524
Popular Tags