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
// ========================================================================
15
package org.mortbay.util;
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;
23
import java.util.HashMap;
25
import org.mortbay.log.Log;
28
/* ------------------------------------------------------------ */
30
* Provides various static utiltiy methods for manipulating types and their
31
* string representations.
34
* @author Greg Wilkins (gregw)
38
public static int CR = '\015';
39
public static int LF = '\012';
41
/* ------------------------------------------------------------ */
42
private static final HashMap name2Class=new HashMap();
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);
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);
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);
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);
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);
89
/* ------------------------------------------------------------ */
90
private static final HashMap class2Name=new HashMap();
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");
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");
112
class2Name.put(null,"void");
113
class2Name.put(java.lang.String.class,"java.lang.String");
116
/* ------------------------------------------------------------ */
117
private static final HashMap class2Value=new HashMap();
122
Class[] s ={java.lang.String.class};
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));
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));
160
/* ------------------------------------------------------------ */
161
private static Class[] stringArg = { java.lang.String.class };
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);
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..
179
public static Class fromName(String name)
181
return (Class)name2Class.get(name);
184
/* ------------------------------------------------------------ */
185
/** Canonical name for a type.
186
* @param type A class , which may be a primitive TYPE field.
187
* @return Canonical name.
189
public static String toName(Class type)
191
return (String)class2Name.get(type);
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.
200
public static Object valueOf(Class type, String value)
204
if (type.equals(java.lang.String.class))
207
Method m = (Method)class2Value.get(type);
209
return m.invoke(null,new Object[] {value});
211
if (type.equals(java.lang.Character.TYPE) ||
212
type.equals(java.lang.Character.class))
213
return new Character(value.charAt(0));
215
Constructor c = type.getConstructor(stringArg);
216
return c.newInstance(new Object[] {value});
218
catch(NoSuchMethodException e)
220
// LogSupport.ignore(log,e);
222
catch(IllegalAccessException e)
224
// LogSupport.ignore(log,e);
226
catch(InstantiationException e)
228
// LogSupport.ignore(log,e);
230
catch(InvocationTargetException e)
232
if (e.getTargetException() instanceof Error)
233
throw (Error)(e.getTargetException());
234
// LogSupport.ignore(log,e);
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.
245
public static Object valueOf(String type, String value)
247
return valueOf(fromName(type),value);
250
/* ------------------------------------------------------------ */
251
/** Convert int to Integer using cache.
253
public static Integer newInteger(int i)
255
if (i>=0 && i<intCacheSize)
257
if (integerCache[i]==null)
258
integerCache[i]=new Integer(i);
259
return integerCache[i];
263
return new Integer(i);
266
/* ------------------------------------------------------------ */
267
/** Convert int to Integer using cache.
269
public static Long newLong(long i)
271
if (i>=0 && i<longCacheSize)
273
if (longCache[(int)i]==null)
274
longCache[(int)i]=new Long(i);
275
return longCache[(int)i];
283
/* ------------------------------------------------------------ */
284
/** Convert int to String using cache.
286
public static String toString(int i)
288
if (i>=0 && i<intCacheSize)
290
if (integerStrCache[i]==null)
291
integerStrCache[i]=Integer.toString(i);
292
return integerStrCache[i];
296
return Integer.toString(i);
299
/* ------------------------------------------------------------ */
300
/** Convert long to String using cache.
302
public static String toString(long i)
304
if (i>=0 && i<intCacheSize)
306
if (integerStrCache[(int)i]==null)
307
integerStrCache[(int)i]=Long.toString(i);
308
return integerStrCache[(int)i];
312
return Long.toString(i);
316
/* ------------------------------------------------------------ */
317
/** Parse an int from a substring.
318
* Negative numbers are not handled.
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
325
public static int parseInt(String s, int offset, int length, int base)
326
throws NumberFormatException
331
length=s.length()-offset;
333
for (int i=0;i<length;i++)
335
char c=s.charAt(offset+i);
338
if (digit<0 || digit>=base || digit>=10)
341
if (digit<10 || digit>=base)
344
if (digit<0 || digit>=base)
345
throw new NumberFormatException(s.substring(offset,offset+length));
346
value=value*base+digit;
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
360
public static int parseInt(byte[] b, int offset, int length, int base)
361
throws NumberFormatException
366
length=b.length-offset;
368
for (int i=0;i<length;i++)
370
char c=(char)(0xff&b[offset+i]);
373
if (digit<0 || digit>=base || digit>=10)
376
if (digit<10 || digit>=base)
379
if (digit<0 || digit>=base)
380
throw new NumberFormatException(new String(b,offset,length));
381
value=value*base+digit;
386
/* ------------------------------------------------------------ */
387
public static byte[] parseBytes(String s, int base)
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);
395
/* ------------------------------------------------------------ */
396
public static String toString(byte[] bytes, int base)
398
StringBuffer buf = new StringBuffer();
399
for (int i=0;i<bytes.length;i++)
401
int bi=0xff&bytes[i];
402
int c='0'+(bi/base)%base;
411
return buf.toString();
414
/* ------------------------------------------------------------ */
416
* @param b An ASCII encoded character 0-9 a-f A-F
417
* @return The byte value of the character 0-16.
419
public static byte convertHexDigit( byte b )
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);
427
/* ------------------------------------------------------------ */
428
public static String toHexString(byte[] b)
430
StringBuffer buf = new StringBuffer();
431
for (int i=0;i<b.length;i++)
434
int c='0'+(bi/16)%16;
443
return buf.toString();
446
/* ------------------------------------------------------------ */
447
public static String toHexString(byte[] b,int offset,int length)
449
StringBuffer buf = new StringBuffer();
450
for (int i=offset;i<offset+length;i++)
453
int c='0'+(bi/16)%16;
462
return buf.toString();
465
/* ------------------------------------------------------------ */
466
public static byte[] fromHexString(String s)
469
throw new IllegalArgumentException(s);
470
byte[] array = new byte[s.length()/2];
471
for (int i=0;i<array.length;i++)
473
int b = Integer.parseInt(s.substring(i*2,i*2+2),16);
474
array[i]=(byte)(0xff&b);
480
public static void dump(Class c)
482
System.err.println("Dump: "+c);
483
dump(c.getClassLoader());
486
public static void dump(ClassLoader cl)
488
System.err.println("Dump Loaders:");
491
System.err.println(" loader "+cl);
497
/* ------------------------------------------------------------ */
498
public static byte[] readLine(InputStream in) throws IOException
500
byte[] buf = new byte[256];
513
// skip a leading LF's
514
if (loops==1 && ch==LF)
517
if (ch==CR || ch==LF)
523
buf=new byte[old_buf.length+256];
524
System.arraycopy(old_buf, 0, buf, 0, old_buf.length);
532
// skip a trailing LF if it exists
533
if (ch==CR && in.available()>=1 && in.markSupported())
543
System.arraycopy(old_buf, 0, buf, 0, i);
548
public static URL jarFor(String className)
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("!/")));