blob: ade5b4eef0a5a60d9403c4b96f8e5e30078d1d5f [file] [log] [blame]
/*
* 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));
}
}