/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * 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 2.1 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.core.types; import static org.junit.Assert.*; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.sql.rowset.serial.SerialBlob; import org.junit.Test; @SuppressWarnings("nls") public class TestDataTypeManager { private void helpDetermineDataType(Object value, Class<?> expectedClass) { Class<?> actualClass = DataTypeManager.determineDataTypeClass(value); assertNotNull("Should never receive null when determining data type of object: " + value); //$NON-NLS-1$ assertEquals("Mismatch in expected and actual MetaMatrix type class for [" + value + "]: ", expectedClass, actualClass); //$NON-NLS-1$ //$NON-NLS-2$ } public static String[] dataTypes = {"string","char","boolean","byte","short","integer","long","biginteger", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ "float","double","bigdecimal","date","time","timestamp","object","blob","clob", DataTypeManager.DefaultDataTypes.XML}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ /** * I - Implicitly Converted * C - Explicitly Converted * N - Cannot be converted * o - No conversion needed */ public static char conversions [][] = { /* Big */ /* i d */ /* s n b d e Time o */ /* t s t i f o c s b */ /* r c b b h e L g l u i d t t j b c */ /* i h o y o g o i o b m a i a e l l x */ /* n a o t r e n n a l a t m m c o o m */ /* g r l e t r g t t e l e e p t b b l */ /* -------------------------------------------------------------------------*/ /*String*/ { 'O','C','C','C','C','C','C','C','C','C','C','C','C','C','I','N','I','C' }, /*char*/ { 'I','O','N','N','N','N','N','N','N','N','N','N','N','N','I','N','N','N' }, /*bool*/ { 'I','N','O','I','I','I','I','I','I','I','I','N','N','N','I','N','N','N' }, /*byte*/ { 'I','N','C','O','I','I','I','I','I','I','I','N','N','N','I','N','N','N' }, /*short*/ { 'I','N','C','C','O','I','I','I','I','I','I','N','N','N','I','N','N','N' }, /*int*/ { 'I','N','C','C','C','O','I','I','C','I','I','N','N','N','I','N','N','N' }, /*long*/ { 'I','N','C','C','C','C','O','I','C','C','I','N','N','N','I','N','N','N' }, /*bigint*/ { 'I','N','C','C','C','C','C','O','C','C','I','N','N','N','I','N','N','N' }, /*float*/ { 'I','N','C','C','C','C','C','C','O','I','I','N','N','N','I','N','N','N' }, /*double*/ { 'I','N','C','C','C','C','C','C','C','O','I','N','N','N','I','N','N','N' }, /*bigdecimal*/ { 'I','N','C','C','C','C','C','C','C','C','O','N','N','N','I','N','N','N' }, /*date*/ { 'I','N','N','N','N','N','N','N','N','N','N','O','N','I','I','N','N','N' }, /*time*/ { 'I','N','N','N','N','N','N','N','N','N','N','N','O','I','I','N','N','N' }, /*timestamp*/ { 'I','N','N','N','N','N','N','N','N','N','N','C','C','O','I','N','N','N' }, /*object*/ { 'C','C','C','C','C','C','C','C','C','C','C','C','C','C','O','C','C','C' }, /*blob*/ { 'N','N','N','N','N','N','N','N','N','N','N','N','N','N','I','O','N','N' }, /*clob*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','O','N' }, /*xml*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','N','O' } }; // ################################## ACTUAL TESTS ################################ @Test public void testTypeMappings() { Set<String> dataTypeNames = DataTypeManager.getAllDataTypeNames(); for (String dataTypeName : dataTypeNames) { Class<?> dataTypeClass = DataTypeManager.getDataTypeClass(dataTypeName); assertNotNull("Data type class was null for type " + dataTypeName, dataTypeClass); //$NON-NLS-1$ String dataTypeName2 = DataTypeManager.getDataTypeName(dataTypeClass); assertEquals("Name to class to name not equals: ", dataTypeName, dataTypeName2); //$NON-NLS-1$ } } @Test public void testCheckConversions() { for (int src = 0; src < dataTypes.length; src++) { for (int tgt =0; tgt < dataTypes.length; tgt++) { char c = conversions[src][tgt]; if (c == 'I') { assertTrue("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should be Implicit", DataTypeManager.isImplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertFalse("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should be not be Explicit", DataTypeManager.isExplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertTrue("src="+dataTypes[src]+" target="+dataTypes[tgt]+" transform should be avaialble", DataTypeManager.isTransformable(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (c == 'C') { assertFalse("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should not be Implicit", DataTypeManager.isImplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertTrue("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should be Explicit", DataTypeManager.isExplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertTrue("src="+dataTypes[src]+" target="+dataTypes[tgt]+" transform should be avaialble", DataTypeManager.isTransformable(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if ( c == 'O' || c == 'N') { assertFalse("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should not be Implicit", DataTypeManager.isImplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertFalse("src="+dataTypes[src]+" target="+dataTypes[tgt]+" should not be Explicit", DataTypeManager.isExplicitConversion(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertFalse("src="+dataTypes[src]+" target="+dataTypes[tgt]+" No transform should be avaialble", DataTypeManager.isTransformable(dataTypes[src], dataTypes[tgt])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } } } /** Test determine data type for a STRING object. */ @Test public void testDetermineDataType1() { helpDetermineDataType("abc", DataTypeManager.DefaultDataClasses.STRING); //$NON-NLS-1$ } /** Test determine data type for a NULL object. */ @Test public void testDetermineDataType2() { helpDetermineDataType(null, DataTypeManager.DefaultDataClasses.NULL); } /** Test determine data type for an unknown object type - should be typed as an OBJECT. */ @Test public void testDetermineDataType3() throws Exception { java.net.URL url = new java.net.URL("http://fake"); //$NON-NLS-1$ helpDetermineDataType(url, DataTypeManager.DefaultDataClasses.OBJECT); } @Test public void testCheckAllConversions() { Set<String> allTypes = DataTypeManager.getAllDataTypeNames(); for (String src : allTypes) { for (String tgt : allTypes) { boolean isImplicit = DataTypeManager.isImplicitConversion(src, tgt); boolean isExplicit = DataTypeManager.isExplicitConversion(src, tgt); if(isImplicit && isExplicit) { fail("Can't be both implicit and explicit for " + src + " to " + tgt); //$NON-NLS-1$ //$NON-NLS-2$ } } } } @Test public void testTimeConversions() { Transform t = DataTypeManager.getTransform(DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.DefaultDataTypes.DATE); assertEquals(DataTypeManager.DefaultDataClasses.DATE, t.getTargetType()); t = DataTypeManager.getTransform(DataTypeManager.DefaultDataTypes.TIME, DataTypeManager.DefaultDataTypes.TIMESTAMP); assertEquals(DataTypeManager.DefaultDataClasses.TIMESTAMP, t.getTargetType()); } @Test public void testJDBCSQLTypeInfo() { Set<String> types = JDBCSQLTypeInfo.getMMTypeNames(); for (String type : types) { assertEquals("Didn't get match for "+ type, JDBCSQLTypeInfo.getSQLType(type), JDBCSQLTypeInfo.getSQLTypeFromRuntimeType(DataTypeManager.getDataTypeClass(type))); //$NON-NLS-1$ //the classnames will not match the runtime types for xml, clob, blob if (!type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.NULL) && !type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.VARBINARY) && !type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.XML) && !type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.CLOB) && !type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.BLOB)) { assertEquals("Didn't get match for "+ type, JDBCSQLTypeInfo.getSQLType(type), JDBCSQLTypeInfo.getSQLTypeFromClass(DataTypeManager.getDataTypeClass(type).getName())); //$NON-NLS-1$ } } assertEquals(Types.TIMESTAMP, JDBCSQLTypeInfo.getSQLTypeFromRuntimeType(DataTypeManager.DefaultDataClasses.TIMESTAMP)); assertEquals(Types.SQLXML, JDBCSQLTypeInfo.getSQLTypeFromRuntimeType(DataTypeManager.DefaultDataClasses.XML)); assertEquals(DataTypeManager.DefaultDataTypes.STRING, JDBCSQLTypeInfo.getTypeName(Types.CHAR)); assertEquals(Types.CHAR, JDBCSQLTypeInfo.getSQLTypeFromRuntimeType(DataTypeManager.DefaultDataClasses.CHAR)); assertEquals(Types.ARRAY, JDBCSQLTypeInfo.getSQLType(DataTypeManager.getDataTypeName(DataTypeManager.getArrayType(DataTypeManager.DefaultDataClasses.BIG_DECIMAL)))); } @Test public void testRuntimeTypeConversion() throws Exception { assertNull(DataTypeManager.convertToRuntimeType(null, true)); assertTrue(DataTypeManager.convertToRuntimeType(new SerialBlob(new byte[0]), true) instanceof BlobType); //unknown type should return as same Object foo = new Object(); assertEquals(foo, DataTypeManager.convertToRuntimeType(foo, true)); //known type should return as same Integer bar = new Integer(1); assertEquals(bar, DataTypeManager.convertToRuntimeType(bar, true)); } @Test public void testObjectType() { assertEquals(DataTypeManager.DefaultDataClasses.OBJECT, DataTypeManager.getDataTypeClass("foo")); //$NON-NLS-1$ assertEquals(DataTypeManager.DefaultDataTypes.OBJECT, DataTypeManager.getDataTypeName(TestDataTypeManager.class)); } @Test public void testImplicitConversions() { List<String> c = new ArrayList<String>(); DataTypeManager.getImplicitConversions(DataTypeManager.DefaultDataTypes.INTEGER, c); assertEquals(Arrays.asList(DataTypeManager.DefaultDataTypes.LONG, DataTypeManager.DefaultDataTypes.BIG_INTEGER, DataTypeManager.DefaultDataTypes.DOUBLE, DataTypeManager.DefaultDataTypes.BIG_DECIMAL, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.OBJECT), c); } @Test(expected=TransformationException.class) public void testStringToXML() throws Exception { DataTypeManager.transformValue("hello", DataTypeManager.DefaultDataClasses.XML); //$NON-NLS-1$ } static class Foo { @Override public String toString() { return "hello"; } } @Test public void testObjectToString() throws Exception { assertEquals("hello", DataTypeManager.transformValue(new Foo(), DataTypeManager.DefaultDataClasses.STRING)); //$NON-NLS-1$ } @Test public void testObjectArrayToObject() throws Exception { Object[] value = {1,2}; assertArrayEquals(value, (Object[])DataTypeManager.transformValue(value, value.getClass(), DataTypeManager.DefaultDataClasses.OBJECT)); } @Test public void testByteArray() throws Exception { byte[] value = {1,2}; assertArrayEquals(value, (byte[])DataTypeManager.convertToRuntimeType(value, false)); assertEquals(new BinaryType(value), DataTypeManager.convertToRuntimeType(value, true)); } }