KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > sqlstore > query > util > type > TypeTable


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * TypeTable.java
26  *
27  * Created on March 8, 2000
28  */

29
30 package com.sun.jdo.spi.persistence.support.sqlstore.query.util.type;
31
32 import java.util.*;
33 import java.math.*;
34
35 import com.sun.jdo.api.persistence.model.Model;
36 import com.sun.jdo.spi.persistence.utility.FieldTypeEnumeration;
37
38 /**
39  *
40  * @author Michael Bouschen
41  * @author Shing Wai Chan
42  * @version 0.1
43  */

44 public class TypeTable
45 {
46     /**
47      * Represents the type of null
48      */

49     public static final NullType nullType = new NullType();
50
51     /**
52      * Represents the internal error type.
53      */

54     public static final ErrorType errorType = new ErrorType();
55
56     /**
57      * Represents the type boolean.
58      */

59     public BooleanType booleanType;
60
61     /**
62      * Represents the type char.
63      */

64     public IntegralType charType;
65
66     /**
67      * Represents the type byte.
68      */

69     public IntegralType byteType;
70
71     /**
72      * Represents the type short.
73      */

74     public IntegralType shortType;
75
76     /**
77      * Represents the type int.
78      */

79     public IntegralType intType;
80
81     /**
82      * Represents the type long.
83      */

84     public IntegralType longType;
85
86     /**
87      * Represents the type float.
88      */

89     public FloatingPointType floatType;
90
91     /**
92      * Represents the type double.
93      */

94     public FloatingPointType doubleType;
95
96     /**
97      * Represents the type java.lang.String.
98      */

99     public StringType stringType;
100
101     /**
102      * Represents the type java.math.BigDecimal
103      */

104     public MathType bigDecimalType;
105
106     /**
107      * Represents the type java.math.BigInteger
108      */

109     public MathType bigIntegerType;
110
111     /**
112      * The model used to access class meta info
113      */

114     protected Model model;
115
116     /**
117      * Store class loader for Class.forName lookup
118      */

119     protected ClassLoader JavaDoc classLoader;
120
121     /**
122      * The list of actual known types.
123      */

124     protected Map types = new HashMap();
125
126     /** Map of TypeTable instances. Key is a classLoader. */
127     private static Map typeTables = new HashMap();
128
129     /** */
130     public static TypeTable getInstance(ClassLoader JavaDoc classLoader)
131     {
132         synchronized (typeTables) {
133             TypeTable typeTable = (TypeTable)typeTables.get(classLoader);
134             if (typeTable == null) {
135                 typeTable = new TypeTable(classLoader);
136                 typeTables.put(classLoader, typeTable);
137             }
138             return typeTable;
139         }
140     }
141
142     /** */
143     public static void removeInstance(ClassLoader JavaDoc classLoader)
144     {
145         synchronized (typeTables) {
146             typeTables.remove(classLoader);
147         }
148     }
149
150     /**
151      *
152      */

153     private TypeTable(ClassLoader JavaDoc classLoader)
154     {
155         // init model
156
// JQLC is only used at runtime => use runtime model
157
this.model = Model.RUNTIME;
158
159         this.classLoader = classLoader;
160
161         booleanType = new BooleanType();
162         types.put(booleanType.getName(), booleanType);
163         charType = new IntegralType("char", char.class, FieldTypeEnumeration.CHARACTER_PRIMITIVE); //NOI18N
164
types.put(charType.getName(), charType);
165         byteType = new IntegralType("byte", byte.class, FieldTypeEnumeration.BYTE_PRIMITIVE); //NOI18N
166
types.put(byteType.getName(), byteType);
167         shortType = new IntegralType("short", short.class, FieldTypeEnumeration.SHORT_PRIMITIVE); //NOI18N
168
types.put(shortType.getName(), shortType);
169         intType = new IntegralType("int", int.class, FieldTypeEnumeration.INTEGER_PRIMITIVE); //NOI18N
170
types.put(intType.getName(), intType);
171         longType = new IntegralType("long", long.class, FieldTypeEnumeration.LONG_PRIMITIVE); //NOI18N
172
types.put(longType.getName(), longType);
173         floatType = new FloatingPointType("float", float.class, FieldTypeEnumeration.FLOAT_PRIMITIVE); //NOI18N
174
types.put(floatType.getName(), floatType);
175         doubleType = new FloatingPointType("double", double.class, FieldTypeEnumeration.DOUBLE_PRIMITIVE); //NOI18N
176
types.put(doubleType.getName(), doubleType);
177
178         stringType = new StringType(this);
179         types.put(stringType.getName(), stringType);
180
181         WrapperClassType booleanClassType =
182             new WrapperClassType("java.lang.Boolean", Boolean JavaDoc.class, FieldTypeEnumeration.BOOLEAN, booleanType, this); //NOI18N
183
types.put(booleanClassType.getName(), booleanClassType);
184         NumericWrapperClassType byteClassType =
185             new NumericWrapperClassType("java.lang.Byte", Byte JavaDoc.class, FieldTypeEnumeration.BYTE, byteType, this); //NOI18N
186
types.put(byteClassType.getName(), byteClassType);
187         NumericWrapperClassType shortClassType =
188             new NumericWrapperClassType("java.lang.Short", Short JavaDoc.class, FieldTypeEnumeration.SHORT, shortType, this); //NOI18N
189
types.put(shortClassType.getName(), shortClassType);
190         NumericWrapperClassType intClassType =
191             new NumericWrapperClassType("java.lang.Integer", Integer JavaDoc.class, FieldTypeEnumeration.INTEGER, intType, this); //NOI18N
192
types.put(intClassType.getName(), intClassType);
193         NumericWrapperClassType longClassType =
194             new NumericWrapperClassType("java.lang.Long", Long JavaDoc.class, FieldTypeEnumeration.LONG, longType, this); //NOI18N
195
types.put(longClassType.getName(), longClassType);
196         NumericWrapperClassType charClassType =
197             new NumericWrapperClassType("java.lang.Character", Character JavaDoc.class, FieldTypeEnumeration.CHARACTER, charType, this); //NOI18N
198
types.put(charClassType.getName(), charClassType);
199         NumericWrapperClassType floatClassType =
200             new NumericWrapperClassType("java.lang.Float", Float JavaDoc.class, FieldTypeEnumeration.FLOAT, floatType, this); //NOI18N
201
types.put(floatClassType.getName(), floatClassType);
202         NumericWrapperClassType doubleClassType =
203             new NumericWrapperClassType("java.lang.Double", Double JavaDoc.class, FieldTypeEnumeration.DOUBLE, doubleType, this); //NOI18N
204
types.put(doubleClassType.getName(), doubleClassType);
205
206         booleanType.setWrapper(booleanClassType);
207         byteType.setWrapper(byteClassType);
208         shortType.setWrapper(shortClassType);
209         intType.setWrapper(intClassType);
210         longType.setWrapper(longClassType);
211         charType.setWrapper(charClassType);
212         floatType.setWrapper(floatClassType);
213         doubleType.setWrapper(doubleClassType);
214
215         bigDecimalType = new MathType("java.math.BigDecimal", BigDecimal.class, FieldTypeEnumeration.BIGDECIMAL, this); //NOI18N
216
types.put(bigDecimalType.getName(), bigDecimalType);
217         bigIntegerType = new MathType("java.math.BigInteger", BigInteger.class, FieldTypeEnumeration.BIGINTEGER, this); //NOI18N
218
types.put(bigIntegerType.getName(), bigIntegerType);
219
220         // Date types
221
DateType dateType = new DateType("java.util.Date", java.util.Date JavaDoc.class, FieldTypeEnumeration.UTIL_DATE, this);
222         types.put(dateType.getName(), dateType);
223         DateType sqldateType = new DateType("java.sql.Date", java.sql.Date JavaDoc.class, FieldTypeEnumeration.SQL_DATE, this);
224         types.put(sqldateType.getName(), sqldateType);
225         DateType sqlTimeType = new DateType("java.sql.Time", java.sql.Time JavaDoc.class, FieldTypeEnumeration.SQL_TIME, this);
226         types.put(sqlTimeType.getName(), sqlTimeType);
227         DateType sqlTimestampType = new DateType("java.sql.Timestamp", java.sql.Timestamp JavaDoc.class, FieldTypeEnumeration.SQL_TIMESTAMP, this);
228         types.put(sqlTimestampType.getName(), sqlTimestampType);
229     }
230
231     /**
232      * Checks for the type with the specified name.
233      * First the internal type table is checked.
234      * If the type is not found it checks Class.forName.
235      * If the type is found the internal type table is updated
236      * (optimization for further access).
237      * If the type is neither in the type table nor found by forName
238      * null is returned and the type table is not changed.
239      * Otherwise the Type representation of the type is returned.
240      * @param name the name of the type to be checked.
241      * @return the Type object representing the type with the
242      * specified name or null when the type was not found.
243      */

244     public Type checkType(String JavaDoc name)
245     {
246         synchronized(types)
247         {
248             Type result = (Type)types.get(name);
249             if (result == null)
250             {
251                 // type not found => check repository
252
try
253                 {
254                     Class JavaDoc clazz = Class.forName(name, true, classLoader);
255                     result = new ClassType(name, clazz, this);
256                     types.put(name, result);
257                 }
258                 catch (ClassNotFoundException JavaDoc ex)
259                 {
260                     // unknown class -> error message?
261
}
262             }
263             return result;
264         }
265     }
266
267     /**
268      * Checks for the type with the specified name.
269      * First the internal type table is checked.
270      * If the type is not found it checks Class.forName.
271      * If the type is found the internal type table is updated
272      * (optimization for further access).
273      * If the type is neither in the type table nor found by forName
274      * null is returned and the type table is not changed.
275      * Otherwise the Type representation of the type is returned.
276      * @param clazz the name of the type to be checked.
277      * @return the Type object representing the type with the
278      * specified name or null when the type was not found.
279      */

280     public Type checkType(Class JavaDoc clazz)
281     {
282         if (clazz == null)
283             return null;
284         String JavaDoc name = clazz.getName();
285         synchronized (types)
286         {
287             Type result = (Type)types.get(name);
288
289             if (result == null)
290             {
291                 // type not found
292
result = new ClassType(name, clazz, this);
293                 types.put(name, result);
294             }
295             return result;
296         }
297     }
298
299     /**
300      * Implements binary numeric promotion as defined in the Java Language Specification section 5.6.2
301      */

302     public Type binaryNumericPromotion(Type left, Type right)
303     {
304         if ((left instanceof NumericType) && (right instanceof NumericType))
305         {
306             if (left.equals(doubleType) || right.equals(doubleType))
307                 return doubleType;
308             else if (left.equals(floatType) || right.equals(floatType))
309                 return floatType;
310             else if (left.equals(longType) || right.equals(longType))
311                 return longType;
312             else
313                 return intType;
314         }
315         else
316         {
317             return errorType;
318         }
319     }
320
321     /**
322      * Implements unray numeric promotion as defined in the Java Language Specification section 5.6.1
323      */

324     public Type unaryNumericPromotion(Type type)
325     {
326         if (type instanceof NumericType)
327         {
328             if (type.equals(byteType) || type.equals(shortType) || type.equals(charType))
329             {
330                 return intType;
331             }
332             else
333             {
334                 return type;
335             }
336         }
337         else
338         {
339             return errorType;
340         }
341     }
342
343     /**
344      * Returns true if type is a NumericType or compatible to java.lang.Number
345      */

346     public boolean isNumberType(Type type)
347     {
348         Type numberType = checkType("java.lang.Number"); //NOI18N
349
Type characterType = checkType("java.lang.Character"); //NOI18N
350
return (type instanceof NumericType) ||
351                (type.isCompatibleWith(numberType)) ||
352                (type.isCompatibleWith(characterType));
353     }
354
355     /**
356      * Returns true if type is an integral type or a Java wrapper class
357      * type wrapping an integral type.
358      */

359     public boolean isIntegralType(Type type)
360     {
361         if (type instanceof IntegralType)
362             return true;
363         else if (type instanceof NumericWrapperClassType)
364             return ((NumericWrapperClassType)type).getPrimitiveType() instanceof IntegralType;
365         return false;
366     }
367
368     /**
369      * Returns true if type is a floating point type or a Java wrapper
370      * class type wrapping a floating point integral type.
371      */

372     public boolean isFloatingPointType(Type type)
373     {
374         if (type instanceof FloatingPointType)
375             return true;
376         else if (type instanceof NumericWrapperClassType)
377             return ((NumericWrapperClassType)type).getPrimitiveType() instanceof FloatingPointType;
378         return false;
379     }
380
381     /**
382      * Returns true if type is double or java.lang.Double
383      */

384     public boolean isDoubleType(Type type)
385     {
386         return (type.equals(doubleType) || type.equals(doubleType.getWrapper()));
387     }
388
389     /**
390      * Returns true if type is int or java.lang.Integer
391      */

392     public boolean isIntType(Type type)
393     {
394         return (type.equals(intType) || type.equals(intType.getWrapper()));
395     }
396
397     /**
398      * Returns true if type is char or java.lang.Character
399      */

400     public boolean isCharType(Type type)
401     {
402         return (type.equals(charType) || type.equals(charType.getWrapper()));
403     }
404
405     /**
406      * Returns true if type is boolean or java.lang.Boolean
407      */

408     public boolean isBooleanType(Type type)
409     {
410         return (type.equals(booleanType) || type.equals(booleanType.getWrapper()));
411     }
412
413     /**
414      * Returns true if type denotes a pertsistence capable class
415      * Note, it returns false for non ClassType values, especially for
416      * NullType and ErrorType.
417      */

418     public boolean isPersistenceCapableType(Type type)
419     {
420         return ((type instanceof ClassType) &&
421                 ((ClassType)type).isPersistenceCapable());
422     }
423
424     /**
425      * Returns true if type denotes a collection type.
426      * Note, it returns false for non ClassType values, especially for
427      * NullType and ErrorType.
428      */

429     public boolean isCollectionType(Type type)
430     {
431         Type collectionType = checkType("java.util.Collection"); //NOI18N
432
return (type instanceof ClassType) && type.isCompatibleWith(collectionType);
433     }
434
435     /**
436      * Returns true if type denotes a collection type.
437      * Note, it returns false for non ClassType values, especially for
438      * NullType and ErrorType.
439      */

440     public boolean isJavaLangMathType(Type type)
441     {
442         Type mathType = checkType("java.lang.Math"); //NOI18N
443
return (type instanceof ClassType) && type.isCompatibleWith(mathType);
444     }
445
446     /**
447      * Return JDO QL return type for Sum function for a given type.
448      * @param type is a number data type
449      */

450     public Type getSumReturnType(Type type) {
451         if (isFloatingPointType(type)) {
452             return doubleType.getWrapper();
453         } else if (bigDecimalType.equals(type)) {
454             return bigDecimalType;
455         } else if (bigIntegerType.equals(type)) {
456             return bigIntegerType;
457         } else if (isNumberType(type)) {
458             return longType.getWrapper();
459         } else {
460             return type;
461         }
462     }
463
464     /**
465      * Return JDO QL return type for Avg function for a given type.
466      * @param type is a number data type
467      */

468     public Type getAvgReturnType(Type type) {
469         if (bigDecimalType.equals(type)) {
470             return bigDecimalType;
471         } else if (bigIntegerType.equals(type)) {
472             return bigIntegerType;
473         } else if (isNumberType(type)) {
474             return doubleType.getWrapper();
475         } else {
476             return type;
477         }
478     }
479
480     /**
481      * Return JDO QL return type for Min/Max function for a given type.
482      * @param type is an orderable data type
483      */

484     public Type getMinMaxReturnType(Type type) {
485         if (isFloatingPointType(type)) {
486             return doubleType.getWrapper();
487         } else if (isCharType(type)) {
488             return charType.getWrapper();
489         } else if (bigDecimalType.equals(type)) {
490             return bigDecimalType;
491         } else if (bigIntegerType.equals(type)) {
492             return bigIntegerType;
493         } else if (isNumberType(type)) {
494             return longType.getWrapper();
495         } else {
496             return type;
497         }
498     }
499 }
500
Popular Tags