--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.types.JSQLType\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.types;\r
+\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+\r
+import java.io.IOException;\r
+import java.io.ObjectInput;\r
+import java.io.ObjectOutput;\r
+\r
+/**\r
+ * Type descriptor which wraps all 3 kinds of types supported in Derby's\r
+ * JSQL language: SQL types, Java primitives, Java classes.\r
+ *\r
+ * This interface was originally added to support the serializing of WorkUnit\r
+ * signatures.\r
+ *\r
+ *\r
+ */\r
+public final class JSQLType implements Formatable\r
+{\r
+ ///////////////////////////////////////////////////////////////////////\r
+ //\r
+ // CONSTANTS\r
+ //\r
+ ///////////////////////////////////////////////////////////////////////\r
+\r
+ public static final byte SQLTYPE = 0;\r
+ public static final byte JAVA_CLASS = 1;\r
+ public static final byte JAVA_PRIMITIVE = 2;\r
+\r
+ public static final byte NOT_PRIMITIVE = -1;\r
+ public static final byte BOOLEAN = 0;\r
+ public static final byte CHAR = 1;\r
+ public static final byte BYTE = 2;\r
+ public static final byte SHORT = 3;\r
+ public static final byte INT = 4;\r
+ public static final byte LONG = 5;\r
+ public static final byte FLOAT = 6;\r
+ public static final byte DOUBLE = 7;\r
+\r
+ // these two arrays are in the order of the primitive constants\r
+ static private final String[] wrapperClassNames =\r
+ {\r
+ "java.lang.Boolean",\r
+ "java.lang.Integer", // we can't serialize char, so we convert it to int\r
+ "java.lang.Integer",\r
+ "java.lang.Integer",\r
+ "java.lang.Integer",\r
+ "java.lang.Long",\r
+ "java.lang.Float",\r
+ "java.lang.Double"\r
+ };\r
+\r
+ static public final String[] primitiveNames =\r
+ {\r
+ "boolean",\r
+ "char",\r
+ "byte",\r
+ "short",\r
+ "int",\r
+ "long",\r
+ "float",\r
+ "double"\r
+ };\r
+\r
+\r
+ // here are the fields we serialize\r
+\r
+ private byte category = JAVA_PRIMITIVE;\r
+ private DataTypeDescriptor sqlType;\r
+ private String javaClassName;\r
+ private byte primitiveKind;\r
+\r
+\r
+ ///////////////////////////////////////////////////////////////////////\r
+ //\r
+ // CONSTRUCTORS\r
+ //\r
+ ///////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Public 0-arg constructor for Formatable machinery.\r
+ */\r
+ public JSQLType() { initialize( INT ); }\r
+\r
+\r
+ /**\r
+ * Create a JSQLType from a SQL type.\r
+ *\r
+ * @param sqlType the SQL type to wrap\r
+ */\r
+ public JSQLType\r
+ (\r
+ DataTypeDescriptor sqlType\r
+ )\r
+ { initialize( sqlType ); }\r
+\r
+ /**\r
+ * Create a JSQLType given the name of a Java primitive or java class.\r
+ *\r
+ * @param javaName name of java primitive or class to wrap\r
+ */\r
+ public JSQLType\r
+ (\r
+ String javaName\r
+ )\r
+ {\r
+ byte primitiveID = getPrimitiveID( javaName );\r
+\r
+ if ( primitiveID != NOT_PRIMITIVE ) { initialize( primitiveID ); }\r
+ else { initialize( javaName ); }\r
+ }\r
+\r
+ /**\r
+ * Create a JSQLType for a Java primitive.\r
+ *\r
+ * @param primitiveKind primitive to wrap\r
+ */\r
+ public JSQLType\r
+ (\r
+ byte primitiveKind\r
+ )\r
+ { initialize( primitiveKind ); }\r
+\r
+ /**\r
+ * What kind of type is this:\r
+ *\r
+ * @return one of the following: SQLTYPE, JAVA_PRIMITIVE, JAVA_CLASS\r
+ */\r
+ public byte getCategory() { return category; }\r
+\r
+ /**\r
+ * If this is a JAVA_PRIMITIVE, what is its name?\r
+ *\r
+ * @return BOOLEAN, INT, ... if this is a JAVA_PRIMITIVE.\r
+ * NOT_PRIMITIVE if this is SQLTYPE or JAVA_CLASS.\r
+ */\r
+ public byte getPrimitiveKind() { return primitiveKind; }\r
+\r
+ /**\r
+ * If this is a JAVA_CLASS, what is it's name?\r
+ *\r
+ * @return java class name if this is a JAVA_CLASS\r
+ * null if this is SQLTYPE or JAVA_PRIMITIVE\r
+ */\r
+ public String getJavaClassName() { return javaClassName; }\r
+\r
+ /**\r
+ * What's our SQLTYPE?\r
+ *\r
+ * @return the DataTypeDescriptor corresponding to this type\r
+ *\r
+ */\r
+ public DataTypeDescriptor getSQLType\r
+ (\r
+ )\r
+ {\r
+ // might not be filled in if this is a JAVA_CLASS or JAVA_PRIMITIVE\r
+ if ( sqlType == null )\r
+ {\r
+ String className;\r
+\r
+ if ( category == JAVA_CLASS )\r
+ {\r
+ className = javaClassName;\r
+ }\r
+ else\r
+ {\r
+ className = getWrapperClassName( primitiveKind );\r
+ }\r
+\r
+ sqlType = DataTypeDescriptor.getSQLDataTypeDescriptor( className );\r
+ }\r
+\r
+ return sqlType;\r
+ }\r
+\r
+ ///////////////////////////////////////////////////////////////////////\r
+ //\r
+ // Formatable BEHAVIOR\r
+ //\r
+ ///////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Get the formatID which corresponds to this class.\r
+ *\r
+ * @return the formatID of this class\r
+ */\r
+ public int getTypeFormatId() { return StoredFormatIds.JSQLTYPEIMPL_ID; }\r
+\r
+ /**\r
+ @see java.io.Externalizable#readExternal\r
+ @exception IOException thrown on error\r
+ @exception ClassNotFoundException thrown on error\r
+ */\r
+ public void readExternal( ObjectInput in )\r
+ throws IOException, ClassNotFoundException\r
+ {\r
+ byte frozenCategory = in.readByte();\r
+\r
+ switch ( frozenCategory )\r
+ {\r
+ case SQLTYPE:\r
+\r
+ initialize( (DataTypeDescriptor) in.readObject() );\r
+ break;\r
+\r
+ case JAVA_CLASS:\r
+\r
+ initialize( (String) in.readObject() );\r
+ break;\r
+\r
+ case JAVA_PRIMITIVE:\r
+\r
+ initialize( in.readByte() );\r
+ break;\r
+ }\r
+ }\r
+\r
+ /**\r
+\r
+ @exception IOException thrown on error\r
+ */\r
+ public void writeExternal( ObjectOutput out )\r
+ throws IOException\r
+ {\r
+ out.writeByte( category );\r
+\r
+ switch ( category )\r
+ {\r
+ case SQLTYPE:\r
+\r
+ out.writeObject( sqlType );\r
+ break;\r
+\r
+ case JAVA_CLASS:\r
+\r
+ out.writeObject( javaClassName );\r
+ break;\r
+\r
+ case JAVA_PRIMITIVE:\r
+\r
+ out.writeByte( primitiveKind );\r
+ break;\r
+\r
+ }\r
+ }\r
+\r
+\r
+ ///////////////////////////////////////////////////////////////////////\r
+ //\r
+ // INITIALIZATION MINIONS\r
+ //\r
+ ///////////////////////////////////////////////////////////////////////\r
+\r
+ private void initialize( byte primitiveKind )\r
+ { initialize( JAVA_PRIMITIVE, null, null, primitiveKind ); }\r
+\r
+ private void initialize( DataTypeDescriptor sqlType )\r
+ { initialize( SQLTYPE, sqlType, null, NOT_PRIMITIVE ); }\r
+\r
+ private void initialize( String javaClassName )\r
+ { initialize( JAVA_CLASS, null, javaClassName, NOT_PRIMITIVE ); }\r
+\r
+ /**\r
+ * Initialize this JSQL type. Minion of all constructors.\r
+ *\r
+ * @param category SQLTYPE, JAVA_CLASS, JAVA_PRIMITIVE\r
+ * @param sqlType corresponding SQL type if category=SQLTYPE\r
+ * @param javaClassName corresponding java class if category=JAVA_CLASS\r
+ * @param primitiveKind kind of primitive if category=JAVA_PRIMITIVE\r
+ */\r
+ private void initialize\r
+ (\r
+ byte category,\r
+ DataTypeDescriptor sqlType,\r
+ String javaClassName,\r
+ byte primitiveKind\r
+ )\r
+ {\r
+ this.category = category;\r
+ this.sqlType = sqlType;\r
+ this.javaClassName = javaClassName;\r
+ this.primitiveKind = primitiveKind;\r
+\r
+ }\r
+ \r
+\r
+ ///////////////////////////////////////////////////////////////////////\r
+ //\r
+ // GENERAL MINIONS\r
+ //\r
+ ///////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Gets the name of the java wrapper class corresponding to a primitive.\r
+ *\r
+ * @param primitive BOOLEAN, INT, ... etc.\r
+ *\r
+ * @return name of the java wrapper class corresponding to the primitive\r
+ */\r
+ private static String getWrapperClassName\r
+ (\r
+ byte primitive\r
+ )\r
+ {\r
+ if ( primitive == NOT_PRIMITIVE ) { return ""; }\r
+ return wrapperClassNames[ primitive ];\r
+ }\r
+\r
+\r
+ /**\r
+ * Translate the name of a java primitive to an id\r
+ *\r
+ * @param name name of primitive\r
+ *\r
+ * @return BOOLEAN, INT, ... etc if the name is that of a primitive.\r
+ * NOT_PRIMITIVE otherwise\r
+ */\r
+ private static byte getPrimitiveID\r
+ (\r
+ String name\r
+ )\r
+ {\r
+ for ( byte ictr = BOOLEAN; ictr <= DOUBLE; ictr++ )\r
+ {\r
+ if ( primitiveNames[ ictr ].equals( name ) ) { return ictr; }\r
+ }\r
+\r
+ return NOT_PRIMITIVE;\r
+ }\r
+\r
+\r
+}\r