/*
* 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.util;
import java.util.ArrayList;
import java.util.List;
import xxl.core.indexStructures.Entry;
import xxl.core.indexStructures.builder.IndexBuilder;
import xxl.core.indexStructures.builder.BPlusTree.BPlusConfiguration;
import xxl.core.relational.JavaType;
import xxl.core.relational.RelationalType;
import xxl.core.relational.tuples.ColumnComparableArrayTuple;
import xxl.core.relational.tuples.Tuple;
/**
* Provides several static methods to convert one type to another.
*
* @author Marcus Pinnecke (pinnecke@mathematik.uni-marburg.de)
*
*/
public class ConvertUtils {
/**
* BPlusTree is able to manage comparable objects or tuples. If tuples are used (wrapped by Entry
* class) the Object <b>o</b> is a tuple (non-comparable) or a tuple subset which is the key (and
* have to be comparable). In order to manage this casting (for delegation to BPlusTree) use this
* method which <i>auto</i>matically cast <b>o</b> to fit the requirements.
*
* @param o Object, e.g. primitive or tuple (or tuple subset)
* @return The matching object
*/
public static Object autoCast(Object o) {
return (o instanceof Entry)
? ((Entry) o).asTuple()
: ((o instanceof Entry.WithKey) ? ((Entry.WithKey) o)
.asComparableArray() : o);
}
public static Comparable autoComparable(Object object, IndexBuilder creator) {
if (object instanceof Tuple) {
// If this is an instance of Tuple it is not possible
// to cast it into Comparable as once because only the
// key subset of this instance is comparable. In order
// to cast it into Comparable project it to the
// comparable subset.
// TODO:
Object[] tuple = ((Tuple) object).toArray();
int[] keyIndices =
((BPlusConfiguration) creator.getIndexConfiguration())
.getManagedType().getCompoundKeyIndices();
Object[] keySubset = new Object[keyIndices.length];
for (int index = 0; index < keyIndices.length; ++index) {
keySubset[index] = (Comparable) tuple[keyIndices[index] - 1];
}
return new ColumnComparableArrayTuple(keySubset);
// throw new IllegalArgumentException();
} else
return (object instanceof Comparable[]) ? new ColumnComparableArrayTuple(
(Comparable[]) object) : (Comparable) object;
}
/**
* Converts a object of {@link xxl.core.relational.RelationalType RelationalType} to
* {@link java.sql.Types SQL Type} which is an integer. <br/>
* <br/>
* <b>Example</b> <code><pre>
* int sqlType = Convert.toInt(RelationalType.ARRAY); // sqlTyp is now equal to java.sql.Types.ARRAY (= 2003)
* </pre></code>
*
* @param relationalType An object of type {@link xxl.core.relational.RelationalType
* RelationalType} which covers SQL types as an enum
* @return The {@link java.sql.Types SQL Type} value of <i>relationalType</i> or
* <b>java.sql.Types.OTHER</b> if it fails
*
* @see xxl.core.relational.RelationalType
* @see java.sql.Types
*/
public static int toInt(final RelationalType relationalType) {
int retval = -1;
switch (relationalType) {
case ARRAY:
retval = java.sql.Types.ARRAY;
break;
case BIGINT:
retval = java.sql.Types.BIGINT;
break;
case BINARY:
retval = java.sql.Types.BINARY;
break;
case BIT:
retval = java.sql.Types.BIT;
break;
case BLOB:
retval = java.sql.Types.BLOB;
break;
case BOOLEAN:
retval = java.sql.Types.BOOLEAN;
break;
case CHAR:
retval = java.sql.Types.CHAR;
break;
case CLOB:
retval = java.sql.Types.CLOB;
break;
case DATALINK:
retval = java.sql.Types.DATALINK;
break;
case DATE:
retval = java.sql.Types.DATE;
break;
case DECIMAL:
retval = java.sql.Types.DECIMAL;
break;
case DISTINCT:
retval = java.sql.Types.DISTINCT;
break;
case DOUBLE:
retval = java.sql.Types.DOUBLE;
break;
case FLOAT:
retval = java.sql.Types.FLOAT;
break;
case INTEGER:
retval = java.sql.Types.INTEGER;
break;
case JAVA_OBJECT:
retval = java.sql.Types.JAVA_OBJECT;
break;
case LONGNVARCHAR:
retval = java.sql.Types.LONGNVARCHAR;
break;
case LONGVARBINARY:
retval = java.sql.Types.LONGVARBINARY;
break;
case LONGVARCHAR:
retval = java.sql.Types.LONGVARCHAR;
break;
case NCHAR:
retval = java.sql.Types.NCHAR;
break;
case NCLOB:
retval = java.sql.Types.NCLOB;
break;
case NULL:
retval = java.sql.Types.NULL;
break;
case NUMERIC:
retval = java.sql.Types.NUMERIC;
break;
case NVARCHAR:
retval = java.sql.Types.NVARCHAR;
break;
case OTHER:
retval = java.sql.Types.OTHER;
break;
case REAL:
retval = java.sql.Types.REAL;
break;
case REF:
retval = java.sql.Types.REF;
break;
case ROWID:
retval = java.sql.Types.ROWID;
break;
case SMALLINT:
retval = java.sql.Types.SMALLINT;
break;
case SQLXML:
retval = java.sql.Types.SQLXML;
break;
case STRUCT:
retval = java.sql.Types.STRUCT;
break;
case TIME:
retval = java.sql.Types.TIME;
break;
case TIMESTAMP:
retval = java.sql.Types.TIMESTAMP;
break;
case TINYINT:
retval = java.sql.Types.TINYINT;
break;
case VARBINARY:
retval = java.sql.Types.VARBINARY;
break;
case VARCHAR:
retval = java.sql.Types.VARCHAR;
break;
default:
retval = java.sql.Types.OTHER;
break;
}
return retval;
}
/**
* Converts {@link xxl.core.relational.RelationalType RelationalType} object into
* {@link xxl.core.relational.JavaType JavaType} type. <br/>
* For type converting, see <a href="http://db.apache.org/ojb/docu/guides/jdbc-types.html">JDBC
* Types</a> and <a href=
* "http://publib.boulder.ibm.com/infocenter/idshelp/v111/index.jsp?topic=/com.ibm.jccids.doc/com.ibm.db2.luw.apdv.java.doc/doc/rjvjdata.htm"
* >IBM: Data types that map to database data types in Java applications</a>
*
* @param relationalType Your object of type <i>RelationalType</i> which should be converted
* @return The assigned java type or <code>JavaType.UNKNOWN</code> if it fails.
* @see xxl.core.relational.RelationalType
* @see xxl.core.relational.JavaType
*/
public static JavaType toJavaType(final RelationalType relationalType) {
JavaType retval = JavaType.UNKNOWN;
switch (relationalType) {
case ARRAY:
retval = JavaType.ARRAY;
break;
case BIGINT:
retval = JavaType.LONG;
break;
case BINARY:
retval = JavaType.BYTE_ARRAY;
break;
case BIT:
retval = JavaType.BOOLEAN;
break;
case BLOB:
retval = JavaType.BLOB;
break;
case BOOLEAN:
retval = JavaType.BOOLEAN;
break;
case CHAR:
retval = JavaType.STRING;
break;
case CLOB:
retval = JavaType.CLOB;
break;
case DATALINK:
retval = JavaType.URL;
break;
case DATE:
retval = JavaType.DATE;
break;
case DECIMAL:
retval = JavaType.BIG_DECIMAL;
break;
case DISTINCT:
retval = JavaType.DISTINCT;
break;
case DOUBLE:
retval = JavaType.DOUBLE;
break;
case FLOAT:
retval = JavaType.FLOAT;
break;
case INTEGER:
retval = JavaType.INT;
break;
case JAVA_OBJECT:
retval = JavaType.OBJECT;
break;
case LONGNVARCHAR:
retval = JavaType.STRING;
break;
case LONGVARBINARY:
retval = JavaType.BYTE_ARRAY;
break;
case LONGVARCHAR:
retval = JavaType.STRING;
break;
case NCHAR:
retval = JavaType.STRING;
break;
case NCLOB:
retval = JavaType.NCLOB;
break;
case NULL:
retval = JavaType.NULL;
break;
case NUMERIC:
retval = JavaType.BIG_DECIMAL;
break;
case NVARCHAR:
retval = JavaType.STRING;
break;
case OTHER:
retval = JavaType.OTHER;
break;
case REAL:
retval = JavaType.FLOAT;
break;
case REF:
retval = JavaType.REF;
break;
case ROWID:
retval = JavaType.ROWID;
break;
case SMALLINT:
retval = JavaType.SHORT;
break;
case SQLXML:
retval = JavaType.SQLXML;
break;
case STRUCT:
retval = JavaType.STRUCT;
break;
case TIME:
retval = JavaType.TIME;
break;
case TIMESTAMP:
retval = JavaType.TIMESTAMP;
break;
case TINYINT:
retval = JavaType.BYTE;
break;
case VARBINARY:
retval = JavaType.BYTE_ARRAY;
break;
case VARCHAR:
retval = JavaType.STRING;
break;
default:
retval = JavaType.UNKNOWN;
break;
}
return retval;
}
/**
* Converts a String representation of {@link xxl.core.relational.JavaType JavaType} type into
* {@link xxl.core.relational.JavaType JavaType} enumeration type. <br/>
*
* @param javaType Your string which represents <i>JavaType</i> member
* @return The assigned java type or <code>JavaType.UNKNOWN</code> if it fails.
* @see xxl.core.relational.JavaType
*/
public static JavaType toJavaType(final String javaType) {
if (javaType.compareToIgnoreCase(JavaType.ARRAY.toString()) == 0)
return JavaType.ARRAY;
else if (javaType.compareToIgnoreCase(JavaType.BIG_DECIMAL.toString()) == 0)
return JavaType.BIG_DECIMAL;
else if (javaType.compareToIgnoreCase(JavaType.BLOB.toString()) == 0)
return JavaType.BLOB;
else if (javaType.compareToIgnoreCase(JavaType.BOOLEAN.toString()) == 0)
return JavaType.BOOLEAN;
else if (javaType.compareToIgnoreCase(JavaType.BYTE.toString()) == 0)
return JavaType.BYTE;
else if (javaType.compareToIgnoreCase(JavaType.BYTE_ARRAY.toString()) == 0)
return JavaType.BYTE_ARRAY;
else if (javaType.compareToIgnoreCase(JavaType.CLOB.toString()) == 0)
return JavaType.CLOB;
else if (javaType.compareToIgnoreCase(JavaType.DATE.toString()) == 0)
return JavaType.DATE;
else if (javaType.compareToIgnoreCase(JavaType.DISTINCT.toString()) == 0)
return JavaType.DISTINCT;
else if (javaType.compareToIgnoreCase(JavaType.DOUBLE.toString()) == 0)
return JavaType.DOUBLE;
else if (javaType.compareToIgnoreCase(JavaType.FLOAT.toString()) == 0)
return JavaType.FLOAT;
else if (javaType.compareToIgnoreCase(JavaType.INT.toString()) == 0)
return JavaType.INT;
else if (javaType.compareToIgnoreCase(JavaType.LONG.toString()) == 0)
return JavaType.LONG;
else if (javaType.compareToIgnoreCase(JavaType.NCLOB.toString()) == 0)
return JavaType.NCLOB;
else if (javaType.compareToIgnoreCase(JavaType.NULL.toString()) == 0)
return JavaType.NULL;
else if (javaType.compareToIgnoreCase(JavaType.OBJECT.toString()) == 0)
return JavaType.OBJECT;
else if (javaType.compareToIgnoreCase(JavaType.OTHER.toString()) == 0)
return JavaType.OTHER;
else if (javaType.compareToIgnoreCase(JavaType.REF.toString()) == 0)
return JavaType.REF;
else if (javaType.compareToIgnoreCase(JavaType.ROWID.toString()) == 0)
return JavaType.ROWID;
else if (javaType.compareToIgnoreCase(JavaType.SHORT.toString()) == 0)
return JavaType.SHORT;
else if (javaType.compareToIgnoreCase(JavaType.SQLXML.toString()) == 0)
return JavaType.SQLXML;
else if (javaType.compareToIgnoreCase(JavaType.STRING.toString()) == 0)
return JavaType.STRING;
else if (javaType.compareToIgnoreCase(JavaType.STRUCT.toString()) == 0)
return JavaType.STRUCT;
else if (javaType.compareToIgnoreCase(JavaType.TIMESTAMP.toString()) == 0)
return JavaType.TIMESTAMP;
else if (javaType.compareToIgnoreCase(JavaType.TIME.toString()) == 0)
return JavaType.TIME;
else
return JavaType.OTHER;
}
/**
* Converts a object of {@link java.sql.Types SQL Type} which is an integer to
* {@link xxl.core.relational.RelationalType RelationalType}. <br/>
* <br/>
* <b>Example</b> <code><pre>
* RelationalType relType = Convert.toRelationalType(java.sql.ARRAY); // relType is now equal to RelationalType.ARRAY
* </pre></code>
*
* @param sqlTypConstant An value of {@link java.sql.Types SQL Type}
* @return The RelationalType value of <i>sqlTypConstant</i> or <b>RelationalType.OTHER</b> if it
* fails
*
* @see xxl.core.relational.RelationalType
* @see xxl.core.relational.JavaType
*/
public static RelationalType toRelationalType(final int sqlTypConstant) {
RelationalType retval = RelationalType.OTHER;
switch (sqlTypConstant) {
case java.sql.Types.ARRAY:
retval = RelationalType.ARRAY;
break;
case java.sql.Types.BIGINT:
retval = RelationalType.BIGINT;
break;
case java.sql.Types.BINARY:
retval = RelationalType.BINARY;
break;
case java.sql.Types.BIT:
retval = RelationalType.BIT;
break;
case java.sql.Types.BLOB:
retval = RelationalType.BLOB;
break;
case java.sql.Types.BOOLEAN:
retval = RelationalType.BOOLEAN;
break;
case java.sql.Types.CHAR:
retval = RelationalType.CHAR;
break;
case java.sql.Types.CLOB:
retval = RelationalType.CLOB;
break;
case java.sql.Types.DATALINK:
retval = RelationalType.DATALINK;
break;
case java.sql.Types.DATE:
retval = RelationalType.DATE;
break;
case java.sql.Types.DECIMAL:
retval = RelationalType.DECIMAL;
break;
case java.sql.Types.DISTINCT:
retval = RelationalType.DISTINCT;
break;
case java.sql.Types.DOUBLE:
retval = RelationalType.DOUBLE;
break;
case java.sql.Types.FLOAT:
retval = RelationalType.FLOAT;
break;
case java.sql.Types.INTEGER:
retval = RelationalType.INTEGER;
break;
case java.sql.Types.JAVA_OBJECT:
retval = RelationalType.JAVA_OBJECT;
break;
case java.sql.Types.LONGNVARCHAR:
retval = RelationalType.LONGNVARCHAR;
break;
case java.sql.Types.LONGVARBINARY:
retval = RelationalType.LONGVARBINARY;
break;
case java.sql.Types.LONGVARCHAR:
retval = RelationalType.LONGVARCHAR;
break;
case java.sql.Types.NCHAR:
retval = RelationalType.NCHAR;
break;
case java.sql.Types.NCLOB:
retval = RelationalType.NCLOB;
break;
case java.sql.Types.NULL:
retval = RelationalType.NULL;
break;
case java.sql.Types.NUMERIC:
retval = RelationalType.NUMERIC;
break;
case java.sql.Types.NVARCHAR:
retval = RelationalType.NVARCHAR;
break;
case java.sql.Types.OTHER:
retval = RelationalType.OTHER;
break;
case java.sql.Types.REAL:
retval = RelationalType.REAL;
break;
case java.sql.Types.REF:
retval = RelationalType.REF;
break;
case java.sql.Types.ROWID:
retval = RelationalType.ROWID;
break;
case java.sql.Types.SMALLINT:
retval = RelationalType.SMALLINT;
break;
case java.sql.Types.SQLXML:
retval = RelationalType.SQLXML;
break;
case java.sql.Types.STRUCT:
retval = RelationalType.STRUCT;
break;
case java.sql.Types.TIME:
retval = RelationalType.TIME;
break;
case java.sql.Types.TIMESTAMP:
retval = RelationalType.TIMESTAMP;
break;
case java.sql.Types.TINYINT:
retval = RelationalType.TINYINT;
break;
case java.sql.Types.VARBINARY:
retval = RelationalType.VARBINARY;
break;
case java.sql.Types.VARCHAR:
retval = RelationalType.VARCHAR;
break;
default:
retval = RelationalType.OTHER;
break;
}
return retval;
}
/**
* Returns the fiber of {@link #toRelationalType(int)} at <code>e</code>, that means the inverse
* image (preimage) of the singleton <code>e</code>. In other words this method returns all
* Integers <code>i</code> for which #toRelationalType(<code>i</code>) equals <code>e</code>
* holds.
*
* @param e a relational type
* @return the preimage of <code>e</code>
*/
public Integer[] getFiber(RelationalType e) {
/*
* Please note, that java.sql.Types is not iterable and update this Integers if necessary
*/
int domain[] =
new int[] {-7, -6, 5, 4, -5, 6, 7, 8, 2, 3, 1, 12, -1, 91, 92, 93, -2,
-3, -4, 0, 1111, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 70, 16,
-8, -15, -9, -16, 2011, 2009};
List<Integer> result = new ArrayList<>();
for (int i : domain)
if (toRelationalType(i) == e) result.add(i);
return result.toArray(new Integer[result.size()]);
}
}