/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2009-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2009-2012, Geomatys
*
* 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geotoolkit.internal.sql;
import java.util.Date;
import java.util.Arrays;
import java.sql.Types;
import org.geotoolkit.lang.Static;
/**
* Maps a few basic Java types to JDBC types.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.09
*
* @since 3.03
* @module
*/
public final class TypeMapper extends Static {
/**
* A list of Java classes to be mapped to SQL types. We don't want to map every SQL types,
* but only the ones which is of interest for the Geotk metadata implementation. The types
* will be tested in the order they are declared, so the last declarations are fallbacks.
* <p>
* The types declared here matches both the JavaDB and PostgreSQL mapping.
*/
private static final TypeMapper[] TYPES = {
// Note: JavaDB does not supports BOOLEAN as of Derby 10.5.
// See http://issues.apache.org/jira/browse/DERBY-499
new TypeMapper(Boolean.class, Types.BOOLEAN, "BOOLEAN"),
new TypeMapper(Date .class, Types.TIMESTAMP, "TIMESTAMP"),
new TypeMapper(Double .class, Types.DOUBLE, "DOUBLE PRECISION"),
new TypeMapper(Float .class, Types.REAL , "REAL"),
new TypeMapper(Long .class, Types.BIGINT, "BIGINT"),
new TypeMapper(Integer.class, Types.INTEGER, "INTEGER"),
new TypeMapper(Short .class, Types.SMALLINT, "SMALLINT"),
new TypeMapper(Byte .class, Types.TINYINT, "SMALLINT"), // JavaDB does not support TINYINT.
new TypeMapper(Number .class, Types.DECIMAL, "DECIMAL") // Implemented by BigDecimal.
};
/**
* The value to add to {@link #type} in order to get only positive or null values.
*/
private static final int OFFSET = 6;
/**
* Maps SQL types to index in the {@link #TYPES} array.
*/
private static final byte[] ITYPES;
static {
ITYPES = new byte[100];
Arrays.fill(ITYPES, (byte) -1);
for (byte i=0; i<TYPES.length; i++) {
ITYPES[TYPES[i].type + OFFSET] = i;
}
}
/**
* The Java class.
*/
private final Class<?> classe;
/**
* A constant from the SQL {@link Types} enumeration.
*/
private final int type;
/**
* The SQL keyword for that type.
*/
private final String keyword;
/**
* For internal use only.
*/
private TypeMapper(final Class<?> classe, final int type, final String keyword) {
this.classe = classe;
this.type = type;
this.keyword = keyword;
}
/**
* Returns the SQL keyword for storing an element of the given type, or {@code null} if
* unknown. This method does not handle the text type, so {@link String} are treated as
* "unknown" as well. We do that way because the caller will need to specify a value in
* its {@code VARCHAR(n)} statement.
*
* @param classe The class for which to get the SQL keyword in a {@code CREATE TABLE} statement.
* @return The SQL keyword, or {@code null} if unknown.
*/
public static String keywordFor(final Class<?> classe) {
if (classe != null) {
for (final TypeMapper type : TYPES) {
if (type.classe.isAssignableFrom(classe)) {
return type.keyword;
}
}
}
return null;
}
/**
* Return the Java class for the given SQL type, or {@code null} if none.
*
* @param sqlType One of the {@link Types} constants.
* @return The Java class, or {@code null} if none.
*
* @since 3.09
*/
public static Class<?> toJavaType(int sqlType) {
sqlType += OFFSET;
if (sqlType >= 0 && sqlType < ITYPES.length) {
final byte mapper = ITYPES[sqlType];
if (mapper >= 0 && mapper < TYPES.length) {
return TYPES[mapper].classe;
}
}
return null;
}
}