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