~ubuntu-branches/ubuntu/utopic/jetty/utopic-proposed

« back to all changes in this revision

Viewing changes to modules/util/src/main/java/org/mortbay/util/TypeUtil.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2009-08-09 08:48:10 UTC
  • Revision ID: james.westby@ubuntu.com-20090809084810-k522b97ind2robyd
ImportĀ upstreamĀ versionĀ 6.1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ========================================================================
 
2
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
 
3
// ------------------------------------------------------------------------
 
4
// Licensed under the Apache License, Version 2.0 (the "License");
 
5
// you may not use this file except in compliance with the License.
 
6
// You may obtain a copy of the License at 
 
7
// http://www.apache.org/licenses/LICENSE-2.0
 
8
// Unless required by applicable law or agreed to in writing, software
 
9
// distributed under the License is distributed on an "AS IS" BASIS,
 
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
11
// See the License for the specific language governing permissions and
 
12
// limitations under the License.
 
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
/** TYPE Utilities.
 
30
 * Provides various static utiltiy methods for manipulating types and their
 
31
 * string representations.
 
32
 *
 
33
 * @since Jetty 4.1
 
34
 * @author Greg Wilkins (gregw)
 
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
    /** Class from a canonical name for a type.
 
176
     * @param name A class or type name.
 
177
     * @return A class , which may be a primitive TYPE field..
 
178
     */
 
179
    public static Class fromName(String name)
 
180
    {
 
181
        return (Class)name2Class.get(name);
 
182
    }
 
183
    
 
184
    /* ------------------------------------------------------------ */
 
185
    /** Canonical name for a type.
 
186
     * @param type A class , which may be a primitive TYPE field.
 
187
     * @return Canonical name.
 
188
     */
 
189
    public static String toName(Class type)
 
190
    {
 
191
        return (String)class2Name.get(type);
 
192
    }
 
193
    
 
194
    /* ------------------------------------------------------------ */
 
195
    /** Convert String value to instance.
 
196
     * @param type The class of the instance, which may be a primitive TYPE field.
 
197
     * @param value The value as a string.
 
198
     * @return The value as an Object.
 
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
            // LogSupport.ignore(log,e);
 
221
        }
 
222
        catch(IllegalAccessException e)
 
223
        {
 
224
            // LogSupport.ignore(log,e);
 
225
        }
 
226
        catch(InstantiationException e)
 
227
        {
 
228
            // LogSupport.ignore(log,e);
 
229
        }
 
230
        catch(InvocationTargetException e)
 
231
        {
 
232
            if (e.getTargetException() instanceof Error)
 
233
                throw (Error)(e.getTargetException());
 
234
            // LogSupport.ignore(log,e);
 
235
        }
 
236
        return null;
 
237
    }
 
238
    
 
239
    /* ------------------------------------------------------------ */
 
240
    /** Convert String value to instance.
 
241
     * @param type classname or type (eg int)
 
242
     * @param value The value as a string.
 
243
     * @return The value as an Object.
 
244
     */
 
245
    public static Object valueOf(String type, String value)
 
246
    {
 
247
        return valueOf(fromName(type),value);
 
248
    }
 
249
    
 
250
    /* ------------------------------------------------------------ */
 
251
    /** Convert int to Integer using cache. 
 
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
    /** Convert int to Integer using cache. 
 
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
    /** Convert int to String using cache. 
 
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
    /** Convert long to String using cache. 
 
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
    /** Parse an int from a substring.
 
318
     * Negative numbers are not handled.
 
319
     * @param s String
 
320
     * @param offset Offset within string
 
321
     * @param length Length of integer or -1 for remainder of string
 
322
     * @param base base of the integer
 
323
     * @exception NumberFormatException 
 
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
    /** Parse an int from a byte array of ascii characters.
 
353
     * Negative numbers are not handled.
 
354
     * @param b byte array
 
355
     * @param offset Offset within string
 
356
     * @param length Length of integer or -1 for remainder of string
 
357
     * @param base base of the integer
 
358
     * @exception NumberFormatException 
 
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
     * @param b An ASCII encoded character 0-9 a-f A-F
 
417
     * @return The byte value of the character 0-16.
 
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
            // skip a leading LF's
 
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
        // skip a trailing LF if it exists
 
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
            // hack to discover jstl libraries
 
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
}