View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software 
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License.
16   */
17  
18  /***
19   * TypeSupport.java
20   *
21   */
22  
23  package org.apache.jdo.impl.model.jdo.util;
24  
25  import java.util.Map;
26  import java.util.Set;
27  import java.util.HashMap;
28  import java.util.HashSet;
29  
30  import org.apache.jdo.model.java.JavaModel;
31  import org.apache.jdo.model.java.JavaType;
32  import org.apache.jdo.model.jdo.JDOModel;
33  
34  /***
35   *
36   */
37  public class TypeSupport
38  {
39      /*** */
40      private final static Set primitiveTypeNames = new HashSet();
41  
42      /*** */
43      private final static Map singleFieldObjectIdClassNames = new HashMap();
44  
45      static 
46      {
47          // initialize set of names of primitive types
48          primitiveTypeNames.add("byte"); // NOI18N
49          primitiveTypeNames.add("short"); // NOI18N
50          primitiveTypeNames.add("int"); // NOI18N
51          primitiveTypeNames.add("long"); // NOI18N
52          primitiveTypeNames.add("char"); // NOI18N
53          primitiveTypeNames.add("float"); // NOI18N
54          primitiveTypeNames.add("double"); // NOI18N
55          primitiveTypeNames.add("boolean"); // NOI18N
56  
57          // initialize map of singleFieldObjectIdClassNames
58          singleFieldObjectIdClassNames.put(
59              "byte", //NOI18N
60              "javax.jdo.identity.ByteIdentity"); //NOI18N
61          singleFieldObjectIdClassNames.put(
62              "java.lang.Byte", //NOI18N
63              "javax.jdo.identity.ByteIdentity"); //NOI18N
64          singleFieldObjectIdClassNames.put(
65              "char", //NOI18N
66              "javax.jdo.identity.CharIdentity"); //NOI18N
67          singleFieldObjectIdClassNames.put(
68              "java.lang.Char", //NOI18N
69              "javax.jdo.identity.CharIdentity"); //NOI18N
70          singleFieldObjectIdClassNames.put(
71              "int", //NOI18N
72              "javax.jdo.identity.IntIdentity"); //NOI18N
73          singleFieldObjectIdClassNames.put(
74              "java.lang.Integer",  //NOI18N
75              "javax.jdo.identity.IntIdentity"); //NOI18N
76          singleFieldObjectIdClassNames.put(
77              "long",  //NOI18N
78              "javax.jdo.identity.LongIdentity"); //NOI18N
79          singleFieldObjectIdClassNames.put(
80              "java.lang.Long",  //NOI18N
81              "javax.jdo.identity.LongIdentity"); //NOI18N
82          singleFieldObjectIdClassNames.put(
83              "short", //NOI18N
84              "javax.jdo.identity.ShortIdentity"); //NOI18N
85          singleFieldObjectIdClassNames.put(
86              "java.lang.Short", //NOI18N
87              "javax.jdo.identity.ShortIdentity"); //NOI18N
88          singleFieldObjectIdClassNames.put(
89              "java.lang.String", //NOI18N
90              "javax.jdo.identity.StringIdentity"); //NOI18N
91      }
92  
93      /*** Fully qualified class name of the ObjectIdentity class. */
94      private static final String OBJECT_IDENTITY_NAME =  
95          "javax.jdo.identity.ObjectIdentity"; //NOI18N
96      
97      /*** 
98       * Returns <code>true</code> if the persistence-modifier of a field
99       * having the specified type defaults to <code>true</code>. 
100      * @param type the type to be checked
101      * @return <code>true</code> if type is a value type; 
102      * <code>false</code> otherwise
103      */
104     public static boolean isPersistenceFieldType(JavaType type)
105     {
106         return type.isValue() ||
107                type.isJDOSupportedCollection() ||
108                type.isJDOSupportedMap() ||
109                type.isPersistenceCapable() ||
110                isPersistenceArrayType(type);
111     }
112      
113     /*** 
114      * Returns <code>true</code> if the embedded-element property of a field 
115      * having the specified type defaults to <code>true</code>.
116      * @param type the type to be checked
117      * @return <code>true</code> if type is a embedded-element type; 
118      * <code>false</code> otherwise
119      */
120     public static boolean isEmbeddedElementType(JavaType type)
121     {
122         return !type.isPersistenceCapable() && !type.isInterface();
123     }
124 
125     /*** 
126      * Returns <code>true</code> if the embedded property of a field having 
127      * the specified type defaults to <code>true</code>.
128      * @param type the type to be checked
129      * @return <code>true</code> if type is a embedded type; 
130      * <code>false</code> otherwise
131      */
132     public static boolean isEmbeddedFieldType(JavaType type)
133     {
134         return type.isValue() ||
135                isPersistenceArrayType(type);
136     }
137 
138     /***
139      * Returns a JavaType representation for the specified type name. 
140      * The method delegates the request to the JavaModel attached to the
141      * specified JDOModel. An unqualified name is qualified using first the 
142      * specified packagePrefix and then "java.lang.", but only if the type
143      * name is the the name of a primitive type. If the method still does
144      * not find a valid type, then it returns <code>null</code>.
145      * @param jdoModel the owning JDOModel
146      * @param typeName the name of the type to be checked
147      * @param packagePrefix the package prefix used to qualify the type name
148      * @return the JavaType representation of the specified type name or
149      * <code>null</code> if it cannot be resolved.
150      */
151     public static JavaType resolveType(JDOModel jdoModel, String typeName, 
152                                        String packagePrefix)
153     {
154         JavaType type = null;
155         JavaModel javaModel = jdoModel.getJavaModel();
156         if (primitiveTypeNames.contains(typeName) ||
157             (typeName.indexOf('.') != -1) || 
158             (packagePrefix == null) || (packagePrefix.length() == 0)) {
159             // Take the typeName as specified, 
160             // if typeName denotes a primitive type or is a qualified name
161             // or if there is no packagePrefix (default package)
162             type = javaModel.getJavaType(typeName);
163         }
164         else {
165             // Not a primitive type and not qualified and packagePrefix
166             // specified => qualify using packagePrefix
167             type = javaModel.getJavaType(packagePrefix + typeName);
168             if (type == null) {
169                 // If type could not be resolved => 
170                 // use java.lang. package prefix as qualifier 
171                 type = javaModel.getJavaType("java.lang." + typeName); //NOI18N
172             }
173         }
174         return type;
175     }
176 
177     /***
178      * Returns <code>true</code> if the specified type represents an array
179      * and its element type is a value type.
180      * @param type the JavaType to be checked
181      * @return <code>true</code> if type is a value array; 
182      * <code>false</code> otherwise.
183      */
184     public static boolean isValueArrayType(JavaType type)
185     {
186         if (type.isArray()) {
187             JavaType elementType = type.getArrayComponentType();
188             return elementType.isValue();
189         }
190         return false;
191     }
192     
193     /*** 
194      * Returns the name of a single field ObjectId class, if the specified
195      * type name denotes a type that is suitable for single field identity.
196      * @param typeName the type to be checked
197      */
198     public static String getSingleFieldObjectIdClassName(String typeName) {
199         if (typeName == null)
200             return null;
201         String singleFieldObjectIdClassName = 
202             (String) singleFieldObjectIdClassNames.get(typeName);
203         if (singleFieldObjectIdClassName == null)
204             singleFieldObjectIdClassName = OBJECT_IDENTITY_NAME;
205         return singleFieldObjectIdClassName;
206     }
207 
208     //========= Internal helper methods ==========
209     
210     /***
211      * Returns <code>true</code> if the specified type represents an array
212      * and its element type is a persistence capable class.
213      * @param type the JavaType to be checked
214      * @return <code>true</code> if type is a persistent array; 
215      * <code>false</code> otherwise.
216      */
217     private static boolean isPersistenceArrayType(JavaType type)
218     {
219          if (type.isArray()) {
220             JavaType elementType = type.getArrayComponentType();
221             return elementType.isValue() ||
222                    elementType.isPersistenceCapable();
223         }
224         return false;
225     }
226     
227 }