Mercurial Hosting > luan
comparison src/org/eclipse/jetty/util/TypeUtil.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
4 // ------------------------------------------------------------------------ | |
5 // All rights reserved. This program and the accompanying materials | |
6 // are made available under the terms of the Eclipse Public License v1.0 | |
7 // and Apache License v2.0 which accompanies this distribution. | |
8 // | |
9 // The Eclipse Public License is available at | |
10 // http://www.eclipse.org/legal/epl-v10.html | |
11 // | |
12 // The Apache License v2.0 is available at | |
13 // http://www.opensource.org/licenses/apache2.0.php | |
14 // | |
15 // You may elect to redistribute this code under either of these licenses. | |
16 // ======================================================================== | |
17 // | |
18 | |
19 package org.eclipse.jetty.util; | |
20 | |
21 import java.io.IOException; | |
22 import java.io.InputStream; | |
23 import java.lang.reflect.Constructor; | |
24 import java.lang.reflect.InvocationTargetException; | |
25 import java.lang.reflect.Method; | |
26 import java.lang.reflect.Modifier; | |
27 import java.net.URL; | |
28 import java.util.Arrays; | |
29 import java.util.Collections; | |
30 import java.util.HashMap; | |
31 import java.util.List; | |
32 | |
33 import org.eclipse.jetty.util.log.Log; | |
34 import org.eclipse.jetty.util.log.Logger; | |
35 | |
36 | |
37 /* ------------------------------------------------------------ */ | |
38 /** | |
39 * TYPE Utilities. | |
40 * Provides various static utiltiy methods for manipulating types and their | |
41 * string representations. | |
42 * | |
43 * @since Jetty 4.1 | |
44 */ | |
45 public class TypeUtil | |
46 { | |
47 private static final Logger LOG = Log.getLogger(TypeUtil.class); | |
48 public static int CR = '\015'; | |
49 public static int LF = '\012'; | |
50 | |
51 /* ------------------------------------------------------------ */ | |
52 private static final HashMap<String, Class<?>> name2Class=new HashMap<String, Class<?>>(); | |
53 static | |
54 { | |
55 name2Class.put("boolean",java.lang.Boolean.TYPE); | |
56 name2Class.put("byte",java.lang.Byte.TYPE); | |
57 name2Class.put("char",java.lang.Character.TYPE); | |
58 name2Class.put("double",java.lang.Double.TYPE); | |
59 name2Class.put("float",java.lang.Float.TYPE); | |
60 name2Class.put("int",java.lang.Integer.TYPE); | |
61 name2Class.put("long",java.lang.Long.TYPE); | |
62 name2Class.put("short",java.lang.Short.TYPE); | |
63 name2Class.put("void",java.lang.Void.TYPE); | |
64 | |
65 name2Class.put("java.lang.Boolean.TYPE",java.lang.Boolean.TYPE); | |
66 name2Class.put("java.lang.Byte.TYPE",java.lang.Byte.TYPE); | |
67 name2Class.put("java.lang.Character.TYPE",java.lang.Character.TYPE); | |
68 name2Class.put("java.lang.Double.TYPE",java.lang.Double.TYPE); | |
69 name2Class.put("java.lang.Float.TYPE",java.lang.Float.TYPE); | |
70 name2Class.put("java.lang.Integer.TYPE",java.lang.Integer.TYPE); | |
71 name2Class.put("java.lang.Long.TYPE",java.lang.Long.TYPE); | |
72 name2Class.put("java.lang.Short.TYPE",java.lang.Short.TYPE); | |
73 name2Class.put("java.lang.Void.TYPE",java.lang.Void.TYPE); | |
74 | |
75 name2Class.put("java.lang.Boolean",java.lang.Boolean.class); | |
76 name2Class.put("java.lang.Byte",java.lang.Byte.class); | |
77 name2Class.put("java.lang.Character",java.lang.Character.class); | |
78 name2Class.put("java.lang.Double",java.lang.Double.class); | |
79 name2Class.put("java.lang.Float",java.lang.Float.class); | |
80 name2Class.put("java.lang.Integer",java.lang.Integer.class); | |
81 name2Class.put("java.lang.Long",java.lang.Long.class); | |
82 name2Class.put("java.lang.Short",java.lang.Short.class); | |
83 | |
84 name2Class.put("Boolean",java.lang.Boolean.class); | |
85 name2Class.put("Byte",java.lang.Byte.class); | |
86 name2Class.put("Character",java.lang.Character.class); | |
87 name2Class.put("Double",java.lang.Double.class); | |
88 name2Class.put("Float",java.lang.Float.class); | |
89 name2Class.put("Integer",java.lang.Integer.class); | |
90 name2Class.put("Long",java.lang.Long.class); | |
91 name2Class.put("Short",java.lang.Short.class); | |
92 | |
93 name2Class.put(null,java.lang.Void.TYPE); | |
94 name2Class.put("string",java.lang.String.class); | |
95 name2Class.put("String",java.lang.String.class); | |
96 name2Class.put("java.lang.String",java.lang.String.class); | |
97 } | |
98 | |
99 /* ------------------------------------------------------------ */ | |
100 private static final HashMap<Class<?>, String> class2Name=new HashMap<Class<?>, String>(); | |
101 static | |
102 { | |
103 class2Name.put(java.lang.Boolean.TYPE,"boolean"); | |
104 class2Name.put(java.lang.Byte.TYPE,"byte"); | |
105 class2Name.put(java.lang.Character.TYPE,"char"); | |
106 class2Name.put(java.lang.Double.TYPE,"double"); | |
107 class2Name.put(java.lang.Float.TYPE,"float"); | |
108 class2Name.put(java.lang.Integer.TYPE,"int"); | |
109 class2Name.put(java.lang.Long.TYPE,"long"); | |
110 class2Name.put(java.lang.Short.TYPE,"short"); | |
111 class2Name.put(java.lang.Void.TYPE,"void"); | |
112 | |
113 class2Name.put(java.lang.Boolean.class,"java.lang.Boolean"); | |
114 class2Name.put(java.lang.Byte.class,"java.lang.Byte"); | |
115 class2Name.put(java.lang.Character.class,"java.lang.Character"); | |
116 class2Name.put(java.lang.Double.class,"java.lang.Double"); | |
117 class2Name.put(java.lang.Float.class,"java.lang.Float"); | |
118 class2Name.put(java.lang.Integer.class,"java.lang.Integer"); | |
119 class2Name.put(java.lang.Long.class,"java.lang.Long"); | |
120 class2Name.put(java.lang.Short.class,"java.lang.Short"); | |
121 | |
122 class2Name.put(null,"void"); | |
123 class2Name.put(java.lang.String.class,"java.lang.String"); | |
124 } | |
125 | |
126 /* ------------------------------------------------------------ */ | |
127 private static final HashMap<Class<?>, Method> class2Value=new HashMap<Class<?>, Method>(); | |
128 static | |
129 { | |
130 try | |
131 { | |
132 Class<?>[] s ={java.lang.String.class}; | |
133 | |
134 class2Value.put(java.lang.Boolean.TYPE, | |
135 java.lang.Boolean.class.getMethod("valueOf",s)); | |
136 class2Value.put(java.lang.Byte.TYPE, | |
137 java.lang.Byte.class.getMethod("valueOf",s)); | |
138 class2Value.put(java.lang.Double.TYPE, | |
139 java.lang.Double.class.getMethod("valueOf",s)); | |
140 class2Value.put(java.lang.Float.TYPE, | |
141 java.lang.Float.class.getMethod("valueOf",s)); | |
142 class2Value.put(java.lang.Integer.TYPE, | |
143 java.lang.Integer.class.getMethod("valueOf",s)); | |
144 class2Value.put(java.lang.Long.TYPE, | |
145 java.lang.Long.class.getMethod("valueOf",s)); | |
146 class2Value.put(java.lang.Short.TYPE, | |
147 java.lang.Short.class.getMethod("valueOf",s)); | |
148 | |
149 class2Value.put(java.lang.Boolean.class, | |
150 java.lang.Boolean.class.getMethod("valueOf",s)); | |
151 class2Value.put(java.lang.Byte.class, | |
152 java.lang.Byte.class.getMethod("valueOf",s)); | |
153 class2Value.put(java.lang.Double.class, | |
154 java.lang.Double.class.getMethod("valueOf",s)); | |
155 class2Value.put(java.lang.Float.class, | |
156 java.lang.Float.class.getMethod("valueOf",s)); | |
157 class2Value.put(java.lang.Integer.class, | |
158 java.lang.Integer.class.getMethod("valueOf",s)); | |
159 class2Value.put(java.lang.Long.class, | |
160 java.lang.Long.class.getMethod("valueOf",s)); | |
161 class2Value.put(java.lang.Short.class, | |
162 java.lang.Short.class.getMethod("valueOf",s)); | |
163 } | |
164 catch(Exception e) | |
165 { | |
166 throw new Error(e); | |
167 } | |
168 } | |
169 | |
170 /* ------------------------------------------------------------ */ | |
171 /** Array to List. | |
172 * <p> | |
173 * Works like {@link Arrays#asList(Object...)}, but handles null arrays. | |
174 * @return a list backed by the array. | |
175 */ | |
176 public static <T> List<T> asList(T[] a) | |
177 { | |
178 if (a==null) | |
179 return Collections.emptyList(); | |
180 return Arrays.asList(a); | |
181 } | |
182 | |
183 /* ------------------------------------------------------------ */ | |
184 /** Class from a canonical name for a type. | |
185 * @param name A class or type name. | |
186 * @return A class , which may be a primitive TYPE field.. | |
187 */ | |
188 public static Class<?> fromName(String name) | |
189 { | |
190 return name2Class.get(name); | |
191 } | |
192 | |
193 /* ------------------------------------------------------------ */ | |
194 /** Canonical name for a type. | |
195 * @param type A class , which may be a primitive TYPE field. | |
196 * @return Canonical name. | |
197 */ | |
198 public static String toName(Class<?> type) | |
199 { | |
200 return class2Name.get(type); | |
201 } | |
202 | |
203 /* ------------------------------------------------------------ */ | |
204 /** Convert String value to instance. | |
205 * @param type The class of the instance, which may be a primitive TYPE field. | |
206 * @param value The value as a string. | |
207 * @return The value as an Object. | |
208 */ | |
209 public static Object valueOf(Class<?> type, String value) | |
210 { | |
211 try | |
212 { | |
213 if (type.equals(java.lang.String.class)) | |
214 return value; | |
215 | |
216 Method m = class2Value.get(type); | |
217 if (m!=null) | |
218 return m.invoke(null, value); | |
219 | |
220 if (type.equals(java.lang.Character.TYPE) || | |
221 type.equals(java.lang.Character.class)) | |
222 return new Character(value.charAt(0)); | |
223 | |
224 Constructor<?> c = type.getConstructor(java.lang.String.class); | |
225 return c.newInstance(value); | |
226 } | |
227 catch(NoSuchMethodException e) | |
228 { | |
229 // LogSupport.ignore(log,e); | |
230 } | |
231 catch(IllegalAccessException e) | |
232 { | |
233 // LogSupport.ignore(log,e); | |
234 } | |
235 catch(InstantiationException e) | |
236 { | |
237 // LogSupport.ignore(log,e); | |
238 } | |
239 catch(InvocationTargetException e) | |
240 { | |
241 if (e.getTargetException() instanceof Error) | |
242 throw (Error)(e.getTargetException()); | |
243 // LogSupport.ignore(log,e); | |
244 } | |
245 return null; | |
246 } | |
247 | |
248 /* ------------------------------------------------------------ */ | |
249 /** Convert String value to instance. | |
250 * @param type classname or type (eg int) | |
251 * @param value The value as a string. | |
252 * @return The value as an Object. | |
253 */ | |
254 public static Object valueOf(String type, String value) | |
255 { | |
256 return valueOf(fromName(type),value); | |
257 } | |
258 | |
259 /* ------------------------------------------------------------ */ | |
260 /** Parse an int from a substring. | |
261 * Negative numbers are not handled. | |
262 * @param s String | |
263 * @param offset Offset within string | |
264 * @param length Length of integer or -1 for remainder of string | |
265 * @param base base of the integer | |
266 * @return the parsed integer | |
267 * @throws NumberFormatException if the string cannot be parsed | |
268 */ | |
269 public static int parseInt(String s, int offset, int length, int base) | |
270 throws NumberFormatException | |
271 { | |
272 int value=0; | |
273 | |
274 if (length<0) | |
275 length=s.length()-offset; | |
276 | |
277 for (int i=0;i<length;i++) | |
278 { | |
279 char c=s.charAt(offset+i); | |
280 | |
281 int digit=convertHexDigit((int)c); | |
282 if (digit<0 || digit>=base) | |
283 throw new NumberFormatException(s.substring(offset,offset+length)); | |
284 value=value*base+digit; | |
285 } | |
286 return value; | |
287 } | |
288 | |
289 /* ------------------------------------------------------------ */ | |
290 /** Parse an int from a byte array of ascii characters. | |
291 * Negative numbers are not handled. | |
292 * @param b byte array | |
293 * @param offset Offset within string | |
294 * @param length Length of integer or -1 for remainder of string | |
295 * @param base base of the integer | |
296 * @return the parsed integer | |
297 * @throws NumberFormatException if the array cannot be parsed into an integer | |
298 */ | |
299 public static int parseInt(byte[] b, int offset, int length, int base) | |
300 throws NumberFormatException | |
301 { | |
302 int value=0; | |
303 | |
304 if (length<0) | |
305 length=b.length-offset; | |
306 | |
307 for (int i=0;i<length;i++) | |
308 { | |
309 char c=(char)(0xff&b[offset+i]); | |
310 | |
311 int digit=c-'0'; | |
312 if (digit<0 || digit>=base || digit>=10) | |
313 { | |
314 digit=10+c-'A'; | |
315 if (digit<10 || digit>=base) | |
316 digit=10+c-'a'; | |
317 } | |
318 if (digit<0 || digit>=base) | |
319 throw new NumberFormatException(new String(b,offset,length)); | |
320 value=value*base+digit; | |
321 } | |
322 return value; | |
323 } | |
324 | |
325 /* ------------------------------------------------------------ */ | |
326 public static byte[] parseBytes(String s, int base) | |
327 { | |
328 byte[] bytes=new byte[s.length()/2]; | |
329 for (int i=0;i<s.length();i+=2) | |
330 bytes[i/2]=(byte)TypeUtil.parseInt(s,i,2,base); | |
331 return bytes; | |
332 } | |
333 | |
334 /* ------------------------------------------------------------ */ | |
335 public static String toString(byte[] bytes, int base) | |
336 { | |
337 StringBuilder buf = new StringBuilder(); | |
338 for (byte b : bytes) | |
339 { | |
340 int bi=0xff&b; | |
341 int c='0'+(bi/base)%base; | |
342 if (c>'9') | |
343 c= 'a'+(c-'0'-10); | |
344 buf.append((char)c); | |
345 c='0'+bi%base; | |
346 if (c>'9') | |
347 c= 'a'+(c-'0'-10); | |
348 buf.append((char)c); | |
349 } | |
350 return buf.toString(); | |
351 } | |
352 | |
353 /* ------------------------------------------------------------ */ | |
354 /** | |
355 * @param c An ASCII encoded character 0-9 a-f A-F | |
356 * @return The byte value of the character 0-16. | |
357 */ | |
358 public static byte convertHexDigit( byte c ) | |
359 { | |
360 byte b = (byte)((c & 0x1f) + ((c >> 6) * 0x19) - 0x10); | |
361 if (b<0 || b>15) | |
362 throw new IllegalArgumentException("!hex "+c); | |
363 return b; | |
364 } | |
365 | |
366 /* ------------------------------------------------------------ */ | |
367 /** | |
368 * @param c An ASCII encoded character 0-9 a-f A-F | |
369 * @return The byte value of the character 0-16. | |
370 */ | |
371 public static int convertHexDigit( int c ) | |
372 { | |
373 int d= ((c & 0x1f) + ((c >> 6) * 0x19) - 0x10); | |
374 if (d<0 || d>15) | |
375 throw new NumberFormatException("!hex "+c); | |
376 return d; | |
377 } | |
378 | |
379 /* ------------------------------------------------------------ */ | |
380 public static void toHex(byte b,Appendable buf) | |
381 { | |
382 try | |
383 { | |
384 int d=0xf&((0xF0&b)>>4); | |
385 buf.append((char)((d>9?('A'-10):'0')+d)); | |
386 d=0xf&b; | |
387 buf.append((char)((d>9?('A'-10):'0')+d)); | |
388 } | |
389 catch(IOException e) | |
390 { | |
391 throw new RuntimeException(e); | |
392 } | |
393 } | |
394 | |
395 /* ------------------------------------------------------------ */ | |
396 public static void toHex(int value,Appendable buf) throws IOException | |
397 { | |
398 int d=0xf&((0xF0000000&value)>>28); | |
399 buf.append((char)((d>9?('A'-10):'0')+d)); | |
400 d=0xf&((0x0F000000&value)>>24); | |
401 buf.append((char)((d>9?('A'-10):'0')+d)); | |
402 d=0xf&((0x00F00000&value)>>20); | |
403 buf.append((char)((d>9?('A'-10):'0')+d)); | |
404 d=0xf&((0x000F0000&value)>>16); | |
405 buf.append((char)((d>9?('A'-10):'0')+d)); | |
406 d=0xf&((0x0000F000&value)>>12); | |
407 buf.append((char)((d>9?('A'-10):'0')+d)); | |
408 d=0xf&((0x00000F00&value)>>8); | |
409 buf.append((char)((d>9?('A'-10):'0')+d)); | |
410 d=0xf&((0x000000F0&value)>>4); | |
411 buf.append((char)((d>9?('A'-10):'0')+d)); | |
412 d=0xf&value; | |
413 buf.append((char)((d>9?('A'-10):'0')+d)); | |
414 | |
415 Integer.toString(0,36); | |
416 } | |
417 | |
418 | |
419 /* ------------------------------------------------------------ */ | |
420 public static void toHex(long value,Appendable buf) throws IOException | |
421 { | |
422 toHex((int)(value>>32),buf); | |
423 toHex((int)value,buf); | |
424 } | |
425 | |
426 /* ------------------------------------------------------------ */ | |
427 public static String toHexString(byte b) | |
428 { | |
429 return toHexString(new byte[]{b}, 0, 1); | |
430 } | |
431 | |
432 /* ------------------------------------------------------------ */ | |
433 public static String toHexString(byte[] b) | |
434 { | |
435 return toHexString(b, 0, b.length); | |
436 } | |
437 | |
438 /* ------------------------------------------------------------ */ | |
439 public static String toHexString(byte[] b,int offset,int length) | |
440 { | |
441 StringBuilder buf = new StringBuilder(); | |
442 for (int i=offset;i<offset+length;i++) | |
443 { | |
444 int bi=0xff&b[i]; | |
445 int c='0'+(bi/16)%16; | |
446 if (c>'9') | |
447 c= 'A'+(c-'0'-10); | |
448 buf.append((char)c); | |
449 c='0'+bi%16; | |
450 if (c>'9') | |
451 c= 'a'+(c-'0'-10); | |
452 buf.append((char)c); | |
453 } | |
454 return buf.toString(); | |
455 } | |
456 | |
457 /* ------------------------------------------------------------ */ | |
458 public static byte[] fromHexString(String s) | |
459 { | |
460 if (s.length()%2!=0) | |
461 throw new IllegalArgumentException(s); | |
462 byte[] array = new byte[s.length()/2]; | |
463 for (int i=0;i<array.length;i++) | |
464 { | |
465 int b = Integer.parseInt(s.substring(i*2,i*2+2),16); | |
466 array[i]=(byte)(0xff&b); | |
467 } | |
468 return array; | |
469 } | |
470 | |
471 | |
472 public static void dump(Class<?> c) | |
473 { | |
474 System.err.println("Dump: "+c); | |
475 dump(c.getClassLoader()); | |
476 } | |
477 | |
478 public static void dump(ClassLoader cl) | |
479 { | |
480 System.err.println("Dump Loaders:"); | |
481 while(cl!=null) | |
482 { | |
483 System.err.println(" loader "+cl); | |
484 cl = cl.getParent(); | |
485 } | |
486 } | |
487 | |
488 | |
489 /* ------------------------------------------------------------ */ | |
490 /** | |
491 * @deprecated | |
492 */ | |
493 public static byte[] readLine(InputStream in) throws IOException | |
494 { | |
495 byte[] buf = new byte[256]; | |
496 | |
497 int i=0; | |
498 int loops=0; | |
499 int ch=0; | |
500 | |
501 while (true) | |
502 { | |
503 ch=in.read(); | |
504 if (ch<0) | |
505 break; | |
506 loops++; | |
507 | |
508 // skip a leading LF's | |
509 if (loops==1 && ch==LF) | |
510 continue; | |
511 | |
512 if (ch==CR || ch==LF) | |
513 break; | |
514 | |
515 if (i>=buf.length) | |
516 { | |
517 byte[] old_buf=buf; | |
518 buf=new byte[old_buf.length+256]; | |
519 System.arraycopy(old_buf, 0, buf, 0, old_buf.length); | |
520 } | |
521 buf[i++]=(byte)ch; | |
522 } | |
523 | |
524 if (ch==-1 && i==0) | |
525 return null; | |
526 | |
527 // skip a trailing LF if it exists | |
528 if (ch==CR && in.available()>=1 && in.markSupported()) | |
529 { | |
530 in.mark(1); | |
531 ch=in.read(); | |
532 if (ch!=LF) | |
533 in.reset(); | |
534 } | |
535 | |
536 byte[] old_buf=buf; | |
537 buf=new byte[i]; | |
538 System.arraycopy(old_buf, 0, buf, 0, i); | |
539 | |
540 return buf; | |
541 } | |
542 | |
543 public static URL jarFor(String className) | |
544 { | |
545 try | |
546 { | |
547 className=className.replace('.','/')+".class"; | |
548 // hack to discover jstl libraries | |
549 URL url = Loader.getResource(null,className,false); | |
550 String s=url.toString(); | |
551 if (s.startsWith("jar:file:")) | |
552 return new URL(s.substring(4,s.indexOf("!/"))); | |
553 } | |
554 catch(Exception e) | |
555 { | |
556 LOG.ignore(e); | |
557 } | |
558 return null; | |
559 } | |
560 | |
561 public static Object call(Class<?> oClass, String method, Object obj, Object[] arg) | |
562 throws InvocationTargetException, NoSuchMethodException | |
563 { | |
564 // Lets just try all methods for now | |
565 Method[] methods = oClass.getMethods(); | |
566 for (int c = 0; methods != null && c < methods.length; c++) | |
567 { | |
568 if (!methods[c].getName().equals(method)) | |
569 continue; | |
570 if (methods[c].getParameterTypes().length != arg.length) | |
571 continue; | |
572 if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null)) | |
573 continue; | |
574 if ((obj == null) && methods[c].getDeclaringClass() != oClass) | |
575 continue; | |
576 | |
577 try | |
578 { | |
579 return methods[c].invoke(obj,arg); | |
580 } | |
581 catch (IllegalAccessException e) | |
582 { | |
583 LOG.ignore(e); | |
584 } | |
585 catch (IllegalArgumentException e) | |
586 { | |
587 LOG.ignore(e); | |
588 } | |
589 } | |
590 | |
591 throw new NoSuchMethodException(method); | |
592 } | |
593 } |