| /* |
| * Copyright (c) 2011, 2012 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: |
| * Caspar De Groot - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.cdo.tests.bugzilla; |
| |
| import org.eclipse.emf.cdo.CDOState; |
| import org.eclipse.emf.cdo.common.id.CDOID; |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.tests.AbstractCDOTest; |
| import org.eclipse.emf.cdo.tests.config.IModelConfig; |
| import org.eclipse.emf.cdo.tests.model1.Model1Factory; |
| import org.eclipse.emf.cdo.tests.model1.Order; |
| import org.eclipse.emf.cdo.tests.model1.OrderDetail; |
| import org.eclipse.emf.cdo.tests.model4.ContainedElementNoOpposite; |
| import org.eclipse.emf.cdo.tests.model4.GenRefMultiContained; |
| import org.eclipse.emf.cdo.tests.model4.GenRefMultiNonContained; |
| import org.eclipse.emf.cdo.tests.model4.model4Factory; |
| import org.eclipse.emf.cdo.tests.model4.model4Package; |
| import org.eclipse.emf.cdo.tests.model4interfaces.model4interfacesPackage; |
| 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.util.ObjectNotFoundException; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.emf.common.command.BasicCommandStack; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.command.CommandStack; |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.util.WrappedException; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.edit.command.AddCommand; |
| import org.eclipse.emf.edit.command.DragAndDropCommand; |
| import org.eclipse.emf.edit.command.RemoveCommand; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| public class Bugzilla_283985_1_Test extends AbstractCDOTest |
| { |
| public void testBugzilla283985_PlainSingle() throws CommitException |
| { |
| runWithClosure(new SingleItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| for (OrderDetail detail : details) |
| { |
| Order order = (Order)detail.eContainer(); |
| order.getOrderDetails().remove(detail); |
| target.getOrderDetails().add(detail); |
| } |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_PlainMultiple() throws CommitException |
| { |
| runWithClosure(new MultiItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| for (OrderDetail detail : details) |
| { |
| Order order = (Order)detail.eContainer(); |
| order.getOrderDetails().remove(detail); |
| target.getOrderDetails().add(detail); |
| } |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_DragAndDropSingle() throws CommitException |
| { |
| runWithClosure(new SingleItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| float location = 0.5f; |
| int operations = 7; |
| int operation = 2; |
| |
| Command cmd = DragAndDropCommand.create(domain, target, location, operations, operation, details); |
| domain.getCommandStack().execute(cmd); |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_DragAndDropMultiple() throws CommitException |
| { |
| runWithClosure(new MultiItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| float location = 0.5f; |
| int operations = 7; |
| int operation = 2; |
| |
| Command cmd = DragAndDropCommand.create(domain, target, location, operations, operation, details); |
| domain.getCommandStack().execute(cmd); |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_DragAndDropMultipleMultiparent() throws CommitException |
| { |
| runWithClosure(new MultiItemMultiParentClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| float location = 0.5f; |
| int operations = 7; |
| int operation = 2; |
| |
| Command cmd = DragAndDropCommand.create(domain, target, location, operations, operation, details); |
| domain.getCommandStack().execute(cmd); |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_RemoveAndAddSingle() throws CommitException |
| { |
| runWithClosure(new SingleItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| Command dragCmd = RemoveCommand.create(domain, details); |
| Command dropCmd = AddCommand.create(domain, target, null, details); |
| domain.getCommandStack().execute(dragCmd); |
| domain.getCommandStack().execute(dropCmd); |
| } |
| }); |
| } |
| |
| public void testBugzilla283985_RemoveAndAddMultiple() throws CommitException |
| { |
| runWithClosure(new MultiItemClosure() |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target) |
| { |
| Command dragCmd = RemoveCommand.create(domain, details); |
| Command dropCmd = AddCommand.create(domain, target, null, details); |
| domain.getCommandStack().execute(dragCmd); |
| domain.getCommandStack().execute(dropCmd); |
| } |
| }); |
| } |
| |
| private void runWithClosure(IClosure closure) throws CommitException |
| { |
| CDOSession session = openSession(); |
| CDOTransaction tx = session.openTransaction(); |
| CDOResource r1 = tx.getOrCreateResource(getResourcePath("/r1")); |
| r1.getContents().clear(); |
| |
| // Set things up |
| Model1Factory factory = getModel1Factory(); |
| Order order1 = factory.createPurchaseOrder(); |
| Order order2 = factory.createPurchaseOrder(); |
| Order order3 = factory.createPurchaseOrder(); |
| OrderDetail detail1 = factory.createOrderDetail(); |
| OrderDetail detail2 = factory.createOrderDetail(); |
| OrderDetail detail3 = factory.createOrderDetail(); |
| OrderDetail detail4 = factory.createOrderDetail(); |
| OrderDetail detail5 = factory.createOrderDetail(); |
| OrderDetail detail6 = factory.createOrderDetail(); |
| OrderDetail detail7 = factory.createOrderDetail(); |
| OrderDetail detail8 = factory.createOrderDetail(); |
| OrderDetail detail9 = factory.createOrderDetail(); |
| OrderDetail detail10 = factory.createOrderDetail(); |
| OrderDetail detail11 = factory.createOrderDetail(); |
| OrderDetail detail12 = factory.createOrderDetail(); |
| order1.getOrderDetails().add(detail1); |
| order1.getOrderDetails().add(detail2); |
| order1.getOrderDetails().add(detail3); |
| order1.getOrderDetails().add(detail4); |
| order2.getOrderDetails().add(detail5); |
| order2.getOrderDetails().add(detail6); |
| order2.getOrderDetails().add(detail7); |
| order2.getOrderDetails().add(detail8); |
| order3.getOrderDetails().add(detail9); |
| order3.getOrderDetails().add(detail10); |
| order3.getOrderDetails().add(detail11); |
| order3.getOrderDetails().add(detail12); |
| r1.getContents().add(order1); |
| r1.getContents().add(order2); |
| r1.getContents().add(order3); |
| |
| // Commit so that everything gets a CDOID |
| tx.commit(); |
| |
| // Create some versions |
| detail1.setPrice(10.0f); |
| tx.commit(); |
| detail1.setPrice(20.0f); |
| tx.commit(); |
| |
| // Ask closure to pick items to be moved |
| // |
| Collection<OrderDetail> details = closure.pickDetails(new OrderDetail[] { detail1, detail2, detail3, detail4, |
| detail5, detail6, detail7, detail8, detail9, detail10, detail11, detail12, }); |
| |
| // Keep references to the current CDOIDs and versions, to be used in the test |
| CDOID[] idsBefore = new CDOID[details.size()]; |
| int[] versionsBefore = new int[details.size()]; |
| int i = 0; |
| for (OrderDetail detail : details) |
| { |
| idsBefore[i] = CDOUtil.getCDOObject(detail).cdoID(); |
| versionsBefore[i] = CDOUtil.getCDOObject(detail).cdoRevision().getVersion(); |
| i++; |
| } |
| |
| // Bring the resourceset under an editing domain |
| ResourceSet rs = tx.getResourceSet(); |
| AdapterFactory adapterFact = new ReflectiveItemProviderAdapterFactory(); |
| CommandStack cs = new SaneCommandStack(); |
| EditingDomain domain = new AdapterFactoryEditingDomain(adapterFact, cs, rs); |
| |
| // Delegate test operation to the closure |
| // |
| closure.test(domain, details, order3); |
| |
| // Are the order details' CDOIDs still the same? |
| // |
| i = 0; |
| for (OrderDetail detail : details) |
| { |
| CDOID idAfter = CDOUtil.getCDOObject(detail).cdoID(); |
| CDOID idBefore = idsBefore[i]; |
| assertEquals(idBefore, idAfter); |
| |
| int versionAfter = CDOUtil.getCDOObject(detail).cdoRevision().getVersion(); |
| int versionBefore = versionsBefore[i]; |
| assertEquals(versionBefore, versionAfter); |
| |
| i++; |
| } |
| |
| tx.commit(); |
| |
| // Check again |
| // |
| i = 0; |
| for (OrderDetail detail : details) |
| { |
| CDOID idAfter = CDOUtil.getCDOObject(detail).cdoID(); |
| CDOID idBefore = idsBefore[i]; |
| assertEquals(idBefore, idAfter); |
| |
| int versionAfter = CDOUtil.getCDOObject(detail).cdoRevision().getVersion(); |
| int versionBefore = versionsBefore[i]; |
| assertEquals(versionBefore + 1, versionAfter); |
| |
| i++; |
| } |
| |
| session.refresh(); |
| |
| // Check again |
| // |
| i = 0; |
| for (OrderDetail detail : details) |
| { |
| CDOID idAfter = CDOUtil.getCDOObject(detail).cdoID(); |
| CDOID idBefore = idsBefore[i]; |
| assertEquals(idBefore, idAfter); |
| |
| int versionAfter = CDOUtil.getCDOObject(detail).cdoRevision().getVersion(); |
| int versionBefore = versionsBefore[i]; |
| assertEquals(versionBefore + 1, versionAfter); |
| |
| i++; |
| } |
| |
| tx.close(); |
| session.close(); |
| } |
| |
| public void testEReferencesCorrupted() throws CommitException |
| { |
| CDOSession session = openSession(); |
| session.getPackageRegistry().putEPackage(model4Package.eINSTANCE); |
| session.getPackageRegistry().putEPackage(model4interfacesPackage.eINSTANCE); |
| |
| CDOTransaction tx = session.openTransaction(); |
| CDOResource res = tx.createResource(getResourcePath("/test/1")); |
| |
| GenRefMultiContained container1 = model4Factory.eINSTANCE.createGenRefMultiContained(); |
| GenRefMultiContained container2 = model4Factory.eINSTANCE.createGenRefMultiContained(); |
| ContainedElementNoOpposite element = model4Factory.eINSTANCE.createContainedElementNoOpposite(); |
| GenRefMultiNonContained referee = model4Factory.eINSTANCE.createGenRefMultiNonContained(); |
| |
| container1.getElements().add(element); |
| referee.getElements().add(element); |
| |
| res.getContents().add(container1); |
| res.getContents().add(container2); |
| res.getContents().add(referee); |
| |
| tx.commit(); |
| |
| container1.getElements().remove(element); |
| container2.getElements().add(element); |
| |
| tx.commit(); |
| tx.close(); |
| |
| // === NEW TX === |
| |
| tx = session.openTransaction(); |
| res = tx.getResource(getResourcePath("/test/1")); |
| |
| container1 = (GenRefMultiContained)res.getContents().get(0); |
| container2 = (GenRefMultiContained)res.getContents().get(1); |
| referee = (GenRefMultiNonContained)res.getContents().get(2); |
| |
| try |
| { |
| element = (ContainedElementNoOpposite)referee.getElements().get(0); |
| } |
| catch (ObjectNotFoundException e) |
| { |
| fail("Should not have thrown ObjectNotFoundException"); |
| } |
| |
| tx.close(); |
| session.close(); |
| clearCache(getRepository().getRevisionManager()); |
| } |
| |
| // TODO Fix bug 344072 |
| @Skips(IModelConfig.CAPABILITY_LEGACY) |
| public void testAddRemoveSequence() throws CommitException |
| { |
| CDOSession session = openSession(); |
| CDOTransaction tx = session.openTransaction(); |
| CDOResource r1 = tx.getOrCreateResource(getResourcePath("/r1")); |
| r1.getContents().clear(); |
| |
| // Set things up |
| Model1Factory factory = getModel1Factory(); |
| Order order1 = factory.createPurchaseOrder(); |
| Order order2 = factory.createPurchaseOrder(); |
| OrderDetail detail1 = factory.createOrderDetail(); |
| r1.getContents().add(order1); |
| r1.getContents().add(order2); |
| order2.getOrderDetails().add(detail1); |
| tx.commit(); |
| |
| order2.getOrderDetails().remove(detail1); |
| assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order1.getOrderDetails().add(detail1); |
| assertEquals(true, order1.getOrderDetails().contains(detail1)); |
| assertEquals(CDOState.DIRTY, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order1.getOrderDetails().remove(detail1); |
| assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order2.getOrderDetails().add(detail1); |
| assertEquals(true, order2.getOrderDetails().contains(detail1)); |
| assertEquals(CDOState.CLEAN, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order2.getOrderDetails().remove(detail1); |
| assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order1.getOrderDetails().add(detail1); |
| assertEquals(true, order1.getOrderDetails().contains(detail1)); |
| assertEquals(CDOState.DIRTY, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| order1.getOrderDetails().remove(detail1); |
| assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| tx.commit(); |
| |
| order1.getOrderDetails().add(detail1); |
| assertEquals(true, order1.getOrderDetails().contains(detail1)); |
| order1.getOrderDetails().remove(detail1); |
| |
| order2.getOrderDetails().add(detail1); |
| assertEquals(true, order2.getOrderDetails().contains(detail1)); |
| order2.getOrderDetails().remove(detail1); |
| |
| order1.getOrderDetails().add(detail1); |
| assertEquals(true, order1.getOrderDetails().contains(detail1)); |
| order1.getOrderDetails().remove(detail1); |
| |
| tx.close(); |
| session.close(); |
| } |
| |
| public void testCanDaDmoreThanOnce() throws CommitException |
| { |
| CDOSession session = openSession(); |
| CDOTransaction tx = session.openTransaction(); |
| CDOResource r1 = tx.getOrCreateResource(getResourcePath("/r1")); |
| r1.getContents().clear(); |
| |
| // Set things up |
| Model1Factory factory = getModel1Factory(); |
| Order order1 = factory.createPurchaseOrder(); |
| Order order2 = factory.createPurchaseOrder(); |
| OrderDetail detail1 = factory.createOrderDetail(); |
| order1.getOrderDetails().add(detail1); |
| r1.getContents().add(order1); |
| r1.getContents().add(order2); |
| |
| // Commit so that everything gets a CDOID |
| tx.commit(); |
| |
| // Bring the resourceset under an editing domain |
| ResourceSet rs = tx.getResourceSet(); |
| AdapterFactory adapterFact = new ReflectiveItemProviderAdapterFactory(); |
| CommandStack cs = new SaneCommandStack(); |
| EditingDomain domain = new AdapterFactoryEditingDomain(adapterFact, cs, rs); |
| |
| float location = 0.5f; |
| int operations = 7; |
| int operation = 2; |
| Collection<OrderDetail> coll = Collections.singleton(detail1); |
| |
| assertSame(order1, detail1.eContainer()); |
| |
| // Drag and drop #1 |
| Command cmd = DragAndDropCommand.create(domain, order2, location, operations, operation, coll); |
| domain.getCommandStack().execute(cmd); |
| assertSame(order2, detail1.eContainer()); |
| |
| // Drag and drop #2 |
| cmd = DragAndDropCommand.create(domain, order1, location, operations, operation, coll); |
| domain.getCommandStack().execute(cmd); |
| assertSame(order1, detail1.eContainer()); |
| tx.commit(); |
| assertSame(order1, detail1.eContainer()); |
| |
| assertSame(CDOState.CLEAN, CDOUtil.getCDOObject(detail1).cdoState()); |
| |
| // Drag and drop #3 |
| cmd = DragAndDropCommand.create(domain, order2, location, operations, operation, coll); |
| domain.getCommandStack().execute(cmd); |
| assertSame(order2, detail1.eContainer()); |
| |
| tx.commit(); |
| tx.close(); |
| session.close(); |
| } |
| |
| public void testCanReattachDirtyObject() throws CommitException |
| { |
| CDOSession session = openSession(); |
| CDOTransaction tx = session.openTransaction(); |
| CDOResource r1 = tx.getOrCreateResource(getResourcePath("/r1")); |
| r1.getContents().clear(); |
| |
| // Set things up |
| Model1Factory factory = getModel1Factory(); |
| Order order1 = factory.createPurchaseOrder(); |
| Order order2 = factory.createPurchaseOrder(); |
| OrderDetail detail1 = factory.createOrderDetail(); |
| r1.getContents().add(order1); |
| r1.getContents().add(order2); |
| order1.getOrderDetails().add(detail1); |
| tx.commit(); |
| |
| // Make the order detail dirty |
| final float PRICE = 10.0f; |
| detail1.setPrice(PRICE); |
| |
| // Now move it |
| order1.getOrderDetails().remove(detail1); |
| order2.getOrderDetails().add(detail1); |
| tx.commit(); |
| |
| // See if the price update was incorporated in the commit |
| { |
| CDOView view = session.openView(); |
| CDOResource res = view.getResource(getResourcePath("/r1")); |
| Order order2prime = (Order)res.getContents().get(1); |
| OrderDetail od1 = order2prime.getOrderDetails().get(0); |
| assertEquals(PRICE, od1.getPrice()); |
| view.close(); |
| } |
| } |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| private static class SaneCommandStack extends BasicCommandStack |
| { |
| @Override |
| protected void handleError(Exception exception) |
| { |
| throw new WrappedException(exception); |
| } |
| } |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| private interface IClosure |
| { |
| public void test(EditingDomain domain, Collection<OrderDetail> details, Order target); |
| |
| public Collection<OrderDetail> pickDetails(OrderDetail[] orderDetails); |
| } |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| private static abstract class SingleItemClosure implements IClosure |
| { |
| public Collection<OrderDetail> pickDetails(OrderDetail[] orderDetails) |
| { |
| return Collections.singleton(orderDetails[0]); |
| } |
| } |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| private static abstract class MultiItemClosure implements IClosure |
| { |
| public Collection<OrderDetail> pickDetails(OrderDetail[] orderDetails) |
| { |
| List<OrderDetail> details = new LinkedList<OrderDetail>(); |
| details.add(orderDetails[0]); |
| details.add(orderDetails[1]); |
| return details; |
| } |
| } |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| private static abstract class MultiItemMultiParentClosure implements IClosure |
| { |
| public Collection<OrderDetail> pickDetails(OrderDetail[] orderDetails) |
| { |
| List<OrderDetail> details = new LinkedList<OrderDetail>(); |
| details.add(orderDetails[1]); |
| details.add(orderDetails[2]); |
| details.add(orderDetails[5]); |
| details.add(orderDetails[6]); |
| return details; |
| } |
| } |
| } |