/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.relational;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import xxl.core.relational.metaData.ColumnMetaData;
import xxl.core.relational.metaData.StoredColumnMetaData;
import xxl.core.util.metaData.MetaDataException;
/**
* This class provides a set of type codes that can be used to identify Java
* types. It also provides methods for converting type codes into type names
* and back again and methods to resolve adequate Java types for SQL types and
* vice versa. The present type mapping follows the conventions made in the
* chapter <i>Mapping SQL and Java Types</i> available
* <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/mapping.html#996857">here</a>.
*
* @see java.sql.Types
*/
public final class Types {
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.lang.Object</code>, i.e., the concrete type of the object is
* unknown.
*/
public static final int UNKNOWN = 0;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.lang.Boolean</code>.
*/
public static final int BOOLEAN = 1;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.lang.Byte</code>.
*/
public static final int BYTE = 2;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.lang.Short</code>.
*/
public static final int SHORT = 3;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.lang.Integer</code>.
*/
public static final int INTEGER = 4;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.lang.Long</code>.
*/
public static final int LONG = 5;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.lang.Float</code>.
*/
public static final int FLOAT = 6;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.lang.Double</code>.
*/
public static final int DOUBLE = 7;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.math.BigDecimal</code>.
*/
public static final int BIG_DECIMAL = 8;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.lang.Character</code>.
*/
public static final int CHARACTER = 9;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.lang.String</code>.
*/
public static final int STRING = 10;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.sql.Date</code>.
*/
public static final int DATE = 11;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>java.sql.Time</code>.
*/
public static final int TIME = 12;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int TIMESTAMP = 13;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int CLOB = 14;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int BLOB = 15;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int ARRAY = 16;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int STRUCT = 17;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type
* <code>java.sql.Timestamp</code>.
*/
public static final int REF = 18;
/**
* The constant in the Java programming language, sometimes referred to as
* a type code, that identifies the Java type <code>byte[]</code>.
*/
public static final int BYTE_ARRAY = 19;
/**
* A map storing the Java types and the associated SQL types. The type
* codes of the Java types are mapped to their names and the SQL type codes
* they are associated with.
*/
private static final Map<Integer, Object[]> javaTypeMap;
/**
* A map storing the SQL types and the associated Java types. The type
* codes of the SQL types are mapped to their names and the Java type codes
* they are associated with.
*/
private static final Map<Integer, Object[]> sqlTypeMap;
static {
javaTypeMap = new HashMap<Integer, Object[]>();
putTypeMapping(javaTypeMap, STRING, "java.lang.String", java.sql.Types.LONGVARCHAR);
putTypeMapping(javaTypeMap, BIG_DECIMAL, "java.math.BigDecimal", java.sql.Types.NUMERIC);
putTypeMapping(javaTypeMap, BOOLEAN, "java.lang.Boolean", java.sql.Types.BIT);
putTypeMapping(javaTypeMap, BYTE, "java.lang.Byte", java.sql.Types.TINYINT);
putTypeMapping(javaTypeMap, SHORT, "java.lang.Short", java.sql.Types.SMALLINT);
putTypeMapping(javaTypeMap, INTEGER, "java.lang.Integer", java.sql.Types.INTEGER);
putTypeMapping(javaTypeMap, LONG, "java.lang.Long", java.sql.Types.BIGINT);
putTypeMapping(javaTypeMap, FLOAT, "java.lang.Float", java.sql.Types.REAL);
putTypeMapping(javaTypeMap, DOUBLE, "java.lang.Double", java.sql.Types.DOUBLE);
putTypeMapping(javaTypeMap, BYTE_ARRAY, "byte[]", java.sql.Types.LONGVARBINARY);
putTypeMapping(javaTypeMap, DATE, "java.sql.Date", java.sql.Types.DATE);
putTypeMapping(javaTypeMap, TIME, "java.sql.Time", java.sql.Types.TIME);
putTypeMapping(javaTypeMap, TIMESTAMP, "java.sql.Timestamp", java.sql.Types.TIMESTAMP);
putTypeMapping(javaTypeMap, CLOB, "java.sql.Clob", java.sql.Types.CLOB);
putTypeMapping(javaTypeMap, BLOB, "java.sql.Blob", java.sql.Types.BLOB);
putTypeMapping(javaTypeMap, ARRAY, "java.sql.Array", java.sql.Types.ARRAY);
putTypeMapping(javaTypeMap, STRUCT, "java.sql.Struct", java.sql.Types.STRUCT);
putTypeMapping(javaTypeMap, REF, "java.sql.Ref", java.sql.Types.REF);
putTypeMapping(javaTypeMap, UNKNOWN, "java.lang.Object", java.sql.Types.JAVA_OBJECT);
// additional types specified in java.sql.Types that are not mentioned
// in the above-mentioned paper
putTypeMapping(javaTypeMap, CHARACTER, "java.lang.Character", java.sql.Types.LONGVARCHAR);
sqlTypeMap = new HashMap<Integer, Object[]>();
putTypeMapping(sqlTypeMap, java.sql.Types.CHAR, "CHAR", STRING);
putTypeMapping(sqlTypeMap, java.sql.Types.VARCHAR, "VARCHAR", STRING);
putTypeMapping(sqlTypeMap, java.sql.Types.LONGVARCHAR, "LONGVARCHAR", STRING);
putTypeMapping(sqlTypeMap, java.sql.Types.NUMERIC, "NUMERIC", BIG_DECIMAL);
putTypeMapping(sqlTypeMap, java.sql.Types.DECIMAL, "DECIMAL", BIG_DECIMAL);
putTypeMapping(sqlTypeMap, java.sql.Types.BIT, "BIT", BOOLEAN);
putTypeMapping(sqlTypeMap, java.sql.Types.TINYINT, "TINYINT", SHORT);
putTypeMapping(sqlTypeMap, java.sql.Types.SMALLINT, "SMALLINT", SHORT);
putTypeMapping(sqlTypeMap, java.sql.Types.INTEGER, "INTEGER", INTEGER);
putTypeMapping(sqlTypeMap, java.sql.Types.BIGINT, "BIGINT", LONG);
putTypeMapping(sqlTypeMap, java.sql.Types.REAL, "REAL", FLOAT);
putTypeMapping(sqlTypeMap, java.sql.Types.FLOAT, "FLOAT", DOUBLE);
putTypeMapping(sqlTypeMap, java.sql.Types.DOUBLE, "DOUBLE", DOUBLE);
putTypeMapping(sqlTypeMap, java.sql.Types.BINARY, "BINARY", BYTE_ARRAY);
putTypeMapping(sqlTypeMap, java.sql.Types.VARBINARY, "VARBINARY", BYTE_ARRAY);
putTypeMapping(sqlTypeMap, java.sql.Types.LONGVARBINARY, "LONGVARBINARY", BYTE_ARRAY);
putTypeMapping(sqlTypeMap, java.sql.Types.DATE, "DATE", DATE);
putTypeMapping(sqlTypeMap, java.sql.Types.TIME, "TIME", TIME);
putTypeMapping(sqlTypeMap, java.sql.Types.TIMESTAMP, "TIMESTAMP", TIMESTAMP);
putTypeMapping(sqlTypeMap, java.sql.Types.DISTINCT, "DISTINCT", UNKNOWN);
putTypeMapping(sqlTypeMap, java.sql.Types.CLOB, "CLOB", CLOB);
putTypeMapping(sqlTypeMap, java.sql.Types.BLOB, "BLOB", BLOB);
putTypeMapping(sqlTypeMap, java.sql.Types.ARRAY, "ARRAY", ARRAY);
putTypeMapping(sqlTypeMap, java.sql.Types.STRUCT, "STRUCT", STRUCT);
putTypeMapping(sqlTypeMap, java.sql.Types.REF, "REF", REF);
putTypeMapping(sqlTypeMap, java.sql.Types.JAVA_OBJECT, "JAVA_OBJECT", UNKNOWN);
// additional types specified in java.sql.Types that are not mentioned
// in the above-mentioned paper
putTypeMapping(sqlTypeMap, java.sql.Types.BOOLEAN, "BOOLEAN", BOOLEAN);
putTypeMapping(sqlTypeMap, java.sql.Types.NULL, "NULL", UNKNOWN);
putTypeMapping(sqlTypeMap, java.sql.Types.OTHER, "OTHER", UNKNOWN);
putTypeMapping(sqlTypeMap, java.sql.Types.DATALINK, "DATALINK", UNKNOWN);
}
/**
* The default constructor has private access in order to ensure
* non-instantiability.
*/
private Types() {
// private access in order to ensure non-instantiability
}
/**
* Puts the type specifed by its type code and its name into the given map
* and associates it with the type specified by the second type code.
*
* @param typeMap the map the specified type should be put into.
* @param typeCode the type code of the type to be put into the map.
* @param typeName the name of the type to be put into the map.
* @param associatedTypeCode the type code the specified type should be
* associated with.
*/
private static void putTypeMapping(Map<Integer, Object[]> typeMap, int typeCode, String typeName, int associatedTypeCode) {
typeMap.put(
typeCode,
new Object[] {
typeName,
associatedTypeCode
}
);
}
/**
* Determines a Java type that is able to store an object of the specified
* SQL type.
*
* @param sqlType the SQL type code for which an adequate Java type should
* be resolved.
* @return a Java type that is able to store an object of the specified SQL
* type.
* @throws IllegalArgumentException if the SQL type code is unknown.
*/
public static int getJavaType(int sqlType) throws IllegalArgumentException {
Object[] value = sqlTypeMap.get(sqlType);
if (value == null)
throw new IllegalArgumentException("unknown SQL type code " + sqlType);
return (Integer)value[1];
}
/**
* Resolve the type code of the specified Java type name.
*
* @param javaTypeName the name of the Java type whose type code should be
* resolved.
* @return the type code of the specified Java type.
* @throws IllegalArgumentException if the Java type name is unknown.
*/
public static int getJavaTypeCode(String javaTypeName) throws IllegalArgumentException {
for (Map.Entry<Integer, Object[]> entry : javaTypeMap.entrySet())
if (((String)entry.getValue()[0]).equalsIgnoreCase(javaTypeName))
return entry.getKey();
throw new IllegalArgumentException("unknown Java type name " + javaTypeName);
}
/**
* Resolve the name of the specified Java type code.
*
* @param javaType the Java type code which name should be resolved.
* @return the name of the specified Java type code.
* @throws IllegalArgumentException if the Java type code is unknown.
*/
public static String getJavaTypeName(int javaType) throws IllegalArgumentException {
Object[] value = javaTypeMap.get(javaType);
if (value == null)
throw new IllegalArgumentException("unknown Java type code " + javaType);
return (String)value[0];
}
/**
* Determines the most general SQL type code that is able to store an
* object of the specified Java type.
*
* @param javaType the Java type code for which an adequate SQL type should
* be resolved.
* @return the most general SQL type that is able to store an object of the
* specified Java type.
* @throws IllegalArgumentException if the Java type code is unknown.
*/
public static int getSqlType(int javaType) throws IllegalArgumentException {
Object[] value = javaTypeMap.get(javaType);
if (value == null)
throw new IllegalArgumentException("unknown Java type code " + javaType);
return (Integer)value[1];
}
/**
* Resolve the type code of the specified SQL type name.
*
* @param sqlTypeName the name of the SQL type whose type code should be
* resolved.
* @return the type code of the specified SQL type.
* @throws IllegalArgumentException if the SQL type name is unknown.
*/
public static int getSqlTypeCode(String sqlTypeName) throws IllegalArgumentException {
for (Map.Entry<Integer, Object[]> entry : sqlTypeMap.entrySet())
if (((String)entry.getValue()[0]).equalsIgnoreCase(sqlTypeName))
return entry.getKey();
throw new IllegalArgumentException("unknown SQL type name " + sqlTypeName);
}
/**
* Resolve the name of the specified SQL type code.
*
* @param sqlType the SQL type code which name should be resolved.
* @return the name of the specified SQL type code.
* @throws IllegalArgumentException if the SQL type code is unknown.
*/
public static String getSqlTypeName(int sqlType) throws IllegalArgumentException {
Object[] value = sqlTypeMap.get(sqlType);
if (value == null)
throw new IllegalArgumentException("unknown SQL type code " + sqlType);
return (String)value[0];
}
/**
* Creates a column metadata describing a column holding objects of the
* specified Java type.
*
* @param javaType the Java type the column must be able to store.
* @return a column metadata describing a column holding objects of the
* specified Java type.
*/
public static ColumnMetaData getColumnMetaData(int javaType) {
switch (javaType) {
case STRING:
case BIG_DECIMAL:
case FLOAT:
case DOUBLE:
case BYTE_ARRAY:
throw new IllegalArgumentException("because of different precision/scale handling this method does not provide column metadata for object of type " + getJavaTypeName(javaType) + ". Use Types.getColumnMetaData(int,java.lang.Object) instead.");
default:
return getColumnMetaData(javaType, null);
}
}
/**
* Creates a column metadata describing a column holding the given object
* of the specified Java type. The object is used to determine the columns
* precision and scale (for <code>String</code>, <code>BigDecimal</code>,
* <code>Float</code>, <code>Double</code> and <code>byte[]</code>
* objects), otherwise it is ignored.
*
* @param javaType the Java type the column must be able to store.
* @param javaObject the Java object used for determining the columns
* precision and scale.
* @return a column metadata describing a column holding the given object
* of the specified Java type.
*/
public static ColumnMetaData getColumnMetaData(int javaType, Object javaObject) {
String javaTypeName = getJavaTypeName(javaType);
int sqlType = getSqlType(javaType);
String sqlTypeName = getSqlTypeName(sqlType);
switch (javaType) {
case CHARACTER:
return new StoredColumnMetaData(false, true, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 1, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case BOOLEAN:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 1, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case BYTE:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 3, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case SHORT:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 5, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case INTEGER:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 10, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case LONG:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 19, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case DATE:
case TIME:
case TIMESTAMP:
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 0, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case CLOB:
case BLOB:
case ARRAY:
case STRUCT:
case REF:
case UNKNOWN:
return new StoredColumnMetaData(false, false, false, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", 0, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case STRING:
String string = (String)javaObject;
return new StoredColumnMetaData(false, true, true, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", string.length(), 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case BIG_DECIMAL:
BigDecimal bigDecimal = (BigDecimal)javaObject;
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, true, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", bigDecimal.precision(), bigDecimal.scale(), "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case FLOAT:
bigDecimal = new BigDecimal((Float)javaObject, new MathContext(8, RoundingMode.HALF_EVEN));
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, true, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", bigDecimal.precision(), bigDecimal.scale(), "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case DOUBLE:
bigDecimal = new BigDecimal((Double)javaObject, new MathContext(16, RoundingMode.HALF_EVEN));
return new StoredColumnMetaData(false, false, true, false, ResultSetMetaData.columnNoNulls, true, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", bigDecimal.precision(), bigDecimal.scale(), "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
case BYTE_ARRAY:
byte[] bytes = (byte[])javaObject;
return new StoredColumnMetaData(false, false, false, false, ResultSetMetaData.columnNoNulls, false, sqlTypeName.length() + 7, sqlTypeName + " column", sqlTypeName + "_COLUMN", "", bytes.length, 0, "", "", sqlType, sqlTypeName, true, false, false, javaTypeName);
default:
throw new IllegalArgumentException("unknown SQL type code " + sqlType);
}
}
/**
* Determines the object size of an object of the given SQL type and
* precision.
*
* @param sqlType the SQL type of the object whose objects size should be
* determined.
* @param precision the precision of the object whose objects size should
* be determined.
* @return the object size of an object of the given SQL type and
* precision.
*/
public static int getObjectSize(int sqlType, int precision) {
switch (getJavaType(sqlType)) {
case BOOLEAN:
case BYTE:
return 1;
case CHARACTER:
case SHORT:
return 2;
case INTEGER:
case FLOAT:
return 4;
case LONG:
case DOUBLE:
case DATE:
case TIME:
case TIMESTAMP:
return 8;
case BYTE_ARRAY:
return precision;
case BIG_DECIMAL:
case STRING:
return precision*2;
case CLOB:
case BLOB:
case ARRAY:
case STRUCT:
case REF:
case UNKNOWN:
return 8;
default:
throw new IllegalArgumentException("unknown SQL type code " + sqlType);
}
}
/**
* Determines the object size of an object stored in a relational column
* specified by the given column metadata.
*
* @param columnMetaData the column metadata describing the column whose
* object size should be determined.
* @return the object size of an object stored in a relational column
* specified by the given column metadata.
*/
public static int getObjectSize(ColumnMetaData columnMetaData) {
try {
return getObjectSize(columnMetaData.getColumnType(), columnMetaData.getPrecision());
}
catch (SQLException sqle) {
throw new MetaDataException("the metadata cannot be accessed properly because of the following SQL exception: " + sqle.getMessage());
}
}
/**
* Determines the object size of an object stored in the
* <code>column</code>th column of a table specified by the given
* relational metadata.
*
* @param resultSetMetaData the relational metadata describing the table
* storing the desired colum.
* @param column the index of the desired column inside the table specified
* by the given relational metadata.
* @return the object size of an object stored in the <code>column</code>th
* column of a table specified by the given relational metadata.
*/
public static int getObjectSize(ResultSetMetaData resultSetMetaData, int column) {
try {
return getObjectSize(resultSetMetaData.getColumnType(column), resultSetMetaData.getPrecision(column));
}
catch (SQLException sqle) {
throw new MetaDataException("the metadata cannot be accessed properly because of the following SQL exception: " + sqle.getMessage());
}
}
/**
* Determines the object size of an object stored in a relational table
* specified by the given relational metadata.
*
* @param resultSetMetaData the relational metadata describing the table
* whose object size should be determined.
* @return the object size of an object stored in a relational table
* specified by the given relational metadata.
*/
public static int getObjectSize(ResultSetMetaData resultSetMetaData) {
try {
int objectSize = 0;
for (int column = 1; column <= resultSetMetaData.getColumnCount(); objectSize += getObjectSize(resultSetMetaData, column++));
return objectSize;
}
catch (SQLException sqle) {
throw new MetaDataException("the metadata cannot be accessed properly because of the following SQL exception: " + sqle.getMessage());
}
}
/**
* Determines whether the given Java types are comparable.
*
* @param type1 the first Java type to be checked.
* @param type2 the second Java type to be checked.
* @return <code>true</code> if the given Java types are comparable,
* otherwise <code>false</code>.
*/
public static boolean areComparable(int type1, int type2) {
switch (type1) {
case BYTE:
case SHORT:
case INTEGER:
case LONG:
case FLOAT:
case DOUBLE:
case BIG_DECIMAL:
return type2 == BYTE || type2 == SHORT || type2 == INTEGER || type2 == LONG || type2 == FLOAT || type2 == DOUBLE || type2 == BIG_DECIMAL;
case CHARACTER:
case STRING:
return type2 == CHARACTER || type2 == STRING;
default:
return type1 == type2;
}
}
}