KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > TypeUtil


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 in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
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 Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.util;
24
25 import java.lang.reflect.*;
26 import java.util.Vector JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28 import java.util.Set JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import com.sun.enterprise.deployment.FieldDescriptor;
32
33 /**
34  * Datatype management utility methods
35  */

36 public class TypeUtil {
37
38     // map a decimal digit to its (real!) character
39
private static final char[] digits = {
40     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
41     };
42
43     // Map of primitive class name and its associated Class object
44
private static Hashtable JavaDoc primitiveClasses_;
45
46     static {
47         primitiveClasses_ = new Hashtable JavaDoc();
48         primitiveClasses_.put(Character.TYPE.getName(), Character.TYPE);
49         primitiveClasses_.put(Boolean.TYPE.getName(), Boolean.TYPE);
50         primitiveClasses_.put(Byte.TYPE.getName(), Byte.TYPE);
51         primitiveClasses_.put(Integer.TYPE.getName(), Integer.TYPE);
52         primitiveClasses_.put(Long.TYPE.getName(), Long.TYPE);
53         primitiveClasses_.put(Short.TYPE.getName(), Short.TYPE);
54         primitiveClasses_.put(Float.TYPE.getName(), Float.TYPE);
55         primitiveClasses_.put(Double.TYPE.getName(), Double.TYPE);
56     }
57
58     /**
59      * Place a character representation of src into the buffer.
60      * No formatting (e.g. localization) is done.
61      *
62      * @param src - the integer to convert. Must not be Integer.MIN_VALUE.
63      * @param buf - the buf to put the result in
64      * @param offset - the offset in buf to place the first digit
65      * @return the number of bytes added to buf
66      * @exception IllegalArgumentException if src is Integer.MIN_VALUE.
67      */

68     public static int intGetChars(
69     int src,
70     char buf[],
71     int offset
72     ) {
73     int power = 1000000000; // magnitude of highest digit this can handle
74
int this_digit;
75     boolean have_emitted = false;
76     int init_offset = offset;
77
78     // special case src is zero
79
if (src == 0) {
80         buf[offset] = digits[0];
81         return 1;
82     }
83     else if (src < 0) {
84         if (src == Integer.MIN_VALUE)
85         throw new IllegalArgumentException JavaDoc();
86         
87         // emit the negation sign and continue as if positive
88
buf[offset++] = '-';
89         src = Math.abs(src);
90     }
91
92     // iterate until there are no more digits to emit
93
while (power > 0) {
94         this_digit = src / power;
95         if (this_digit != 0 || have_emitted) {
96         // emit this digit
97
have_emitted = true;
98         buf[offset++] = digits[this_digit];
99         }
100         src = src % power;
101         power = power / 10;
102     }
103     return offset - init_offset;
104     }
105
106
107     // map a digit to its single byte character
108
private static final byte[] charval = {
109     (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',(byte) '6',(byte) '7',(byte) '8',(byte) '9'
110     };
111
112     /**
113      * Place a byte representation of src into the byte array buf.
114      * No commas or any other formatting is done to the integer.
115      * @param src - the integer to convert. Must not be Integer.MIN_VALUE.
116      * @param buf - the buf to put the result in
117      * @param offset - the offset in buf to place the first digit
118      * @return the number of bytes added to buf
119      * @exception IllegalArgumentException if src is Integer.MIN_VALUE.
120      */

121     public static int intGetBytes(
122     int src,
123     byte buf[],
124     int offset
125     ) {
126     int power = 1000000000; // magnitude of highest digit this can handle
127
int this_digit;
128     boolean have_emitted = false;
129     int init_offset = offset;
130
131     // special case src is zero
132
if (src == 0) {
133         buf[offset] = charval[0];
134         return 1;
135     }
136     else if (src < 0) {
137         if (src == Integer.MIN_VALUE)
138         throw new IllegalArgumentException JavaDoc();
139         
140         // emit the negation sign and continue as if positive
141
buf[offset++] = (byte) '-';
142         src = Math.abs(src);
143     }
144
145     // iterate until there are no more digits to emit
146
while (power > 0) {
147         this_digit = src / power;
148         if (this_digit != 0 || have_emitted) {
149         // emit this digit
150
have_emitted = true;
151         buf[offset++] = charval[this_digit];
152         }
153         src = src % power;
154         power = power / 10;
155     }
156     return offset - init_offset;
157     }
158
159
160     /**
161      * Work around a performance bug in String.hashCode() for strings longer
162      * than sixteen characters, by calculating a (slower) hash on all the
163      * characters in the string. Not needed starting in the JDK 1.2 release.
164      */

165     public static int hashCode(String JavaDoc s)
166     {
167     int length = s.length();
168     int h = 1;
169
170     for (int i = 0; i < length; i++)
171         h = (h * 37) + (int) s.charAt(i);
172     return h;
173     }
174
175
176     /**
177      * Word-wrap a string into an array of strings. Space is the only
178      * separator character recognized.
179      */

180     public static String JavaDoc[] wordWrap(String JavaDoc msg, int widthInChars) {
181     int width = widthInChars;
182     int nextBreak =0;
183     int lastBreak = 0;
184     int length = msg.length();
185     int lengthLeft = length;
186     boolean breakFound = true;
187     Vector JavaDoc v = new Vector JavaDoc();
188     int nextNewline = msg.indexOf("\n");
189         
190     while (lengthLeft > width || nextNewline != -1) {
191         // Find a convenient word break, always respecting explicit line
192
// breaks.
193
nextBreak = nextNewline;
194
195         // If no newline, look for a space.
196
if (nextBreak == -1 ||
197         nextBreak <= lastBreak ||
198         nextBreak > lastBreak + width) {
199         nextBreak = msg.lastIndexOf(" ", lastBreak + width);
200         }
201
202         // No space, break it at the wrap width.
203
if (nextBreak == -1 || nextBreak <= lastBreak) {
204         nextBreak = lastBreak + width - 1;
205         breakFound = false;
206         if (nextBreak > length) {
207             break;
208         }
209         }
210
211         // Save the substring and adjust indexes.
212
String JavaDoc substr = msg.substring(lastBreak, nextBreak);
213         v.addElement(substr);
214         lengthLeft -= substr.length();
215
216         lastBreak = nextBreak;
217         if (breakFound) {
218         ++lastBreak;
219         }
220         breakFound = true;
221         nextNewline = msg.indexOf("\n", lastBreak);
222     }
223
224     v.addElement(msg.substring(lastBreak));
225     String JavaDoc[] lines = new String JavaDoc[v.size()];
226     v.copyInto(lines);
227     return lines;
228     }
229
230
231     /**
232      * Convert an array of strings to a single line with elements separated
233      * by the given separator. Similar to Tcl's <code>join</code>.
234      * @param from the array of strings to convert
235      * @param separator the string to insert between each element
236      */

237     public static String JavaDoc arrayToString(String JavaDoc[] from, String JavaDoc separator) {
238     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(100);
239     String JavaDoc sep = "";
240     for (int i = 0; i < from.length; i++) {
241        sb.append(sep);
242        sb.append(from[i]);
243        sep = separator;
244     }
245     return sb.toString();
246     }
247
248
249     /**
250      * Convert a string of delimited strings to an array of strings.
251      * Similar to AWK's and Tcl's <code>split</code>.
252      * @param from the string to convert
253      * @param separator the delimiter
254      */

255     public static String JavaDoc[] stringToArray(String JavaDoc from, String JavaDoc separator) {
256     if (from == null) {
257         return null;
258     }
259     if (separator == null) {
260         separator = " ";
261     }
262     StringTokenizer JavaDoc toks = new StringTokenizer JavaDoc(from, separator);
263     String JavaDoc[] result = new String JavaDoc[toks.countTokens()];
264     int i = 0;
265     while (toks.hasMoreTokens()) {
266         result[i++] = toks.nextToken().trim();
267     }
268     return result;
269     }
270
271
272     /**
273      * Truncate a float to the required number of significant digits.
274      */

275     public static String JavaDoc truncateFloat(float f, int digits) {
276     double factor = Math.pow(10, digits);
277     f = (float)(Math.round(f * factor) / factor);
278     return Float.toString(f);
279     }
280
281
282     /**
283      * Add commas to a number for "123,456.7" style formatting.
284      * @deprecated Use standard java.* APIs which create the correct
285      * localized number format.
286      */

287     public static String JavaDoc addCommas(float f) {
288     String JavaDoc floatStr = truncateFloat(f, 0);
289     return addCommas(floatStr);
290     }
291
292
293     /**
294      * Add commas to a number for "123,456.7" style formatting.
295      * @deprecated Use standard java.* APIs which create the correct
296      * localized number format.
297      */

298     public static String JavaDoc addCommas(String JavaDoc numStr) {
299     int dotIndex = numStr.lastIndexOf('.');
300     String JavaDoc n;
301
302     String JavaDoc fraction = "";
303     if (dotIndex >= 0) {
304         fraction = numStr.substring(dotIndex);
305         n = numStr.substring(0, dotIndex);
306     } else {
307         n = numStr;
308     }
309
310     String JavaDoc val = "";
311     int lastIndex = 0;
312     for (int i = n.length(); i > 0; i -= 3) {
313         String JavaDoc comma;
314         if (i > 3) {
315         comma = ",";
316         } else {
317         comma = "";
318         }
319         int start = Math.max(i - 3, 0);
320         val = comma + n.substring(start, i) + val;
321         lastIndex = start;
322     }
323     val = n.substring(0, lastIndex) + val + fraction;
324     return val;
325     }
326
327
328     /**
329      * Test if a class is a subclass of another.
330      * @deprecated Use <em>sup.isAssignableFrom(sub)</em>
331      */

332     public static boolean isSubclassOf(Class JavaDoc sub, Class JavaDoc sup) {
333     if (sub == sup) {
334         return true;
335     }
336     Class JavaDoc superclass = sub.getSuperclass();
337     while (superclass != null && superclass != sup) {
338         superclass = superclass.getSuperclass();
339     }
340     return (superclass != null);
341     }
342
343     /**
344      * Get all super-interfaces of a class, excluding the
345      * given base interface.
346      * Returns a set of strings containing class names.
347      */

348     public static Set JavaDoc getSuperInterfaces(ClassLoader JavaDoc cl, String JavaDoc className, String JavaDoc baseClassName) throws ClassNotFoundException JavaDoc {
349         Set JavaDoc allSuper = new HashSet JavaDoc();
350         if( !className.equals(baseClassName) ) {
351             Class JavaDoc theClass = cl.loadClass(className);
352             Class JavaDoc[] superInterfaces = theClass.getInterfaces();
353
354             for(int superIndex = 0; superIndex < superInterfaces.length; superIndex++) {
355                 Class JavaDoc currentClass = superInterfaces[superIndex];
356                 String JavaDoc currentClassName = currentClass.getName();
357                 if( !currentClassName.equals(baseClassName) ) {
358                     allSuper.add(currentClassName);
359                     allSuper.addAll(getSuperInterfaces(cl, currentClassName, baseClassName));
360                 }
361             } // End for -- each super interface
362
}
363         return allSuper;
364     }
365
366     public static Method getMethod(Class JavaDoc declaringClass, ClassLoader JavaDoc loader,
367                                    String JavaDoc name, String JavaDoc[] paramClassNames)
368        throws Exception JavaDoc
369     {
370
371         Class JavaDoc[] parameterTypes=null;
372         if (paramClassNames!=null) {
373             parameterTypes = new Class JavaDoc[paramClassNames.length];
374             for(int pIndex = 0; pIndex < parameterTypes.length; pIndex++) {
375                 String JavaDoc next = paramClassNames[pIndex];
376                 if( primitiveClasses_.containsKey(next) ) {
377                     parameterTypes[pIndex] =
378                         (Class JavaDoc) primitiveClasses_.get(next);
379                 } else {
380                     parameterTypes[pIndex] = Class.forName(next, true, loader);
381                 }
382             }
383         }
384         return declaringClass.getMethod(name, parameterTypes);
385     }
386
387     public static Method getDeclaredMethod(Class JavaDoc declaringClass, ClassLoader JavaDoc loader,
388                                    String JavaDoc name, String JavaDoc[] paramClassNames)
389        throws Exception JavaDoc
390     {
391
392         Class JavaDoc[] parameterTypes=null;
393         if (paramClassNames!=null) {
394             parameterTypes = new Class JavaDoc[paramClassNames.length];
395             for(int pIndex = 0; pIndex < parameterTypes.length; pIndex++) {
396                 String JavaDoc next = paramClassNames[pIndex];
397                 if( primitiveClasses_.containsKey(next) ) {
398                     parameterTypes[pIndex] =
399                         (Class JavaDoc) primitiveClasses_.get(next);
400                 } else {
401                     parameterTypes[pIndex] = Class.forName(next, true, loader);
402                 }
403             }
404         }
405         return declaringClass.getDeclaredMethod(name, parameterTypes);
406     }
407
408     /**
409      * Compares the signatures of two methods to see if they
410      * have the same numer of parameters and same parameter types.
411      *
412      * Note that this equality check does NOT cover :
413      * 1) declaring class 2) exceptions 3) method name
414      * 4) return type
415      *
416      */

417     public static boolean sameParamTypes(Method m1, Method m2) {
418
419         boolean same = false;
420
421         Class JavaDoc[] pm1 = m1.getParameterTypes();
422         Class JavaDoc[] pm2 = m2.getParameterTypes();
423         
424         if( (pm1.length == pm2.length) ) {
425             same = true;
426             for(int i = 0; i < pm1.length; i++) {
427                 if( pm1[i] != pm2[i] ) {
428                     same = false;
429                     break;
430                 }
431             }
432         }
433
434         return same;
435     }
436
437     /**
438      * Compares the signatures of two methods to see if they
439      * have the same method name, parameters, and return type.
440      *
441      * Note that this equality check does NOT cover :
442      * 1) declaring class 2) exceptions
443      *
444      */

445     public static boolean sameMethodSignature(Method m1, Method m2) {
446
447         boolean same = false;
448
449         Class JavaDoc[] pm1 = m1.getParameterTypes();
450         Class JavaDoc[] pm2 = m2.getParameterTypes();
451         
452         if( (m1.getName().equals(m2.getName())) &&
453             (m1.getReturnType() == m2.getReturnType()) ) {
454             same = sameParamTypes(m1, m2);
455         }
456
457         return same;
458     }
459
460     public static Vector JavaDoc getPossibleCmpCmrFields(ClassLoader JavaDoc cl,
461                                                  String JavaDoc className)
462         throws Exception JavaDoc {
463
464         Vector JavaDoc fieldDescriptors = new Vector JavaDoc();
465         Class JavaDoc theClass = cl.loadClass(className);
466
467         // Start with all *public* methods
468
Method[] methods = theClass.getMethods();
469
470         // Find all accessors that could be cmp fields. This list
471
// will contain all cmr field accessors as well, since there
472
// is no good way to distinguish between the two purely based
473
// on method signature.
474
for(int mIndex = 0; mIndex < methods.length; mIndex++) {
475             Method next = methods[mIndex];
476             String JavaDoc nextName = next.getName();
477             int nextModifiers = next.getModifiers();
478             if( Modifier.isAbstract(nextModifiers) ) {
479                 if( nextName.startsWith("get") &&
480                     nextName.length() > 3 ) {
481                     String JavaDoc field =
482                         nextName.substring(3,4).toLowerCase() +
483                         nextName.substring(4);
484                     fieldDescriptors.add(new FieldDescriptor(field));
485                 }
486             }
487         }
488         return fieldDescriptors;
489     }
490
491     /**
492      * Convert a java beans setter method to its property name.
493      */

494     public static String JavaDoc setterMethodToPropertyName(String JavaDoc setterMethodName) {
495
496         if( (setterMethodName == null) ||
497             (setterMethodName.length() <= 3) ||
498             !setterMethodName.startsWith("set") ) {
499             throw new IllegalArgumentException JavaDoc("Invalid setter method name " +
500                                                setterMethodName);
501         }
502
503         return ( setterMethodName.substring(3, 4).toLowerCase() +
504                  setterMethodName.substring(4) );
505
506     }
507
508     /**
509      * Convert a java beans property name to a setter method name
510      */

511     public static String JavaDoc propertyNameToSetterMethod(String JavaDoc propertyName) {
512
513         if( (propertyName == null) ||
514             (propertyName.length() == 0) ) {
515             throw new IllegalArgumentException JavaDoc("Invalid property name " +
516                                                propertyName);
517         }
518
519         return ( "set" + propertyName.substring(0, 1).toUpperCase() +
520                  propertyName.substring(1) );
521
522     }
523     
524 }
525
Popular Tags