KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > ejb > ejbqlc > TypeSupport


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
26 /*
27  * TypeSupport.java
28  *
29  * Created on November 22, 2001
30  */

31
32 package com.sun.jdo.spi.persistence.support.ejb.ejbqlc;
33
34 import java.util.*;
35
36 import com.sun.jdo.spi.persistence.utility.I18NHelper;
37 import com.sun.jdo.api.persistence.model.Model;
38 import com.sun.jdo.api.persistence.model.jdo.*;
39 import com.sun.jdo.spi.persistence.support.ejb.model.util.NameMapper;
40
41 /**
42  * Helper class to support type info access.
43  * A type info is statically an object, internally the helper uses the type name
44  * as type info. The helper uses a model instance to access meta model info and
45  * uses a NameMapper to map EJB names to JDO names and vice versa.
46  *
47  * @author Michael Bouschen
48  * @author Shing Wai Chan
49  */

50 public class TypeSupport
51 {
52     /** Represents the internal error type. */
53     public static final Object JavaDoc errorType = "error";
54     
55     /** Represents the primitive type boolean. */
56     public static final Object JavaDoc booleanType = "boolean";
57
58     /** Represents the primitive type byte. */
59     public static final Object JavaDoc byteType = "byte";
60
61     /** Represents the primitive type short. */
62     public static final Object JavaDoc shortType = "short";
63
64     /** Represents the primitive type char. */
65     public static final Object JavaDoc charType = "char";
66
67     /** Represents the primitive type int. */
68     public static final Object JavaDoc intType = "int";
69
70     /** Represents the primitive type long. */
71     public static final Object JavaDoc longType = "long";
72
73     /** Represents the primitive type float. */
74     public static final Object JavaDoc floatType = "float";
75     
76     /** Represents the primitive type double. */
77     public static final Object JavaDoc doubleType = "double";
78     
79     /** Represents the wrapper class type boolean. */
80     public static final Object JavaDoc booleanClassType = "java.lang.Boolean";
81
82     /** Represents the wrapper class type byte. */
83     public static final Object JavaDoc byteClassType = "java.lang.Byte";
84
85     /** Represents the wrapper class type short. */
86     public static final Object JavaDoc shortClassType = "java.lang.Short";
87
88     /** Represents the wrapper class type char. */
89     public static final Object JavaDoc characterClassType = "java.lang.Character";
90
91     /** Represents the wrapper class type int. */
92     public static final Object JavaDoc integerClassType = "java.lang.Integer";
93
94     /** Represents the wrapper class type long. */
95     public static final Object JavaDoc longClassType = "java.lang.Long";
96
97     /** Represents the wrapper class type float. */
98     public static final Object JavaDoc floatClassType = "java.lang.Float";
99     
100     /** Represents the wrapper class type double. */
101     public static final Object JavaDoc doubleClassType = "java.lang.Double";
102     
103     /** Represents the type java.lang.String. */
104     public static final Object JavaDoc stringType = "java.lang.String";
105
106     /** Represents the type java.math.BigDecimal. */
107     public static final Object JavaDoc bigDecimalType = "java.math.BigDecimal";
108
109     /** Represents the type java.math.BigInteger. */
110     public static final Object JavaDoc bigIntegerType = "java.math.BigInteger";
111
112     /** Set of names of numeric types. */
113     protected static Set numericTypes = new HashSet();
114
115     /** Set of names of numeric wrapper classes. */
116     protected static Set numericWrapperTypes = new HashSet();
117
118     /** Set of names of date and time types. */
119     protected static Set dateTimeTypes = new HashSet();
120
121     /** Meta data access. */
122     protected Model model;
123     
124     /** Name mapping EJB <-> JDO. */
125     protected NameMapper nameMapper;
126     
127     /** I18N support. */
128     protected final static ResourceBundle msgs = I18NHelper.loadBundle(
129         TypeSupport.class);
130     
131     /** Inilialize static fields numericTypes numericWrapperTypes. */
132     static
133     {
134         numericTypes.add(byteType);
135         numericTypes.add(shortType);
136         numericTypes.add(charType);
137         numericTypes.add(intType);
138         numericTypes.add(longType);
139         numericTypes.add(floatType);
140         numericTypes.add(doubleType);
141         
142         numericWrapperTypes.add(byteClassType);
143         numericWrapperTypes.add(shortClassType);
144         numericWrapperTypes.add(characterClassType);
145         numericWrapperTypes.add(integerClassType);
146         numericWrapperTypes.add(longClassType);
147         numericWrapperTypes.add(floatClassType);
148         numericWrapperTypes.add(doubleClassType);
149
150         dateTimeTypes.add("java.util.Date"); //NOI18N
151
dateTimeTypes.add("java.sql.Date"); //NOI18N
152
dateTimeTypes.add("java.sql.Time"); //NOI18N
153
dateTimeTypes.add("java.sql.Timestamp"); //NOI18N
154
}
155     
156     /**
157      * Creates a new TypeSupport using the specified model instance to
158      * access meta data and the specified nameMapper for EJB <-> JDO
159      * name mapping.
160      */

161     public TypeSupport(Model model, NameMapper nameMapper)
162     {
163         this.model = model;
164         this.nameMapper = nameMapper;
165     }
166
167     /**
168      * The method returns a type info by type name.
169      * If the type name denotes a class the name should be fully qualified.
170      * The method uses the type name as type info.
171      */

172     public Object JavaDoc getTypeInfo(String JavaDoc name)
173     {
174         return name;
175     }
176     
177     /**
178      * The method returns a type info by type name by class object.
179      */

180     public Object JavaDoc getTypeInfo(Class JavaDoc clazz)
181     {
182         return getTypeInfo(clazz.getName());
183     }
184
185     /**
186      * Returns <code>true</code> if type denotes the error type.
187      */

188     public static boolean isErrorType(Object JavaDoc type)
189     {
190         return type.equals(errorType);
191     }
192
193     /**
194      * Returns <code>true</code> if type is boolean or java.lang.Boolean
195      */

196     public static boolean isBooleanType(Object JavaDoc type)
197     {
198         return type.equals(booleanType) ||
199                type.equals(booleanClassType);
200     }
201
202     /**
203      * Returns <code>true</code> if type is char or java.lang.Character
204      */

205     public static boolean isCharType(Object JavaDoc type)
206     {
207         return type.equals(charType) ||
208                type.equals(characterClassType);
209     }
210
211     /**
212      * Returns <code>true</code> if type is int or java.lang.Integer
213      */

214     public static boolean isIntType(Object JavaDoc type)
215     {
216         return type.equals(intType) ||
217                type.equals(integerClassType);
218     }
219
220     /**
221      * Returns <code>true</code> if type is double or java.lang.Double.
222      */

223     public static boolean isDoubleType(Object JavaDoc type)
224     {
225         return type.equals(doubleType) ||
226                type.equals(doubleClassType);
227     }
228
229     /**
230      * Returns <code>true</code> if type is a primitive numeric type such as
231      * byte, int etc.
232      */

233     public static boolean isNumericType(Object JavaDoc type)
234     {
235         return numericTypes.contains(type);
236     }
237
238     /**
239      * Returns <code>true</code> if type is a wrapper class of a primitive
240      * numeric type such as java.lang.Byte, java.lang.Integer etc.
241      */

242     public static boolean isNumericWrapperType(Object JavaDoc type)
243     {
244         return numericWrapperTypes.contains(type);
245     }
246
247     /**
248      * Returns <code>true</code> if type is a NumerType, which means it is either
249      * a numeric primitive or a numeric wrapper class.
250      */

251     public static boolean isNumberType(Object JavaDoc type)
252     {
253         return isNumericType(type) ||
254                isNumericWrapperType(type) ||
255                bigDecimalType.equals(type) ||
256                bigIntegerType.equals(type);
257     }
258
259     /**
260      * Returns <code>true</code> if type is a floating point type or
261      * wrapper class of a floating point type.
262      */

263     public static boolean isFloatingPointType(Object JavaDoc type)
264     {
265         return doubleType.equals(type) ||
266                doubleClassType.equals(type) ||
267                floatType.equals(type) ||
268                floatClassType.equals(type);
269     }
270
271     /** Returns <code>true</code> if type denotes java.lang.String. */
272     public static boolean isStringType(Object JavaDoc type)
273     {
274         return type.equals(stringType);
275     }
276
277     /** Returns <code>true</code> if type is a collection type. */
278     public boolean isCollectionType(Object JavaDoc type)
279     {
280         return model.isCollection((String JavaDoc)type);
281     }
282     
283     /** Returns <code>true</code> if type is a date or time type */
284     public boolean isDateTimeType(Object JavaDoc type)
285     {
286         return dateTimeTypes.contains(getTypeName(type));
287     }
288    
289     /** Returns <code>true</code> if type is an orderable type */
290     public boolean isOrderableType(Object JavaDoc type)
291     {
292         return isNumberType(type) || isDateTimeType(type) || isStringType(type);
293     }
294    
295     /**
296      * Returns the type info for a primitive type. The method returns
297      * {@link #errorType} if the specified type is not a primitive type.
298      */

299     public static Object JavaDoc getPrimitiveType(Object JavaDoc type)
300     {
301         Object JavaDoc result = errorType;
302         if (type.equals(booleanClassType))
303             result = booleanType;
304         else if (type.equals(integerClassType))
305             result = intType;
306         else if (type.equals(longClassType))
307             result = longType;
308         else if (type.equals(floatClassType))
309             result = floatType;
310         else if (type.equals(doubleClassType))
311             result = doubleType;
312         else if (type.equals(byteClassType))
313             result = byteType;
314         else if (type.equals(shortClassType))
315             result = shortType;
316         else if (type.equals(characterClassType))
317             result = charType;
318         return result;
319     }
320
321     /**
322      * Returns the type info for a wrapper class type. The method returns
323      * {@link #errorType} if the specified type is not a wrapper class type.
324      */

325     public static Object JavaDoc getWrapperType(Object JavaDoc type)
326     {
327         Object JavaDoc result = errorType;
328         if (type.equals(booleanType))
329             result = booleanClassType;
330         else if (type.equals(intType))
331             result = integerClassType;
332         else if (type.equals(longType))
333             result = longClassType;
334         else if (type.equals(floatType))
335             result = floatClassType;
336         else if (type.equals(doubleType))
337             result = doubleClassType;
338         else if (type.equals(byteType))
339             result = byteClassType;
340         else if (type.equals(shortType))
341             result = shortClassType;
342         else if (type.equals(charType))
343             result = characterClassType;
344         return result;
345     }
346
347     /**
348      * Implements binary numeric promotion as defined in the
349      * Java Language Specification section 5.6.2
350      */

351     public static Object JavaDoc binaryNumericPromotion(Object JavaDoc left, Object JavaDoc right)
352     {
353         if (isNumericType(left) && isNumericType(right)) {
354             if (left.equals(doubleType) || right.equals(doubleType))
355                 return doubleType;
356             else if (left.equals(floatType) || right.equals(floatType))
357                 return floatType;
358             else if (left.equals(longType) || right.equals(longType))
359                 return longType;
360             else
361                 return intType;
362         }
363         return errorType;
364     }
365
366     /**
367      * Implements unray numeric promotion as defined in the
368      * Java Language Specification section 5.6.1
369      */

370     public static Object JavaDoc unaryNumericPromotion(Object JavaDoc type)
371     {
372         if (isNumericType(type)) {
373             if (type.equals(byteType) || type.equals(shortType) ||
374                 type.equals(charType)) {
375                 return intType;
376             }
377             else {
378                 return type;
379             }
380         }
381         return errorType;
382     }
383
384     /**
385      * Implements type compatibility. The method returns <code>true</code>
386      * if left is compatible with right. This is equivalent to
387      * rightClass.isAssignableFrom(leftClass).
388      * Note, the method does not support inheritance.
389      */

390     public boolean isCompatibleWith(Object JavaDoc left, Object JavaDoc right)
391     {
392         String JavaDoc leftTypeName = getTypeName(left);
393         String JavaDoc rightTypeName = getTypeName(right);
394
395         if (nameMapper.isLocalInterface(leftTypeName) &&
396             nameMapper.isEjbName(rightTypeName))
397             rightTypeName = nameMapper.getLocalInterfaceForEjbName(rightTypeName);
398         else if (nameMapper.isRemoteInterface(leftTypeName) &&
399             nameMapper.isEjbName(rightTypeName))
400             rightTypeName = nameMapper.getRemoteInterfaceForEjbName(rightTypeName);
401         else if (nameMapper.isLocalInterface(rightTypeName) &&
402             nameMapper.isEjbName(leftTypeName))
403             leftTypeName = nameMapper.getLocalInterfaceForEjbName(leftTypeName);
404         else if (nameMapper.isRemoteInterface(rightTypeName) &&
405             nameMapper.isEjbName(leftTypeName))
406             leftTypeName = nameMapper.getRemoteInterfaceForEjbName(leftTypeName);
407
408         // does not handle inheritance!
409
return leftTypeName.equals(rightTypeName);
410     }
411
412     /** Returns the type name for a specified type info. */
413     public static String JavaDoc getTypeName(Object JavaDoc type)
414     {
415         return (String JavaDoc)type;
416     }
417     
418     /** Returns the typeInfo (the ejb name) for the specified abstract schema. */
419     public Object JavaDoc getTypeInfoForAbstractSchema(String JavaDoc abstractSchema)
420     {
421         return nameMapper.getEjbNameForAbstractSchema(abstractSchema);
422     }
423
424     /** Returns the typeInfo (the ejb name) for the specified abstract schema. */
425     public String JavaDoc getAbstractSchemaForTypeInfo(Object JavaDoc typeInfo)
426     {
427         String JavaDoc typeName = getTypeName(typeInfo);
428         return nameMapper.isEjbName(typeName) ?
429             nameMapper.getAbstractSchemaForEjbName(typeName) :
430             typeName;
431     }
432
433     /** Returns the type info for the type of the given field. */
434     public Object JavaDoc getFieldType(Object JavaDoc typeInfo, String JavaDoc fieldName)
435     {
436         String JavaDoc typeName = getTypeName(typeInfo);
437         if (!nameMapper.isEjbName(typeName)) {
438             ErrorMsg.fatal(I18NHelper.getMessage(
439                 msgs, "ERR_EjbNameExpected", //NOI18N
440
"TypeSupport.getFieldType", typeName)); //NOI18N
441
}
442         
443         String JavaDoc fieldType = model.getFieldType(typeName, fieldName);
444         // check for local or remote interface, map to ejb name
445
if (nameMapper.isLocalInterface(fieldType)) {
446             fieldType = nameMapper.getEjbNameForLocalInterface(
447                 typeName, fieldName, fieldType);
448         }
449         else if (nameMapper.isRemoteInterface(fieldType)) {
450
451             fieldType = nameMapper.getEjbNameForRemoteInterface(
452                 typeName, fieldName, fieldType);
453         }
454         return getTypeInfo(fieldType);
455     }
456     
457     /**
458      * Returns the field info for the specified field of the specified type.
459      * The field info is opaque for the caller. Methods {@link #isRelationship}
460      * and {@link #getElementType} allow to get details for a given field info.
461      */

462     public Object JavaDoc getFieldInfo(Object JavaDoc typeInfo, String JavaDoc fieldName)
463     {
464         Object JavaDoc fieldInfo = null;
465         String JavaDoc typeName = getTypeName(typeInfo);
466         if (!nameMapper.isEjbName(typeName)) {
467             ErrorMsg.fatal(I18NHelper.getMessage(
468                 msgs, "ERR__EjbNameExpected", //NOI18N
469
"TypeSupport.getFieldInfo", typeName)); //NOI18N
470
}
471         String JavaDoc pcClassName = nameMapper.getPersistenceClassForEjbName(typeName);
472         String JavaDoc pcFieldName = nameMapper.getPersistenceFieldForEjbField(
473             typeName, fieldName);
474         PersistenceClassElement pce = model.getPersistenceClass(pcClassName);
475         if (pce != null) {
476             fieldInfo = pce.getField(pcFieldName);
477         }
478         return fieldInfo;
479     }
480     
481     /**
482      * Returns <code>true</code> if the specified field info denotes a
483      * relationship field.
484      */

485     public boolean isRelationship(Object JavaDoc fieldInfo)
486     {
487         return (fieldInfo != null) && (fieldInfo instanceof RelationshipElement);
488     }
489
490     /**
491      * Returns the type info of the element type if the specified field info
492      * denotes a collection relationship. Otherwise it returns <code>null</code>.
493      */

494     public Object JavaDoc getElementType(Object JavaDoc fieldInfo)
495     {
496         if ((fieldInfo != null) && (fieldInfo instanceof RelationshipElement)) {
497             String JavaDoc elementClass = ((RelationshipElement)fieldInfo).getElementClass();
498             return nameMapper.getEjbNameForPersistenceClass(elementClass);
499         }
500         else
501             return null;
502     }
503
504     /**
505      * Gets the name of the persistence-capable class which corresponds to
506      * the specified typeInfo (assuming an ejb name). The method returs the
507      * type name of the specified typeInfo, it the typeInfo does not denote
508      * an ejb-name (e.g. a local or remote interface).
509      */

510     public String JavaDoc getPCForTypeInfo(Object JavaDoc typeInfo)
511     {
512         String JavaDoc typeName = getTypeName(typeInfo);
513         String JavaDoc pcClassName =
514             nameMapper.getPersistenceClassForEjbName(typeName);
515         return (pcClassName != null) ? pcClassName : typeName;
516     }
517     
518     /**
519      * Returns <code>true</code> if the specified type info denotes an ejb name.
520      */

521     public boolean isEjbName(Object JavaDoc typeInfo)
522     {
523         return nameMapper.isEjbName(getTypeName(typeInfo));
524     }
525     
526     /**
527      * Returns <code>true</code> if the specified type info denotes an ejb name
528      * or the name of a local interface or the name of a remote interface.
529      */

530     public boolean isEjbOrInterfaceName(Object JavaDoc typeInfo)
531     {
532         String JavaDoc typeName = getTypeName(typeInfo);
533         return nameMapper.isEjbName(typeName) ||
534                nameMapper.isLocalInterface(typeName) ||
535                nameMapper.isRemoteInterface(typeName);
536     }
537
538     /**
539      * Returns <code>true</code> if the specified type info denotes the
540      * remote interface of the bean with the specified ejb name.
541      */

542     public boolean isRemoteInterfaceOfEjb(Object JavaDoc typeInfo, String JavaDoc ejbName)
543     {
544         String JavaDoc typeName = getTypeName(typeInfo);
545         String JavaDoc remoteInterface = nameMapper.getRemoteInterfaceForEjbName(ejbName);
546         return (remoteInterface != null) && remoteInterface.equals(typeName);
547         
548     }
549
550     /**
551      * Returns <code>true</code> if the specified type info denotes the
552      * local interface of the bean with the specified ejb name.
553      */

554     public boolean isLocalInterfaceOfEjb(Object JavaDoc typeInfo, String JavaDoc ejbName)
555     {
556         String JavaDoc typeName = getTypeName(typeInfo);
557         String JavaDoc localInterface = nameMapper.getLocalInterfaceForEjbName(ejbName);
558         return (localInterface != null) && localInterface.equals(typeName);
559     }
560
561     /**
562      * Returns <code>true</code> if the specified type info denotes
563      * a remote interface.
564      */

565     public boolean isRemoteInterface(Object JavaDoc typeInfo)
566     {
567         return nameMapper.isRemoteInterface(getTypeName(typeInfo));
568     }
569
570     /**
571      * Returns <code>true</code> if the specified type info denotes
572      * a local interface.
573      */

574     public boolean isLocalInterface(Object JavaDoc typeInfo)
575     {
576         return nameMapper.isLocalInterface(getTypeName(typeInfo));
577     }
578
579     /**
580      * Returns <code>true</code> if the bean with the specified ejb name
581      * has a remote interface.
582      */

583     public boolean hasRemoteInterface(Object JavaDoc typeInfo)
584     {
585         return nameMapper.getRemoteInterfaceForEjbName(
586             getTypeName(typeInfo)) != null;
587     }
588
589     /**
590      * Returns <code>true</code> if the bean with the specified ejb name
591      * has a local interface.
592      */

593     public boolean hasLocalInterface(Object JavaDoc typeInfo)
594     {
595         return nameMapper.getLocalInterfaceForEjbName(
596             getTypeName(typeInfo)) != null;
597     }
598
599     /**
600      * Return JDO QL return type for Sum function for a given type.
601      * @param type is a number data type
602      */

603     public Object JavaDoc getSumReturnType(Object JavaDoc type) {
604         if (isFloatingPointType(type)) {
605             return doubleClassType;
606         } else if (isNumericType(type) || isNumericWrapperType(type)) {
607             return longClassType;
608         } else {
609             return type;
610         }
611     }
612
613     /**
614      * Return JDO QL return type for Avg function for a given type.
615      * @param type is a number data type
616      */

617     public Object JavaDoc getAvgReturnType(Object JavaDoc type) {
618         if (isNumericType(type) || isNumericWrapperType(type)) {
619             return doubleClassType;
620         } else {
621             return type;
622         }
623     }
624
625     /**
626      * Return JDO QL return type for Min/Max function for a given type.
627      * @param type is an orderable data type
628      */

629     public Object JavaDoc getMinMaxReturnType(Object JavaDoc type) {
630         if (isFloatingPointType(type)) {
631             return doubleClassType;
632         } else if (isCharType(type)) {
633             return characterClassType;
634         } else if (isNumericType(type) || isNumericWrapperType(type)) {
635             return longClassType;
636         } else {
637             return type;
638         }
639     }
640 }
641
Popular Tags