/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.engine.spi; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Iterator; import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.action.spi.AfterTransactionCompletionProcess; import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.action.spi.Executable; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * @author Anton Marsden */ public class SortedExecutableListTest extends BaseUnitTestCase { // For testing, we need an Executable that is also Comparable and Serializable private static class AnExecutable implements Executable, Comparable, Serializable { private final int n; private Serializable[] spaces; private transient boolean afterDeserializeCalled; public AnExecutable(int n, String... spaces) { this.n = n; this.spaces = spaces; } @Override public int compareTo(Object o) { return new Integer(n).compareTo( new Integer(( (AnExecutable) o ).n )); } @Override public int hashCode() { return n; } @Override public boolean equals(Object obj) { if ( this == obj ) return true; if ( obj == null ) return false; AnExecutable other = (AnExecutable) obj; return n == other.n; } @Override public Serializable[] getPropertySpaces() { return spaces; } @Override public void beforeExecutions() throws HibernateException { } @Override public void execute() throws HibernateException { } @Override public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() { return null; } @Override public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() { return null; } @Override public void afterDeserialize(SharedSessionContractImplementor session) { this.afterDeserializeCalled = true; } public String toString() { return String.valueOf(n); } } private ExecutableList<AnExecutable> l; private AnExecutable action1 = new AnExecutable( 0, "a" ); private AnExecutable action2 = new AnExecutable( 1, "b", "c" ); private AnExecutable action3 = new AnExecutable( 2, "b", "d" ); private AnExecutable action4 = new AnExecutable( 3 ); @Before public void setUp() { l = new ExecutableList<AnExecutable>(); } @After public void tearDown() { l = null; } @Test public void testAdd() { Assert.assertEquals( 0, l.size() ); l.add( action1 ); Assert.assertEquals( action1, l.get( 0 ) ); Assert.assertEquals( 1, l.size() ); l.add( action2 ); Assert.assertEquals( action2, l.get( 1 ) ); l.add( action3 ); Assert.assertEquals( action3, l.get( 2 ) ); Assert.assertEquals( 3, l.size() ); } @Test public void testClear() { Assert.assertTrue( l.isEmpty() ); l.add( action1 ); Assert.assertFalse( l.isEmpty() ); l.add( action2 ); l.clear(); Assert.assertTrue( l.isEmpty() ); Assert.assertEquals( 0, l.size() ); } @Test public void testIterator() { l.add( action1 ); l.add( action2 ); l.add( action3 ); Iterator<AnExecutable> iterator = l.iterator(); Assert.assertEquals(action1, iterator.next()); Assert.assertEquals(action2, iterator.next()); Assert.assertEquals(action3, iterator.next()); Assert.assertFalse(iterator.hasNext()); } @Test public void testRemoveLastN() { l.add( action1 ); l.add( action2 ); l.add( action3 ); l.removeLastN( 0 ); Assert.assertEquals( 3, l.size() ); l.removeLastN( 2 ); Assert.assertEquals( 1, l.size() ); Assert.assertEquals( action1, l.get( 0 ) ); } @Test public void testGetSpaces() { l.add( action1 ); Set<Serializable> ss = l.getQuerySpaces(); Assert.assertEquals( 1, ss.size() ); Assert.assertTrue( ss.contains( "a" ) ); l.add( action2 ); l.add( action3 ); l.add( action4 ); Set<Serializable> ss2 = l.getQuerySpaces(); Assert.assertEquals( 4, ss2.size() ); Assert.assertTrue( ss2.contains( "a" ) ); Assert.assertTrue( ss2.contains( "b" ) ); Assert.assertTrue( ss2.contains( "c" ) ); Assert.assertTrue( ss2.contains( "d" ) ); Assert.assertTrue( ss == ss2 ); // same Set (cached) // now remove action4 l.remove( 3 ); ss2 = l.getQuerySpaces(); Assert.assertTrue( ss == ss2 ); // same Set (action4 has no spaces) Assert.assertEquals( 4, ss2.size() ); l.remove( 2 ); ss2 = l.getQuerySpaces(); Assert.assertTrue( ss != ss2 ); // Different Set because it has been rebuilt. This would be incorrect if // Set.clear() was used } @Test public void testSort() { l.add( action4 ); l.add( action3 ); l.add( action2 ); l.add( action1 ); l.sort(); Assert.assertEquals( action1, l.get( 0 ) ); Assert.assertEquals( action2, l.get( 1 ) ); Assert.assertEquals( action3, l.get( 2 ) ); Assert.assertEquals( action4, l.get( 3 ) ); } @Test public void testSerializeDeserialize() throws IOException, ClassNotFoundException { l.add( action4 ); l.add( action3 ); l.add( action2 ); l.add( action1 ); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos ); l.writeExternal( oos ); // this OOS stream needs to be flushed... oos.flush(); ByteArrayInputStream bin = new ByteArrayInputStream( baos.toByteArray() ); ObjectInputStream ois = new ObjectInputStream( bin ); l = new ExecutableList<SortedExecutableListTest.AnExecutable>(); l.readExternal( ois ); Assert.assertEquals( 4, l.size() ); Assert.assertEquals( action4, l.get( 0 ) ); Assert.assertEquals( action3, l.get( 1 ) ); Assert.assertEquals( action2, l.get( 2 ) ); Assert.assertEquals( action1, l.get( 3 ) ); Assert.assertFalse(l.get(0).afterDeserializeCalled); Assert.assertFalse(l.get(1).afterDeserializeCalled); Assert.assertFalse(l.get(2).afterDeserializeCalled); Assert.assertFalse( l.get( 3 ).afterDeserializeCalled ); l.afterDeserialize( null ); Assert.assertTrue( l.get( 0 ).afterDeserializeCalled ); Assert.assertTrue( l.get( 1 ).afterDeserializeCalled ); Assert.assertTrue( l.get( 2 ).afterDeserializeCalled ); Assert.assertTrue( l.get( 3 ).afterDeserializeCalled ); Assert.assertEquals( action4, l.get( 0 ) ); Assert.assertEquals( action3, l.get( 1 ) ); Assert.assertEquals( action2, l.get( 2 ) ); Assert.assertEquals( action1, l.get( 3 ) ); // sort after deserializing l.sort(); Assert.assertEquals( action1, l.get( 0 ) ); Assert.assertEquals( action2, l.get( 1 ) ); Assert.assertEquals( action3, l.get( 2 ) ); Assert.assertEquals( action4, l.get( 3 ) ); } }