| /* |
| * Copyright (c) 2007-2014 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.tests; |
| |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.tests.model1.Address; |
| import org.eclipse.emf.cdo.tests.model1.Category; |
| import org.eclipse.emf.cdo.tests.model1.Company; |
| import org.eclipse.emf.cdo.tests.model1.Model1Factory; |
| import org.eclipse.emf.cdo.tests.model1.Order; |
| import org.eclipse.emf.cdo.tests.model1.Supplier; |
| import org.eclipse.emf.cdo.tests.model2.PersistentContainment; |
| import org.eclipse.emf.cdo.tests.model2.SpecialPurchaseOrder; |
| import org.eclipse.emf.cdo.tests.model2.Task; |
| import org.eclipse.emf.cdo.tests.model2.TaskContainer; |
| import org.eclipse.emf.cdo.tests.model2.TransientContainer; |
| 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.DanglingReferenceException; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; |
| import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class ContainmentTest extends AbstractCDOTest |
| { |
| public void testTransientContainment() throws Exception |
| { |
| msg("Creating supplier"); |
| Supplier supplier = getModel1Factory().createSupplier(); |
| |
| msg("Setting name"); |
| supplier.setName("Stepper"); |
| |
| msg("Creating company"); |
| Company company = getModel1Factory().createCompany(); |
| |
| msg("Adding supplier"); |
| company.getSuppliers().add(supplier); |
| |
| assertTransient(company); |
| assertTransient(supplier); |
| assertContent(company, supplier); |
| } |
| |
| public void testBasicContainment() throws Exception |
| { |
| msg("Creating supplier"); |
| Supplier supplier = getModel1Factory().createSupplier(); |
| |
| msg("Setting name"); |
| supplier.setName("Stepper"); |
| |
| msg("Creating company"); |
| Company company = getModel1Factory().createCompany(); |
| |
| msg("Adding supplier"); |
| company.getSuppliers().add(supplier); |
| |
| msg("Opening session"); |
| CDOSession session = openSession(); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Creating resource"); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| msg("Adding company"); |
| resource.getContents().add(company); |
| |
| msg("Committing"); |
| transaction.commit(); |
| |
| assertClean(resource, transaction); |
| assertClean(company, transaction); |
| assertClean(supplier, transaction); |
| assertContent(resource, company); |
| assertContent(company, supplier); |
| } |
| |
| public void test3Levels() throws Exception |
| { |
| msg("Creating category1"); |
| Category category1 = getModel1Factory().createCategory(); |
| category1.setName("category1"); |
| |
| msg("Creating category2"); |
| Category category2 = getModel1Factory().createCategory(); |
| category2.setName("category2"); |
| |
| msg("Creating category3"); |
| Category category3 = getModel1Factory().createCategory(); |
| category3.setName("category3"); |
| |
| msg("Creating company"); |
| Company company = getModel1Factory().createCompany(); |
| |
| msg("Adding categories"); |
| company.getCategories().add(category1); |
| category1.getCategories().add(category2); |
| category2.getCategories().add(category3); |
| |
| msg("Opening session"); |
| CDOSession session = openSession(); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Creating resource"); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| msg("Adding company"); |
| resource.getContents().add(company); |
| |
| msg("Committing"); |
| transaction.commit(); |
| |
| assertClean(resource, transaction); |
| assertClean(company, transaction); |
| assertClean(category1, transaction); |
| assertClean(category2, transaction); |
| assertClean(category3, transaction); |
| assertContent(resource, company); |
| assertContent(company, category1); |
| assertContent(category1, category2); |
| assertContent(category2, category3); |
| } |
| |
| public void testSeparateView() throws Exception |
| { |
| msg("Opening session"); |
| CDOSession session = openSession(); |
| |
| { |
| msg("Creating category1"); |
| Category category1 = getModel1Factory().createCategory(); |
| category1.setName("category1"); |
| |
| msg("Creating category2"); |
| Category category2 = getModel1Factory().createCategory(); |
| category2.setName("category2"); |
| |
| msg("Creating category3"); |
| Category category3 = getModel1Factory().createCategory(); |
| category3.setName("category3"); |
| |
| msg("Creating company"); |
| Company company = getModel1Factory().createCompany(); |
| |
| msg("Adding categories"); |
| company.getCategories().add(category1); |
| category1.getCategories().add(category2); |
| category2.getCategories().add(category3); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Creating resource"); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| msg("Adding company"); |
| resource.getContents().add(company); |
| |
| msg("Committing"); |
| transaction.commit(); |
| } |
| |
| clearCache(getRepository().getRevisionManager()); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Loading resource"); |
| CDOResource resource = transaction.getResource(getResourcePath("/test1")); |
| assertProxy(resource); |
| |
| EList<EObject> contents = resource.getContents(); |
| Company company = (Company)contents.get(0); |
| assertClean(company, transaction); |
| assertClean(resource, transaction); |
| assertContent(resource, company); |
| |
| Category category1 = company.getCategories().get(0); |
| assertClean(category1, transaction); |
| assertClean(company, transaction); |
| assertContent(company, category1); |
| |
| Category category2 = category1.getCategories().get(0); |
| assertClean(category2, transaction); |
| assertClean(category1, transaction); |
| assertContent(category1, category2); |
| |
| Category category3 = category2.getCategories().get(0); |
| assertClean(category3, transaction); |
| assertClean(category2, transaction); |
| assertContent(category2, category3); |
| assertClean(category3, transaction); |
| } |
| |
| public void testSeparateSession() throws Exception |
| { |
| { |
| msg("Opening session"); |
| CDOSession session = openSession(); |
| |
| msg("Creating category1"); |
| Category category1 = getModel1Factory().createCategory(); |
| category1.setName("category1"); |
| |
| msg("Creating category2"); |
| Category category2 = getModel1Factory().createCategory(); |
| category2.setName("category2"); |
| |
| msg("Creating category3"); |
| Category category3 = getModel1Factory().createCategory(); |
| category3.setName("category3"); |
| |
| msg("Creating company"); |
| Company company = getModel1Factory().createCompany(); |
| |
| msg("Adding categories"); |
| company.getCategories().add(category1); |
| category1.getCategories().add(category2); |
| category2.getCategories().add(category3); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Creating resource"); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| msg("Adding company"); |
| resource.getContents().add(company); |
| |
| msg("Committing"); |
| transaction.commit(); |
| } |
| |
| clearCache(getRepository().getRevisionManager()); |
| |
| msg("Opening session"); |
| CDOSession session = openSession(); |
| |
| msg("Opening transaction"); |
| CDOTransaction transaction = session.openTransaction(); |
| |
| msg("Loading resource"); |
| CDOResource resource = transaction.getResource(getResourcePath("/test1")); |
| assertProxy(resource); |
| |
| EList<EObject> contents = resource.getContents(); |
| Company company = (Company)contents.get(0); |
| assertClean(company, transaction); |
| assertClean(resource, transaction); |
| assertContent(resource, company); |
| |
| Category category1 = company.getCategories().get(0); |
| assertClean(category1, transaction); |
| assertClean(company, transaction); |
| assertContent(company, category1); |
| |
| Category category2 = category1.getCategories().get(0); |
| assertClean(category2, transaction); |
| assertClean(category1, transaction); |
| assertContent(category1, category2); |
| |
| Category category3 = category2.getCategories().get(0); |
| assertClean(category3, transaction); |
| assertClean(category2, transaction); |
| assertContent(category2, category3); |
| assertClean(category3, transaction); |
| } |
| |
| public void testSetSingleContainment() throws Exception |
| { |
| Address address = getModel1Factory().createAddress(); |
| address.setName("Stepper"); |
| address.setStreet("Home Ave. 007"); |
| address.setCity("Berlin"); |
| |
| SpecialPurchaseOrder order = getModel2Factory().createSpecialPurchaseOrder(); |
| order.setShippingAddress(address); |
| |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| resource.getContents().add(order); |
| transaction.commit(); |
| |
| assertClean(resource, transaction); |
| assertClean(order, transaction); |
| assertClean(address, transaction); |
| assertContent(resource, order); |
| assertContent(order, address); |
| } |
| |
| public void testUnsetSingleContainment() throws Exception |
| { |
| Address address = getModel1Factory().createAddress(); |
| address.setName("Stepper"); |
| address.setStreet("Home Ave. 007"); |
| address.setCity("Berlin"); |
| |
| SpecialPurchaseOrder order = getModel2Factory().createSpecialPurchaseOrder(); |
| order.setShippingAddress(address); |
| |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/test1")); |
| |
| resource.getContents().add(order); |
| transaction.commit(); |
| |
| order.setShippingAddress(null); |
| transaction.commit(); |
| |
| assertClean(resource, transaction); |
| assertClean(order, transaction); |
| assertTransient(address); |
| assertContent(resource, order); |
| assertNull(order.getShippingAddress()); |
| } |
| |
| public void testObjectNotSameResourceThanItsContainerCDO() throws Exception |
| { |
| { |
| CDOSession session = openSession(); |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| |
| CDOTransaction transaction = session.openTransaction(resourceSet); |
| Resource resource1 = transaction.createResource(getResourcePath("testA")); |
| Resource resource2 = transaction.createResource(getResourcePath("testB")); |
| |
| EPackage packageObject = createDynamicEPackage(); |
| session.getPackageRegistry().putEPackage(packageObject); |
| EClass eClass = (EClass)packageObject.getEClassifier("SchoolBook"); |
| |
| EObject container = packageObject.getEFactoryInstance().create(eClass); |
| Order contained = getModel1Factory().createPurchaseOrder(); |
| |
| resource1.getContents().add(container); |
| resource2.getContents().add(contained); |
| |
| container.eSet(container.eClass().getEStructuralFeature("proxyElement"), contained); |
| |
| assertEquals(resource1, container.eResource()); |
| assertEquals(resource2, contained.eResource()); |
| |
| // If the relationship is define has resolveProxy this is true if not.. this is false. |
| assertEquals(container, contained.eContainer()); |
| transaction.commit(); |
| } |
| |
| clearCache(getRepository().getRevisionManager()); |
| |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(resourceSet); |
| Resource resource1 = transaction.getResource(getResourcePath("testA")); |
| Resource resource2 = transaction.getResource(getResourcePath("testB")); |
| |
| EObject container = resource1.getContents().get(0); |
| Order order = (Order)resource2.getContents().get(0); |
| |
| assertEquals(resource1.getContents().get(0), order.eContainer()); |
| resource2.getContents().remove(order); |
| |
| Order order2 = (Order)CDOUtil.getEObject((EObject)container.eGet(container.eClass().getEStructuralFeature( |
| "proxyElement"))); |
| assertSame(order, order2); |
| } |
| |
| public void testObjectNotSameResourceThanItsContainer_WithoutCDO() throws Exception |
| { |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| |
| resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl()); |
| |
| Resource resource1 = resourceSet.createResource(URI.createURI("test://1")); |
| Resource resource2 = resourceSet.createResource(URI.createURI("test://2")); |
| EPackage packageObject = createDynamicEPackage(); |
| EClass eClass = (EClass)packageObject.getEClassifier("SchoolBook"); |
| |
| EObject container = packageObject.getEFactoryInstance().create(eClass); |
| EObject contained = packageObject.getEFactoryInstance().create(eClass); |
| |
| resource1.getContents().add(container); |
| resource2.getContents().add(contained); |
| |
| container.eSet(container.eClass().getEStructuralFeature("proxyElement"), contained); |
| // resource1.getContents().add(container); |
| |
| assertEquals(resource1, container.eResource()); |
| assertEquals(resource2, contained.eResource()); |
| |
| // If the relationship is define has resolveProxy this is true if not.. this is false. |
| assertEquals(container, contained.eContainer()); |
| } |
| |
| public void testModeledBackPointer() throws Exception |
| { |
| Task task = getModel2Factory().createTask(); |
| task.setDescription("Task 1"); |
| |
| TaskContainer taskContainer = getModel2Factory().createTaskContainer(); |
| taskContainer.getTasks().add(task); |
| assertEquals(taskContainer, task.eContainer()); |
| assertEquals(taskContainer, task.getTaskContainer()); |
| |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/resource1")); |
| resource.getContents().add(taskContainer); |
| |
| transaction.commit(); |
| assertEquals(taskContainer, task.eContainer()); |
| assertEquals(taskContainer, task.getTaskContainer()); |
| session.close(); |
| } |
| |
| public void testModeledBackPointer_Transient() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/resource1")); |
| |
| PersistentContainment parent1 = createPersistentContainment(); |
| parent1.getChildren().add(createTransientContainer()); |
| parent1.getChildren().add(createTransientContainer()); |
| parent1.getChildren().add(createTransientContainer()); |
| resource.getContents().add(parent1); |
| transaction.commit(); |
| |
| // Move child |
| PersistentContainment parent2 = createPersistentContainment(); |
| parent2.getChildren().add(parent1.getChildren().get(0)); |
| transaction.commit(); |
| |
| // Remove child |
| parent1.getChildren().remove(0); |
| transaction.commit(); |
| |
| // Remove child |
| parent1.getChildren().remove(0); |
| transaction.commit(); |
| } |
| |
| public void testModeledBackPointer_Transient_Load() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/resource1")); |
| |
| PersistentContainment parent1 = createPersistentContainment(); |
| parent1.getChildren().add(createTransientContainer()); |
| parent1.getChildren().add(createTransientContainer()); |
| parent1.getChildren().add(createTransientContainer()); |
| resource.getContents().add(parent1); |
| transaction.commit(); |
| |
| session.close(); |
| session = openSession(); |
| transaction = session.openTransaction(); |
| resource = transaction.getResource(getResourcePath("/resource1")); |
| parent1 = (PersistentContainment)resource.getContents().get(0); |
| |
| // Move child |
| PersistentContainment parent2 = createPersistentContainment(); |
| parent2.getChildren().add(parent1.getChildren().get(0)); |
| transaction.commit(); |
| |
| // Remove child |
| parent1.getChildren().remove(0); |
| transaction.commit(); |
| |
| // Remove child |
| parent1.getChildren().remove(0); |
| transaction.commit(); |
| } |
| |
| private PersistentContainment createPersistentContainment() |
| { |
| PersistentContainment result = getModel2Factory().createPersistentContainment(); |
| result.setAttrBefore("BEFORE"); |
| result.setAttrAfter("AFTER"); |
| return result; |
| } |
| |
| private TransientContainer createTransientContainer() |
| { |
| TransientContainer result = getModel2Factory().createTransientContainer(); |
| result.setAttrBefore("BEFORE"); |
| result.setAttrAfter("AFTER"); |
| return result; |
| } |
| |
| private EPackage createDynamicEPackage() |
| { |
| final EcoreFactory efactory = EcoreFactory.eINSTANCE; |
| final EcorePackage epackage = EcorePackage.eINSTANCE; |
| |
| EClass schoolBookEClass = efactory.createEClass(); |
| schoolBookEClass.setName("SchoolBook"); |
| |
| // create a new attribute for this EClass |
| EAttribute level = efactory.createEAttribute(); |
| level.setName("level"); |
| level.setEType(epackage.getEInt()); |
| schoolBookEClass.getEStructuralFeatures().add(level); |
| |
| EReference proxyElement = efactory.createEReference(); |
| proxyElement.setName("proxyElement"); |
| proxyElement.setEType(epackage.getEObject()); |
| proxyElement.setResolveProxies(true); |
| proxyElement.setContainment(true); |
| schoolBookEClass.getEStructuralFeatures().add(proxyElement); |
| |
| EReference element = efactory.createEReference(); |
| element.setName("element"); |
| element.setEType(epackage.getEObject()); |
| element.setContainment(true); |
| element.setResolveProxies(false); |
| schoolBookEClass.getEStructuralFeatures().add(element); |
| |
| // Create a new EPackage and add the new EClasses |
| EPackage schoolPackage = createUniquePackage(); |
| schoolPackage.getEClassifiers().add(schoolBookEClass); |
| if (!isConfig(LEGACY)) |
| { |
| CDOUtil.prepareDynamicEPackage(schoolPackage); |
| } |
| |
| return schoolPackage; |
| } |
| |
| public void testRemovedContainment() throws Exception |
| { |
| CDOSession session = openSession(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.getOrCreateResource(getResourcePath("res1")); |
| EList<EObject> contents = resource.getContents(); |
| |
| Company company = getModel1Factory().createCompany(); |
| contents.add(company); |
| |
| Category category = getModel1Factory().createCategory(); |
| company.getCategories().add(category); |
| |
| Supplier supplier = getModel1Factory().createSupplier(); |
| supplier.setName("supplier" + System.currentTimeMillis()); |
| contents.add(supplier); |
| |
| EList<Supplier> suppliers = company.getSuppliers(); |
| suppliers.add(supplier); |
| |
| // "Control" all company contents (supplier + category) to resource contents. |
| // These two objects now have eContainer and eDirectResource set |
| contents.addAll(company.eContents()); |
| |
| // Detach the eContainer of supplier + category |
| contents.remove(company); |
| |
| try |
| { |
| transaction.commit(); |
| fail("CommitException expected"); |
| } |
| catch (CommitException expected) |
| { |
| assertInstanceOf(DanglingReferenceException.class, expected.getCause()); |
| } |
| |
| // Unset eContainer of supplier + category |
| company.getSuppliers().remove(supplier); |
| company.getCategories().remove(category); |
| |
| transaction.commit(); |
| } |
| |
| public void testContainmentChangeInSameResource() |
| { |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("model1", new Resource.Factory() |
| { |
| public Resource createResource(URI uri) |
| { |
| return new XMIResourceImpl(uri) |
| { |
| @Override |
| protected boolean useUUIDs() |
| { |
| return true; |
| } |
| }; |
| } |
| }); |
| |
| Category category1 = Model1Factory.eINSTANCE.createCategory(); |
| Category category2 = Model1Factory.eINSTANCE.createCategory(); |
| |
| Company company = Model1Factory.eINSTANCE.createCompany(); |
| company.getCategories().add(category1); |
| company.getCategories().add(category2); |
| |
| Resource resource = resourceSet.createResource(URI.createURI("test.model1", true)); |
| resource.getContents().add(company); |
| |
| String originalID = resource.getURIFragment(category2); |
| |
| // Change object of containment feature |
| category1.getCategories().add(category2); |
| assertEquals("The id of the object changed while it should not", originalID, resource.getURIFragment(category2)); |
| } |
| } |