001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JavaType.java 8121 2006-03-14 07:58:28Z durieuxp $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.lib;
025:
026: import java.util.Hashtable;
027:
028: /**
029: * This class implements methods which permit to get informations about Java Types:
030: * <ul>
031: * <li>
032: * the JDBC Types associated
033: * <li>
034: * the ResultSet.getXXX() methods associated
035: * <li>
036: * the PreparedStatement.setXXX() methods associated
037: * </ul>
038: * <br>
039: * (The Java Type may be or not a primitive type)
040: *
041: * @author Helene Joanin : Initial developer
042: * @author ico.Hoogervorst@nl.compuware.com : Support for BigInteger and avoid cast exceptions with rs.getObject()
043: */
044: public class JavaType {
045:
046: // Default values for Java primitive type
047: private static Hashtable tableDefaultValues = new Hashtable();
048: static {
049: tableDefaultValues.put(java.lang.Boolean.TYPE, "false");
050: tableDefaultValues.put(java.lang.Character.TYPE, "'\u0000'");
051: tableDefaultValues.put(java.lang.Byte.TYPE, "(byte)0");
052: tableDefaultValues.put(java.lang.Short.TYPE, "(short)0");
053: tableDefaultValues.put(java.lang.Integer.TYPE, "0");
054: tableDefaultValues.put(java.lang.Long.TYPE, "0L");
055: tableDefaultValues.put(java.lang.Float.TYPE, "0.0f");
056: tableDefaultValues.put(java.lang.Double.TYPE, "0.0d");
057: }
058:
059: private static Hashtable tableWrapperType = new Hashtable();
060: static {
061: tableWrapperType.put(java.lang.Boolean.TYPE,
062: "java.lang.Boolean");
063: tableWrapperType.put(java.lang.Character.TYPE,
064: "java.lang.Character");
065: tableWrapperType.put(java.lang.Byte.TYPE, "java.lang.Byte");
066: tableWrapperType.put(java.lang.Short.TYPE, "java.lang.Short");
067: tableWrapperType.put(java.lang.Integer.TYPE,
068: "java.lang.Integer");
069: tableWrapperType.put(java.lang.Long.TYPE, "java.lang.Long");
070: tableWrapperType.put(java.lang.Float.TYPE, "java.lang.Float");
071: tableWrapperType.put(java.lang.Double.TYPE, "java.lang.Double");
072: }
073:
074: /**
075: * Returns true if the given type is the type 'void'
076: */
077: public static boolean isVoid(Class c) {
078: return (c.equals(java.lang.Void.TYPE));
079: }
080:
081: /**
082: * Returns the name of the given type
083: */
084: public static String getName(Class c) {
085: String name;
086: if (c.isArray()) {
087: name = getName(c.getComponentType()) + "[]";
088: } else {
089: // The '$' in the name of a inner class is no more allowed since JDK 1.4.2
090: name = c.getName().replace('$', '.');
091: }
092: return (name);
093: }
094:
095: /**
096: * Returns true if the given class is a Serializable Java Type,
097: * false otherwise.
098: */
099: public static boolean isSerializable(Class c) {
100: boolean isSerializable = false;
101: if (c.isArray()) {
102: isSerializable = isSerializable(c.getComponentType());
103: } else if (c.isPrimitive()) {
104: isSerializable = true;
105: } else {
106: isSerializable = java.io.Serializable.class
107: .isAssignableFrom(c);
108: }
109: return (isSerializable);
110: }
111:
112: /**
113: * Returns true if the given class is a valid type for RMI,
114: * false otherwise.
115: * Valid types for RMI are primitive types, remote objects,
116: * and non-remote objects that implement the java.io.Serializable interface
117: */
118: public static boolean isValidForRmi(Class c) {
119: return (JavaType.isSerializable(c) || java.rmi.Remote.class
120: .isAssignableFrom(c));
121: }
122:
123: /**
124: * Returns true if the given class implements java.uti.Collection or java.util.Enumeration
125: * false otherwise.
126: */
127: public static boolean isCollecOrEnum(Class c) {
128: return (java.util.Collection.class.isAssignableFrom(c) || java.util.Enumeration.class
129: .isAssignableFrom(c));
130: }
131:
132: /**
133: * Returns the name of the getXXX method associated with the given type in
134: * java.sql.ResultSet.
135: * @param c the class object for a Java type.
136: * @return a string representing the name of the get method, null in error case
137: */
138: public static String getSQLGetMethod(Class c) {
139: return (JavaTypesForSQL.getSQLGetMethod(c));
140: }
141:
142: /**
143: * Returns the name of the setXXX method associated with the given type in
144: * java.sql.ResultSet.
145: * @param c the class object for a Java type.
146: * @return a string representing the name of the set method, null in error case
147: */
148: public static String getSQLSetMethod(Class c) {
149: return (JavaTypesForSQL.getSQLSetMethod(c));
150: }
151:
152: /**
153: * Returns true if the given method name is getObject() or setObject()
154: */
155: public static boolean isXxxObjectMethod(String name) {
156: return (name.equals("getObject") || name.equals("setObject"));
157: }
158:
159: /**
160: * Returns the SQL Type mapping the given Java Type.
161: * @param c the class object for a Java type.
162: * @return the SQL Type mapping the given Java Type, (Types.OTHER in error case)
163: */
164: public static String getSQLType(Class c) {
165: return (JavaTypesForSQL.getSQLType(c));
166: }
167:
168: /**
169: * Returns the default value of the given Java Type.
170: * @param c the class object for a Java type.
171: * @return the default value of the given Java Type
172: */
173: public static String getDefaultValue(Class c) {
174: String val = null;
175: if (c.isPrimitive()) {
176: val = (String) tableDefaultValues.get(c);
177: } else {
178: val = new String("null");
179: }
180: if (val == null) {
181: throw new Error(
182: "JavaType ERROR: No default value for the class "
183: + c.getName());
184: }
185: return (val);
186: }
187:
188: /**
189: * Returns the wrapper type of the given Java Type.
190: * @param c the class object for a Java type.
191: * @return the wrapper type of the given Java Type. Empty String for non primitive classes
192: */
193: public static String getWrapperType(Class c) {
194: String val = null;
195: if (c.isPrimitive()) {
196: val = (String) tableWrapperType.get(c);
197: } else {
198: val = new String("");
199: }
200: if (val == null) {
201: throw new Error(
202: "JavaType ERROR: No wrapper type for the class "
203: + c.getName());
204: }
205: return (val);
206: }
207:
208: public static Boolean toObject(boolean val) {
209: return new Boolean(val);
210: }
211:
212: public static Byte toObject(byte val) {
213: return new Byte(val);
214: }
215:
216: public static Short toObject(short val) {
217: return new Short(val);
218: }
219:
220: public static Integer toObject(int val) {
221: return new Integer(val);
222: }
223:
224: public static Long toObject(long val) {
225: return new Long(val);
226: }
227:
228: public static Float toObject(float val) {
229: return new Float(val);
230: }
231:
232: public static Double toObject(double val) {
233: return new Double(val);
234: }
235:
236: public static Character toObject(char val) {
237: return new Character(val);
238: }
239:
240: public static Object toObject(Object val) {
241: return val;
242: }
243:
244: /**
245: * If it is a primitive type, return a new Object constructor,
246: * else return the same object.
247: * There are nine predefined Class objects to represent the eight
248: * primitive types and void. These are created by the Java Virtual Machine,
249: * and have the same names as the primitive types that they represent,
250: * namely boolean, byte, char, short, int, long, float, and double.
251: * @param name name of the var
252: * @param val the object value
253: * @return new object
254: */
255: public static String toStringObject(String name, Class c) {
256: if (c.isPrimitive()) {
257: if (c == Boolean.TYPE) {
258: return "Boolean.valueOf(" + name + ")";
259: } else if (c == Byte.TYPE) {
260: return "new Byte(" + name + ")";
261: } else if (c == Character.TYPE) {
262: return "new Character(" + name + ")";
263: } else if (c == Short.TYPE) {
264: return "new Short(" + name + ")";
265: } else if (c == Integer.TYPE) {
266: return "new Integer(" + name + ")";
267: } else if (c == Long.TYPE) {
268: return "new Long(" + name + ")";
269: } else if (c == Float.TYPE) {
270: return "new Float(" + name + ")";
271: } else if (c == Double.TYPE) {
272: return "new Double(" + name + ")";
273: } else {
274: return name;
275: }
276: } else {
277: return name;
278: }
279: }
280:
281: }
282:
283: /**
284: * This inner class allows to calculate, for a given Java Type:
285: * - the corresponding SQL type,
286: * - the corresponding set method of the java.sql.PreparedStatement,
287: * - the corresponding get method of the java.sql.ResultSet.
288: */
289: class JavaTypesForSQL {
290:
291: private static JavaTypesForSQL mTypesForSQL = new JavaTypesForSQL();
292: private static Hashtable mGets;
293: private static Hashtable mSets;
294: private static Hashtable mSQLTypes;
295:
296: private JavaTypesForSQL() {
297:
298: mGets = new Hashtable();
299: mSets = new Hashtable();
300: mSQLTypes = new Hashtable();
301:
302: mGets.put(java.lang.Boolean.TYPE, "getBoolean");
303: mSets.put(java.lang.Boolean.TYPE, "setBoolean");
304: mSQLTypes.put(java.lang.Boolean.TYPE, "Types.BIT");
305: mGets.put(java.lang.Byte.TYPE, "getByte");
306: mSets.put(java.lang.Byte.TYPE, "setByte");
307: mSQLTypes.put(java.lang.Byte.TYPE, "Types.TINYINT");
308: mGets.put(java.lang.Short.TYPE, "getShort");
309: mSets.put(java.lang.Short.TYPE, "setShort");
310: mSQLTypes.put(java.lang.Short.TYPE, "Types.SMALLINT");
311: mGets.put(java.lang.Integer.TYPE, "getInt");
312: mSets.put(java.lang.Integer.TYPE, "setInt");
313: mSQLTypes.put(java.lang.Integer.TYPE, "Types.INTEGER");
314: mGets.put(java.lang.Long.TYPE, "getLong");
315: mSets.put(java.lang.Long.TYPE, "setLong");
316: mSQLTypes.put(java.lang.Long.TYPE, "Types.BIGINT");
317: mGets.put(java.lang.Float.TYPE, "getFloat");
318: mSets.put(java.lang.Float.TYPE, "setFloat");
319: mSQLTypes.put(java.lang.Float.TYPE, "Types.FLOAT");
320: mGets.put(java.lang.Double.TYPE, "getDouble");
321: mSets.put(java.lang.Double.TYPE, "setDouble");
322: mSQLTypes.put(java.lang.Double.TYPE, "Types.DOUBLE");
323: //mGets.put(java.lang.Character.TYPE, "????");
324: //mSets.put(java.lang.Character.TYPE, "????");
325: //mSQLTypes.put(java.lang.Character.TYPE, "???");
326: mGets.put(java.lang.String.class, "getString");
327: mSets.put(java.lang.String.class, "setString");
328: mSQLTypes.put(java.lang.String.class, "Types.VARCHAR");
329: mGets.put(java.sql.Date.class, "getDate");
330: mSets.put(java.sql.Date.class, "setDate");
331: mSQLTypes.put(java.sql.Date.class, "Types.DATE");
332: mGets.put(java.sql.Time.class, "getTime");
333: mSets.put(java.sql.Time.class, "setTime");
334: mSQLTypes.put(java.sql.Time.class, "Types.TIME");
335: mGets.put(java.sql.Timestamp.class, "getTimestamp");
336: mSets.put(java.sql.Timestamp.class, "setTimestamp");
337: mSQLTypes.put(java.sql.Timestamp.class, "Types.TIMESTAMP");
338: mGets.put(java.lang.Boolean.class, "getBoolean");
339: mSets.put(java.lang.Boolean.class, "setObject");
340: mSQLTypes.put(java.lang.Boolean.class, "Types.BIT");
341: mGets.put(java.lang.Integer.class, "getInt");
342: mSets.put(java.lang.Integer.class, "setObject");
343: mSQLTypes.put(java.lang.Integer.class, "Types.INTEGER");
344: mGets.put(java.lang.Long.class, "getLong");
345: mSets.put(java.lang.Long.class, "setObject");
346: mSQLTypes.put(java.lang.Long.class, "Types.BIGINT");
347: mGets.put(java.lang.Float.class, "getFloat");
348: mSets.put(java.lang.Float.class, "setObject");
349: mSQLTypes.put(java.lang.Float.class, "Types.REAL");
350: mGets.put(java.lang.Double.class, "getDouble");
351: mSets.put(java.lang.Double.class, "setObject");
352: mSQLTypes.put(java.lang.Double.class, "Types.DOUBLE");
353: mGets.put(java.lang.Byte.class, "getByte");
354: mSets.put(java.lang.Byte.class, "setObject");
355: mSQLTypes.put(java.lang.Byte.class, "Types.TINYINT");
356: mGets.put(java.lang.Short.class, "getShort");
357: mSets.put(java.lang.Short.class, "setObject");
358: mSQLTypes.put(java.lang.Short.class, "Types.SMALLINT");
359: mGets.put(java.math.BigDecimal.class, "getBigDecimal");
360: mSets.put(java.math.BigDecimal.class, "setObject");
361: mSQLTypes.put(java.math.BigDecimal.class, "Types.NUMERIC");
362: mGets.put(java.math.BigInteger.class, "getBigDecimal");
363: mSets.put(java.math.BigInteger.class, "setObject");
364: mSQLTypes.put(java.math.BigInteger.class, "Types.NUMERIC");
365: }
366:
367: /**
368: * Returns the name of the getXXX method associated with the given type
369: * in java.sql.ResultSet.
370: * @param c the class object for a Java type.
371: * @return a string representing the name of the get method, null in error case
372: */
373: static String getSQLGetMethod(Class c) {
374: String val = null;
375: val = (String) mGets.get(c);
376: if (val == null) {
377: if (c.isArray()) {
378: // See if c is byte[] or serializable[]
379: Class component = c.getComponentType();
380: if (component != null) {
381: if (component.equals(java.lang.Byte.TYPE)) {
382: val = new String("getBytes");
383: } else if (JavaType.isSerializable(component)) {
384: val = new String("getSerializable");
385: }
386: }
387: } else if (JavaType.isSerializable(c)) {
388: // See if c is serializable
389: val = new String("getSerializable");
390: }
391: }
392: return (val);
393: }
394:
395: /**
396: * Returns the name of the setXXX method associated with the given type
397: * in java.sql.PreparedStatement.
398: * @param c the class object for a Java type.
399: * @return a string representing the name of the set method, null in error case
400: */
401: static String getSQLSetMethod(Class c) {
402: String val = null;
403: val = (String) mSets.get(c);
404: if (val == null) {
405: if (c.isArray()) {
406: // See if c is byte[] or serializable[]
407: Class component = c.getComponentType();
408: if (component != null) {
409: if (component.equals(java.lang.Byte.TYPE)) {
410: val = new String("setBytes");
411: } else if (JavaType.isSerializable(component)) {
412: val = new String("setSerializable");
413: }
414: }
415: } else if (JavaType.isSerializable(c)) {
416: // See if c is serializable
417: val = new String("setSerializable");
418: }
419: }
420: return (val);
421: }
422:
423: /**
424: * Returns the SQL Type mapping the given Java Type.
425: * @param c the class object for a Java type.
426: * @return the SQL Type mapping the given Java Type, (Types.OTHER in error case)
427: */
428: static String getSQLType(Class c) {
429: String val = null;
430: val = (String) mSQLTypes.get(c);
431: if (val == null) {
432: val = new String("Types.OTHER");
433: if (c.isArray()) {
434: // See if c is byte[] or serializable[]
435: Class component = c.getComponentType();
436: if (component != null) {
437: if (component.equals(java.lang.Byte.TYPE)) {
438: val = new String("Types.VARBINARY");
439: } else if (JavaType.isSerializable(component)) {
440: val = new String("Types.VARBINARY");
441: }
442: }
443: } else if (JavaType.isSerializable(c)) {
444: // See if c is serializable
445: val = new String("Types.VARBINARY");
446: }
447: }
448: return (val);
449: }
450:
451: }
|