1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.util;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.net.URL;
23 import java.util.HashMap;
24
25 import org.mortbay.log.Log;
26
27
28
29
30
31
32
33
34
35
36 public class TypeUtil
37 {
38 public static int CR = '\015';
39 public static int LF = '\012';
40
41
42 private static final HashMap name2Class=new HashMap();
43 static
44 {
45 name2Class.put("boolean",java.lang.Boolean.TYPE);
46 name2Class.put("byte",java.lang.Byte.TYPE);
47 name2Class.put("char",java.lang.Character.TYPE);
48 name2Class.put("double",java.lang.Double.TYPE);
49 name2Class.put("float",java.lang.Float.TYPE);
50 name2Class.put("int",java.lang.Integer.TYPE);
51 name2Class.put("long",java.lang.Long.TYPE);
52 name2Class.put("short",java.lang.Short.TYPE);
53 name2Class.put("void",java.lang.Void.TYPE);
54
55 name2Class.put("java.lang.Boolean.TYPE",java.lang.Boolean.TYPE);
56 name2Class.put("java.lang.Byte.TYPE",java.lang.Byte.TYPE);
57 name2Class.put("java.lang.Character.TYPE",java.lang.Character.TYPE);
58 name2Class.put("java.lang.Double.TYPE",java.lang.Double.TYPE);
59 name2Class.put("java.lang.Float.TYPE",java.lang.Float.TYPE);
60 name2Class.put("java.lang.Integer.TYPE",java.lang.Integer.TYPE);
61 name2Class.put("java.lang.Long.TYPE",java.lang.Long.TYPE);
62 name2Class.put("java.lang.Short.TYPE",java.lang.Short.TYPE);
63 name2Class.put("java.lang.Void.TYPE",java.lang.Void.TYPE);
64
65 name2Class.put("java.lang.Boolean",java.lang.Boolean.class);
66 name2Class.put("java.lang.Byte",java.lang.Byte.class);
67 name2Class.put("java.lang.Character",java.lang.Character.class);
68 name2Class.put("java.lang.Double",java.lang.Double.class);
69 name2Class.put("java.lang.Float",java.lang.Float.class);
70 name2Class.put("java.lang.Integer",java.lang.Integer.class);
71 name2Class.put("java.lang.Long",java.lang.Long.class);
72 name2Class.put("java.lang.Short",java.lang.Short.class);
73
74 name2Class.put("Boolean",java.lang.Boolean.class);
75 name2Class.put("Byte",java.lang.Byte.class);
76 name2Class.put("Character",java.lang.Character.class);
77 name2Class.put("Double",java.lang.Double.class);
78 name2Class.put("Float",java.lang.Float.class);
79 name2Class.put("Integer",java.lang.Integer.class);
80 name2Class.put("Long",java.lang.Long.class);
81 name2Class.put("Short",java.lang.Short.class);
82
83 name2Class.put(null,java.lang.Void.TYPE);
84 name2Class.put("string",java.lang.String.class);
85 name2Class.put("String",java.lang.String.class);
86 name2Class.put("java.lang.String",java.lang.String.class);
87 }
88
89
90 private static final HashMap class2Name=new HashMap();
91 static
92 {
93 class2Name.put(java.lang.Boolean.TYPE,"boolean");
94 class2Name.put(java.lang.Byte.TYPE,"byte");
95 class2Name.put(java.lang.Character.TYPE,"char");
96 class2Name.put(java.lang.Double.TYPE,"double");
97 class2Name.put(java.lang.Float.TYPE,"float");
98 class2Name.put(java.lang.Integer.TYPE,"int");
99 class2Name.put(java.lang.Long.TYPE,"long");
100 class2Name.put(java.lang.Short.TYPE,"short");
101 class2Name.put(java.lang.Void.TYPE,"void");
102
103 class2Name.put(java.lang.Boolean.class,"java.lang.Boolean");
104 class2Name.put(java.lang.Byte.class,"java.lang.Byte");
105 class2Name.put(java.lang.Character.class,"java.lang.Character");
106 class2Name.put(java.lang.Double.class,"java.lang.Double");
107 class2Name.put(java.lang.Float.class,"java.lang.Float");
108 class2Name.put(java.lang.Integer.class,"java.lang.Integer");
109 class2Name.put(java.lang.Long.class,"java.lang.Long");
110 class2Name.put(java.lang.Short.class,"java.lang.Short");
111
112 class2Name.put(null,"void");
113 class2Name.put(java.lang.String.class,"java.lang.String");
114 }
115
116
117 private static final HashMap class2Value=new HashMap();
118 static
119 {
120 try
121 {
122 Class[] s ={java.lang.String.class};
123
124 class2Value.put(java.lang.Boolean.TYPE,
125 java.lang.Boolean.class.getMethod("valueOf",s));
126 class2Value.put(java.lang.Byte.TYPE,
127 java.lang.Byte.class.getMethod("valueOf",s));
128 class2Value.put(java.lang.Double.TYPE,
129 java.lang.Double.class.getMethod("valueOf",s));
130 class2Value.put(java.lang.Float.TYPE,
131 java.lang.Float.class.getMethod("valueOf",s));
132 class2Value.put(java.lang.Integer.TYPE,
133 java.lang.Integer.class.getMethod("valueOf",s));
134 class2Value.put(java.lang.Long.TYPE,
135 java.lang.Long.class.getMethod("valueOf",s));
136 class2Value.put(java.lang.Short.TYPE,
137 java.lang.Short.class.getMethod("valueOf",s));
138
139 class2Value.put(java.lang.Boolean.class,
140 java.lang.Boolean.class.getMethod("valueOf",s));
141 class2Value.put(java.lang.Byte.class,
142 java.lang.Byte.class.getMethod("valueOf",s));
143 class2Value.put(java.lang.Double.class,
144 java.lang.Double.class.getMethod("valueOf",s));
145 class2Value.put(java.lang.Float.class,
146 java.lang.Float.class.getMethod("valueOf",s));
147 class2Value.put(java.lang.Integer.class,
148 java.lang.Integer.class.getMethod("valueOf",s));
149 class2Value.put(java.lang.Long.class,
150 java.lang.Long.class.getMethod("valueOf",s));
151 class2Value.put(java.lang.Short.class,
152 java.lang.Short.class.getMethod("valueOf",s));
153 }
154 catch(Exception e)
155 {
156 e.printStackTrace();
157 }
158 }
159
160
161 private static Class[] stringArg = { java.lang.String.class };
162
163
164 private static int intCacheSize=
165 Integer.getInteger("org.mortbay.util.TypeUtil.IntegerCacheSize",600).intValue();
166 private static Integer[] integerCache = new Integer[intCacheSize];
167 private static String[] integerStrCache = new String[intCacheSize];
168 private static Integer minusOne = new Integer(-1);
169 private static int longCacheSize=
170 Integer.getInteger("org.mortbay.util.TypeUtil.LongCacheSize",64).intValue();
171 private static Long[] longCache = new Long[longCacheSize];
172 private static Long minusOneL = new Long(-1);
173
174
175
176
177
178
179 public static Class fromName(String name)
180 {
181 return (Class)name2Class.get(name);
182 }
183
184
185
186
187
188
189 public static String toName(Class type)
190 {
191 return (String)class2Name.get(type);
192 }
193
194
195
196
197
198
199
200 public static Object valueOf(Class type, String value)
201 {
202 try
203 {
204 if (type.equals(java.lang.String.class))
205 return value;
206
207 Method m = (Method)class2Value.get(type);
208 if (m!=null)
209 return m.invoke(null,new Object[] {value});
210
211 if (type.equals(java.lang.Character.TYPE) ||
212 type.equals(java.lang.Character.class))
213 return new Character(value.charAt(0));
214
215 Constructor c = type.getConstructor(stringArg);
216 return c.newInstance(new Object[] {value});
217 }
218 catch(NoSuchMethodException e)
219 {
220
221 }
222 catch(IllegalAccessException e)
223 {
224
225 }
226 catch(InstantiationException e)
227 {
228
229 }
230 catch(InvocationTargetException e)
231 {
232 if (e.getTargetException() instanceof Error)
233 throw (Error)(e.getTargetException());
234
235 }
236 return null;
237 }
238
239
240
241
242
243
244
245 public static Object valueOf(String type, String value)
246 {
247 return valueOf(fromName(type),value);
248 }
249
250
251
252
253 public static Integer newInteger(int i)
254 {
255 if (i>=0 && i<intCacheSize)
256 {
257 if (integerCache[i]==null)
258 integerCache[i]=new Integer(i);
259 return integerCache[i];
260 }
261 else if (i==-1)
262 return minusOne;
263 return new Integer(i);
264 }
265
266
267
268
269 public static Long newLong(long i)
270 {
271 if (i>=0 && i<longCacheSize)
272 {
273 if (longCache[(int)i]==null)
274 longCache[(int)i]=new Long(i);
275 return longCache[(int)i];
276 }
277 else if (i==-1)
278 return minusOneL;
279 return new Long(i);
280 }
281
282
283
284
285
286 public static String toString(int i)
287 {
288 if (i>=0 && i<intCacheSize)
289 {
290 if (integerStrCache[i]==null)
291 integerStrCache[i]=Integer.toString(i);
292 return integerStrCache[i];
293 }
294 else if (i==-1)
295 return "-1";
296 return Integer.toString(i);
297 }
298
299
300
301
302 public static String toString(long i)
303 {
304 if (i>=0 && i<intCacheSize)
305 {
306 if (integerStrCache[(int)i]==null)
307 integerStrCache[(int)i]=Long.toString(i);
308 return integerStrCache[(int)i];
309 }
310 else if (i==-1)
311 return "-1";
312 return Long.toString(i);
313 }
314
315
316
317
318
319
320
321
322
323
324
325 public static int parseInt(String s, int offset, int length, int base)
326 throws NumberFormatException
327 {
328 int value=0;
329
330 if (length<0)
331 length=s.length()-offset;
332
333 for (int i=0;i<length;i++)
334 {
335 char c=s.charAt(offset+i);
336
337 int digit=c-'0';
338 if (digit<0 || digit>=base || digit>=10)
339 {
340 digit=10+c-'A';
341 if (digit<10 || digit>=base)
342 digit=10+c-'a';
343 }
344 if (digit<0 || digit>=base)
345 throw new NumberFormatException(s.substring(offset,offset+length));
346 value=value*base+digit;
347 }
348 return value;
349 }
350
351
352
353
354
355
356
357
358
359
360 public static int parseInt(byte[] b, int offset, int length, int base)
361 throws NumberFormatException
362 {
363 int value=0;
364
365 if (length<0)
366 length=b.length-offset;
367
368 for (int i=0;i<length;i++)
369 {
370 char c=(char)(0xff&b[offset+i]);
371
372 int digit=c-'0';
373 if (digit<0 || digit>=base || digit>=10)
374 {
375 digit=10+c-'A';
376 if (digit<10 || digit>=base)
377 digit=10+c-'a';
378 }
379 if (digit<0 || digit>=base)
380 throw new NumberFormatException(new String(b,offset,length));
381 value=value*base+digit;
382 }
383 return value;
384 }
385
386
387 public static byte[] parseBytes(String s, int base)
388 {
389 byte[] bytes=new byte[s.length()/2];
390 for (int i=0;i<s.length();i+=2)
391 bytes[i/2]=(byte)TypeUtil.parseInt(s,i,2,base);
392 return bytes;
393 }
394
395
396 public static String toString(byte[] bytes, int base)
397 {
398 StringBuffer buf = new StringBuffer();
399 for (int i=0;i<bytes.length;i++)
400 {
401 int bi=0xff&bytes[i];
402 int c='0'+(bi/base)%base;
403 if (c>'9')
404 c= 'a'+(c-'0'-10);
405 buf.append((char)c);
406 c='0'+bi%base;
407 if (c>'9')
408 c= 'a'+(c-'0'-10);
409 buf.append((char)c);
410 }
411 return buf.toString();
412 }
413
414
415
416
417
418
419 public static byte convertHexDigit( byte b )
420 {
421 if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
422 if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
423 if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
424 return 0;
425 }
426
427
428 public static String toHexString(byte[] b)
429 {
430 StringBuffer buf = new StringBuffer();
431 for (int i=0;i<b.length;i++)
432 {
433 int bi=0xff&b[i];
434 int c='0'+(bi/16)%16;
435 if (c>'9')
436 c= 'A'+(c-'0'-10);
437 buf.append((char)c);
438 c='0'+bi%16;
439 if (c>'9')
440 c= 'a'+(c-'0'-10);
441 buf.append((char)c);
442 }
443 return buf.toString();
444 }
445
446
447 public static String toHexString(byte[] b,int offset,int length)
448 {
449 StringBuffer buf = new StringBuffer();
450 for (int i=offset;i<offset+length;i++)
451 {
452 int bi=0xff&b[i];
453 int c='0'+(bi/16)%16;
454 if (c>'9')
455 c= 'A'+(c-'0'-10);
456 buf.append((char)c);
457 c='0'+bi%16;
458 if (c>'9')
459 c= 'a'+(c-'0'-10);
460 buf.append((char)c);
461 }
462 return buf.toString();
463 }
464
465
466 public static byte[] fromHexString(String s)
467 {
468 if (s.length()%2!=0)
469 throw new IllegalArgumentException(s);
470 byte[] array = new byte[s.length()/2];
471 for (int i=0;i<array.length;i++)
472 {
473 int b = Integer.parseInt(s.substring(i*2,i*2+2),16);
474 array[i]=(byte)(0xff&b);
475 }
476 return array;
477 }
478
479
480 public static void dump(Class c)
481 {
482 System.err.println("Dump: "+c);
483 dump(c.getClassLoader());
484 }
485
486 public static void dump(ClassLoader cl)
487 {
488 System.err.println("Dump Loaders:");
489 while(cl!=null)
490 {
491 System.err.println(" loader "+cl);
492 cl = cl.getParent();
493 }
494 }
495
496
497
498 public static byte[] readLine(InputStream in) throws IOException
499 {
500 byte[] buf = new byte[256];
501
502 int i=0;
503 int loops=0;
504 int ch=0;
505
506 while (true)
507 {
508 ch=in.read();
509 if (ch<0)
510 break;
511 loops++;
512
513
514 if (loops==1 && ch==LF)
515 continue;
516
517 if (ch==CR || ch==LF)
518 break;
519
520 if (i>=buf.length)
521 {
522 byte[] old_buf=buf;
523 buf=new byte[old_buf.length+256];
524 System.arraycopy(old_buf, 0, buf, 0, old_buf.length);
525 }
526 buf[i++]=(byte)ch;
527 }
528
529 if (ch==-1 && i==0)
530 return null;
531
532
533 if (ch==CR && in.available()>=1 && in.markSupported())
534 {
535 in.mark(1);
536 ch=in.read();
537 if (ch!=LF)
538 in.reset();
539 }
540
541 byte[] old_buf=buf;
542 buf=new byte[i];
543 System.arraycopy(old_buf, 0, buf, 0, i);
544
545 return buf;
546 }
547
548 public static URL jarFor(String className)
549 {
550 try
551 {
552 className=className.replace('.','/')+".class";
553
554 URL url = Loader.getResource(null,className,false);
555 String s=url.toString();
556 if (s.startsWith("jar:file:"))
557 return new URL(s.substring(4,s.indexOf("!/")));
558 }
559 catch(Exception e)
560 {
561 Log.ignore(e);
562 }
563 return null;
564 }
565 }