| /* |
| * Copyright (c) 2007-2012, 2015 Eike Stepper (Berlin, Germany) 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: |
| * Simon McDuff - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.cdo.tests; |
| |
| import org.eclipse.emf.cdo.common.id.CDOID; |
| import org.eclipse.emf.cdo.common.revision.CDORevision; |
| import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.internal.common.revision.delta.CDOListFeatureDeltaImpl; |
| import org.eclipse.emf.cdo.internal.server.mem.MEMStore; |
| import org.eclipse.emf.cdo.server.IStore; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager; |
| import org.eclipse.emf.cdo.tests.model1.Category; |
| import org.eclipse.emf.cdo.tests.model1.Company; |
| import org.eclipse.emf.cdo.tests.model1.Customer; |
| import org.eclipse.emf.cdo.tests.model1.SalesOrder; |
| import org.eclipse.emf.cdo.tests.model3.NodeD; |
| import org.eclipse.emf.cdo.transaction.CDOTransaction; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.util.CommitException; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.net4j.util.WrappedException; |
| import org.eclipse.net4j.util.io.IOUtil; |
| |
| import org.eclipse.emf.common.util.BasicEList; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.spi.cdo.InternalCDOTransaction; |
| |
| /** |
| * See bug 201266 |
| * |
| * @author Simon McDuff |
| */ |
| public class RevisionDeltaTest extends AbstractCDOTest |
| { |
| public RevisionDeltaTest() |
| { |
| } |
| |
| public void testBasicRevisionDelta() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource1 = transaction.createResource(getResourcePath("/test1")); |
| |
| Company company1 = getModel1Factory().createCompany(); |
| Category category1 = getModel1Factory().createCategory(); |
| |
| resource1.getContents().add(company1); |
| company1.getCategories().add(category1); |
| |
| company1.setName("TEST"); |
| InternalCDORevision rev1 = getCopyCDORevision(company1); |
| |
| // Test simple attributes |
| company1.setName("TEST3"); |
| InternalCDORevision rev2 = getCopyCDORevision(company1); |
| |
| CDORevisionDelta revisionDelta = rev2.compare(rev1); |
| assertEquals(1, revisionDelta.getFeatureDeltas().size()); |
| CDOSetFeatureDelta setDelta = (CDOSetFeatureDelta)revisionDelta.getFeatureDeltas().get(0); |
| assertEquals("TEST3", setDelta.getValue()); |
| |
| // Test List clear |
| company1.getCategories().clear(); |
| InternalCDORevision rev3 = getCopyCDORevision(company1); |
| |
| CDORevisionDelta revisionDelta3 = rev3.compare(rev2); |
| assertEquals(1, revisionDelta3.getFeatureDeltas().size()); |
| CDOListFeatureDeltaImpl delta3List = (CDOListFeatureDeltaImpl)revisionDelta3.getFeatureDeltas().get(0); |
| |
| assertEquals(1, delta3List.getListChanges().size()); |
| assertEquals(true, delta3List.getListChanges().get(0) instanceof CDOClearFeatureDelta); |
| |
| // Test List Add |
| for (int i = 0; i < 5; i++) |
| { |
| Category category = getModel1Factory().createCategory(); |
| company1.getCategories().add(category); |
| } |
| |
| InternalCDORevision rev4 = getCopyCDORevision(company1); |
| |
| CDORevisionDelta revisionDelta4 = rev4.compare(rev3); |
| assertEquals(1, revisionDelta4.getFeatureDeltas().size()); |
| CDOListFeatureDeltaImpl delta4List = (CDOListFeatureDeltaImpl)revisionDelta4.getFeatureDeltas().get(0); |
| |
| assertEquals(5, delta4List.getListChanges().size()); |
| assertEquals(true, delta4List.getListChanges().get(0) instanceof CDOAddFeatureDelta); |
| transaction.rollback(); |
| transaction.close(); |
| session.close(); |
| } |
| |
| /** |
| * Sending deltas doesn't adjust CDOIDs |
| * <p> |
| * See bug 214374 |
| */ |
| public void testBugzilla214374() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| SalesOrder salesOrder = getModel1Factory().createSalesOrder(); |
| resource.getContents().add(salesOrder); |
| transaction.commit(); |
| |
| Customer customer = getModel1Factory().createCustomer(); |
| salesOrder.setCustomer(customer); |
| |
| resource.getContents().add(customer); |
| transaction.commit(); |
| transaction.close(); |
| |
| CDOTransaction transaction2 = session.openTransaction(); |
| SalesOrder salesOrder2 = (SalesOrder)CDOUtil |
| .getEObject(transaction2.getObject(CDOUtil.getCDOObject(salesOrder).cdoID(), true)); |
| CDORevision salesRevision = CDOUtil.getCDOObject(salesOrder2).cdoRevision(); |
| EStructuralFeature customerFeature = getModel1Package().getSalesOrder_Customer(); |
| |
| Object value = salesRevision.data().get(customerFeature, 0); |
| assertEquals(true, value instanceof CDOID); |
| transaction2.close(); |
| session.close(); |
| } |
| |
| /** |
| * CDOView.getRevision() does not work for transactions/dirty objects (INVALID) |
| * <p> |
| * See bug 214431 |
| */ |
| public void testBugzilla214431() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| SalesOrder salesOrder = getModel1Factory().createSalesOrder(); |
| resource.getContents().add(salesOrder); |
| transaction.commit(); |
| |
| salesOrder.setId(4711); |
| assertNotSame(CDOUtil.getCDOObject(salesOrder).cdoRevision(), |
| ((InternalCDOTransaction)transaction).getRevision(CDOUtil.getCDOObject(salesOrder).cdoID(), true)); |
| assertEquals(CDOUtil.getCDOObject(salesOrder).cdoRevision(), |
| transaction.getDirtyObjects().get(CDOUtil.getCDOObject(salesOrder).cdoID()).cdoRevision()); |
| transaction.close(); |
| session.close(); |
| } |
| |
| /** |
| * CDOView.getRevision() does not work for transactions/dirty objects (INVALID) |
| * <p> |
| * See bug 214374 |
| */ |
| public void testBugzilla214374_HandleClear() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| Customer customer = getModel1Factory().createCustomer(); |
| resource.getContents().add(customer); |
| |
| SalesOrder salesOrder = getModel1Factory().createSalesOrder(); |
| resource.getContents().add(salesOrder); |
| customer.getSalesOrders().add(salesOrder); |
| customer.getSalesOrders().add(salesOrder); |
| transaction.commit(); |
| |
| salesOrder = getModel1Factory().createSalesOrder(); |
| customer = getModel1Factory().createCustomer(); |
| resource.getContents().add(salesOrder); |
| resource.getContents().add(customer); |
| salesOrder.setCustomer(customer); |
| transaction.commit(); |
| transaction.close(); |
| session.close(); |
| } |
| |
| /** |
| * java.lang.IllegalStateException with MEMStore |
| * <p> |
| * See bug 243282 |
| */ |
| public void testBugzilla243282_Exception() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| Customer customer = getModel1Factory().createCustomer(); |
| resource.getContents().add(customer); |
| |
| transaction.commit(); |
| |
| InternalCDORevisionManager revisionManager = getRepository().getRevisionManager(); |
| CDORevision revision = CDOUtil.getCDOObject(customer).cdoRevision(); |
| revisionManager.getCache().removeRevision(revision.getID(), revision); |
| |
| SalesOrder salesOrder = getModel1Factory().createSalesOrder(); |
| resource.getContents().add(salesOrder); |
| customer.getSalesOrders().add(salesOrder); |
| |
| IStore store = getRepository().getStore(); |
| if (store instanceof MEMStore) |
| { |
| MEMStore memStore = (MEMStore)store; |
| CDORevisionUtil.dumpAllRevisions(memStore.getAllRevisions(), IOUtil.OUT()); |
| } |
| |
| transaction.commit(); |
| transaction.close(); |
| session.close(); |
| } |
| |
| @SuppressWarnings("unused") |
| public void testDetachWithXRef() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| NodeD a = getModel3Factory().createNodeD(); |
| NodeD b = getModel3Factory().createNodeD(); |
| NodeD c = getModel3Factory().createNodeD(); |
| |
| a.getChildren().add(b); |
| c.getOtherNodes().add(b); |
| |
| resource.getContents().add(a); |
| resource.getContents().add(c); |
| |
| if (true) |
| { |
| transaction.commit(); |
| transaction.close(); |
| transaction = session.openTransaction(); |
| resource = transaction.getResource(getResourcePath("/test1")); |
| } |
| |
| // Start test logic |
| |
| a = (NodeD)resource.getContents().get(0); |
| b = a.getChildren().get(0); |
| c = (NodeD)resource.getContents().get(1); |
| |
| a.getChildren().remove(0); |
| Object[] cB = c.getOtherNodes().toArray(); |
| |
| CDORevisionDelta aDelta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(a).cdoID()); |
| CDORevisionDelta cDelta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(c).cdoID()); |
| |
| session.close(); |
| } |
| |
| @SuppressWarnings("unused") |
| public void testDetachWithXRef_Remove() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| NodeD a = getModel3Factory().createNodeD(); |
| NodeD b = getModel3Factory().createNodeD(); |
| NodeD c = getModel3Factory().createNodeD(); |
| |
| a.getChildren().add(b); |
| c.getOtherNodes().add(b); |
| |
| resource.getContents().add(a); |
| resource.getContents().add(c); |
| |
| if (true) |
| { |
| transaction.commit(); |
| transaction.close(); |
| transaction = session.openTransaction(); |
| resource = transaction.getResource(getResourcePath("/test1")); |
| } |
| |
| // Start test logic |
| |
| a = (NodeD)resource.getContents().get(0); |
| b = a.getChildren().get(0); |
| c = (NodeD)resource.getContents().get(1); |
| |
| a.getChildren().remove(0); |
| c.getOtherNodes().remove(0); |
| |
| Object[] cB = c.getOtherNodes().toArray(); |
| |
| CDORevisionDelta aDelta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(a).cdoID()); |
| CDORevisionDelta cDelta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(c).cdoID()); |
| |
| CDOListFeatureDelta list = (CDOListFeatureDelta)cDelta.getFeatureDelta(getModel3Package().getNodeD_OtherNodes()); |
| assertEquals(1, list.getListChanges().size()); |
| |
| session.close(); |
| } |
| |
| public void testListRemoveMiddle() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.remove(5); |
| } |
| }); |
| } |
| |
| public void testListRemoveLast() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.remove(list.size() - 1); |
| } |
| }); |
| } |
| |
| public void testListRemoveFirst() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.remove(0); |
| } |
| }); |
| } |
| |
| public void testListSimpleMove() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.move(2, 7); |
| } |
| }); |
| } |
| |
| public void testListMoveToLast() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.move(2, list.size() - 1); |
| } |
| }); |
| } |
| |
| public void testListMoveToFirst() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.move(2, 0); |
| } |
| }); |
| } |
| |
| public void testListTwoIndependentMoves() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.move(1, 3); |
| list.move(7, 4); |
| } |
| }); |
| } |
| |
| public void testListTwoIntersectingMoves() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| public void doManipulations(EList<?> list) |
| { |
| list.move(1, 7); |
| list.move(3, 4); |
| } |
| }); |
| } |
| |
| public void testListInsertFirst() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry"); |
| l.add(0, company); |
| } |
| }); |
| } |
| |
| public void testListInsertMiddle() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry"); |
| l.add(5, company); |
| } |
| }); |
| } |
| |
| public void testListInsertLast() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry"); |
| l.add(company); |
| } |
| }); |
| } |
| |
| public void testListMultipleOpsWithClear() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| |
| l.remove(4); |
| l.remove(7); |
| |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(5, company); |
| |
| l.move(1, 2); |
| l.move(7, 0); |
| |
| l.clear(); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 2"); |
| l.add(company); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 3"); |
| l.add(company); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 4"); |
| l.add(0, company); |
| |
| l.move(1, 2); |
| } |
| }); |
| } |
| |
| public void testListMultipleOps() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| |
| l.remove(7); |
| |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(5, company); |
| |
| l.move(1, 2); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 2"); |
| l.add(company); |
| |
| l.move(7, 0); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 3"); |
| l.add(company); |
| |
| l.remove(4); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 4"); |
| l.add(0, company); |
| |
| l.move(1, 2); |
| } |
| }); |
| } |
| |
| public void testMultipleInserts() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(7, company); |
| company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 2"); |
| l.add(12, company); |
| } |
| }); |
| } |
| |
| public void testInsertAndRemove() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(7, company); |
| l.remove(12); |
| } |
| }); |
| } |
| |
| public void testInsertAndMove() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(7, company); |
| l.move(12, 7); |
| } |
| }); |
| } |
| |
| public void testMoveAndDelete() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| l.move(12, 7); |
| l.remove(12); |
| } |
| }); |
| } |
| |
| public void testInsertAndMoveAndRemove() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(7, company); |
| l.move(12, 7); |
| l.remove(12); |
| } |
| }); |
| } |
| |
| public void testInsertAndSet() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| l.add(7, company); |
| Company company2 = getModel1Factory().createCompany(); |
| company2.setName("NewEntry 2"); |
| l.set(7, company2); |
| l.add(19, company); // <- needed because the set operation makes the company a dangling reference |
| } |
| }); |
| } |
| |
| public void testSetAndRemove() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| Company company = getModel1Factory().createCompany(); |
| company.setName("NewEntry 1"); |
| Company oldCompany = l.get(7); |
| l.set(7, company); |
| l.add(19, oldCompany); |
| l.remove(7); // <- needed because the set operation makes the company a dangling reference |
| } |
| }); |
| } |
| |
| public void testMultipleRemoves() |
| { |
| testStoreDelta(new ListManipulator() |
| { |
| @SuppressWarnings("unchecked") |
| public void doManipulations(EList<?> list) |
| { |
| EList<Company> l = (EList<Company>)list; |
| l.remove(7); |
| l.remove(12); |
| } |
| }); |
| } |
| |
| private InternalCDORevision getCopyCDORevision(Object object) |
| { |
| return (InternalCDORevision)CDOUtil.getCDOObject((EObject)object).cdoRevision().copy(); |
| } |
| |
| protected void testStoreDelta(ListManipulator manipulator) |
| { |
| BasicEList<Company> reference = new BasicEList<Company>(); |
| |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| for (int i = 0; i < 20; i++) |
| { |
| String name = "company " + i; |
| Company company = getModel1Factory().createCompany(); |
| company.setName(name); |
| resource.getContents().add(company); |
| |
| company = getModel1Factory().createCompany(); |
| company.setName(name); |
| reference.add(company); |
| } |
| |
| try |
| { |
| transaction.commit(); |
| } |
| catch (CommitException ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| |
| transaction.close(); |
| session.close(); |
| } |
| |
| clearCache(getRepository().getRevisionManager()); |
| |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.getResource(getResourcePath("/test1")); |
| |
| manipulator.doManipulations(resource.getContents()); |
| manipulator.doManipulations(reference); |
| |
| try |
| { |
| transaction.commit(); |
| } |
| catch (CommitException ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| |
| transaction.close(); |
| session.close(); |
| } |
| |
| clearCache(getRepository().getRevisionManager()); |
| |
| { |
| CDOSession session = openSession(); |
| CDOView view = session.openView(); |
| CDOResource resource = view.getResource(getResourcePath("/test1")); |
| |
| assertEquals(reference.size(), resource.getContents().size()); |
| |
| for (int i = 0; i < reference.size(); i++) |
| { |
| assertEquals(reference.get(i).getName(), ((Company)resource.getContents().get(i)).getName()); |
| } |
| |
| view.close(); |
| session.close(); |
| } |
| } |
| |
| /** |
| * @author Simon McDuff |
| */ |
| protected static interface ListManipulator |
| { |
| public void doManipulations(EList<?> list); |
| } |
| } |