| /******************************************************************************* |
| * Copyright (c) 2010-2014 SAP AG and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * SAP AG - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.skalli.core.persistence; |
| |
| import static org.eclipse.skalli.testutil.StorageKey.keyOf; |
| |
| import java.util.ArrayList; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.UUID; |
| |
| import org.eclipse.skalli.commons.CollectionUtils; |
| import org.eclipse.skalli.commons.XMLUtils; |
| import org.eclipse.skalli.model.EntityBase; |
| import org.eclipse.skalli.model.ExtensibleEntityBase; |
| import org.eclipse.skalli.model.ExtensionEntityBase; |
| import org.eclipse.skalli.services.entity.EntityService; |
| import org.eclipse.skalli.services.extension.ExtensionService; |
| import org.eclipse.skalli.testutil.AssertUtils; |
| import org.eclipse.skalli.testutil.BundleManager; |
| import org.eclipse.skalli.testutil.HashMapStorageService; |
| import org.eclipse.skalli.testutil.TestEntityBase; |
| import org.eclipse.skalli.testutil.TestExtensibleEntityBase; |
| import org.eclipse.skalli.testutil.TestExtensibleEntityEntityService; |
| import org.eclipse.skalli.testutil.TestExtensibleEntityExtensionService; |
| import org.eclipse.skalli.testutil.TestExtension; |
| import org.eclipse.skalli.testutil.TestExtension1; |
| import org.eclipse.skalli.testutil.TestUUIDs; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.framework.ServiceRegistration; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| @SuppressWarnings("nls") |
| public class XStreamPersistenceComponentTest { |
| |
| private XStreamPersistenceComponent persistenceService; |
| private HashMapStorageService hashMapStorageService; |
| |
| private TestEntityBase parent1; |
| private TestEntityBase parent2; |
| private TestEntityBase entity1; |
| private TestEntityBase entity2; |
| private TestEntityBase entity3; |
| private TestEntityBase entity4; |
| private TestEntityBase entity5; |
| private TestEntityBase entity6; |
| private TestEntityBase entity7; |
| |
| private List<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>(); |
| |
| @Before |
| public void setup() throws Exception { |
| serviceRegistrations.add(BundleManager.registerService(ExtensionService.class, |
| new TestExtensibleEntityExtensionService(), null)); |
| serviceRegistrations.add(BundleManager.registerService(EntityService.class, |
| new TestExtensibleEntityEntityService(0), null)); |
| Assert.assertEquals(2, serviceRegistrations.size()); |
| hashMapStorageService = new HashMapStorageService(); |
| persistenceService = new XStreamPersistenceComponent(hashMapStorageService); |
| |
| parent1 = new TestEntityBase(TestUUIDs.TEST_UUIDS[0]); |
| parent2 = new TestEntityBase(TestUUIDs.TEST_UUIDS[1]); |
| parent2.setDeleted(true); |
| |
| // non-deleted entities referencing non-deleted parent entities |
| // hierarchy: entity2 -> entity1 -> parent1 |
| entity1 = new TestEntityBase(TestUUIDs.TEST_UUIDS[2], TestUUIDs.TEST_UUIDS[0]); |
| entity2 = new TestEntityBase(TestUUIDs.TEST_UUIDS[3], TestUUIDs.TEST_UUIDS[2]); |
| |
| // non-deleted entity referencing a deleted parent entity |
| entity3 = new TestEntityBase(TestUUIDs.TEST_UUIDS[4], TestUUIDs.TEST_UUIDS[1]); |
| |
| // deleted entity referencing a deleted parent entity |
| entity4 = new TestEntityBase(TestUUIDs.TEST_UUIDS[5], TestUUIDs.TEST_UUIDS[1]); |
| entity4.setDeleted(true); |
| |
| // deleted entity referencing a non-deleted parent entity |
| entity5 = new TestEntityBase(TestUUIDs.TEST_UUIDS[6], TestUUIDs.TEST_UUIDS[0]); |
| entity5.setDeleted(true); |
| |
| // siblings of entity1 |
| entity6 = new TestEntityBase(TestUUIDs.TEST_UUIDS[7], TestUUIDs.TEST_UUIDS[0]); |
| entity7 = new TestEntityBase(TestUUIDs.TEST_UUIDS[8], TestUUIDs.TEST_UUIDS[0]); |
| } |
| |
| @After |
| public void tearDown() { |
| for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) { |
| serviceRegistration.unregister(); |
| } |
| } |
| |
| @Test |
| public void testPersistAndLoad() throws Exception { |
| // create and persist test entities |
| List<TestExtensibleEntityBase> expectedEntities = createTestEntityHierarchy(); |
| for (ExtensibleEntityBase entity : expectedEntities) { |
| persistenceService.persist(entity.getClass(), entity, "anyonomous"); |
| } |
| |
| // read the persisted files as DOM and do some asserts |
| for (TestExtensibleEntityBase entity : expectedEntities) { |
| Assert.assertNotNull(entity); |
| |
| byte[] blob = hashMapStorageService.asMap().get( |
| keyOf(entity.getClass().getSimpleName(), entity.getUuid().toString())); |
| Document doc = XMLUtils.documentFromString(new String(blob, "UTF-8")); |
| |
| // check that the extensible entity has been persisted with its default alias |
| // and check some nodes (uuid, extensions etc.) |
| NodeList nodes = doc.getElementsByTagName("entity-foobar"); |
| Assert.assertEquals(1, nodes.getLength()); |
| nodes = ((Element)nodes.item(0)).getChildNodes(); |
| for (int i = 0; i < nodes.getLength(); ++i) { |
| assertNode(nodes.item(i), entity); |
| } |
| } |
| |
| // create a new instance for loading of persisted entities |
| List<TestExtensibleEntityBase> actualEntities = persistenceService.getEntities(TestExtensibleEntityBase.class); |
| List<TestExtensibleEntityBase> actualDeletedEntities = persistenceService.getDeletedEntities(TestExtensibleEntityBase.class); |
| Assert.assertEquals(3, actualEntities.size()); |
| Assert.assertEquals(2, actualDeletedEntities.size()); |
| |
| // assert that unmarshalled entities equal the original entities |
| // see assertEquals() methods in TestExtensibleEntityBase and TestExtension |
| for (TestExtensibleEntityBase actualEntity : actualEntities) { |
| UUID uuid = actualEntity.getUuid(); |
| boolean found = false; |
| for (TestExtensibleEntityBase expected : expectedEntities) { |
| if (expected.getUuid().equals(uuid)) { |
| TestExtensibleEntityBase.assertEquals(expected, actualEntity); |
| found = true; |
| } |
| } |
| if (!found) { |
| Assert.fail("Should have been found"); |
| } |
| } |
| } |
| |
| @Test |
| public void testPersistLoadPersistCycle() throws Exception { |
| List<TestExtensibleEntityBase> expectedEntities = createTestEntityHierarchy(); |
| for (ExtensibleEntityBase entity : expectedEntities) { |
| persistenceService.persist(entity.getClass(), entity, "anyonomous"); |
| } |
| |
| // load a project with a parent and a child |
| TestExtensibleEntityBase parent = |
| persistenceService.loadEntity(TestExtensibleEntityBase.class, TestUUIDs.TEST_UUIDS[1]); |
| // ensure that it has no parent |
| Assert.assertEquals(TestUUIDs.TEST_UUIDS[2], parent.getParentEntityId()); |
| Assert.assertEquals(TestUUIDs.TEST_UUIDS[2], parent.getParentEntity().getUuid()); |
| // ensure that the children have not been reseolved |
| Assert.assertNull(parent.getFirstChild()); |
| |
| // save the loaded entity again |
| persistenceService.persist(TestExtensibleEntityBase.class, parent, "anonymous"); |
| |
| // ensure we still have the same parent |
| Assert.assertEquals(TestUUIDs.TEST_UUIDS[2], parent.getParentEntityId()); |
| Assert.assertEquals(TestUUIDs.TEST_UUIDS[2], parent.getParentEntity().getUuid()); |
| // ensure that the children have now been resolved! |
| Assert.assertNotNull(parent.getFirstChild()); |
| Assert.assertEquals(TestUUIDs.TEST_UUIDS[0], parent.getFirstChild().getUuid()); |
| } |
| |
| @Test(expected = RuntimeException.class) |
| public void testPersistUnknownParent() throws Exception { |
| List<TestExtensibleEntityBase> expectedEntities = createTestEntityHierarchy(); |
| TestExtensibleEntityBase entity = expectedEntities.get(1); |
| persistenceService.persist(entity.getClass(), entity, "anonymous"); |
| } |
| |
| @Test |
| public void testResolveEntityRelations() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| // insert all the entities and calculate the relations |
| updateCache(p, parent1, parent2, entity1, entity2, entity3, entity4, entity5, entity6, entity7); |
| p.resolveEntityRelations(TestEntityBase.class); |
| |
| // assert that the caches contain the expected entities |
| AssertUtils.assertEqualsAnyOrder("keySet()", |
| CollectionUtils.asSet(TestUUIDs.TEST_UUIDS[0], TestUUIDs.TEST_UUIDS[2], TestUUIDs.TEST_UUIDS[3], |
| TestUUIDs.TEST_UUIDS[4], TestUUIDs.TEST_UUIDS[7], TestUUIDs.TEST_UUIDS[8]), |
| p.keySet(TestEntityBase.class)); |
| AssertUtils.assertEqualsAnyOrder("deletedSet()", |
| CollectionUtils.asSet(TestUUIDs.TEST_UUIDS[1], TestUUIDs.TEST_UUIDS[5], TestUUIDs.TEST_UUIDS[6]), |
| p.deletedSet(TestEntityBase.class)); |
| |
| // assert the parent and siblings pointers |
| TestEntityBase testEntity = p.getEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[0]); |
| TestEntityBase.assertEquals(parent1, testEntity); |
| Assert.assertNull(testEntity.getParentEntity()); |
| Assert.assertNull(testEntity.getNextSibling()); |
| TestEntityBase.assertEquals(entity6, testEntity.getFirstChild()); |
| TestEntityBase.assertEquals(entity1, entity6.getNextSibling()); |
| TestEntityBase.assertEquals(entity2, entity1.getFirstChild()); |
| TestEntityBase.assertEquals(entity7, entity1.getNextSibling()); |
| Assert.assertNull(entity7.getNextSibling()); |
| TestEntityBase.assertEquals(parent1, p.getEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[2]).getParentEntity()); |
| TestEntityBase.assertEquals(entity1, p.getEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[3]).getParentEntity()); |
| Assert.assertNull(p.getDeletedEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[1]).getParentEntity()); |
| |
| // non-deleted entity MUST NOT reference a deleted parent entity: |
| Assert.assertNull(p.getEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[4]).getParentEntity()); |
| |
| // deleted entity MAY reference a deleted parent entity |
| TestEntityBase.assertEquals(parent2, p.getDeletedEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[5]).getParentEntity()); |
| |
| // deleted entity MAY reference a non-deleted parent entity |
| TestEntityBase.assertEquals(parent1, p.getDeletedEntity(TestEntityBase.class, TestUUIDs.TEST_UUIDS[6]).getParentEntity()); |
| |
| } |
| |
| @Test |
| public void testGetParentEntity() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| // insert all the entities and calculate the relations |
| updateCache(p, parent1, parent2, entity1, entity2, entity3, entity4, entity5, entity6, entity7); |
| p.resolveEntityRelations(TestEntityBase.class); |
| |
| TestEntityBase.assertEquals(parent1, entity1.getParentEntity()); |
| TestEntityBase.assertEquals(entity1, entity2.getParentEntity()); |
| Assert.assertNull(entity3.getParentEntity()); |
| TestEntityBase.assertEquals(parent2, entity4.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity5.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity6.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity7.getParentEntity()); |
| |
| assertParentEntity(p, null, parent1); |
| assertParentEntity(p, null, parent2); |
| assertParentEntity(p, parent1, entity1); |
| assertParentEntity(p, entity1, entity2); |
| assertParentEntity(p, null, entity3); |
| assertParentEntity(p, parent2, entity4); |
| assertParentEntity(p, parent1, entity5); |
| assertParentEntity(p, parent1, entity6); |
| assertParentEntity(p, parent1, entity7); |
| } |
| |
| @Test |
| public void testResolveSingleEntityRelations() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| updateCache(p, parent1, parent2, entity1, entity2, entity3, entity4, entity5, entity6, entity7); |
| resolveRelations(p, parent1, parent2, entity1, entity2, entity3, entity4, entity5, entity6, entity7); |
| |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| assertSiblingChain(parent2, entity4); |
| assertSiblingChain(entity1, entity2); |
| assertSiblingChain(entity2, (EntityBase[])null); |
| assertSiblingChain(entity3, (EntityBase[])null); |
| assertSiblingChain(entity4, (EntityBase[])null); |
| assertSiblingChain(entity5, (EntityBase[])null); |
| assertSiblingChain(entity6, (EntityBase[])null); |
| assertSiblingChain(entity7, (EntityBase[])null); |
| } |
| |
| @Test |
| public void testAdjustEntityRelations() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| TestEntityBase parent3 = new TestEntityBase(TestUUIDs.TEST_UUIDS[10]); |
| updateCache(p, parent1, parent2, parent3, entity1, entity4); |
| resolveRelations(p, parent1, parent2, parent3, entity1, entity4); |
| assertSiblingChain(parent1, entity1); |
| assertSiblingChain(parent2, entity4); |
| assertSiblingChain(parent3, (EntityBase[])null); |
| |
| // adding new children not previously in the child list |
| p.adjustEntityRelations(TestEntityBase.class, null, entity6); |
| assertSiblingChain(parent1, entity1, entity6); |
| p.adjustEntityRelations(TestEntityBase.class, null, entity7); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| |
| // replacing an unchanged entity with itself does nothing |
| p.adjustEntityRelations(TestEntityBase.class, entity1, entity1); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| p.adjustEntityRelations(TestEntityBase.class, entity6, entity6); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| p.adjustEntityRelations(TestEntityBase.class, entity7, entity7); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| p.adjustEntityRelations(TestEntityBase.class, entity4, entity4); |
| assertSiblingChain(parent2, entity4); |
| |
| // adding a deleted child to a non-deleted parent does not change |
| // the child list of that parent, but the deleted child gets a parent |
| p.adjustEntityRelations(TestEntityBase.class, null, entity5); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| TestEntityBase.assertEquals(parent1, entity5.getParentEntity()); |
| |
| // changing the content of an entity just replaces the instance in the child list |
| TestEntityBase entity8 = new TestEntityBase(TestUUIDs.TEST_UUIDS[2], TestUUIDs.TEST_UUIDS[0]); |
| entity8.setStr("foobar"); |
| p.adjustEntityRelations(TestEntityBase.class, entity1, entity8); |
| assertSiblingChain(parent1, entity8, entity6, entity7); |
| TestEntityBase.assertEquals(parent1, entity1.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity8.getParentEntity()); |
| |
| // removing the parent pointer from an entity removes it from the child list of that parent |
| TestEntityBase entity9 = new TestEntityBase(TestUUIDs.TEST_UUIDS[2], null); |
| p.adjustEntityRelations(TestEntityBase.class, entity8, entity9); |
| assertSiblingChain(parent1, entity6, entity7); |
| TestEntityBase.assertEquals(parent1, entity8.getParentEntity()); |
| Assert.assertNull(entity9.getParentEntity()); |
| |
| // setting the parent pointer of an entity adds it to the child list of that parent |
| p.adjustEntityRelations(TestEntityBase.class, entity9, entity8); |
| assertSiblingChain(parent1, entity6, entity7, entity8); |
| TestEntityBase.assertEquals(parent1, entity8.getParentEntity()); |
| Assert.assertNull(entity9.getParentEntity()); |
| |
| // setting the deleted flag on an entity removes that entity from the child list |
| // of its parent but does not change its parent pointer: a deleted entity can have a |
| // non-deleted parent |
| TestEntityBase entity10 = new TestEntityBase(TestUUIDs.TEST_UUIDS[7], TestUUIDs.TEST_UUIDS[0]); |
| entity10.setDeleted(true); |
| p.adjustEntityRelations(TestEntityBase.class, entity6, entity10); |
| assertSiblingChain(parent1, entity7, entity8); |
| TestEntityBase.assertEquals(parent1, entity6.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity10.getParentEntity()); |
| |
| // clearing the deleted flag of a deleted entity with a pointer to a non-deleted parent |
| // adds that entity to the child list of that parent |
| TestEntityBase entity11 = new TestEntityBase(TestUUIDs.TEST_UUIDS[7], TestUUIDs.TEST_UUIDS[0]); |
| p.adjustEntityRelations(TestEntityBase.class, entity10, entity11); |
| assertSiblingChain(parent1, entity7, entity8, entity11); |
| TestEntityBase.assertEquals(parent1, entity10.getParentEntity()); |
| TestEntityBase.assertEquals(parent1, entity11.getParentEntity()); |
| |
| // adding another deleted entity to a deleted parent |
| TestEntityBase entity12 = new TestEntityBase(TestUUIDs.TEST_UUIDS[9], TestUUIDs.TEST_UUIDS[1]); |
| entity12.setDeleted(true); |
| p.adjustEntityRelations(TestEntityBase.class, null, entity12); |
| assertSiblingChain(parent2, entity4, entity12); |
| TestEntityBase.assertEquals(parent2, entity12.getParentEntity()); |
| |
| // clearing the deleted flag of a deleted entity removes that entity from the child list of its parent |
| // and sets its parent pointer to null: a non-deleted entity must not have a deleted parent! |
| TestEntityBase entity13 = new TestEntityBase(TestUUIDs.TEST_UUIDS[5], TestUUIDs.TEST_UUIDS[1]); |
| p.adjustEntityRelations(TestEntityBase.class, entity4, entity13); |
| assertSiblingChain(parent2, entity12); |
| TestEntityBase.assertEquals(parent2, entity4.getParentEntity()); |
| Assert.assertNull(entity13.getParentEntity()); |
| |
| // setting the deleted flag of an entity with a pointer to a deleted parent |
| // adds the entity to the child list of that parent |
| TestEntityBase entity14 = new TestEntityBase(TestUUIDs.TEST_UUIDS[5], TestUUIDs.TEST_UUIDS[1]); |
| entity14.setDeleted(true); |
| p.adjustEntityRelations(TestEntityBase.class, entity13, entity14); |
| assertSiblingChain(parent2, entity12, entity14); |
| TestEntityBase.assertEquals(parent2, entity14.getParentEntity()); |
| |
| // changing the parent of an entity removes the entity from the children of the old parent |
| // and adds it to the children of the new parent |
| TestEntityBase entity15 = new TestEntityBase(TestUUIDs.TEST_UUIDS[8], TestUUIDs.TEST_UUIDS[10]); |
| p.adjustEntityRelations(TestEntityBase.class, entity7, entity15); |
| assertSiblingChain(parent1, entity8, entity11); |
| assertSiblingChain(parent3, entity15); |
| TestEntityBase.assertEquals(parent1, entity8.getParentEntity()); |
| TestEntityBase.assertEquals(parent3, entity15.getParentEntity()); |
| } |
| |
| @Test |
| public void testInsertChildEntity() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| // inserting entity1: parent1 has now a child, but entity1 has no siblings yet |
| p.insertChildEntity(parent1, entity1); |
| assertSiblingChain(parent1, entity1); |
| |
| // inserting the unchanged entity1 again has no effect |
| p.insertChildEntity(parent1, entity1); |
| assertSiblingChain(parent1, entity1); |
| |
| // inserting entity6 with string content "foo" |
| entity6.setStr("foo"); |
| p.insertChildEntity(parent1, entity6); |
| assertSiblingChain(parent1, entity1, entity6); |
| |
| // inserting entity7 and again entity1 |
| p.insertChildEntity(parent1, entity7); |
| p.insertChildEntity(parent1, entity1); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| |
| // inserting entity6 again, but with a different content "bar" |
| entity6.setStr("bar"); |
| p.insertChildEntity(parent1, entity6); |
| assertSiblingChain(parent1, entity1, entity6, entity7); |
| |
| // inserting entity8, which has the same uuid as entity6 |
| TestEntityBase entity8 = new TestEntityBase(TestUUIDs.TEST_UUIDS[7], TestUUIDs.TEST_UUIDS[0]); |
| entity8.setStr("foobar"); |
| p.insertChildEntity(parent1, entity8); |
| assertSiblingChain(parent1, entity1, entity8, entity7); |
| |
| // inserting entity9, which has the same uuid as entity1 |
| TestEntityBase entity9 = new TestEntityBase(TestUUIDs.TEST_UUIDS[2], TestUUIDs.TEST_UUIDS[0]); |
| entity9.setStr("foobar"); |
| p.insertChildEntity(parent1, entity9); |
| assertSiblingChain(parent1, entity9, entity8, entity7); |
| |
| // inserting entity10, which has the same uuid as entity7 |
| TestEntityBase entity10 = new TestEntityBase(TestUUIDs.TEST_UUIDS[8], TestUUIDs.TEST_UUIDS[0]); |
| entity10.setStr("foobar"); |
| p.insertChildEntity(parent1, entity10); |
| assertSiblingChain(parent1, entity9, entity8, entity10); |
| |
| // adding a deleted entity to a non-deleted parent does nothing |
| TestEntityBase entity11 = new TestEntityBase(TestUUIDs.TEST_UUIDS[3], TestUUIDs.TEST_UUIDS[0]); |
| entity11.setDeleted(true); |
| p.insertChildEntity(parent1, entity11); |
| assertSiblingChain(parent1, entity9, entity8, entity10); |
| |
| // adding a deleted entity to the deleted parent2 works: |
| p.insertChildEntity(parent2, entity11); |
| assertSiblingChain(parent2, entity11); |
| |
| // adding a non-deleted entity to the deleted parent2 does nothing |
| p.insertChildEntity(parent2, entity1); |
| assertSiblingChain(parent2, entity11); |
| } |
| |
| @Test |
| public void testRemoveChildEntity() throws Exception { |
| XStreamPersistenceComponent p = new XStreamPersistenceComponent(); |
| p.registerEntityClass(TestEntityBase.class); |
| |
| // removing an entity that has never been inserted has no effect |
| assertSiblingChain(parent1); |
| p.removeChildEntity(parent1, entity1); |
| assertSiblingChain(parent1); |
| |
| // now inserting entity1: parent1 has a child |
| p.insertChildEntity(parent1, entity1); |
| assertSiblingChain(parent1, entity1); |
| |
| // and removing it again: parent1 has no children |
| p.removeChildEntity(parent1, entity1); |
| assertSiblingChain(parent1); |
| |
| // inserting some entities, then removing entity2 |
| p.insertChildEntity(parent1, entity1); |
| p.insertChildEntity(parent1, entity6); |
| p.insertChildEntity(parent1, entity7); |
| p.removeChildEntity(parent1, entity6); |
| assertSiblingChain(parent1, entity1, entity7); |
| |
| // removing the tail of the siblings chain |
| p.removeChildEntity(parent1, entity7); |
| assertSiblingChain(parent1, entity1); |
| |
| // removing entity3 again has no effect: it was never a child |
| p.removeChildEntity(parent1, entity3); |
| assertSiblingChain(parent1, entity1); |
| |
| // finally removing entity1: parent1 has no children |
| p.removeChildEntity(parent1, entity1); |
| assertSiblingChain(parent1); |
| } |
| |
| private List<TestExtensibleEntityBase> createTestEntityHierarchy() |
| throws Exception { |
| List<TestExtensibleEntityBase> entities = new LinkedList<TestExtensibleEntityBase>(); |
| |
| TestExtensibleEntityBase parentParent = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[2]); |
| entities.add(parentParent); |
| ExtensionEntityBase exts2[] = { createExtension(TestExtension.class, true, "foo", "1", "2"), |
| createExtension(TestExtension1.class, false, "bar", "3") }; |
| addExtensions(parentParent, exts2); |
| |
| TestExtensibleEntityBase parent = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[1]); |
| entities.add(parent); |
| ExtensionEntityBase exts1[] = { createExtension(TestExtension.class, true, "Z", "F", "G", "H", "I"), |
| createExtension(TestExtension1.class, true, "Y", "D", "E") }; |
| addExtensions(parent, exts1); |
| parent.setParentEntity(parentParent); |
| |
| TestExtensibleEntityBase base = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[0]); |
| entities.add(base); |
| ExtensionEntityBase exts0[] = { createExtension(TestExtension.class, false, "X", "A", "B", "C") }; |
| base.setInherited(TestExtension1.class, true); |
| addExtensions(base, exts0); |
| base.setParentEntity(parent); |
| |
| TestExtensibleEntityBase deletedParent = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[4]); |
| deletedParent.setDeleted(true); |
| entities.add(deletedParent); |
| ExtensionEntityBase exts4[] = { createExtension(TestExtension1.class, false, "deleted parent", "d", "e") }; |
| addExtensions(deletedParent, exts4); |
| |
| TestExtensibleEntityBase deleted = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[3]); |
| deleted.setDeleted(true); |
| entities.add(deleted); |
| ExtensionEntityBase exts3[] = { createExtension(TestExtension.class, false, "deleted", "a", "b", "c") }; |
| addExtensions(deleted, exts3); |
| deleted.setParentEntity(deletedParent); |
| |
| return entities; |
| } |
| |
| private void addExtensions(ExtensibleEntityBase base, ExtensionEntityBase... exts) { |
| for (ExtensionEntityBase ext : exts) { |
| base.addExtension(ext); |
| } |
| } |
| |
| private ExtensionEntityBase createExtension(Class<? extends ExtensionEntityBase> clazz, |
| boolean bool, String str, String... items) throws Exception { |
| TestExtension ext = (TestExtension) clazz.newInstance(); |
| ext.setBool(bool); |
| ext.setStr(str); |
| for (String item : items) { |
| ext.addItem(item); |
| } |
| return ext; |
| } |
| |
| private void updateCache(XStreamPersistenceComponent p, EntityBase...entities) { |
| for (EntityBase entity: entities) { |
| p.updateCache(entity); |
| } |
| } |
| |
| private void resolveRelations(XStreamPersistenceComponent p, EntityBase...entities) { |
| for (EntityBase entity: entities) { |
| p.resolveEntityRelations(TestEntityBase.class, entity); |
| } |
| } |
| |
| private void assertParentEntity(XStreamPersistenceComponent p, EntityBase expectedParent, EntityBase entity) { |
| TestEntityBase.assertEquals(expectedParent, p.getParentEntity(TestEntityBase.class, entity)); |
| } |
| |
| private void assertSiblingChain(EntityBase parent, EntityBase...expectedSiblings) { |
| if (expectedSiblings == null || expectedSiblings.length == 0) { |
| Assert.assertNull(parent.getFirstChild()); |
| return; |
| } |
| EntityBase sibling = parent.getFirstChild(); |
| for (EntityBase expectedSibling: expectedSiblings) { |
| Assert.assertNotNull(parent + " misses expected sibling " + expectedSibling, sibling); |
| // assert that the instances are not only equal (which means for |
| // EntityBase equality of the UUIDs), but identical pointers! |
| Assert.assertTrue(expectedSibling == sibling); |
| // assert that all siblings have the given parent |
| Assert.assertTrue(parent == sibling.getParentEntity()); |
| sibling = sibling.getNextSibling(); |
| } |
| Assert.assertNull(parent + " has more siblings than expected", sibling); |
| } |
| |
| private void assertNode(Node node, TestExtensibleEntityBase entity) { |
| String nodeName = node.getNodeName(); |
| if ("uuid".equals(nodeName)) { |
| Assert.assertEquals(entity.getUuid().toString(), node.getTextContent()); |
| } |
| else if ("deleted".equals(nodeName)) { |
| Assert.assertEquals(Boolean.toString(entity.isDeleted()), node.getTextContent()); |
| } |
| else if ("parentEntityId".equals(nodeName)) { |
| Assert.assertEquals(entity.getParentEntityId().toString(), node.getTextContent()); |
| } |
| else if ("extensions".equals(nodeName)) { |
| assertExtensions(node, entity); |
| } |
| else if ("inheritedExtensions".equals(nodeName)) { |
| assertInheritedExtensions(node, entity); |
| } |
| } |
| |
| private void assertExtensions(Node node, TestExtensibleEntityBase entity) { |
| NodeList extNodes = node.getChildNodes(); |
| for (int j = 0; j < extNodes.getLength(); ++j) { |
| Node extNode = extNodes.item(j); |
| String extNodeName = extNode.getNodeName(); |
| if (TestExtension.class.getName().equals(extNodeName)) { |
| assertExtension(extNode, entity.getExtension(TestExtension.class)); |
| } |
| else if (TestExtension1.class.getName().equals(extNodeName)) { |
| assertExtension(extNode, entity.getExtension(TestExtension1.class)); |
| } |
| } |
| } |
| |
| private void assertExtension(Node extNode, TestExtension extension) { |
| Assert.assertNotNull(extension); |
| NodeList nodes = extNode.getChildNodes(); |
| for (int i = 0; i < nodes.getLength(); ++i) { |
| Node node = nodes.item(i); |
| String nodeName = node.getNodeName(); |
| if ("bool".equals(nodeName)) { |
| Assert.assertEquals(Boolean.toString(extension.isBool()), node.getTextContent()); |
| } |
| else if ("str".equals(nodeName)) { |
| Assert.assertEquals(extension.getStr(), node.getTextContent()); |
| } |
| else if ("items".equals(nodeName)) { |
| assertItems(node, extension.getItems()); |
| } |
| } |
| } |
| |
| private void assertItems(Node node, List<String> items) { |
| NodeList itemNodes = node.getChildNodes(); |
| int n = 0; |
| for (int j = 0; j < itemNodes.getLength(); ++j) { |
| Node itemNode = itemNodes.item(j); |
| if ("string".equals(itemNode.getNodeName())) { |
| Assert.assertEquals(items.get(n++), itemNode.getTextContent()); |
| } |
| } |
| } |
| |
| private void assertInheritedExtensions(Node node, TestExtensibleEntityBase entity) { |
| NodeList extNodes = node.getChildNodes(); |
| for (int j = 0; j < extNodes.getLength(); ++j) { |
| Node extNode = extNodes.item(j); |
| String extNodeName = extNode.getNodeName(); |
| if ("string".equals(extNodeName)) { |
| String inheritedEntityName = extNode.getTextContent(); |
| if (TestExtension.class.getName().equals(inheritedEntityName)) { |
| Assert.assertTrue(entity.isInherited(TestExtension.class)); |
| } |
| else if (TestExtension1.class.getName().equals(inheritedEntityName)) { |
| Assert.assertTrue(entity.isInherited(TestExtension1.class)); |
| } |
| } |
| } |
| } |
| } |