KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > helper > Helper


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.helper;
23
24 import java.util.*;
25 import java.io.*;
26 import java.lang.reflect.*;
27 import java.security.AccessController JavaDoc;
28 import java.security.PrivilegedActionException JavaDoc;
29 import java.sql.Timestamp JavaDoc;
30
31 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper;
32 import oracle.toplink.essentials.internal.security.PrivilegedNewInstanceFromClass;
33 import oracle.toplink.essentials.internal.security.PrivilegedGetField;
34 import oracle.toplink.essentials.internal.security.PrivilegedGetMethod;
35 import oracle.toplink.essentials.exceptions.*;
36
37 /**
38  * INTERNAL:
39  * <p>
40  * <b>Purpose</b>: Define any usefull methods that are missing from the base Java.
41  */

42 public class Helper implements Serializable {
43
44     /** Used to configure JDBC level date optimization. */
45     protected static boolean shouldOptimizeDates = false;
46
47     /** Used to store null values in hashtables, is helper because need to be serializable. */
48     protected static Object JavaDoc nullWrapper = new Helper();
49
50     /** PERF: Used to cache a set of calendars for conversion/printing purposes. */
51     protected static Vector calendarCache = new Vector(10);
52
53     /** PERF: Cache default timezone for calendar conversion. */
54     protected static TimeZone defaultTimeZone = TimeZone.getDefault();
55
56     // Changed static initialization to lazy initialization for bug 2756643
57

58     /** Store CR string, for some reason \n is not platform independent. */
59     protected static String JavaDoc CR = null;
60
61     /** Prime the platform-dependent path separator */
62     protected static String JavaDoc PATH_SEPARATOR = null;
63
64     /** Prime the platform-dependent file separator */
65     protected static String JavaDoc FILE_SEPARATOR = null;
66
67     /** Prime the platform-dependent current working directory */
68     protected static String JavaDoc CURRENT_WORKING_DIRECTORY = null;
69
70     /** Prime the platform-dependent temporary directory */
71     protected static String JavaDoc TEMP_DIRECTORY = null;
72
73     /**
74      * Return if JDBC date access should be optimized.
75      */

76     public static boolean shouldOptimizeDates() {
77         return shouldOptimizeDates;
78     }
79
80     /**
81      * Return if JDBC date access should be optimized.
82      */

83     public static void setShouldOptimizeDates(boolean value) {
84         shouldOptimizeDates = value;
85     }
86
87     /**
88      * PERF: This is used to optimize Calendar conversion/printing.
89      * This should only be used when a calendar is temporarily required,
90      * when finished it must be released back.
91      */

92     public static Calendar allocateCalendar() {
93         Calendar calendar = null;
94         synchronized (calendarCache) {
95             if (calendarCache.size() > 0) {
96                 calendar = (Calendar)calendarCache.remove(calendarCache.size() - 1);
97             }
98         }
99         if (calendar == null) {
100             calendar = Calendar.getInstance();
101         }
102         return calendar;
103     }
104
105     /**
106      * PERF: Return the cached default platform.
107      * Used for ensuring Calendar are in the local timezone.
108      * The JDK method clones the timezone, so cache it locally.
109      */

110     public static TimeZone getDefaultTimeZone() {
111         return defaultTimeZone;
112     }
113
114     /**
115      * PERF: This is used to optimize Calendar conversion/printing.
116      * This should only be used when a calendar is temporarily required,
117      * when finished it must be released back.
118      */

119     public static void releaseCalendar(Calendar calendar) {
120         if (calendarCache.size() < 10) {
121             calendarCache.add(calendar);
122         }
123     }
124
125     public static void addAllToVector(Vector theVector, Vector elementsToAdd) {
126         for (Enumeration stream = elementsToAdd.elements(); stream.hasMoreElements();) {
127             theVector.addElement(stream.nextElement());
128         }
129     }
130
131     public static void addAllToVector(Vector theVector, List elementsToAdd) {
132         theVector.addAll(elementsToAdd);
133     }
134
135     public static Vector addAllUniqueToVector(Vector theVector, Vector elementsToAdd) {
136         for (Enumeration stream = elementsToAdd.elements(); stream.hasMoreElements();) {
137             Object JavaDoc element = stream.nextElement();
138             if (!theVector.contains(element)) {
139                 theVector.addElement(element);
140             }
141         }
142
143         return theVector;
144     }
145
146     /**
147     * Convert the specified vector into an array.
148     */

149     public static Object JavaDoc[] arrayFromVector(Vector vector) {
150         Object JavaDoc[] result = new Object JavaDoc[vector.size()];
151         for (int i = 0; i < vector.size(); i++) {
152             result[i] = vector.elementAt(i);
153         }
154         return result;
155     }
156
157     /**
158      * Convert the HEX string to a byte array.
159      * HEX allows for binary data to be printed.
160      */

161     public static byte[] buildBytesFromHexString(String JavaDoc hex) {
162         String JavaDoc tmpString = (String JavaDoc)hex;
163         if ((tmpString.length() % 2) != 0) {
164             throw ConversionException.couldNotConvertToByteArray(hex);
165         }
166         byte[] bytes = new byte[tmpString.length() / 2];
167         int byteIndex;
168         int strIndex;
169         byte digit1;
170         byte digit2;
171         for (byteIndex = bytes.length - 1, strIndex = tmpString.length() - 2; byteIndex >= 0;
172                  byteIndex--, strIndex -= 2) {
173             digit1 = (byte)Character.digit(tmpString.charAt(strIndex), 16);
174             digit2 = (byte)Character.digit(tmpString.charAt(strIndex + 1), 16);
175             if ((digit1 == -1) || (digit2 == -1)) {
176                 throw ConversionException.couldNotBeConverted(hex, ClassConstants.APBYTE);
177             }
178             bytes[byteIndex] = (byte)((digit1 * 16) + digit2);
179         }
180         return bytes;
181     }
182
183     /**
184      * Convert the passed Vector to a Hashtable
185      * Return the Hashtable
186      */

187     public static Hashtable buildHashtableFromVector(Vector theVector) {
188         Hashtable toReturn = new Hashtable(theVector.size());
189
190         Iterator iter = theVector.iterator();
191         while (iter.hasNext()) {
192             Object JavaDoc next = iter.next();
193             toReturn.put(next, next);
194         }
195         return toReturn;
196     }
197
198     /**
199      * Convert the byte array to a HEX string.
200      * HEX allows for binary data to be printed.
201      */

202     public static String JavaDoc buildHexStringFromBytes(byte[] bytes) {
203         char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
204         StringBuffer JavaDoc stringBuffer = new StringBuffer JavaDoc();
205         int tempByte;
206         for (int byteIndex = 0; byteIndex < ((byte[])bytes).length; byteIndex++) {
207             tempByte = ((byte[])bytes)[byteIndex];
208             if (tempByte < 0) {
209                 tempByte = tempByte + 256;//compensate for the fact that byte is signed in Java
210
}
211             tempByte = (byte)(tempByte / 16);//get the first digit
212
if (tempByte > 16) {
213                 throw ConversionException.couldNotBeConverted(bytes, ClassConstants.STRING);
214             }
215             stringBuffer.append(hexArray[tempByte]);
216
217             tempByte = ((byte[])bytes)[byteIndex];
218             if (tempByte < 0) {
219                 tempByte = tempByte + 256;
220             }
221             tempByte = (byte)(tempByte % 16);//get the second digit
222
if (tempByte > 16) {
223                 throw ConversionException.couldNotBeConverted(bytes, ClassConstants.STRING);
224             }
225             stringBuffer.append(hexArray[tempByte]);
226         }
227         return stringBuffer.toString();
228     }
229
230     /**
231       * Create a new Vector containing all of the hashtable elements
232       *
233       */

234     public static Vector buildVectorFromHashtableElements(Hashtable hashtable) {
235         Vector vector = new Vector(hashtable.size());
236         Enumeration enumeration = hashtable.elements();
237
238         while (enumeration.hasMoreElements()) {
239             vector.addElement(enumeration.nextElement());
240         }
241
242         return vector;
243     }
244
245     /**
246       * Create a new Vector containing all of the map elements.
247       */

248     public static Vector buildVectorFromMapElements(Map map) {
249         Vector vector = new Vector(map.size());
250         Iterator iterator = map.values().iterator();
251
252         while (iterator.hasNext()) {
253             vector.addElement(iterator.next());
254         }
255
256         return vector;
257     }
258
259     /**
260       * Create a new Vector containing all of the hashtable elements
261       *
262       */

263     public static Vector buildVectorFromHashtableElements(IdentityHashtable hashtable) {
264         Vector vector = new Vector(hashtable.size());
265         Enumeration enumeration = hashtable.elements();
266
267         while (enumeration.hasMoreElements()) {
268             vector.addElement(enumeration.nextElement());
269         }
270
271         return vector;
272     }
273
274     /**
275      * Answer a Calendar from a date.
276      */

277     public static Calendar calendarFromUtilDate(java.util.Date JavaDoc date) {
278         Calendar calendar = Calendar.getInstance();
279         calendar.setTime(date);
280         //In jdk1.3, millisecond is missing
281
if (date instanceof Timestamp JavaDoc) {
282             calendar.set(Calendar.MILLISECOND, ((Timestamp JavaDoc)date).getNanos() / 1000000);
283         }
284         return calendar;
285     }
286
287     /**
288      * INTERNAL:
289      * Return whether a Class implements a specific interface, either directly or indirectly
290      * (through interface or implementation inheritance).
291      * @return boolean
292      */

293     public static boolean classImplementsInterface(Class JavaDoc aClass, Class JavaDoc anInterface) {
294         // quick check
295
if (aClass == anInterface) {
296             return true;
297         }
298
299         Class JavaDoc[] interfaces = aClass.getInterfaces();
300
301         // loop through the "directly declared" interfaces
302
for (int i = 0; i < interfaces.length; i++) {
303             if (interfaces[i] == anInterface) {
304                 return true;
305             }
306         }
307
308         // recurse through the interfaces
309
for (int i = 0; i < interfaces.length; i++) {
310             if (classImplementsInterface(interfaces[i], anInterface)) {
311                 return true;
312             }
313         }
314
315         // finally, recurse up through the superclasses to Object
316
Class JavaDoc superClass = aClass.getSuperclass();
317         if (superClass == null) {
318             return false;
319         }
320         return classImplementsInterface(superClass, anInterface);
321     }
322
323     /**
324      * INTERNAL:
325      * Return whether a Class is a subclass of, or the same as, another Class.
326      * @return boolean
327      */

328     public static boolean classIsSubclass(Class JavaDoc subClass, Class JavaDoc superClass) {
329         Class JavaDoc temp = subClass;
330
331         if (superClass == null) {
332             return false;
333         }
334
335         while (temp != null) {
336             if (temp == superClass) {
337                 return true;
338             }
339             temp = temp.getSuperclass();
340         }
341         return false;
342     }
343
344     public static boolean compareArrays(Object JavaDoc[] array1, Object JavaDoc[] array2) {
345         if (array1.length != array2.length) {
346             return false;
347         }
348         for (int index = 0; index < array1.length; index++) {
349             //Related to Bug#3128838 fix. ! is added to correct the logic.
350
if (!array1[index].equals(array2[index])) {
351                 return false;
352             }
353         }
354         return true;
355     }
356
357     /**
358      * Compare two BigDecimals.
359      * This is required because the .equals method of java.math.BigDecimal ensures that
360      * the scale of the two numbers are equal. Therefore 0.0 != 0.00.
361      * @see java.math.BigDecimal#equals(Object)
362      */

363     public static boolean compareBigDecimals(java.math.BigDecimal JavaDoc one, java.math.BigDecimal JavaDoc two) {
364         if (one.scale() != two.scale()) {
365             double doubleOne = ((java.math.BigDecimal JavaDoc)one).doubleValue();
366             double doubleTwo = ((java.math.BigDecimal JavaDoc)two).doubleValue();
367             if ((doubleOne != Double.POSITIVE_INFINITY) && (doubleOne != Double.NEGATIVE_INFINITY) && (doubleTwo != Double.POSITIVE_INFINITY) && (doubleTwo != Double.NEGATIVE_INFINITY)) {
368                 return doubleOne == doubleTwo;
369             }
370         }
371         return one.equals(two);
372     }
373
374     public static boolean compareByteArrays(byte[] array1, byte[] array2) {
375         if (array1.length != array2.length) {
376             return false;
377         }
378         for (int index = 0; index < array1.length; index++) {
379             if (array1[index] != array2[index]) {
380                 return false;
381             }
382         }
383         return true;
384     }
385
386     public static boolean compareCharArrays(char[] array1, char[] array2) {
387         if (array1.length != array2.length) {
388             return false;
389         }
390         for (int index = 0; index < array1.length; index++) {
391             if (array1[index] != array2[index]) {
392                 return false;
393             }
394         }
395         return true;
396     }
397
398     /**
399     * PUBLIC:
400     *
401     * Compare two vectors of types. Return true if the size of the vectors is the
402     * same and each of the types in the first Vector are assignable from the types
403     * in the corresponding objects in the second Vector.
404     */

405     public static boolean areTypesAssignable(Vector types1, Vector types2) {
406         if ((types1 == null) || (types2 == null)) {
407             return false;
408         }
409
410         if (types1.size() == types2.size()) {
411             for (int i = 0; i < types1.size(); i++) {
412                 Class JavaDoc type1 = (Class JavaDoc)types1.elementAt(i);
413                 Class JavaDoc type2 = (Class JavaDoc)types2.elementAt(i);
414
415                 // if either are null then we assume assignability.
416
if ((type1 != null) && (type2 != null)) {
417                     if (!type1.isAssignableFrom(type2)) {
418                         return false;
419                     }
420                 }
421             }
422             return true;
423         }
424
425         return false;
426     }
427
428     /**
429       * PUBLIC:
430       * Compare the elements in 2 hashtables to see if they are equal
431       *
432       * Added Nov 9, 2000 JED Patch 2.5.1.8
433       */

434     public static boolean compareHashtables(Hashtable hashtable1, Hashtable hashtable2) {
435         Enumeration enumtr;
436         Object JavaDoc element;
437         Hashtable clonedHashtable;
438
439         if (hashtable1.size() != hashtable2.size()) {
440             return false;
441         }
442
443         clonedHashtable = (Hashtable)hashtable2.clone();
444
445         enumtr = hashtable1.elements();
446         while (enumtr.hasMoreElements()) {
447             element = enumtr.nextElement();
448             if (clonedHashtable.remove(element) == null) {
449                 return false;
450             }
451         }
452
453         return clonedHashtable.isEmpty();
454     }
455
456     /**
457      * Compare the elements in two <code>Vector</code>s to see if they are equal.
458      * The order of the elements is significant.
459      * @return whether the two vectors are equal
460      */

461     public static boolean compareOrderedVectors(Vector vector1, Vector vector2) {
462         if (vector1 == vector2) {
463             return true;
464         }
465         if (vector1.size() != vector2.size()) {
466             return false;
467         }
468         for (int index = 0; index < vector1.size(); index++) {
469             Object JavaDoc element1 = vector1.elementAt(index);
470             Object JavaDoc element2 = vector2.elementAt(index);
471             if (element1 == null) {// avoid null pointer exception
472
if (element2 != null) {
473                     return false;
474                 }
475             } else {
476                 if (!element1.equals(element2)) {
477                     return false;
478                 }
479             }
480         }
481         return true;
482     }
483
484     /**
485      * Compare the elements in two <code>Vector</code>s to see if they are equal.
486      * The order of the elements is ignored.
487      * @param v1 a vector
488      * @param v2 a vector
489      * @return whether the two vectors contain the same elements
490      */

491     public static boolean compareUnorderedVectors(Vector v1, Vector v2) {
492         if (v1 == v2) {
493             return true;
494         }
495         if (v1.size() != v2.size()) {
496             return false;
497         }
498
499         // One of the Vectors must be cloned so we don't miscompare
500
// vectors with the same elements but in different quantities.
501
// e.g. [fred, sam, sam] != [fred, sam, fred]
502
Vector v3 = (Vector)v2.clone();
503         for (int i = 0; i < v1.size(); i++) {
504             Object JavaDoc e1 = v1.elementAt(i);
505             if (e1 == null) {// avoid null pointer exception
506
// Helper.removeNullElement() will return false if the element was not present to begin with
507
if (!removeNullElement(v3)) {
508                     return false;
509                 }
510             } else {
511                 // Vector.removeElement() will return false if the element was not present to begin with
512
if (!v3.removeElement(e1)) {
513                     return false;
514                 }
515             }
516         }
517         return true;
518     }
519
520     public static Hashtable concatenateHashtables(Hashtable first, Hashtable second) {
521         Hashtable concatenation;
522         Object JavaDoc key;
523         Object JavaDoc value;
524
525         concatenation = new Hashtable(first.size() + second.size() + 4);
526
527         for (Enumeration keys = first.keys(); keys.hasMoreElements();) {
528             key = keys.nextElement();
529             value = first.get(key);
530             concatenation.put(key, value);
531         }
532
533         for (Enumeration keys = second.keys(); keys.hasMoreElements();) {
534             key = keys.nextElement();
535             value = second.get(key);
536             concatenation.put(key, value);
537         }
538
539         return concatenation;
540     }
541     
542     /**
543      * Merge the two Maps into a new HashMap.
544      */

545     public static Map concatenateMaps(Map first, Map second) {
546         Map concatenation = new HashMap(first.size() + second.size() + 4);
547
548         for (Iterator keys = first.keySet().iterator(); keys.hasNext();) {
549             Object JavaDoc key = keys.next();
550             Object JavaDoc value = first.get(key);
551             concatenation.put(key, value);
552         }
553
554         for (Iterator keys = second.keySet().iterator(); keys.hasNext();) {
555             Object JavaDoc key = keys.next();
556             Object JavaDoc value = second.get(key);
557             concatenation.put(key, value);
558         }
559
560         return concatenation;
561     }
562
563     /**
564       * Return a new vector with no duplicated values
565       *
566       */

567     public static Vector concatenateUniqueVectors(Vector first, Vector second) {
568         Vector concatenation;
569         Object JavaDoc element;
570
571         concatenation = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
572
573         for (Enumeration stream = first.elements(); stream.hasMoreElements();) {
574             concatenation.addElement(stream.nextElement());
575         }
576
577         for (Enumeration stream = second.elements(); stream.hasMoreElements();) {
578             element = stream.nextElement();
579             if (!concatenation.contains(element)) {
580                 concatenation.addElement(element);
581             }
582         }
583
584         return concatenation;
585
586     }
587
588     public static Vector concatenateVectors(Vector first, Vector second) {
589         Vector concatenation;
590
591         concatenation = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
592
593         for (Enumeration stream = first.elements(); stream.hasMoreElements();) {
594             concatenation.addElement(stream.nextElement());
595         }
596
597         for (Enumeration stream = second.elements(); stream.hasMoreElements();) {
598             concatenation.addElement(stream.nextElement());
599         }
600
601         return concatenation;
602
603     }
604
605     /**
606      * Returns whether the given <code>Vector</code> contains a <code>null</code> element
607      * Return <code>true</code> if the Vector contains a null element
608      * Return <code>false</code> otherwise.
609      * This is needed in jdk1.1, where <code>Vector.contains(Object)</code>
610      * for a <code>null</code> element will result in a <code>NullPointerException</code>....
611      */

612     public static boolean containsNull(Vector v, int index) {
613         return indexOfNullElement(v, 0) != -1;
614     }
615
616     /** Return a copy of the vector containing a subset starting at startIndex
617      * and ending at stopIndex.
618      * @param vector - original vector
619      * @param startIndex - starting position in vector
620      * @param stopIndex - ending position in vector
621      * @exception TopLinkException
622      */

623     public static Vector copyVector(Vector originalVector, int startIndex, int stopIndex) throws ValidationException {
624         Vector newVector;
625
626         if (stopIndex < startIndex) {
627             return oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
628         }
629
630         if ((startIndex < 0) || (startIndex > originalVector.size())) {
631             throw ValidationException.startIndexOutOfRange();
632         }
633
634         if ((stopIndex < 0) || (stopIndex > originalVector.size())) {
635             throw ValidationException.stopIndexOutOfRange();
636         }
637
638         newVector = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
639
640         for (int index = startIndex; index < stopIndex; index++) {
641             newVector.addElement(originalVector.elementAt(index));
642         }
643
644         return newVector;
645     }
646
647     /**
648      * Return a string containing the platform-appropriate
649      * characters for carriage return.
650      */

651     public static String JavaDoc cr() {
652         // bug 2756643
653
if (CR == null) {
654             CR = System.getProperty("line.separator");
655         }
656         return CR;
657     }
658
659     /**
660      * Return the name of the "current working directory".
661      */

662     public static String JavaDoc currentWorkingDirectory() {
663         // bug 2756643
664
if (CURRENT_WORKING_DIRECTORY == null) {
665             CURRENT_WORKING_DIRECTORY = System.getProperty("user.dir");
666         }
667         return CURRENT_WORKING_DIRECTORY;
668     }
669
670     /**
671      * Return the name of the "temporary directory".
672      */

673     public static String JavaDoc tempDirectory() {
674         // Bug 2756643
675
if (TEMP_DIRECTORY == null) {
676             TEMP_DIRECTORY = System.getProperty("java.io.tmpdir");
677         }
678         return TEMP_DIRECTORY;
679     }
680
681     /**
682      * Answer a Date from a long
683      *
684      * This implementation is based on the java.sql.Date class, not java.util.Date.
685      * @param longObject - milliseconds from the epoch (00:00:00 GMT
686      * Jan 1, 1970). Negative values represent dates prior to the epoch.
687      */

688     public static java.sql.Date JavaDoc dateFromLong(Long JavaDoc longObject) {
689         return new java.sql.Date JavaDoc(longObject.longValue());
690     }
691     
692     /**
693      * Answer a Date with the year, month, date.
694      * This builds a date avoiding the deprecated, inefficient and concurrency bottleneck date constructors.
695      * This implementation is based on the java.sql.Date class, not java.util.Date.
696      * The year, month, day are the values calendar uses,
697      * i.e. year is from 0, month is 0-11, date is 1-31.
698      */

699     public static java.sql.Date JavaDoc dateFromYearMonthDate(int year, int month, int day) {
700         // Use a calendar to compute the correct millis for the date.
701
Calendar localCalendar = allocateCalendar();
702         localCalendar.clear();
703         localCalendar.set(year, month, day, 0, 0, 0);
704         long millis = JavaPlatform.getTimeInMillis(localCalendar);
705         java.sql.Date JavaDoc date = new java.sql.Date JavaDoc(millis);
706         releaseCalendar(localCalendar);
707         return date;
708     }
709
710     /**
711      * Answer a Date from a string representation.
712      * The string MUST be a valid date and in one of the following
713      * formats: YYYY/MM/DD, YYYY-MM-DD, YY/MM/DD, YY-MM-DD.
714      *
715      * This implementation is based on the java.sql.Date class, not java.util.Date.
716      *
717      * The Date class contains some minor gotchas that you have to watch out for.
718      * @param dateString - string representation of date
719      * @return - date representation of string
720      */

721     public static java.sql.Date JavaDoc dateFromString(String JavaDoc dateString) throws ConversionException {
722         int year;
723         int month;
724         int day;
725         StringTokenizer dateStringTokenizer;
726
727         if (dateString.indexOf('/') != -1) {
728             dateStringTokenizer = new StringTokenizer(dateString, "/");
729         } else if (dateString.indexOf('-') != -1) {
730             dateStringTokenizer = new StringTokenizer(dateString, "- ");
731         } else {
732             throw ConversionException.incorrectDateFormat(dateString);
733         }
734
735         try {
736             year = Integer.parseInt(dateStringTokenizer.nextToken());
737             month = Integer.parseInt(dateStringTokenizer.nextToken());
738             day = Integer.parseInt(dateStringTokenizer.nextToken());
739         } catch (NumberFormatException JavaDoc exception) {
740             throw ConversionException.incorrectDateFormat(dateString);
741         }
742
743         // Java returns the month in terms of 0 - 11 instead of 1 - 12.
744
month = month - 1;
745
746         return dateFromYearMonthDate(year, month, day);
747     }
748
749     /**
750      * Answer a Date from a timestamp
751      *
752      * This implementation is based on the java.sql.Date class, not java.util.Date.
753      * @param timestampObject - timestamp representation of date
754      * @return - date representation of timestampObject
755      */

756     public static java.sql.Date JavaDoc dateFromTimestamp(java.sql.Timestamp JavaDoc timestamp) {
757         return sqlDateFromUtilDate(timestamp);
758     }
759
760     /**
761      * Returns true if the file of this name does indeed exist
762      */

763     public static boolean doesFileExist(String JavaDoc fileName) {
764         try {
765             new FileReader(fileName);
766         } catch (FileNotFoundException fnfException) {
767             return false;
768         }
769
770         return true;
771
772     }
773
774     /**
775      * Double up \ to allow printing of directories for source code generation.
776      */

777     public static String JavaDoc doubleSlashes(String JavaDoc path) {
778         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(path.length() + 5);
779         for (int index = 0; index < path.length(); index++) {
780             char charater = path.charAt(index);
781             buffer.append(charater);
782             if (charater == '\\') {
783                 buffer.append('\\');
784             }
785         }
786
787         return buffer.toString();
788     }
789
790     /**
791      * Extracts the actual path to the jar file.
792      */

793     public static String JavaDoc extractJarNameFromURL(java.net.URL JavaDoc url) {
794         String JavaDoc tempName = url.getFile();
795         int start = tempName.indexOf("file:") + 5;
796         int end = tempName.indexOf("!/");
797         return tempName.substring(start, end);
798     }
799
800     /**
801      * Return a string containing the platform-appropriate
802      * characters for separating directory and file names.
803      */

804     public static String JavaDoc fileSeparator() {
805         //Bug 2756643
806
if (FILE_SEPARATOR == null) {
807             FILE_SEPARATOR = System.getProperty("file.separator");
808         }
809         return FILE_SEPARATOR;
810     }
811
812     /**
813      * INTERNAL:
814      * Returns a Field for the specified Class and field name.
815      * Uses Class.getDeclaredField(String) to find the field.
816      * If the field is not found on the specified class
817      * the superclass is checked, and so on, recursively.
818      * Set accessible to true, so we can access private/package/protected fields.
819      */

820     public static Field getField(Class JavaDoc javaClass, String JavaDoc fieldName) throws NoSuchFieldException JavaDoc {
821         if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
822             try {
823                 return (Field)AccessController.doPrivileged(new PrivilegedGetField(javaClass, fieldName, true));
824             } catch (PrivilegedActionException JavaDoc exception) {
825                 throw (NoSuchFieldException JavaDoc)exception.getException();
826             }
827         } else {
828             return PrivilegedAccessHelper.getField(javaClass, fieldName, true);
829         }
830     }
831
832     /**
833      * INTERNAL:
834      * Returns a Method for the specified Class, method name,
835      * and formal parameter types.
836      * Uses Class.getDeclaredMethod(String Class[]) to find the method.
837      * If the method is not found on the specified class
838      * the superclass is checked, and so on, recursively.
839      * Set accessible to true, so we can access private/package/protected methods.
840      */

841     public static Method getDeclaredMethod(Class JavaDoc javaClass, String JavaDoc methodName, Class JavaDoc[] methodParameterTypes) throws NoSuchMethodException JavaDoc {
842         if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
843             try {
844                 return (Method)AccessController.doPrivileged(new PrivilegedGetMethod(javaClass, methodName, methodParameterTypes, true));
845             } catch (PrivilegedActionException JavaDoc exception) {
846                 return null;
847             }
848         } else {
849             return PrivilegedAccessHelper.getMethod(javaClass, methodName, methodParameterTypes, true);
850         }
851     }
852
853     /**
854      * Return the class instance from the class
855      */

856     public static Object JavaDoc getInstanceFromClass(Class JavaDoc classFullName) {
857         if (classFullName == null) {
858             return null;
859         }
860
861         try {
862             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
863                 try {
864                     return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(classFullName));
865                 } catch (PrivilegedActionException JavaDoc exception) {
866                     Exception JavaDoc throwableException = exception.getException();
867                     if (throwableException instanceof InstantiationException JavaDoc) {
868                         ValidationException exc = new ValidationException();
869                         exc.setInternalException(throwableException);
870                         throw exc;
871                     } else {
872                         ValidationException exc = new ValidationException();
873                         exc.setInternalException(throwableException);
874                         throw exc;
875                     }
876                 }
877             } else {
878                 return PrivilegedAccessHelper.newInstanceFromClass(classFullName);
879             }
880         } catch (InstantiationException JavaDoc notInstantiatedException) {
881             ValidationException exception = new ValidationException();
882             exception.setInternalException(notInstantiatedException);
883             throw exception;
884         } catch (IllegalAccessException JavaDoc notAccessedException) {
885             ValidationException exception = new ValidationException();
886             exception.setInternalException(notAccessedException);
887             throw exception;
888         }
889     }
890
891     /**
892      * Used to store null values in hashtables, is helper because need to be serializable.
893      */

894     public static Object JavaDoc getNullWrapper() {
895         return nullWrapper;
896     }
897
898     /**
899      * Returns the object class. If a class is primitive return its non primitive class
900      */

901     public static Class JavaDoc getObjectClass(Class JavaDoc javaClass) {
902         return ConversionManager.getObjectClass(javaClass);
903     }
904
905     /**
906      * Answers the unqualified class name for the provided class.
907      */

908     public static String JavaDoc getShortClassName(Class JavaDoc javaClass) {
909         return getShortClassName(javaClass.getName());
910     }
911
912     /**
913      * Answers the unqualified class name from the specified String.
914      */

915     public static String JavaDoc getShortClassName(String JavaDoc javaClassName) {
916         return javaClassName.substring(javaClassName.lastIndexOf('.') + 1);
917     }
918
919     /**
920      * Answers the unqualified class name for the specified object.
921      */

922     public static String JavaDoc getShortClassName(Object JavaDoc object) {
923         return getShortClassName(object.getClass());
924     }
925
926     /**
927      * return a package name for the specified class.
928      */

929     public static String JavaDoc getPackageName(Class JavaDoc javaClass) {
930         String JavaDoc className = Helper.getShortClassName(javaClass);
931         return javaClass.getName().substring(0, (javaClass.getName().length() - (className.length() + 1)));
932     }
933
934     /**
935      * Return a string containing the specified number of tabs.
936      */

937     public static String JavaDoc getTabs(int noOfTabs) {
938         StringWriter writer = new StringWriter();
939         for (int index = 0; index < noOfTabs; index++) {
940             writer.write("\t");
941         }
942         return writer.toString();
943     }
944
945     /**
946      * Returns the index of the the first <code>null</code> element found in the specified
947      * <code>Vector</code> starting the search at the starting index specified.
948      * Return an int >= 0 and less than size if a <code>null</code> element was found.
949      * Return -1 if a <code>null</code> element was not found.
950      * This is needed in jdk1.1, where <code>Vector.contains(Object)</code>
951      * for a <code>null</code> element will result in a <code>NullPointerException</code>....
952      */

953     public static int indexOfNullElement(Vector v, int index) {
954         for (int i = index; i < v.size(); i++) {
955             if (v.elementAt(i) == null) {
956                 return i;
957             }
958         }
959         return -1;
960     }
961
962     /**
963      * Return true if the object implements the Collection interface
964      * Creation date: (9/7/00 1:59:51 PM)
965      * @return boolean
966      * @param testObject java.lang.Object
967      */

968     public static boolean isCollection(Object JavaDoc testObject) {
969         // Does it implement the Collection interface
970
if (testObject instanceof Collection) {
971             return true;
972         }
973
974         // It's not a collection
975
return false;
976     }
977
978     /**
979      * ADVANCED
980      * returns true if the class in question is a primitive wrapper
981      */

982     public static boolean isPrimitiveWrapper(Class JavaDoc classInQuestion) {
983         return classInQuestion.equals(Character JavaDoc.class) || classInQuestion.equals(Boolean JavaDoc.class) || classInQuestion.equals(Byte JavaDoc.class) || classInQuestion.equals(Short JavaDoc.class) || classInQuestion.equals(Integer JavaDoc.class) || classInQuestion.equals(Long JavaDoc.class) || classInQuestion.equals(Float JavaDoc.class) || classInQuestion.equals(Double JavaDoc.class);
984     }
985
986     /**
987      * Returns true if the string given is an all upper case string
988      */

989     public static boolean isUpperCaseString(String JavaDoc s) {
990         char[] c = s.toCharArray();
991         for (int i = 0; i < s.length(); i++) {
992             if (Character.isLowerCase(c[i])) {
993                 return false;
994             }
995         }
996         return true;
997     }
998
999     /**
1000     * Returns true if the character given is a vowel. I.e. one of a,e,i,o,u,A,E,I,O,U.
1001     */

1002    public static boolean isVowel(char c) {
1003        return (c == 'A') || (c == 'a') || (c == 'e') || (c == 'E') || (c == 'i') || (c == 'I') || (c == 'o') || (c == 'O') || (c == 'u') || (c == 'U');
1004    }
1005
1006    /**
1007     * Return an array of the files in the specified directory.
1008     * This allows us to simplify jdk1.1 code a bit.
1009     */

1010    public static File[] listFilesIn(File directory) {
1011        if (directory.isDirectory()) {
1012            return directory.listFiles();
1013        } else {
1014            return new File[0];
1015        }
1016    }
1017
1018    /**
1019     * Make a Vector from the passed object.
1020     * If it's a Collection, iterate over the collection and add each item to the Vector.
1021     * If it's not a collection create a Vector and add the object to it.
1022     */

1023    public static Vector makeVectorFromObject(Object JavaDoc theObject) {
1024        if (theObject instanceof Vector) {
1025            return ((Vector)theObject);
1026        }
1027        if (theObject instanceof Collection) {
1028            Vector returnVector = new Vector(((Collection)theObject).size());
1029            Iterator iterator = ((Collection)theObject).iterator();
1030            while (iterator.hasNext()) {
1031                returnVector.add(iterator.next());
1032            }
1033            return returnVector;
1034        }
1035
1036        Vector returnVector = new Vector();
1037        returnVector.addElement(theObject);
1038        return returnVector;
1039    }
1040
1041    /**
1042     * Return a string containing the platform-appropriate
1043     * characters for separating entries in a path (e.g. the classpath)
1044     */

1045    public static String JavaDoc pathSeparator() {
1046        // Bug 2756643
1047
if (PATH_SEPARATOR == null) {
1048            PATH_SEPARATOR = System.getProperty("path.separator");
1049        }
1050        return PATH_SEPARATOR;
1051    }
1052
1053    /**
1054     * Return a String containing the printed stacktrace of an exception.
1055     */

1056    public static String JavaDoc printStackTraceToString(Throwable JavaDoc aThrowable) {
1057        StringWriter swriter = new StringWriter();
1058        PrintWriter writer = new PrintWriter(swriter, true);
1059        aThrowable.printStackTrace(writer);
1060        writer.close();
1061        return swriter.toString();
1062    }
1063
1064    /* Return a string representation of a number of milliseconds in terms of seconds, minutes, or
1065     * milliseconds, whichever is most appropriate.
1066     */

1067    public static String JavaDoc printTimeFromMilliseconds(long milliseconds) {
1068        if ((milliseconds > 1000) && (milliseconds < 60000)) {
1069            return (milliseconds / 1000) + "s";
1070        }
1071        if (milliseconds > 60000) {
1072            return (milliseconds / 60000) + "min " + printTimeFromMilliseconds(milliseconds % 60000);
1073        }
1074        return milliseconds + "ms";
1075    }
1076
1077    /**
1078     * Given a Vector, print it, even if there is a null in it
1079     */

1080    public static String JavaDoc printVector(Vector vector) {
1081        StringWriter stringWriter = new StringWriter();
1082        stringWriter.write("[");
1083        Enumeration enumtr = vector.elements();
1084        stringWriter.write(String.valueOf(enumtr.nextElement()));
1085        while (enumtr.hasMoreElements()) {
1086            stringWriter.write(" ");
1087            stringWriter.write(String.valueOf(enumtr.nextElement()));
1088        }
1089        stringWriter.write("]");
1090        return stringWriter.toString();
1091
1092    }
1093
1094    public static Hashtable rehashHashtable(Hashtable table) {
1095        Hashtable rehashedTable = new Hashtable(table.size() + 2);
1096
1097        Enumeration values = table.elements();
1098        for (Enumeration keys = table.keys(); keys.hasMoreElements();) {
1099            Object JavaDoc key = keys.nextElement();
1100            Object JavaDoc value = values.nextElement();
1101            rehashedTable.put(key, value);
1102        }
1103
1104        return rehashedTable;
1105    }
1106    
1107    public static Map rehashMap(Map table) {
1108        HashMap rehashedTable = new HashMap(table.size() + 2);
1109
1110        Iterator values = table.values().iterator();
1111        for (Iterator keys = table.keySet().iterator(); keys.hasNext();) {
1112            Object JavaDoc key = keys.next();
1113            Object JavaDoc value = values.next();
1114            rehashedTable.put(key, value);
1115        }
1116
1117        return rehashedTable;
1118    }
1119
1120    /**
1121     * Returns a String which has had enough non-alphanumeric characters removed to be equal to
1122     * the maximumStringLength.
1123     */

1124    public static String JavaDoc removeAllButAlphaNumericToFit(String JavaDoc s1, int maximumStringLength) {
1125        int s1Size = s1.length();
1126        if (s1Size <= maximumStringLength) {
1127            return s1;
1128        }
1129
1130        // Remove the necessary number of characters
1131
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1132        int numberOfCharsToBeRemoved = s1.length() - maximumStringLength;
1133        int s1Index = 0;
1134        while ((numberOfCharsToBeRemoved > 0) && (s1Index < s1Size)) {
1135            char currentChar = s1.charAt(s1Index);
1136            if (Character.isLetterOrDigit(currentChar)) {
1137                buf.append(currentChar);
1138            } else {
1139                numberOfCharsToBeRemoved--;
1140            }
1141            s1Index++;
1142        }
1143
1144        // Append the rest of the character that were not parsed through.
1145
// Is it quicker to build a substring and append that?
1146
while (s1Index < s1Size) {
1147            buf.append(s1.charAt(s1Index));
1148            s1Index++;
1149        }
1150
1151        //
1152
return buf.toString();
1153    }
1154
1155    /**
1156     * Returns a String which has had enough of the specified character removed to be equal to
1157     * the maximumStringLength.
1158     */

1159    public static String JavaDoc removeCharacterToFit(String JavaDoc s1, char aChar, int maximumStringLength) {
1160        int s1Size = s1.length();
1161        if (s1Size <= maximumStringLength) {
1162            return s1;
1163        }
1164
1165        // Remove the necessary number of characters
1166
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1167        int numberOfCharsToBeRemoved = s1.length() - maximumStringLength;
1168        int s1Index = 0;
1169        while ((numberOfCharsToBeRemoved > 0) && (s1Index < s1Size)) {
1170            char currentChar = s1.charAt(s1Index);
1171            if (currentChar == aChar) {
1172                numberOfCharsToBeRemoved--;
1173            } else {
1174                buf.append(currentChar);
1175            }
1176            s1Index++;
1177        }
1178
1179        // Append the rest of the character that were not parsed through.
1180
// Is it quicker to build a substring and append that?
1181
while (s1Index < s1Size) {
1182            buf.append(s1.charAt(s1Index));
1183            s1Index++;
1184        }
1185
1186        //
1187
return buf.toString();
1188    }
1189
1190    /**
1191     * Remove the first <code>null</code> element found in the specified <code>Vector</code>.
1192     * Return <code>true</code> if a <code>null</code> element was found and removed.
1193     * Return <code>false</code> if a <code>null</code> element was not found.
1194     * This is needed in jdk1.1, where <code>Vector.removeElement(Object)</code>
1195     * for a <code>null</code> element will result in a <code>NullPointerException</code>....
1196     */

1197    public static boolean removeNullElement(Vector v) {
1198        int indexOfNull = indexOfNullElement(v, 0);
1199        if (indexOfNull != -1) {
1200            v.removeElementAt(indexOfNull);
1201            return true;
1202        }
1203        return false;
1204    }
1205
1206    /**
1207     * Returns a String which has had enough of the specified character removed to be equal to
1208     * the maximumStringLength.
1209     */

1210    public static String JavaDoc removeVowels(String JavaDoc s1) {
1211        // Remove the vowels
1212
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1213        int s1Size = s1.length();
1214        int s1Index = 0;
1215        while (s1Index < s1Size) {
1216            char currentChar = s1.charAt(s1Index);
1217            if (!isVowel(currentChar)) {
1218                buf.append(currentChar);
1219            }
1220            s1Index++;
1221        }
1222
1223        //
1224
return buf.toString();
1225    }
1226
1227    /**
1228     * Replaces the first subString of the source with the replacement.
1229     */

1230    public static String JavaDoc replaceFirstSubString(String JavaDoc source, String JavaDoc subString, String JavaDoc replacement) {
1231        int index = source.indexOf(subString);
1232
1233        if (index >= 0) {
1234            return source.substring(0, index) + replacement + source.substring(index + subString.length());
1235        }
1236        return null;
1237    }
1238
1239    public static Vector reverseVector(Vector theVector) {
1240        Vector tempVector = new Vector(theVector.size());
1241        Object JavaDoc currentElement;
1242
1243        for (int i = theVector.size() - 1; i > -1; i--) {
1244            currentElement = theVector.elementAt(i);
1245            tempVector.addElement(currentElement);
1246        }
1247
1248        return tempVector;
1249    }
1250
1251    /**
1252     * Returns a new string with all space characters removed from the right
1253     *
1254     * @param originalString - timestamp representation of date
1255     * @return - String
1256     */

1257    public static String JavaDoc rightTrimString(String JavaDoc originalString) {
1258        int len = originalString.length();
1259        while ((len > 0) && (originalString.charAt(len - 1) <= ' ')) {
1260            len--;
1261        }
1262        return originalString.substring(0, len);
1263    }
1264
1265    /**
1266     * Returns a String which is a concatenation of two string which have had enough
1267     * vowels removed from them so that the sum of the sized of the two strings is less than
1268     * or equal to the specified size.
1269     */

1270    public static String JavaDoc shortenStringsByRemovingVowelsToFit(String JavaDoc s1, String JavaDoc s2, int maximumStringLength) {
1271        int size = s1.length() + s2.length();
1272        if (size <= maximumStringLength) {
1273            return s1 + s2;
1274        }
1275
1276        // Remove the necessary number of characters
1277
int s1Size = s1.length();
1278        int s2Size = s2.length();
1279        StringBuffer JavaDoc buf1 = new StringBuffer JavaDoc();
1280        StringBuffer JavaDoc buf2 = new StringBuffer JavaDoc();
1281        int numberOfCharsToBeRemoved = size - maximumStringLength;
1282        int s1Index = 0;
1283        int s2Index = 0;
1284        int modulo2 = 0;
1285
1286        // While we still want to remove characters, and not both string are done.
1287
while ((numberOfCharsToBeRemoved > 0) && !((s1Index >= s1Size) && (s2Index >= s2Size))) {
1288            if ((modulo2 % 2) == 0) {
1289                // Remove from s1
1290
if (s1Index < s1Size) {
1291                    if (isVowel(s1.charAt(s1Index))) {
1292                        numberOfCharsToBeRemoved--;
1293                    } else {
1294                        buf1.append(s1.charAt(s1Index));
1295                    }
1296                    s1Index++;
1297                }
1298            } else {
1299                // Remove from s2
1300
if (s2Index < s2Size) {
1301                    if (isVowel(s2.charAt(s2Index))) {
1302                        numberOfCharsToBeRemoved--;
1303                    } else {
1304                        buf2.append(s2.charAt(s2Index));
1305                    }
1306                    s2Index++;
1307                }
1308            }
1309            modulo2++;
1310        }
1311
1312        // Append the rest of the character that were not parsed through.
1313
// Is it quicker to build a substring and append that?
1314
while (s1Index < s1Size) {
1315            buf1.append(s1.charAt(s1Index));
1316            s1Index++;
1317        }
1318        while (s2Index < s2Size) {
1319            buf2.append(s2.charAt(s2Index));
1320            s2Index++;
1321        }
1322
1323        //
1324
return buf1.toString() + buf2.toString();
1325    }
1326
1327    /**
1328     * Answer a sql.Date from a timestamp.
1329     */

1330    public static java.sql.Date JavaDoc sqlDateFromUtilDate(java.util.Date JavaDoc utilDate) {
1331        // PERF: Avoid deprecated get methods, that are now very inefficient.
1332
Calendar calendar = allocateCalendar();
1333        calendar.setTime(utilDate);
1334        java.sql.Date JavaDoc date = dateFromCalendar(calendar);
1335        releaseCalendar(calendar);
1336        return date;
1337    }
1338
1339    /**
1340     * Print the sql.Date.
1341     */

1342    public static String JavaDoc printDate(java.sql.Date JavaDoc date) {
1343        // PERF: Avoid deprecated get methods, that are now very inefficient and used from toString.
1344
Calendar calendar = allocateCalendar();
1345        calendar.setTime(date);
1346        String JavaDoc string = printDate(calendar);
1347        releaseCalendar(calendar);
1348        return string;
1349    }
1350
1351    /**
1352     * Print the date part of the calendar.
1353     */

1354    public static String JavaDoc printDate(Calendar calendar) {
1355        return printDate(calendar, true);
1356    }
1357
1358    /**
1359     * Print the date part of the calendar.
1360     * Normally the calendar must be printed in the local time, but if the timezone is printed,
1361     * it must be printing in its timezone.
1362     */

1363    public static String JavaDoc printDate(Calendar calendar, boolean useLocalTime) {
1364        int year;
1365        int month;
1366        int day;
1367        if (useLocalTime && (!defaultTimeZone.equals(calendar.getTimeZone()))) {
1368            // Must convert the calendar to the local timezone if different, as dates have no timezone (always local).
1369
Calendar localCalendar = allocateCalendar();
1370            JavaPlatform.setTimeInMillis(localCalendar, JavaPlatform.getTimeInMillis(calendar));
1371            year = localCalendar.get(Calendar.YEAR);
1372            month = localCalendar.get(Calendar.MONTH) + 1;
1373            day = localCalendar.get(Calendar.DATE);
1374            releaseCalendar(localCalendar);
1375        } else {
1376            year = calendar.get(Calendar.YEAR);
1377            month = calendar.get(Calendar.MONTH) + 1;
1378            day = calendar.get(Calendar.DATE);
1379        }
1380
1381        char[] buf = "2000-00-00".toCharArray();
1382        buf[0] = Character.forDigit(year / 1000, 10);
1383        buf[1] = Character.forDigit((year / 100) % 10, 10);
1384        buf[2] = Character.forDigit((year / 10) % 10, 10);
1385        buf[3] = Character.forDigit(year % 10, 10);
1386        buf[5] = Character.forDigit(month / 10, 10);
1387        buf[6] = Character.forDigit(month % 10, 10);
1388        buf[8] = Character.forDigit(day / 10, 10);
1389        buf[9] = Character.forDigit(day % 10, 10);
1390
1391        return new String JavaDoc(buf);
1392    }
1393
1394    /**
1395     * Print the sql.Time.
1396     */

1397    public static String JavaDoc printTime(java.sql.Time JavaDoc time) {
1398        // PERF: Avoid deprecated get methods, that are now very inefficient and used from toString.
1399
Calendar calendar = allocateCalendar();
1400        calendar.setTime(time);
1401        String JavaDoc string = printTime(calendar);
1402        releaseCalendar(calendar);
1403        return string;
1404    }
1405
1406    /**
1407     * Print the time part of the calendar.
1408     */

1409    public static String JavaDoc printTime(Calendar calendar) {
1410        return printTime(calendar, true);
1411    }
1412
1413    /**
1414     * Print the time part of the calendar.
1415     * Normally the calendar must be printed in the local time, but if the timezone is printed,
1416     * it must be printing in its timezone.
1417     */

1418    public static String JavaDoc printTime(Calendar calendar, boolean useLocalTime) {
1419        int hour;
1420        int minute;
1421        int second;
1422        if (useLocalTime && (!defaultTimeZone.equals(calendar.getTimeZone()))) {
1423            // Must convert the calendar to the local timezone if different, as dates have no timezone (always local).
1424
Calendar localCalendar = allocateCalendar();
1425            JavaPlatform.setTimeInMillis(localCalendar, JavaPlatform.getTimeInMillis(calendar));
1426            hour = localCalendar.get(Calendar.HOUR_OF_DAY);
1427            minute = localCalendar.get(Calendar.MINUTE);
1428            second = localCalendar.get(Calendar.SECOND);
1429            releaseCalendar(localCalendar);
1430        } else {
1431            hour = calendar.get(Calendar.HOUR_OF_DAY);
1432            minute = calendar.get(Calendar.MINUTE);
1433            second = calendar.get(Calendar.SECOND);
1434        }
1435        String JavaDoc hourString;
1436        String JavaDoc minuteString;
1437        String JavaDoc secondString;
1438        if (hour < 10) {
1439            hourString = "0" + hour;
1440        } else {
1441            hourString = Integer.toString(hour);
1442        }
1443        if (minute < 10) {
1444            minuteString = "0" + minute;
1445        } else {
1446            minuteString = Integer.toString(minute);
1447        }
1448        if (second < 10) {
1449            secondString = "0" + second;
1450        } else {
1451            secondString = Integer.toString(second);
1452        }
1453        return (hourString + ":" + minuteString + ":" + secondString);
1454    }
1455
1456    /**
1457     * Print the Calendar.
1458     */

1459    public static String JavaDoc printCalendar(Calendar calendar) {
1460        return printCalendar(calendar, true);
1461    }
1462
1463    /**
1464     * Print the Calendar.
1465     * Normally the calendar must be printed in the local time, but if the timezone is printed,
1466     * it must be printing in its timezone.
1467     */

1468    public static String JavaDoc printCalendar(Calendar calendar, boolean useLocalTime) {
1469        String JavaDoc millisString;
1470
1471        // String zeros = "000000000";
1472
if (calendar.get(Calendar.MILLISECOND) == 0) {
1473            millisString = "0";
1474        } else {
1475            millisString = buildZeroPrefixAndTruncTrailZeros(calendar.get(Calendar.MILLISECOND), 3);
1476        }
1477
1478        StringBuffer JavaDoc timestampBuf = new StringBuffer JavaDoc();
1479        timestampBuf.append(printDate(calendar, useLocalTime));
1480        timestampBuf.append(" ");
1481        timestampBuf.append(printTime(calendar, useLocalTime));
1482        timestampBuf.append(".");
1483        timestampBuf.append(millisString);
1484
1485        return timestampBuf.toString();
1486    }
1487
1488    /**
1489     * Print the sql.Timestamp.
1490     */

1491    public static String JavaDoc printTimestamp(java.sql.Timestamp JavaDoc timestamp) {
1492        // PERF: Avoid deprecated get methods, that are now very inefficient and used from toString.
1493
Calendar calendar = allocateCalendar();
1494        calendar.setTime(timestamp);
1495
1496        String JavaDoc nanosString;
1497
1498        // String zeros = "000000000";
1499
String JavaDoc yearZeros = "0000";
1500
1501        if (timestamp.getNanos() == 0) {
1502            nanosString = "0";
1503        } else {
1504            nanosString = buildZeroPrefixAndTruncTrailZeros(timestamp.getNanos(), 9);
1505        }
1506
1507        StringBuffer JavaDoc timestampBuf = new StringBuffer JavaDoc();
1508        timestampBuf.append(printDate(calendar));
1509        timestampBuf.append(" ");
1510        timestampBuf.append(printTime(calendar));
1511        timestampBuf.append(".");
1512        timestampBuf.append(nanosString);
1513
1514        releaseCalendar(calendar);
1515
1516        return (timestampBuf.toString());
1517    }
1518
1519    /**
1520     * Build a numerical string with leading 0s. number is an existing number that
1521     * the new string will be built on. totalDigits is the number of the required
1522     * digits of the string.
1523     */

1524    public static String JavaDoc buildZeroPrefix(int number, int totalDigits) {
1525        String JavaDoc zeros = "000000000";
1526        int absValue = (number < 0) ? (-number) : number;
1527        String JavaDoc numbString = Integer.toString(absValue);
1528
1529        // Add leading zeros
1530
numbString = zeros.substring(0, (totalDigits - numbString.length())) + numbString;
1531
1532        if (number < 0) {
1533            numbString = "-" + numbString;
1534        } else {
1535            numbString = "+" + numbString;
1536        }
1537        return numbString;
1538    }
1539 
1540    /**
1541     * Build a numerical string with leading 0s and truncate trailing zeros. number is
1542     * an existing number that the new string will be built on. totalDigits is the number
1543     * of the required digits of the string.
1544     */

1545    public static String JavaDoc buildZeroPrefixAndTruncTrailZeros(int number, int totalDigits) {
1546        String JavaDoc zeros = "000000000";
1547        String JavaDoc numbString = Integer.toString(number);
1548
1549        // Add leading zeros
1550
numbString = zeros.substring(0, (totalDigits - numbString.length())) + numbString;
1551        // Truncate trailing zeros
1552
char[] numbChar = new char[numbString.length()];
1553        numbString.getChars(0, numbString.length(), numbChar, 0);
1554        int truncIndex = totalDigits - 1;
1555        while (numbChar[truncIndex] == '0') {
1556            truncIndex--;
1557        }
1558        return new String JavaDoc(numbChar, 0, truncIndex + 1);
1559    }
1560
1561    /**
1562     * Print the sql.Timestamp without the nanos portion.
1563     */

1564    public static String JavaDoc printTimestampWithoutNanos(java.sql.Timestamp JavaDoc timestamp) {
1565        // PERF: Avoid deprecated get methods, that are now very inefficient and used from toString.
1566
Calendar calendar = allocateCalendar();
1567        calendar.setTime(timestamp);
1568        String JavaDoc string = printCalendarWithoutNanos(calendar);
1569        releaseCalendar(calendar);
1570        return string;
1571    }
1572
1573    /**
1574     * Print the Calendar without the nanos portion.
1575     */

1576    public static String JavaDoc printCalendarWithoutNanos(Calendar calendar) {
1577        StringBuffer JavaDoc timestampBuf = new StringBuffer JavaDoc();
1578        timestampBuf.append(printDate(calendar));
1579        timestampBuf.append(" ");
1580        timestampBuf.append(printTime(calendar));
1581        return timestampBuf.toString();
1582    }
1583
1584    /**
1585     * Answer a sql.Date from a Calendar.
1586     */

1587    public static java.sql.Date JavaDoc dateFromCalendar(Calendar calendar) {
1588        if (!defaultTimeZone.equals(calendar.getTimeZone())) {
1589            // Must convert the calendar to the local timezone if different, as dates have no timezone (always local).
1590
Calendar localCalendar = allocateCalendar();
1591            JavaPlatform.setTimeInMillis(localCalendar, JavaPlatform.getTimeInMillis(calendar));
1592            java.sql.Date JavaDoc date = dateFromYearMonthDate(localCalendar.get(Calendar.YEAR), localCalendar.get(Calendar.MONTH), localCalendar.get(Calendar.DATE));
1593            releaseCalendar(localCalendar);
1594            return date;
1595        }
1596        return dateFromYearMonthDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
1597    }
1598
1599    /**
1600     * Can be used to mark code if a workaround is added for a JDBC driver or other bug.
1601     */

1602    public static void systemBug(String JavaDoc description) {
1603        // Use sender to find what is needy.
1604
}
1605
1606    /**
1607     * Answer a Time from a Date
1608     *
1609     * This implementation is based on the java.sql.Date class, not java.util.Date.
1610     * @param timestampObject - time representation of date
1611     * @return - time representation of dateObject
1612     */

1613    public static java.sql.Time JavaDoc timeFromDate(java.util.Date JavaDoc date) {
1614        // PERF: Avoid deprecated get methods, that are now very inefficient.
1615
Calendar calendar = allocateCalendar();
1616        calendar.setTime(date);
1617        java.sql.Time JavaDoc time = timeFromCalendar(calendar);
1618        releaseCalendar(calendar);
1619        return time;
1620    }
1621
1622    /**
1623     * Answer a Time from a long
1624     *
1625     * @param longObject - milliseconds from the epoch (00:00:00 GMT
1626     * Jan 1, 1970). Negative values represent dates prior to the epoch.
1627     */

1628    public static java.sql.Time JavaDoc timeFromLong(Long JavaDoc longObject) {
1629        return new java.sql.Time JavaDoc(longObject.longValue());
1630    }
1631        
1632    /**
1633     * Answer a Time with the hour, minute, second.
1634     * This builds a time avoiding the deprecated, inefficient and concurrency bottleneck date constructors.
1635     * The hour, minute, second are the values calendar uses,
1636     * i.e. year is from 0, month is 0-11, date is 1-31.
1637     */

1638    public static java.sql.Time JavaDoc timeFromHourMinuteSecond(int hour, int minute, int second) {
1639        // Use a calendar to compute the correct millis for the date.
1640
Calendar localCalendar = allocateCalendar();
1641        localCalendar.clear();
1642        localCalendar.set(1970, 0, 1, hour, minute, second);
1643        long millis = JavaPlatform.getTimeInMillis(localCalendar);
1644        java.sql.Time JavaDoc time = new java.sql.Time JavaDoc(millis);
1645        releaseCalendar(localCalendar);
1646        return time;
1647    }
1648
1649    /**
1650     * Answer a Time from a string representation.
1651     * This method will accept times in the following
1652     * formats: HH-MM-SS, HH:MM:SS
1653     *
1654     * @param timeString - string representation of time
1655     * @return - time representation of string
1656     */

1657    public static java.sql.Time JavaDoc timeFromString(String JavaDoc timeString) throws ConversionException {
1658        int hour;
1659        int minute;
1660        int second;
1661        String JavaDoc timePortion = timeString;
1662
1663        if (timeString.length() > 12) {
1664            // Longer strings are Timestamp format (ie. Sybase & Oracle)
1665
timePortion = timeString.substring(11, 19);
1666        }
1667
1668        if ((timePortion.indexOf('-') == -1) && (timePortion.indexOf('/') == -1) && (timePortion.indexOf('.') == -1) && (timePortion.indexOf(':') == -1)) {
1669            throw ConversionException.incorrectTimeFormat(timePortion);
1670        }
1671        StringTokenizer timeStringTokenizer = new StringTokenizer(timePortion, " /:.-");
1672
1673        try {
1674            hour = Integer.parseInt(timeStringTokenizer.nextToken());
1675            minute = Integer.parseInt(timeStringTokenizer.nextToken());
1676            second = Integer.parseInt(timeStringTokenizer.nextToken());
1677        } catch (NumberFormatException JavaDoc exception) {
1678            throw ConversionException.incorrectTimeFormat(timeString);
1679        }
1680
1681        return timeFromHourMinuteSecond(hour, minute, second);
1682    }
1683
1684    /**
1685     * Answer a Time from a Timestamp
1686     * Usus the Hours, Minutes, Seconds instead of getTime() ms value.
1687     */

1688    public static java.sql.Time JavaDoc timeFromTimestamp(java.sql.Timestamp JavaDoc timestamp) {
1689        return timeFromDate(timestamp);
1690    }
1691
1692    /**
1693     * Answer a sql.Time from a Calendar.
1694     */

1695    public static java.sql.Time JavaDoc timeFromCalendar(Calendar calendar) {
1696        if (!defaultTimeZone.equals(calendar.getTimeZone())) {
1697            // Must convert the calendar to the local timezone if different, as dates have no timezone (always local).
1698
Calendar localCalendar = allocateCalendar();
1699            JavaPlatform.setTimeInMillis(localCalendar, JavaPlatform.getTimeInMillis(calendar));
1700            java.sql.Time JavaDoc date = timeFromHourMinuteSecond(localCalendar.get(Calendar.HOUR_OF_DAY), localCalendar.get(Calendar.MINUTE), localCalendar.get(Calendar.SECOND));
1701            releaseCalendar(localCalendar);
1702            return date;
1703        }
1704        return timeFromHourMinuteSecond(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
1705    }
1706
1707    /**
1708     * Answer a Timestamp from a Calendar.
1709     */

1710    public static java.sql.Timestamp JavaDoc timestampFromCalendar(Calendar calendar) {
1711        return timestampFromLong(JavaPlatform.getTimeInMillis(calendar));
1712    }
1713
1714    /**
1715     * Answer a Timestamp from a java.util.Date.
1716     */

1717    public static java.sql.Timestamp JavaDoc timestampFromDate(java.util.Date JavaDoc date) {
1718        return timestampFromLong(date.getTime());
1719    }
1720
1721    /**
1722     * Answer a Time from a long
1723     *
1724     * @param longObject - milliseconds from the epoch (00:00:00 GMT
1725     * Jan 1, 1970). Negative values represent dates prior to the epoch.
1726     */

1727    public static java.sql.Timestamp JavaDoc timestampFromLong(Long JavaDoc millis) {
1728        return timestampFromLong(millis.longValue());
1729    }
1730
1731    /**
1732     * Answer a Time from a long
1733     *
1734     * @param longObject - milliseconds from the epoch (00:00:00 GMT
1735     * Jan 1, 1970). Negative values represent dates prior to the epoch.
1736     */

1737    public static java.sql.Timestamp JavaDoc timestampFromLong(long millis) {
1738        java.sql.Timestamp JavaDoc timestamp = new java.sql.Timestamp JavaDoc(millis);
1739
1740        // P2.0.1.3: Didn't account for negative millis < 1970
1741
// Must account for the jdk millis bug where it does not set the nanos.
1742
if ((millis % 1000) > 0) {
1743            timestamp.setNanos((int)(millis % 1000) * 1000000);
1744        } else if ((millis % 1000) < 0) {
1745            timestamp.setNanos((int)(1000000000 - (Math.abs((millis % 1000) * 1000000))));
1746        }
1747        return timestamp;
1748    }
1749
1750    /**
1751     * Answer a Timestamp from a string representation.
1752     * This method will accept strings in the following
1753     * formats: YYYY/MM/DD HH:MM:SS, YY/MM/DD HH:MM:SS, YYYY-MM-DD HH:MM:SS, YY-MM-DD HH:MM:SS
1754     *
1755     * @param timestampString - string representation of timestamp
1756     * @return - timestamp representation of string
1757     */

1758    public static java.sql.Timestamp JavaDoc timestampFromString(String JavaDoc timestampString) throws ConversionException {
1759        if ((timestampString.indexOf('-') == -1) && (timestampString.indexOf('/') == -1) && (timestampString.indexOf('.') == -1) && (timestampString.indexOf(':') == -1)) {
1760            throw ConversionException.incorrectTimestampFormat(timestampString);
1761        }
1762        StringTokenizer timestampStringTokenizer = new StringTokenizer(timestampString, " /:.-");
1763
1764        int year;
1765        int month;
1766        int day;
1767        int hour;
1768        int minute;
1769        int second;
1770        int nanos;
1771        try {
1772            year = Integer.parseInt(timestampStringTokenizer.nextToken());
1773            month = Integer.parseInt(timestampStringTokenizer.nextToken());
1774            day = Integer.parseInt(timestampStringTokenizer.nextToken());
1775            try {
1776                hour = Integer.parseInt(timestampStringTokenizer.nextToken());
1777                minute = Integer.parseInt(timestampStringTokenizer.nextToken());
1778                second = Integer.parseInt(timestampStringTokenizer.nextToken());
1779            } catch (java.util.NoSuchElementException JavaDoc endOfStringException) {
1780                // May be only a date string desired to be used as a timestamp.
1781
hour = 0;
1782                minute = 0;
1783                second = 0;
1784            }
1785        } catch (NumberFormatException JavaDoc exception) {
1786            throw ConversionException.incorrectTimestampFormat(timestampString);
1787        }
1788
1789        try {
1790            String JavaDoc nanoToken = timestampStringTokenizer.nextToken();
1791            nanos = Integer.parseInt(nanoToken);
1792            for (int times = 0; times < (9 - nanoToken.length()); times++) {
1793                nanos = nanos * 10;
1794            }
1795        } catch (java.util.NoSuchElementException JavaDoc endOfStringException) {
1796            nanos = 0;
1797        } catch (NumberFormatException JavaDoc exception) {
1798            throw ConversionException.incorrectTimestampFormat(timestampString);
1799        }
1800
1801        // Java dates are based on year after 1900 so I need to delete it.
1802
year = year - 1900;
1803
1804        // Java returns the month in terms of 0 - 11 instead of 1 - 12.
1805
month = month - 1;
1806
1807        java.sql.Timestamp JavaDoc timestamp;
1808        // This was not converted to use Calendar for the conversion because calendars do not take nanos.
1809
// but it should be, and then just call setNanos.
1810
timestamp = new java.sql.Timestamp JavaDoc(year, month, day, hour, minute, second, nanos);
1811        return timestamp;
1812    }
1813    
1814    /**
1815     * Answer a Timestamp with the year, month, day, hour, minute, second.
1816     * The hour, minute, second are the values calendar uses,
1817     * i.e. year is from 0, month is 0-11, date is 1-31, time is 0-23/59.
1818     */

1819    public static java.sql.Timestamp JavaDoc timestampFromYearMonthDateHourMinuteSecondNanos(int year, int month, int date, int hour, int minute, int second, int nanos) {
1820        // This was not converted to use Calendar for the conversion because calendars do not take nanos.
1821
// but it should be, and then just call setNanos.
1822
return new java.sql.Timestamp JavaDoc(year - 1900, month, date, hour, minute, second, nanos);
1823    }
1824
1825    /**
1826     * Can be used to mark code as need if something strange is seen.
1827     */

1828    public static void toDo(String JavaDoc description) {
1829        // Use sender to find what is needy.
1830
}
1831
1832    /**
1833     * If the size of the original string is larger than the passed in size,
1834     * this method will remove the vowels from the original string.
1835     *
1836     * The removal starts backward from the end of original string, and stops if the
1837     * resulting string size is equal to the passed in size.
1838     *
1839     * If the resulting string is still larger than the passed in size after
1840     * removing all vowels, the end of the resulting string will be truncated.
1841     */

1842    public static String JavaDoc truncate(String JavaDoc originalString, int size) {
1843        if (originalString.length() <= size) {
1844            //no removal and truncation needed
1845
return originalString;
1846        }
1847        String JavaDoc vowels = "AaEeIiOoUu";
1848        StringBuffer JavaDoc newStringBufferTmp = new StringBuffer JavaDoc(originalString.length());
1849
1850        //need to remove the extra characters
1851
int counter = originalString.length() - size;
1852        for (int index = (originalString.length() - 1); index >= 0; index--) {
1853            //search from the back to the front, if vowel found, do not append it to the resulting (temp) string!
1854
//i.e. if vowel not found, append the chararcter to the new string buffer.
1855
if (vowels.indexOf(originalString.charAt(index)) == -1) {
1856                newStringBufferTmp.append(originalString.charAt(index));
1857            } else {
1858                //vowel found! do NOT append it to the temp buffer, and decrease the counter
1859
counter--;
1860                if (counter == 0) {
1861                    //if the exceeded characters (counter) of vowel haven been removed, the total
1862
//string size should be equal to the limits, so append the reversed remaining string
1863
//to the new string, break the loop and return the shrunk string.
1864
StringBuffer JavaDoc newStringBuffer = new StringBuffer JavaDoc(size);
1865                    newStringBuffer.append(originalString.substring(0, index));
1866                    //need to reverse the string
1867
//bug fix: 3016423. append(BunfferString) is jdk1.4 version api. Use append(String) instead
1868
//in order to support jdk1.3.
1869
newStringBuffer.append(newStringBufferTmp.reverse().toString());
1870                    return newStringBuffer.toString();
1871                }
1872            }
1873        }
1874
1875        //the shrunk string still too long, revrese the order back and truncate it!
1876
return newStringBufferTmp.reverse().toString().substring(0, size);
1877    }
1878
1879    /**
1880     * Answer a Date from a long
1881     *
1882     * This implementation is based on the java.sql.Date class, not java.util.Date.
1883     * @param longObject - milliseconds from the epoch (00:00:00 GMT
1884     * Jan 1, 1970). Negative values represent dates prior to the epoch.
1885     */

1886    public static java.util.Date JavaDoc utilDateFromLong(Long JavaDoc longObject) {
1887        return new java.util.Date JavaDoc(longObject.longValue());
1888    }
1889
1890    /**
1891     * Answer a java.util.Date from a sql.date
1892     *
1893     * @param sqlDate - sql.date representation of date
1894     * @return - java.util.Date representation of the sql.date
1895     */

1896    public static java.util.Date JavaDoc utilDateFromSQLDate(java.sql.Date JavaDoc sqlDate) {
1897        return new java.util.Date JavaDoc(sqlDate.getTime());
1898    }
1899
1900    /**
1901     * Answer a java.util.Date from a sql.Time
1902     *
1903     * @param time - time representation of util date
1904     * @return - java.util.Date representation of the time
1905     */

1906    public static java.util.Date JavaDoc utilDateFromTime(java.sql.Time JavaDoc time) {
1907        return new java.util.Date JavaDoc(time.getTime());
1908    }
1909
1910    /**
1911     * Answer a java.util.Date from a timestamp
1912     *
1913     * @param timestampObject - timestamp representation of date
1914     * @return - java.util.Date representation of timestampObject
1915     */

1916    public static java.util.Date JavaDoc utilDateFromTimestamp(java.sql.Timestamp JavaDoc timestampObject) {
1917        // Bug 2719624 - Conditionally remove workaround for java bug which truncated
1918
// nanoseconds from timestamp.getTime(). We will now only recalculate the nanoseconds
1919
// When timestamp.getTime() results in nanoseconds == 0;
1920
long time = timestampObject.getTime();
1921        boolean appendNanos = ((time % 1000) == 0);
1922        if (appendNanos) {
1923            return new java.util.Date JavaDoc(time + (timestampObject.getNanos() / 1000000));
1924        } else {
1925            return new java.util.Date JavaDoc(time);
1926        }
1927    }
1928
1929    /**
1930    * Convert the specified array into a vector.
1931    */

1932    public static Vector vectorFromArray(Object JavaDoc[] array) {
1933        Vector result = new Vector(array.length);
1934        for (int i = 0; i < array.length; i++) {
1935            result.addElement(array[i]);
1936        }
1937        return result;
1938    }
1939
1940    /**
1941     * Convert the byte array to a HEX string.
1942     * HEX allows for binary data to be printed.
1943     */

1944    public static void writeHexString(byte[] bytes, Writer writer) throws IOException {
1945        writer.write(buildHexStringFromBytes(bytes));
1946    }
1947}
1948
Popular Tags