/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.type; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Currency; import java.util.GregorianCalendar; import java.util.Locale; import java.util.SimpleTimeZone; import java.util.TimeZone; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.hibernate.EntityMode; import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.testing.junit4.BaseUnitTestCase; /** * @author Steve Ebersole */ @SuppressWarnings( {"UnnecessaryBoxing"}) public class TypeTest extends BaseUnitTestCase { private SessionImplementor session; @Before public void setUp() throws Exception { session = (SessionImplementor) Proxy.newProxyInstance( getClass().getClassLoader(), new Class[] { Session.class, SessionImplementor.class }, new SessionProxyHandler() ); } public static class SessionProxyHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ( "getEntityMode".equals( method.getName() ) ) { return EntityMode.POJO; } throw new UnsupportedOperationException( "Unexpected method call : " + method.getName() ); } } @Test public void testBigDecimalType() { final BigDecimal original = BigDecimal.valueOf( 100 ); final BigDecimal copy = BigDecimal.valueOf( 100 ); final BigDecimal different = BigDecimal.valueOf( 999 ); runBasicTests( BigDecimalType.INSTANCE, original, copy, different ); } @Test public void testBigIntegerType() { final BigInteger original = BigInteger.valueOf( 100 ); final BigInteger copy = BigInteger.valueOf( 100 ); final BigInteger different = BigInteger.valueOf( 999 ); runBasicTests( BigIntegerType.INSTANCE, original, copy, different ); } @Test public void testBinaryType() { final byte[] original = new byte[] { 1, 2, 3, 4 }; final byte[] copy = new byte[] { 1, 2, 3, 4 }; final byte[] different = new byte[] { 4, 3, 2, 1 }; runBasicTests( BinaryType.INSTANCE, original, copy, different ); runBasicTests( ImageType.INSTANCE, original, copy, different ); runBasicTests( MaterializedBlobType.INSTANCE, original, copy, different ); } @Test @SuppressWarnings( {"BooleanConstructorCall"}) public void testBooleanType() { final Boolean original = Boolean.TRUE; final Boolean copy = new Boolean( true ); final Boolean different = Boolean.FALSE; runBasicTests( BooleanType.INSTANCE, original, copy, different ); runBasicTests( NumericBooleanType.INSTANCE, original, copy, different ); runBasicTests( YesNoType.INSTANCE, original, copy, different ); runBasicTests( TrueFalseType.INSTANCE, original, copy, different ); } @Test public void testByteType() { final Byte original = 0; final Byte copy = new Byte( (byte) 0 ); final Byte different = 9; runBasicTests( ByteType.INSTANCE, original, copy, different ); } @Test public void testCalendarDateType() { final Calendar original = new GregorianCalendar(); final Calendar copy = new GregorianCalendar(); final Calendar different = new GregorianCalendar(); different.set( Calendar.MONTH, 9 ); different.set( Calendar.DAY_OF_MONTH, 9 ); different.set( Calendar.YEAR, 2999 ); runBasicTests( CalendarDateType.INSTANCE, original, copy, different ); } @Test public void testCalendarType() { final long now = System.currentTimeMillis(); final Calendar original = new GregorianCalendar(); original.clear(); original.setTimeInMillis( now ); final Calendar copy = new GregorianCalendar(); copy.clear(); copy.setTimeInMillis( now ); final Calendar different = new GregorianCalendar(); different.setTimeInMillis( now + 9999 ); runBasicTests( CalendarType.INSTANCE, original, copy, different ); } @Test public void testCharacterArrayType() { final Character[] original = new Character[] { 'a', 'b' }; final Character[] copy = new Character[] { 'a', 'b' }; final Character[] different = new Character[] { 'a', 'b', 'c' }; runBasicTests( CharacterArrayType.INSTANCE, original, copy, different ); } @Test public void testCharacterType() { final Character original = 'a'; final Character copy = new Character( 'a' ); final Character different = 'b'; runBasicTests( CharacterType.INSTANCE, original, copy, different ); } @Test public void testCharArrayType() { final char[] original = new char[] { 'a', 'b' }; final char[] copy = new char[] { 'a', 'b' }; final char[] different = new char[] { 'a', 'b', 'c' }; runBasicTests( CharArrayType.INSTANCE, original, copy, different ); runBasicTests( CharArrayType.INSTANCE, original, copy, different ); } @Test public void testClassType() { final Class original = TypeTest.class; final Class copy = (Class) SerializationHelper.clone( original ); final Class different = String.class; runBasicTests( ClassType.INSTANCE, original, copy, different ); } @Test public void testCurrencyType() { final Currency original = Currency.getInstance( Locale.US ); final Currency copy = Currency.getInstance( Locale.US ); final Currency different = Currency.getInstance( Locale.UK ); runBasicTests( CurrencyType.INSTANCE, original, copy, different ); } @Test public void testDateType() { final long now = System.currentTimeMillis(); final java.sql.Date original = new java.sql.Date( now ); final java.sql.Date copy = new java.sql.Date( now ); Calendar cal = new GregorianCalendar(); cal.clear(); cal.setTimeInMillis( now ); cal.add( Calendar.YEAR, 1 ); final java.sql.Date different = new java.sql.Date( cal.getTime().getTime() ); runBasicTests( DateType.INSTANCE, original, copy, different ); } @Test public void testDoubleType() { final Double original = Double.valueOf( 100 ); final Double copy = Double.valueOf( 100 ); final Double different = Double.valueOf( 999 ); runBasicTests( DoubleType.INSTANCE, original, copy, different ); } @Test public void testFloatType() { final Float original = Float.valueOf( 100 ); final Float copy = Float.valueOf( 100 ); final Float different = Float.valueOf( 999 ); runBasicTests( FloatType.INSTANCE, original, copy, different ); } @Test public void testIntegerType() { final Integer original = 100; final Integer copy = new Integer( 100 ); final Integer different = 999; runBasicTests( IntegerType.INSTANCE, original, copy, different ); } @Test public void testLocaleType() { final Locale original = new Locale( "ab" ); final Locale copy = new Locale( "ab" ); final Locale different = new Locale( "yz" ); runBasicTests( LocaleType.INSTANCE, original, copy, different ); } @Test public void testLongType() { final Long original = 100L; final Long copy = new Long( 100L ); final Long different = 999L; runBasicTests( LongType.INSTANCE, original, copy, different ); } private static class SerializableImpl implements Serializable { private final int number; SerializableImpl(int number) { this.number = number; } @SuppressWarnings( {"EqualsWhichDoesntCheckParameterClass"}) public boolean equals(Object obj) { return this.number == ( (SerializableImpl) obj ).number; } } @Test public void testSerializableType() { final SerializableImpl original = new SerializableImpl(1); final SerializableImpl copy = new SerializableImpl(1); final SerializableImpl different = new SerializableImpl(2); runBasicTests( SerializableType.INSTANCE, original, copy, different ); runBasicTests( new SerializableType<SerializableImpl>( SerializableImpl.class ), original, copy, different ); } @Test public void testShortType() { final Short original = 100; final Short copy = new Short( (short) 100 ); final Short different = 999; runBasicTests( ShortType.INSTANCE, original, copy, different ); } @Test public void testStringType() { final String original = "abc"; final String copy = new String( original.toCharArray() ); final String different = "xyz"; runBasicTests( StringType.INSTANCE, original, copy, different ); runBasicTests( TextType.INSTANCE, original, copy, different ); runBasicTests( MaterializedClobType.INSTANCE, original, copy, different ); } @Test public void testTimestampType() { final long now = System.currentTimeMillis(); final Timestamp original = new Timestamp( now ); final Timestamp copy = new Timestamp( now ); final Timestamp different = new Timestamp( now + 9999 ); runBasicTests( TimestampType.INSTANCE, original, copy, different ); } @Test public void testTimeType() { final long now = System.currentTimeMillis(); final Time original = new Time( now ); final Time copy = new Time( now ); final Time different = new Time( now + 9999 ); runBasicTests( TimeType.INSTANCE, original, copy, different ); } @Test public void testDates() { final long now = System.currentTimeMillis(); final java.util.Date original = new java.util.Date( now ); final java.util.Date copy = new java.util.Date( now ); final java.util.Date different = new java.util.Date( now + 9999 ); final java.util.Date different2 = new java.util.Date( now + ( 1000L * 60L * 60L * 24L * 365L ) ); runBasicTests( TimeType.INSTANCE, original, copy, different ); runBasicTests( TimestampType.INSTANCE, original, copy, different ); runBasicTests( DateType.INSTANCE, original, copy, different2 ); } @Test public void testTimeZoneType() { final TimeZone original = new SimpleTimeZone( -1, "abc" ); final TimeZone copy = new SimpleTimeZone( -1, "abc" ); final TimeZone different = new SimpleTimeZone( -2, "xyz" ); runBasicTests( TimeZoneType.INSTANCE, original, copy, different ); } protected <T> void runBasicTests(AbstractSingleColumnStandardBasicType<T> type, T original, T copy, T different) { final boolean nonCopyable = Class.class.isInstance( original ) || Currency.class.isInstance( original ); if ( ! nonCopyable ) { // these checks exclude classes which cannot really be cloned (singetons/enums) assertFalse( original == copy ); } assertTrue( original == type.replace( original, copy, null, null, null ) ); assertTrue( type.isSame( original, copy ) ); assertTrue( type.isEqual( original, copy ) ); assertTrue( type.isEqual( original, copy ) ); assertTrue( type.isEqual( original, copy, null ) ); assertFalse( type.isSame( original, different ) ); assertFalse( type.isEqual( original, different ) ); assertFalse( type.isEqual( original, different ) ); assertFalse( type.isEqual( original, different, null ) ); assertFalse( type.isDirty( original, copy , session ) ); assertFalse( type.isDirty( original, copy , ArrayHelper.FALSE, session ) ); assertFalse( type.isDirty( original, copy , ArrayHelper.TRUE, session ) ); assertTrue( type.isDirty( original, different , session ) ); assertFalse( type.isDirty( original, different , ArrayHelper.FALSE, session ) ); assertTrue( type.isDirty( original, different , ArrayHelper.TRUE, session ) ); assertFalse( type.isModified( original, copy, ArrayHelper.FALSE, session ) ); assertFalse( type.isModified( original, copy, ArrayHelper.TRUE, session ) ); assertTrue( type.isModified( original, different, ArrayHelper.FALSE, session ) ); assertTrue( type.isModified( original, different, ArrayHelper.TRUE, session ) ); } }