KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > util > Util


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

19
20 package org.apache.cayenne.util;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.BufferedOutputStream JavaDoc;
24 import java.io.BufferedReader JavaDoc;
25 import java.io.ByteArrayInputStream JavaDoc;
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.File JavaDoc;
28 import java.io.FileInputStream JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.FileReader JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33 import java.io.ObjectInputStream JavaDoc;
34 import java.io.ObjectOutputStream JavaDoc;
35 import java.io.OutputStream JavaDoc;
36 import java.io.Serializable JavaDoc;
37 import java.lang.reflect.Member JavaDoc;
38 import java.lang.reflect.Modifier JavaDoc;
39 import java.net.URL JavaDoc;
40 import java.sql.SQLException JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Collection JavaDoc;
43 import java.util.Collections JavaDoc;
44 import java.util.Comparator JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.Map JavaDoc;
49 import java.util.regex.Pattern JavaDoc;
50
51 import javax.xml.parsers.ParserConfigurationException JavaDoc;
52 import javax.xml.parsers.SAXParser JavaDoc;
53 import javax.xml.parsers.SAXParserFactory JavaDoc;
54
55 import org.apache.commons.lang.builder.EqualsBuilder;
56 import org.apache.commons.lang.builder.HashCodeBuilder;
57 import org.xml.sax.SAXException JavaDoc;
58 import org.xml.sax.XMLReader JavaDoc;
59
60 /**
61  * Contains various unorganized static utility methods used across Cayenne.
62  *
63  * @author Andrus Adamchik
64  */

65 public class Util {
66
67     /**
68      * Reads file contents, returning it as a String, using System default line separator.
69      */

70     public static String JavaDoc stringFromFile(File JavaDoc file) throws IOException JavaDoc {
71         return stringFromFile(file, System.getProperty("line.separator"));
72     }
73
74     /**
75      * Reads file contents, returning it as a String, joining lines with provided
76      * separator.
77      */

78     public static String JavaDoc stringFromFile(File JavaDoc file, String JavaDoc joinWith) throws IOException JavaDoc {
79         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
80         BufferedReader JavaDoc in = new BufferedReader JavaDoc(new FileReader JavaDoc(file));
81
82         try {
83             String JavaDoc line = null;
84             while ((line = in.readLine()) != null) {
85                 buf.append(line).append(joinWith);
86             }
87         }
88         finally {
89             in.close();
90         }
91         return buf.toString();
92     }
93
94     /**
95      * Copies file contents from source to destination. Makes up for the lack of file
96      * copying utilities in Java
97      */

98     public static boolean copy(File JavaDoc source, File JavaDoc destination) {
99         BufferedInputStream JavaDoc fin = null;
100         BufferedOutputStream JavaDoc fout = null;
101         try {
102             int bufSize = 8 * 1024;
103             fin = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(source), bufSize);
104             fout = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(destination), bufSize);
105             copyPipe(fin, fout, bufSize);
106         }
107         catch (IOException JavaDoc ioex) {
108             return false;
109         }
110         catch (SecurityException JavaDoc sx) {
111             return false;
112         }
113         finally {
114             if (fin != null) {
115                 try {
116                     fin.close();
117                 }
118                 catch (IOException JavaDoc cioex) {
119                 }
120             }
121             if (fout != null) {
122                 try {
123                     fout.close();
124                 }
125                 catch (IOException JavaDoc cioex) {
126                 }
127             }
128         }
129         return true;
130     }
131
132     /**
133      * Save URL contents to a file.
134      */

135     public static boolean copy(URL JavaDoc from, File JavaDoc to) {
136         BufferedInputStream JavaDoc urlin = null;
137         BufferedOutputStream JavaDoc fout = null;
138         try {
139             int bufSize = 8 * 1024;
140             urlin = new BufferedInputStream JavaDoc(
141                     from.openConnection().getInputStream(),
142                     bufSize);
143             fout = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(to), bufSize);
144             copyPipe(urlin, fout, bufSize);
145         }
146         catch (IOException JavaDoc ioex) {
147             return false;
148         }
149         catch (SecurityException JavaDoc sx) {
150             return false;
151         }
152         finally {
153             if (urlin != null) {
154                 try {
155                     urlin.close();
156                 }
157                 catch (IOException JavaDoc cioex) {
158                 }
159             }
160             if (fout != null) {
161                 try {
162                     fout.close();
163                 }
164                 catch (IOException JavaDoc cioex) {
165                 }
166             }
167         }
168         return true;
169     }
170
171     /**
172      * Reads data from the input and writes it to the output, until the end of the input
173      * stream.
174      *
175      * @param in
176      * @param out
177      * @param bufSizeHint
178      * @throws IOException
179      */

180     public static void copyPipe(InputStream JavaDoc in, OutputStream JavaDoc out, int bufSizeHint)
181             throws IOException JavaDoc {
182         int read = -1;
183         byte[] buf = new byte[bufSizeHint];
184         while ((read = in.read(buf, 0, bufSizeHint)) >= 0) {
185             out.write(buf, 0, read);
186         }
187         out.flush();
188     }
189
190     /**
191      * Deletes a file or directory, allowing recursive directory deletion. This is an
192      * improved version of File.delete() method.
193      */

194     public static boolean delete(String JavaDoc filePath, boolean recursive) {
195         File JavaDoc file = new File JavaDoc(filePath);
196         if (!file.exists()) {
197             return true;
198         }
199
200         if (!recursive || !file.isDirectory())
201             return file.delete();
202
203         String JavaDoc[] list = file.list();
204         for (int i = 0; i < list.length; i++) {
205             if (!delete(filePath + File.separator + list[i], true))
206                 return false;
207         }
208
209         return file.delete();
210     }
211
212     /**
213      * Replaces all backslashes "\" with forward slashes "/". Convenience method to
214      * convert path Strings to URI format.
215      */

216     public static String JavaDoc substBackslashes(String JavaDoc string) {
217         return RegexUtil.substBackslashes(string);
218     }
219
220     /**
221      * Looks up and returns the root cause of an exception. If none is found, returns
222      * supplied Throwable object unchanged. If root is found, recursively "unwraps" it,
223      * and returns the result to the user.
224      */

225     public static Throwable JavaDoc unwindException(Throwable JavaDoc th) {
226         if (th instanceof SAXException JavaDoc) {
227             SAXException JavaDoc sax = (SAXException JavaDoc) th;
228             if (sax.getException() != null) {
229                 return unwindException(sax.getException());
230             }
231         }
232         else if (th instanceof SQLException JavaDoc) {
233             SQLException JavaDoc sql = (SQLException JavaDoc) th;
234             if (sql.getNextException() != null) {
235                 return unwindException(sql.getNextException());
236             }
237         }
238         else if (th.getCause() != null) {
239             return unwindException(th.getCause());
240         }
241
242         return th;
243     }
244
245     /**
246      * Compares two objects similar to "Object.equals(Object)". Unlike Object.equals(..),
247      * this method doesn't throw an exception if any of the two objects is null.
248      */

249     public static boolean nullSafeEquals(Object JavaDoc o1, Object JavaDoc o2) {
250
251         if (o1 == null) {
252             return o2 == null;
253         }
254
255         // Arrays must be handled differently since equals() only does
256
// an "==" for an array and ignores equivalence. If an array, use
257
// the Jakarta Commons Language component EqualsBuilder to determine
258
// the types contained in the array and do individual comparisons.
259
if (o1.getClass().isArray()) {
260             EqualsBuilder builder = new EqualsBuilder();
261             builder.append(o1, o2);
262             return builder.isEquals();
263         }
264         else { // It is NOT an array, so use regular equals()
265
return o1.equals(o2);
266         }
267     }
268
269     /**
270      * Compares two objects similar to "Comparable.compareTo(Object)". Unlike
271      * Comparable.compareTo(..), this method doesn't throw an exception if any of the two
272      * objects is null.
273      *
274      * @since 1.1
275      */

276     public static int nullSafeCompare(boolean nullsFirst, Comparable JavaDoc o1, Object JavaDoc o2) {
277         if (o1 == null && o2 == null) {
278             return 0;
279         }
280         else if (o1 == null) {
281             return nullsFirst ? -1 : 1;
282         }
283         else if (o2 == null) {
284             return nullsFirst ? 1 : -1;
285         }
286         else {
287             return o1.compareTo(o2);
288         }
289     }
290
291     /**
292      * Returns true, if the String is null or an empty string.
293      */

294     public static boolean isEmptyString(String JavaDoc string) {
295         return string == null || string.length() == 0;
296     }
297
298     /**
299      * Creates Serializable object copy using serialization/deserialization.
300      */

301     public static Object JavaDoc cloneViaSerialization(Serializable JavaDoc obj) throws Exception JavaDoc {
302         ByteArrayOutputStream JavaDoc bytes = new ByteArrayOutputStream JavaDoc() {
303
304             public synchronized byte[] toByteArray() {
305                 return buf;
306             }
307         };
308
309         ObjectOutputStream JavaDoc out = new ObjectOutputStream JavaDoc(bytes);
310         out.writeObject(obj);
311         out.close();
312
313         ObjectInputStream JavaDoc in = new ObjectInputStream JavaDoc(new ByteArrayInputStream JavaDoc(bytes
314                 .toByteArray()));
315         Object JavaDoc objCopy = in.readObject();
316
317         // no need to close the stream - we created it and now will be throwing away...
318
// in.close();
319

320         return objCopy;
321     }
322
323     /**
324      * Creates an XMLReader with default feature set. Note that all Cayenne internal XML
325      * parsers should probably use XMLReader obtained via this method for consistency
326      * sake, and can customize feature sets as needed.
327      */

328     public static XMLReader JavaDoc createXmlReader() throws SAXException JavaDoc,
329             ParserConfigurationException JavaDoc {
330         SAXParserFactory JavaDoc spf = SAXParserFactory.newInstance();
331
332         // Create a JAXP SAXParser
333
SAXParser JavaDoc saxParser = spf.newSAXParser();
334
335         // Get the encapsulated SAX XMLReader
336
XMLReader JavaDoc reader = saxParser.getXMLReader();
337
338         // set default features
339
reader.setFeature("http://xml.org/sax/features/namespaces", true);
340
341         return reader;
342     }
343
344     /**
345      * Returns package name for the Java class as a path separated with forward slash
346      * ("/"). Method is used to lookup resources that are located in package
347      * subdirectories. For example, a String "a/b/c" will be returned for class name
348      * "a.b.c.ClassName".
349      */

350     public static String JavaDoc getPackagePath(String JavaDoc className) {
351         return RegexUtil.getPackagePath(className);
352     }
353
354     /**
355      * Creates a mutable map out of two arrays with keys and values.
356      *
357      * @since 1.2
358      */

359     public static Map JavaDoc toMap(Object JavaDoc[] keys, Object JavaDoc[] values) {
360         int keysSize = (keys != null) ? keys.length : 0;
361         int valuesSize = (values != null) ? values.length : 0;
362
363         if (keysSize == 0 && valuesSize == 0) {
364             // return mutable map
365
return new HashMap JavaDoc();
366         }
367
368         if (keysSize != valuesSize) {
369             throw new IllegalArgumentException JavaDoc(
370                     "The number of keys doesn't match the number of values.");
371         }
372
373         Map JavaDoc map = new HashMap JavaDoc();
374         for (int i = 0; i < keysSize; i++) {
375             map.put(keys[i], values[i]);
376         }
377
378         return map;
379     }
380
381     /**
382      * Extracts extension from the file name. Dot is not included in the returned string.
383      */

384     public static String JavaDoc extractFileExtension(String JavaDoc fileName) {
385         int dotInd = fileName.lastIndexOf('.');
386
387         // if dot is in the first position,
388
// we are dealing with a hidden file rather than an extension
389
return (dotInd > 0 && dotInd < fileName.length()) ? fileName
390                 .substring(dotInd + 1) : null;
391     }
392
393     /**
394      * Strips extension from the file name.
395      */

396     public static String JavaDoc stripFileExtension(String JavaDoc fileName) {
397         int dotInd = fileName.lastIndexOf('.');
398
399         // if dot is in the first position,
400
// we are dealing with a hidden file rather than an extension
401
return (dotInd > 0) ? fileName.substring(0, dotInd) : fileName;
402     }
403
404     /**
405      * Strips "\n", "\r\n", "\r" from the argument string.
406      *
407      * @since 1.2
408      */

409     public static String JavaDoc stripLineBreaks(String JavaDoc string, String JavaDoc replaceWith) {
410         if (isEmptyString(string)) {
411             return string;
412         }
413
414         int len = string.length();
415         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(len);
416         for (int i = 0; i < len; i++) {
417             char c = string.charAt(i);
418
419             // skip \n, \r, \r\n
420
switch (c) {
421                 case '\n':
422                 case '\r': // do lookahead
423
if (i + 1 < len && string.charAt(i + 1) == '\n') {
424                         i++;
425                     }
426
427                     buffer.append(replaceWith);
428                     break;
429                 default:
430                     buffer.append(c);
431             }
432         }
433
434         return buffer.toString();
435     }
436
437     /**
438      * Encodes a string so that it can be used as an attribute value in an XML document.
439      * Will do conversion of the greater/less signs, quotes and ampersands.
440      */

441     public static String JavaDoc encodeXmlAttribute(String JavaDoc str) {
442         if (str == null)
443             return null;
444
445         int len = str.length();
446         if (len == 0)
447             return str;
448
449         StringBuffer JavaDoc encoded = new StringBuffer JavaDoc();
450         for (int i = 0; i < len; i++) {
451             char c = str.charAt(i);
452             if (c == '<')
453                 encoded.append("&lt;");
454             else if (c == '\"')
455                 encoded.append("&quot;");
456             else if (c == '>')
457                 encoded.append("&gt;");
458             else if (c == '\'')
459                 encoded.append("&apos;");
460             else if (c == '&')
461                 encoded.append("&amp;");
462             else
463                 encoded.append(c);
464         }
465
466         return encoded.toString();
467     }
468
469     /**
470      * Trims long strings substituting middle part with "...".
471      *
472      * @param str String to trim.
473      * @param maxLength maximum allowable length. Must be at least 5, or an
474      * IllegalArgumentException is thrown.
475      * @return String
476      */

477     public static String JavaDoc prettyTrim(String JavaDoc str, int maxLength) {
478         if (maxLength < 5) {
479             throw new IllegalArgumentException JavaDoc(
480                     "Algorithm for 'prettyTrim' works only with length >= 5. "
481                             + "Supplied length is "
482                             + maxLength);
483         }
484
485         if (str == null || str.length() <= maxLength) {
486             return str;
487         }
488
489         // find a section to cut off
490
int len = maxLength - 3;
491         int startLen = len / 2;
492         int endLen = len - startLen;
493
494         return str.substring(0, startLen) + "..." + str.substring(str.length() - endLen);
495     }
496
497     /**
498      * Returns a sorted iterator from an unsorted one. Use this method as a last resort,
499      * since it is much less efficient then just sorting a collection that backs the
500      * original iterator.
501      */

502     public static Iterator JavaDoc sortedIterator(Iterator JavaDoc it, Comparator JavaDoc comparator) {
503         List JavaDoc list = new ArrayList JavaDoc();
504         while (it.hasNext()) {
505             list.add(it.next());
506         }
507
508         Collections.sort(list, comparator);
509         return list.iterator();
510     }
511
512     /**
513      * Builds a hashCode of Collection.
514      */

515     public static int hashCode(Collection JavaDoc c) {
516         HashCodeBuilder builder = new HashCodeBuilder();
517         for (Iterator JavaDoc i = c.iterator(); i.hasNext();)
518             builder.append(i.next());
519         return builder.toHashCode();
520     }
521
522     /**
523      * @since 1.2
524      */

525     public static Pattern JavaDoc sqlPatternToPattern(String JavaDoc pattern, boolean ignoreCase) {
526         String JavaDoc preprocessed = RegexUtil.sqlPatternToRegex(pattern);
527
528         int flag = (ignoreCase) ? Pattern.CASE_INSENSITIVE : 0;
529         return Pattern.compile(preprocessed, flag);
530     }
531
532     /**
533      * Returns true if a Member is accessible via reflection under normal Java access
534      * controls.
535      *
536      * @since 1.2
537      */

538     public static boolean isAccessible(Member JavaDoc member) {
539         return Modifier.isPublic(member.getModifiers())
540                 && Modifier.isPublic(member.getDeclaringClass().getModifiers());
541     }
542
543     /**
544      * Creates a Java class, handling regular class names as well as single-dimensional
545      * arrays and primitive types.
546      *
547      * @since 1.2
548      */

549     public static Class JavaDoc getJavaClass(String JavaDoc className) throws ClassNotFoundException JavaDoc {
550
551         // is there a better way to get array class from string name?
552

553         if (className == null) {
554             throw new ClassNotFoundException JavaDoc("Null class name");
555         }
556
557         ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
558
559         if (classLoader == null) {
560             classLoader = Util.class.getClassLoader();
561         }
562
563         // use custom logic on failure only, assuming primitives and arrays are not that
564
// common
565
try {
566             return Class.forName(className, true, classLoader);
567         }
568         catch (ClassNotFoundException JavaDoc e) {
569             if (!className.endsWith("[]")) {
570                 if ("byte".equals(className)) {
571                     return Byte.TYPE;
572                 }
573                 else if ("int".equals(className)) {
574                     return Integer.TYPE;
575                 }
576                 else if ("short".equals(className)) {
577                     return Short.TYPE;
578                 }
579                 else if ("char".equals(className)) {
580                     return Character.TYPE;
581                 }
582                 else if ("double".equals(className)) {
583                     return Double.TYPE;
584                 }
585                 else if ("long".equals(className)) {
586                     return Long.TYPE;
587                 }
588                 else if ("float".equals(className)) {
589                     return Float.TYPE;
590                 }
591                 else if ("boolean".equals(className)) {
592                     return Boolean.TYPE;
593                 }
594                 // try inner class often specified with "." instead of $
595
else {
596                     int dot = className.lastIndexOf('.');
597                     if (dot > 0 && dot + 1 < className.length()) {
598                         className = className.substring(0, dot)
599                                 + "$"
600                                 + className.substring(dot + 1);
601                         try {
602                             return Class.forName(className, true, classLoader);
603                         }
604                         catch (ClassNotFoundException JavaDoc nestedE) {
605                             // ignore, throw the original exception...
606
}
607                     }
608                 }
609
610                 throw e;
611             }
612
613             if (className.length() < 3) {
614                 throw new IllegalArgumentException JavaDoc("Invalid class name: " + className);
615             }
616
617             // TODO: support for multi-dim arrays
618
className = className.substring(0, className.length() - 2);
619
620             if ("byte".equals(className)) {
621                 return byte[].class;
622             }
623             else if ("int".equals(className)) {
624                 return int[].class;
625             }
626             else if ("short".equals(className)) {
627                 return short[].class;
628             }
629             else if ("char".equals(className)) {
630                 return char[].class;
631             }
632             else if ("double".equals(className)) {
633                 return double[].class;
634             }
635             else if ("float".equals(className)) {
636                 return float[].class;
637             }
638             else if ("boolean".equals(className)) {
639                 return boolean[].class;
640             }
641
642             return Class.forName("[L" + className + ";", true, classLoader);
643         }
644     }
645 }
646
Popular Tags