/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.modules.misc.tablemodel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import java.net.URL;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Struct;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
/**
* @author $Author$
* @version $Id$
*/
public class TypeMapper {
private static final Log logger = LogFactory.getLog( TypeMapper.class );
private static final Class byteArrayClass = byte[].class;
private static Class mapSQLType( final int t ) {
switch ( t ) {
case Types.ARRAY:
return Object[].class;
case Types.BIGINT:
return Long.class;
case Types.BINARY:
return byteArrayClass;
case Types.BIT:
return Boolean.class;
case Types.BLOB:
return Blob.class;
case Types.BOOLEAN: // Types.BOOLEAN was not part of JDK1.2.2
return Boolean.class;
case Types.CHAR:
return String.class;
case Types.CLOB:
return Clob.class;
case Types.DATALINK: // Types.DATALINK was not part of JDK 1.2.2
return URL.class;
case Types.DATE:
return java.sql.Date.class;
case Types.DECIMAL:
return java.math.BigDecimal.class;
case Types.DISTINCT:
return Object.class;
case Types.DOUBLE:
return Double.class;
case Types.FLOAT:
return Double.class;
case Types.INTEGER:
return Integer.class;
case Types.JAVA_OBJECT:
return Object.class;
case Types.LONGVARBINARY:
return byteArrayClass;
case Types.LONGVARCHAR:
return String.class;
case Types.NCLOB:
return NClob.class;
case Types.NULL:
return Object.class;
case Types.NUMERIC:
return java.math.BigDecimal.class;
case Types.NCHAR:
case Types.NVARCHAR:
case Types.LONGNVARCHAR:
return String.class;
case Types.OTHER:
return Object.class;
case Types.REAL:
return Float.class;
case Types.REF:
return Ref.class;
case Types.ROWID:
return RowId.class;
case Types.SMALLINT:
return Short.class;
case Types.STRUCT:
return Struct.class;
case Types.SQLXML:
return SQLXML.class;
case Types.TIME:
return Time.class;
case Types.TIMESTAMP:
return Timestamp.class;
case Types.TINYINT:
return Byte.class;
case Types.VARBINARY:
return byteArrayClass;
case Types.VARCHAR:
return String.class;
default:
return Object.class;
}
}
public static Class[] mapTypes( final ResultSetMetaData rsmd ) {
final Class[] types;
try {
types = new Class[ rsmd.getColumnCount() ];
} catch ( SQLException sqle ) {
// indicate that we do not have knowledge about any types ..
return null;
}
final int typeLength = types.length;
for ( int i = 0; i < typeLength; i++ ) {
types[ i ] = mapForColumn( rsmd, i );
if ( types[ i ] == null ) {
logger.error( "JDBC Driver returned <null> as column type. This driver violates the JDBC specifications." );
types[ i ] = Object.class;
}
}
return types;
}
public static Class<?> mapForColumn( ResultSetMetaData rsmd, int i ) {
try {
final ClassLoader cl = ObjectUtilities.getClassLoader( TypeMapper.class );
try {
final String tn = rsmd.getColumnClassName( i + 1 );
if ( tn == null ) {
final int colType = rsmd.getColumnType( i + 1 );
return mapSQLType( colType );
} else {
return Class.forName( tn, false, cl );
}
} catch ( final Exception oops ) {
// ignore exception
final int colType = rsmd.getColumnType( i + 1 );
return mapSQLType( colType );
}
} catch ( Exception e ) {
// still ignore the exception
return Object.class;
}
}
private TypeMapper() {
}
}