blob: b8f54b0f785390ff8405855a9592182a74049c50 [file] [log] [blame]
/*
* Copyright (c) 2010-2013, 2016, 2017, 2020 Eike Stepper (Loehne, 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
* Stefan Winkler - additional tests
*/
package org.eclipse.emf.cdo.tests;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOObjectReference;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.util.EList;
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.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Bug 300149: Support remote cross referencing with a convenient API on the client and SPI on the server.
*
* @author Eike Stepper
* @since 4.0
*/
public class XRefTest extends AbstractCDOTest
{
@Override
protected void doSetUp() throws Exception
{
super.doSetUp();
skipStoreWithoutQueryXRefs();
}
public void testCrossReferenceMultivalueEReferenceQuery() throws Exception
{
CDOSession session1 = openSession();
CDOTransaction transaction = session1.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
Supplier supplier = getModel1Factory().createSupplier();
resource.getContents().add(supplier);
PurchaseOrder purchaseOrder1 = addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
assertResult(transaction, supplier, 4);
PurchaseOrder purchaseOrder5 = addPurchaseOrder(supplier);
PurchaseOrder purchaseOrder6 = addPurchaseOrder(supplier);
assertResult(transaction, supplier, 6);
EcoreUtil.delete(purchaseOrder5);
EcoreUtil.delete(purchaseOrder6);
assertResult(transaction, supplier, 4);
transaction.commit();
supplier.getPurchaseOrders().remove(purchaseOrder1);
assertResult(transaction, supplier, 3);
transaction.commit();
supplier.getPurchaseOrders().add(purchaseOrder1);
assertResult(transaction, supplier, 4);
transaction.commit();
/******************/
CDOSession session2 = openSession();
CDOView view = session2.openView();
assertResult(view, supplier, 4);
}
private void assertResult(CDOView view, EObject targetObject, int expectedXRefs)
{
List<CDOObjectReference> results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(targetObject)));
assertEquals(expectedXRefs, results.size());
for (CDOObjectReference result : results)
{
CDOObject sourceObject = result.getSourceObject();
assertInstanceOf(PurchaseOrder.class, CDOUtil.getEObject(sourceObject));
}
}
public void testLocallyDetachedTarget() throws Exception
{
CDOSession session1 = openSession();
CDOTransaction transaction = session1.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
Supplier supplier = getModel1Factory().createSupplier();
resource.getContents().add(supplier);
addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
addPurchaseOrder(supplier);
transaction.commit();
/******************/
CDOSession session2 = openSession();
CDOTransaction transaction2 = session2.openTransaction();
supplier = (Supplier)transaction2.getResource(getResourcePath("/test1")).getContents().remove(0);
List<CDOObjectReference> results = transaction2.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(supplier)));
assertEquals(4, results.size());
for (CDOObjectReference result : results)
{
CDOObject sourceObject = result.getSourceObject();
assertInstanceOf(PurchaseOrder.class, CDOUtil.getEObject(sourceObject));
}
}
@Skips(IRepositoryConfig.CAPABILITY_UNORDERED_LISTS)
@SuppressWarnings("unchecked")
public void testXRefsToMany() throws Exception
{
// create model
EPackage pkg = createUniquePackage();
EClass cls1 = EMFUtil.createEClass(pkg, "referencer", false, false);
EAttribute id1 = EMFUtil.createEAttribute(cls1, "id", EcorePackage.eINSTANCE.getEInt());
EClass cls2 = EMFUtil.createEClass(pkg, "referencee", false, false);
EAttribute id2 = EMFUtil.createEAttribute(cls2, "id", EcorePackage.eINSTANCE.getEInt());
EReference ref = EMFUtil.createEReference(cls1, "ref", cls2, false, true);
if (!isConfig(LEGACY))
{
CDOUtil.prepareDynamicEPackage(pkg);
}
// create instances
EObject obj2_1 = EcoreUtil.create(cls2);
obj2_1.eSet(id2, 11);
EObject obj2_2 = EcoreUtil.create(cls2);
obj2_2.eSet(id2, 12);
EObject obj2_3 = EcoreUtil.create(cls2);
obj2_3.eSet(id2, 13);
EObject obj2_4 = EcoreUtil.create(cls2);
obj2_4.eSet(id2, 14);
EObject obj1_1 = EcoreUtil.create(cls1);
obj1_1.eSet(id1, 1);
EObject obj1_2 = EcoreUtil.create(cls1);
obj1_2.eSet(id1, 2);
EObject obj1_3 = EcoreUtil.create(cls1);
obj1_3.eSet(id1, 3);
EObject obj1_4 = EcoreUtil.create(cls1);
obj1_4.eSet(id1, 4);
// configure references
((EList<EObject>)obj1_1.eGet(ref)).add(obj2_2);
((EList<EObject>)obj1_1.eGet(ref)).add(obj2_3);
((EList<EObject>)obj1_2.eGet(ref)).add(obj2_2);
((EList<EObject>)obj1_3.eGet(ref)).add(obj2_1);
((EList<EObject>)obj1_3.eGet(ref)).add(obj2_2);
// store objects
CDOSession session1 = openSession();
CDOTransaction transaction = session1.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
resource.getContents().addAll(Arrays.asList(obj1_1, obj1_2, obj1_3, obj1_4, obj2_1, obj2_2, obj2_3, obj2_4));
assertXRefsToMany(transaction, ref, obj2_1, obj2_2, obj2_3);
transaction.commit();
// check XRefs
CDOSession session2 = openSession();
CDOView view = session2.openView();
assertXRefsToMany(view, ref, obj2_1, obj2_2, obj2_3);
}
private void assertXRefsToMany(CDOView view, EReference ref, EObject obj2_1, EObject obj2_2, EObject obj2_3)
{
List<CDOObjectReference> results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_1)));
assertEquals(1, results.size());
{
CDOObjectReference result = results.get(0);
assertEquals(0, result.getSourceIndex());
assertEquals(ref.getName(), result.getSourceReference().getName());
CDOObject sourceObject = results.get(0).getSourceObject();
assertEquals(3, sourceObject.eGet(sourceObject.eClass().getEStructuralFeature("id")));
}
results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_3)));
assertEquals(1, results.size());
{
CDOObjectReference result = results.get(0);
assertEquals(1, result.getSourceIndex());
assertEquals(ref.getName(), result.getSourceReference().getName());
CDOObject sourceObject = results.get(0).getSourceObject();
assertEquals(1, sourceObject.eGet(sourceObject.eClass().getEStructuralFeature("id")));
}
results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_2)));
assertEquals(3, results.size());
boolean found1 = false;
boolean found2 = false;
boolean found3 = false;
for (CDOObjectReference result : results)
{
assertEquals(ref.getName(), results.get(0).getSourceReference().getName());
CDOObject sourceObject = result.getSourceObject();
Integer id = (Integer)sourceObject.eGet(sourceObject.eClass().getEStructuralFeature("id"));
switch (id.intValue())
{
case 1:
assertEquals(0, result.getSourceIndex());
found1 = true;
break;
case 2:
assertEquals(0, result.getSourceIndex());
found2 = true;
break;
case 3:
assertEquals(1, result.getSourceIndex());
found3 = true;
break;
default:
// must not happen!
assertEquals(true, false);
}
}
assertEquals(true, found1 && found2 && found3);
}
public void testXRefsToOne() throws Exception
{
// create model
EPackage pkg = createUniquePackage();
EClass cls1 = EMFUtil.createEClass(pkg, "referencer", false, false);
EAttribute id1 = EMFUtil.createEAttribute(cls1, "id", EcorePackage.eINSTANCE.getEInt());
EClass cls2 = EMFUtil.createEClass(pkg, "referencee", false, false);
EAttribute id2 = EMFUtil.createEAttribute(cls2, "id", EcorePackage.eINSTANCE.getEInt());
EReference ref = EMFUtil.createEReference(cls1, "ref", cls2, false, false);
if (!isConfig(LEGACY))
{
CDOUtil.prepareDynamicEPackage(pkg);
}
// create instances
EObject obj2_1 = EcoreUtil.create(cls2);
obj2_1.eSet(id2, 11);
EObject obj2_2 = EcoreUtil.create(cls2);
obj2_2.eSet(id2, 12);
EObject obj2_3 = EcoreUtil.create(cls2);
obj2_3.eSet(id2, 13);
EObject obj2_4 = EcoreUtil.create(cls2);
obj2_4.eSet(id2, 14);
EObject obj1_1 = EcoreUtil.create(cls1);
obj1_1.eSet(id1, 1);
EObject obj1_2 = EcoreUtil.create(cls1);
obj1_2.eSet(id1, 2);
EObject obj1_3 = EcoreUtil.create(cls1);
obj1_3.eSet(id1, 3);
EObject obj1_4 = EcoreUtil.create(cls1);
obj1_4.eSet(id1, 4);
// configure references
obj1_1.eSet(ref, obj2_2);
obj1_2.eSet(ref, obj2_2);
obj1_3.eSet(ref, obj2_3);
// store objects
CDOSession session1 = openSession();
CDOTransaction transaction = session1.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
resource.getContents().addAll(Arrays.asList(obj1_1, obj1_2, obj1_3, obj1_4, obj2_1, obj2_2, obj2_3, obj2_4));
assertXRefsToOne(transaction, ref, obj2_1, obj2_2, obj2_3);
transaction.commit();
// check XRefs
CDOSession session2 = openSession();
CDOView view = session2.openView();
assertXRefsToOne(view, ref, obj2_1, obj2_2, obj2_3);
}
private void assertXRefsToOne(CDOView view, EReference ref, EObject obj2_1, EObject obj2_2, EObject obj2_3)
{
List<CDOObjectReference> results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_1)));
assertEquals(true, results.isEmpty());
results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_3)));
assertEquals(1, results.size());
{
CDOObjectReference result = results.get(0);
assertEquals(0, result.getSourceIndex());
assertEquals(ref.getName(), result.getSourceReference().getName());
CDOObject sourceObject = results.get(0).getSourceObject();
assertEquals(3, sourceObject.eGet(sourceObject.eClass().getEStructuralFeature("id")));
}
results = view.queryXRefs(Collections.singleton(CDOUtil.getCDOObject(obj2_2)));
assertEquals(2, results.size());
boolean found1 = false;
boolean found2 = false;
for (CDOObjectReference result : results)
{
assertEquals(ref.getName(), results.get(0).getSourceReference().getName());
CDOObject sourceObject = result.getSourceObject();
Integer id = (Integer)sourceObject.eGet(sourceObject.eClass().getEStructuralFeature("id"));
assertEquals(true, id == 1 || id == 2);
assertEquals(0, result.getSourceIndex());
if (id == 1)
{
found1 = true;
}
else if (id == 2)
{
found2 = true;
}
}
assertEquals(true, found1 && found2);
}
@Skips(IRepositoryConfig.CAPABILITY_UNORDERED_LISTS)
@SuppressWarnings({ "unchecked", "unused" })
public void testSpecificReferences0() throws Exception
{
EClass a = EcoreFactory.eINSTANCE.createEClass();
a.setName("A");
EClass b = EcoreFactory.eINSTANCE.createEClass();
b.setName("B");
EReference aa1 = addReference(a, a, true);
EReference aa2 = addReference(a, a, true);
EReference aa3 = addReference(a, a, false);
EReference aa4 = addReference(a, a, false);
EReference ab5 = addReference(a, b, true);
EReference ab6 = addReference(a, b, true);
EReference ab7 = addReference(a, b, false);
EReference ab8 = addReference(a, b, false);
EReference ba1 = addReference(b, a, true);
EReference ba2 = addReference(b, a, true);
EReference ba3 = addReference(b, a, false);
EReference ba4 = addReference(b, a, false);
EReference bb5 = addReference(b, b, true);
EReference bb6 = addReference(b, b, true);
EReference bb7 = addReference(b, b, false);
EReference bb8 = addReference(b, b, false);
EPackage xref = createUniquePackage();
xref.getEClassifiers().add(a);
xref.getEClassifiers().add(b);
CDOSession session = openSession();
session.getPackageRegistry().putEPackage(xref);
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
EObject a1 = addObject(resource, a);
EObject a2 = addObject(resource, a);
EObject a3 = addObject(resource, a);
EObject a4 = addObject(resource, a);
EObject b1 = addObject(resource, b);
EObject b2 = addObject(resource, b);
EObject b3 = addObject(resource, b);
EObject b4 = addObject(resource, b);
((EList<EObject>)a1.eGet(ab5)).add(b1);
((EList<EObject>)a1.eGet(ab5)).add(b2);
((EList<EObject>)a1.eGet(ab5)).add(b3);
((EList<EObject>)a1.eGet(ab5)).add(b4);
((EList<EObject>)a1.eGet(ab6)).add(b1);
((EList<EObject>)a1.eGet(ab6)).add(b2);
((EList<EObject>)a1.eGet(ab6)).add(b3);
((EList<EObject>)a1.eGet(ab6)).add(b4);
for (int i = 0; i < 2; i++)
{
List<CDOObjectReference> results = transaction.queryXRefs(CDOUtil.getCDOObject(b1));
assertEquals(2, results.size());
assertEquals(0, results.get(0).getSourceIndex());
assertEquals(ab5, results.get(0).getSourceReference());
assertEquals(a1, results.get(0).getSourceObject());
assertEquals(b1, results.get(0).getTargetObject());
assertEquals(0, results.get(1).getSourceIndex());
assertEquals(ab6, results.get(1).getSourceReference());
assertEquals(a1, results.get(1).getSourceObject());
assertEquals(b1, results.get(1).getTargetObject());
transaction.commit();
}
}
@Skips(IRepositoryConfig.CAPABILITY_UNORDERED_LISTS)
@SuppressWarnings({ "unchecked", "unused" })
public void testSpecificReferences1() throws Exception
{
EClass a = EcoreFactory.eINSTANCE.createEClass();
a.setName("A");
EClass b = EcoreFactory.eINSTANCE.createEClass();
b.setName("B");
EReference aa1 = addReference(a, a, true);
EReference aa2 = addReference(a, a, true);
EReference aa3 = addReference(a, a, false);
EReference aa4 = addReference(a, a, false);
EReference ab5 = addReference(a, b, true);
EReference ab6 = addReference(a, b, true);
EReference ab7 = addReference(a, b, false);
EReference ab8 = addReference(a, b, false);
EReference ba1 = addReference(b, a, true);
EReference ba2 = addReference(b, a, true);
EReference ba3 = addReference(b, a, false);
EReference ba4 = addReference(b, a, false);
EReference bb5 = addReference(b, b, true);
EReference bb6 = addReference(b, b, true);
EReference bb7 = addReference(b, b, false);
EReference bb8 = addReference(b, b, false);
EPackage xref = createUniquePackage();
xref.getEClassifiers().add(a);
xref.getEClassifiers().add(b);
CDOSession session = openSession();
session.getPackageRegistry().putEPackage(xref);
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
EObject a1 = addObject(resource, a);
EObject a2 = addObject(resource, a);
EObject a3 = addObject(resource, a);
EObject a4 = addObject(resource, a);
EObject b1 = addObject(resource, b);
EObject b2 = addObject(resource, b);
EObject b3 = addObject(resource, b);
EObject b4 = addObject(resource, b);
((EList<EObject>)a1.eGet(ab5)).add(b1);
((EList<EObject>)a1.eGet(ab5)).add(b2);
((EList<EObject>)a1.eGet(ab5)).add(b3);
((EList<EObject>)a1.eGet(ab5)).add(b4);
((EList<EObject>)a1.eGet(ab6)).add(b1);
((EList<EObject>)a1.eGet(ab6)).add(b2);
((EList<EObject>)a1.eGet(ab6)).add(b3);
((EList<EObject>)a1.eGet(ab6)).add(b4);
for (int i = 0; i < 2; i++)
{
List<CDOObjectReference> results = transaction.queryXRefs(CDOUtil.getCDOObject(b1), ab5);
assertEquals(1, results.size());
assertEquals(0, results.get(0).getSourceIndex());
assertEquals(ab5, results.get(0).getSourceReference());
assertEquals(a1, results.get(0).getSourceObject());
assertEquals(b1, results.get(0).getTargetObject());
transaction.commit();
}
}
@Skips(IRepositoryConfig.CAPABILITY_UNORDERED_LISTS)
@SuppressWarnings({ "unchecked", "unused" })
public void testSpecificReferences2() throws Exception
{
EClass a = EcoreFactory.eINSTANCE.createEClass();
a.setName("A");
EClass b = EcoreFactory.eINSTANCE.createEClass();
b.setName("B");
EReference aa1 = addReference(a, a, true);
EReference aa2 = addReference(a, a, true);
EReference aa3 = addReference(a, a, false);
EReference aa4 = addReference(a, a, false);
EReference ab5 = addReference(a, b, true);
EReference ab6 = addReference(a, b, true);
EReference ab7 = addReference(a, b, false);
EReference ab8 = addReference(a, b, false);
EReference ba1 = addReference(b, a, true);
EReference ba2 = addReference(b, a, true);
EReference ba3 = addReference(b, a, false);
EReference ba4 = addReference(b, a, false);
EReference bb5 = addReference(b, b, true);
EReference bb6 = addReference(b, b, true);
EReference bb7 = addReference(b, b, false);
EReference bb8 = addReference(b, b, false);
EPackage xref = createUniquePackage();
xref.getEClassifiers().add(a);
xref.getEClassifiers().add(b);
CDOSession session = openSession();
session.getPackageRegistry().putEPackage(xref);
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
EObject a1 = addObject(resource, a);
EObject a2 = addObject(resource, a);
EObject a3 = addObject(resource, a);
EObject a4 = addObject(resource, a);
EObject b1 = addObject(resource, b);
EObject b2 = addObject(resource, b);
EObject b3 = addObject(resource, b);
EObject b4 = addObject(resource, b);
((EList<EObject>)a1.eGet(ab5)).add(b1);
((EList<EObject>)a1.eGet(ab5)).add(b2);
((EList<EObject>)a1.eGet(ab5)).add(b3);
((EList<EObject>)a1.eGet(ab5)).add(b4);
((EList<EObject>)a1.eGet(ab6)).add(b1);
((EList<EObject>)a1.eGet(ab6)).add(b2);
((EList<EObject>)a1.eGet(ab6)).add(b3);
((EList<EObject>)a1.eGet(ab6)).add(b4);
for (int i = 0; i < 2; i++)
{
List<CDOObjectReference> results = transaction.queryXRefs(CDOUtil.getCDOObject(b1), ab6);
assertEquals(1, results.size());
assertEquals(0, results.get(0).getSourceIndex());
assertEquals(ab6, results.get(0).getSourceReference());
assertEquals(a1, results.get(0).getSourceObject());
assertEquals(b1, results.get(0).getTargetObject());
transaction.commit();
}
}
private PurchaseOrder addPurchaseOrder(Supplier supplier)
{
PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
supplier.getPurchaseOrders().add(purchaseOrder);
supplier.eResource().getContents().add(purchaseOrder);
return purchaseOrder;
}
private static EObject addObject(CDOResource resource, EClass eClass)
{
EObject object = EcoreUtil.create(eClass);
resource.getContents().add(object);
return object;
}
private static EReference addReference(EClass source, EClass target, boolean many)
{
EReference reference = EcoreFactory.eINSTANCE.createEReference();
EList<EStructuralFeature> features = source.getEStructuralFeatures();
features.add(reference);
reference.setName(target.getName().toLowerCase() + features.size());
reference.setEType(target);
reference.setUpperBound(many ? -1 : 1);
return reference;
}
}