001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.TypeCompilerFactoryImpl
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
025: import org.apache.derby.iapi.sql.compile.TypeCompiler;
026: import org.apache.derby.iapi.types.TypeId;
027:
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: import org.apache.derby.iapi.reference.JDBC20Translation;
031: import org.apache.derby.iapi.reference.JDBC30Translation;
032:
033: import org.apache.derby.iapi.services.io.StoredFormatIds;
034: import java.util.Properties;
035:
036: import java.sql.Types;
037:
038: public class TypeCompilerFactoryImpl implements TypeCompilerFactory {
039: private static final String PACKAGE_NAME = "org.apache.derby.impl.sql.compile.";
040:
041: // These are all the TypeCompilers that are stateless, so we can
042: // use a single instance of each. Initialize all to null, and fault
043: // them in.
044: static TypeCompiler bitTypeCompiler;
045: static TypeCompiler booleanTypeCompiler;
046: static TypeCompiler charTypeCompiler;
047: static TypeCompiler decimalTypeCompiler;
048: static TypeCompiler doubleTypeCompiler;
049: static TypeCompiler intTypeCompiler;
050: static TypeCompiler longintTypeCompiler;
051: static TypeCompiler longvarbitTypeCompiler;
052: static TypeCompiler longvarcharTypeCompiler;
053: static TypeCompiler nationalCharTypeCompiler;
054: static TypeCompiler nationalLongvarcharTypeCompiler;
055: static TypeCompiler nationalVarcharTypeCompiler;
056: static TypeCompiler realTypeCompiler;
057: static TypeCompiler smallintTypeCompiler;
058: static TypeCompiler tinyintTypeCompiler;
059: static TypeCompiler dateTypeCompiler;
060: static TypeCompiler timeTypeCompiler;
061: static TypeCompiler timestampTypeCompiler;
062: static TypeCompiler varbitTypeCompiler;
063: static TypeCompiler varcharTypeCompiler;
064: static TypeCompiler refTypeCompiler;
065: static TypeCompiler blobTypeCompiler;
066: static TypeCompiler clobTypeCompiler;
067: static TypeCompiler nclobTypeCompiler;
068: static TypeCompiler xmlTypeCompiler;
069:
070: /**
071: * Get a TypeCompiler corresponding to the given TypeId
072: *
073: * @param typeId The TypeId to get a TypeCompiler for
074: *
075: * @return The corresponding TypeCompiler
076: */
077:
078: public TypeCompiler getTypeCompiler(TypeId typeId) {
079: return staticGetTypeCompiler(typeId);
080: }
081:
082: static TypeCompiler staticGetTypeCompiler(TypeId typeId) {
083: String sqlTypeName;
084:
085: switch (typeId.getJDBCTypeId()) {
086: case Types.BINARY:
087: return bitTypeCompiler = getAnInstance(PACKAGE_NAME
088: + "BitTypeCompiler", bitTypeCompiler, typeId);
089:
090: case Types.BIT:
091: case JDBC30Translation.SQL_TYPES_BOOLEAN:
092: return booleanTypeCompiler = getAnInstance(PACKAGE_NAME
093: + "BooleanTypeCompiler", booleanTypeCompiler,
094: typeId);
095:
096: case Types.CHAR:
097: sqlTypeName = typeId.getSQLTypeName();
098: if (sqlTypeName.equals(TypeId.CHAR_NAME)) {
099: return charTypeCompiler = getAnInstance(PACKAGE_NAME
100: + "CharTypeCompiler", charTypeCompiler, typeId);
101: } else {
102: return nationalCharTypeCompiler = getAnInstance(
103: PACKAGE_NAME + "CharTypeCompiler",
104: nationalCharTypeCompiler, typeId);
105: }
106:
107: case Types.NUMERIC:
108: case Types.DECIMAL:
109: return decimalTypeCompiler = getAnInstance(PACKAGE_NAME
110: + "NumericTypeCompiler", decimalTypeCompiler,
111: typeId);
112:
113: case Types.DOUBLE:
114: return doubleTypeCompiler = getAnInstance(PACKAGE_NAME
115: + "NumericTypeCompiler", doubleTypeCompiler, typeId);
116:
117: case Types.INTEGER:
118: return intTypeCompiler = getAnInstance(PACKAGE_NAME
119: + "NumericTypeCompiler", intTypeCompiler, typeId);
120:
121: case Types.BIGINT:
122: return longintTypeCompiler = getAnInstance(PACKAGE_NAME
123: + "NumericTypeCompiler", longintTypeCompiler,
124: typeId);
125:
126: case JDBC20Translation.SQL_TYPES_BLOB:
127: return blobTypeCompiler = getAnInstance(PACKAGE_NAME
128: + "LOBTypeCompiler", blobTypeCompiler, typeId);
129:
130: case Types.LONGVARBINARY:
131: return longvarbitTypeCompiler = getAnInstance(PACKAGE_NAME
132: + "BitTypeCompiler", longvarbitTypeCompiler, typeId);
133:
134: case JDBC20Translation.SQL_TYPES_CLOB:
135: sqlTypeName = typeId.getSQLTypeName();
136: if (sqlTypeName.equals(TypeId.CLOB_NAME)) {
137: return clobTypeCompiler = getAnInstance(PACKAGE_NAME
138: + "CLOBTypeCompiler", clobTypeCompiler, typeId);
139: } else {
140: return nclobTypeCompiler = getAnInstance(PACKAGE_NAME
141: + "CLOBTypeCompiler", nclobTypeCompiler, typeId);
142: }
143: case Types.LONGVARCHAR:
144: sqlTypeName = typeId.getSQLTypeName();
145: if (sqlTypeName.equals(TypeId.LONGVARCHAR_NAME)) {
146: return longvarcharTypeCompiler = getAnInstance(
147: PACKAGE_NAME + "CharTypeCompiler",
148: longvarcharTypeCompiler, typeId);
149: } else {
150: return nationalLongvarcharTypeCompiler = getAnInstance(
151: PACKAGE_NAME + "CharTypeCompiler",
152: nationalLongvarcharTypeCompiler, typeId);
153: }
154:
155: case Types.REAL:
156: return realTypeCompiler = getAnInstance(PACKAGE_NAME
157: + "NumericTypeCompiler", realTypeCompiler, typeId);
158:
159: case Types.SMALLINT:
160: return smallintTypeCompiler = getAnInstance(PACKAGE_NAME
161: + "NumericTypeCompiler", smallintTypeCompiler,
162: typeId);
163:
164: case Types.TINYINT:
165: return tinyintTypeCompiler = getAnInstance(PACKAGE_NAME
166: + "NumericTypeCompiler", tinyintTypeCompiler,
167: typeId);
168:
169: case Types.DATE:
170: return dateTypeCompiler = getAnInstance(PACKAGE_NAME
171: + "DateTypeCompiler", dateTypeCompiler, typeId);
172:
173: case Types.TIME:
174: return timeTypeCompiler = getAnInstance(PACKAGE_NAME
175: + "TimeTypeCompiler", timeTypeCompiler, typeId);
176: case Types.TIMESTAMP:
177: return timestampTypeCompiler = getAnInstance(PACKAGE_NAME
178: + "TimestampTypeCompiler", timestampTypeCompiler,
179: typeId);
180: case Types.VARBINARY:
181: return varbitTypeCompiler = getAnInstance(PACKAGE_NAME
182: + "BitTypeCompiler", varbitTypeCompiler, typeId);
183:
184: case Types.VARCHAR:
185: sqlTypeName = typeId.getSQLTypeName();
186: if (sqlTypeName.equals(TypeId.VARCHAR_NAME)) {
187: return varcharTypeCompiler = getAnInstance(PACKAGE_NAME
188: + "CharTypeCompiler", varcharTypeCompiler,
189: typeId);
190: } else {
191: return nationalVarcharTypeCompiler = getAnInstance(
192: PACKAGE_NAME + "CharTypeCompiler",
193: nationalVarcharTypeCompiler, typeId);
194: }
195:
196: case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
197: case Types.OTHER:
198: if (typeId.isRefTypeId()) {
199: return refTypeCompiler = getAnInstance(PACKAGE_NAME
200: + "RefTypeCompiler", refTypeCompiler, typeId);
201: } else {
202: // Cannot re-use instances of user-defined type compilers,
203: // because they contain the class name
204: BaseTypeCompiler btc = new UserDefinedTypeCompiler();
205: btc.setTypeId(typeId);
206: return btc;
207: }
208:
209: case StoredFormatIds.XML_TYPE_ID:
210: return xmlTypeCompiler = getAnInstance(PACKAGE_NAME
211: + "XMLTypeCompiler", xmlTypeCompiler, typeId);
212:
213: }
214:
215: if (SanityManager.DEBUG) {
216: SanityManager.THROWASSERT("Unexpected JDBC type id "
217: + typeId.getJDBCTypeId() + " for typeId of class "
218: + typeId.getClass().getName());
219: }
220:
221: return null;
222: }
223:
224: /**
225: * Check whether the given TypeCompiler has been allocated yet.
226: * If so, just return it, otherwise allocate a new instance
227: * given its class.
228: */
229: private static TypeCompiler getAnInstance(String className,
230: TypeCompiler anInstance, TypeId typeId) {
231: if (anInstance == null) {
232: Exception exc = null;
233: Class typeCompilerClass = null;
234:
235: try {
236: typeCompilerClass = Class.forName(className);
237: anInstance = (TypeCompiler) typeCompilerClass
238: .newInstance();
239: ((BaseTypeCompiler) anInstance).setTypeId(typeId);
240: } catch (ClassNotFoundException cnfe) {
241: exc = cnfe;
242: } catch (IllegalAccessException iae) {
243: exc = iae;
244: } catch (InstantiationException ie) {
245: exc = ie;
246: }
247:
248: if (SanityManager.DEBUG) {
249: if (exc != null) {
250: SanityManager.THROWASSERT("Exception " + exc
251: + " while trying to get new instance of a "
252: + typeCompilerClass.getName());
253: }
254: }
255: }
256:
257: return anInstance;
258: }
259: }
|