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