/*
* Copyright (c) 2015 Guillaume Hillairet.
* 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:
* Guillaume Hillairet - initial API and implementation
*
*/
package org.emfjson.jackson.tests;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
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.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.emfjson.jackson.junit.model.*;
import org.emfjson.jackson.junit.model.impl.PhysicalNodeImpl;
import org.emfjson.jackson.support.StandardFixture;
import org.junit.ClassRule;
import org.junit.Test;
import java.io.IOException;
import static org.emfjson.jackson.databind.EMFContext.Attributes.RESOURCE_SET;
import static org.junit.Assert.*;
public class ContainmentTest {
@ClassRule
public static StandardFixture fixture = new StandardFixture();
private ObjectMapper mapper = fixture.mapper();
private ResourceSet resourceSet = fixture.getResourceSet();
@Test
public void testSaveOneRootObjectWithAttributes() throws IOException {
JsonNode expected = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//User")
.put("userId", "1")
.put("name", "John");
User user = ModelFactory.eINSTANCE.createUser();
user.setUserId("1");
user.setName("John");
Resource resource = resourceSet.createResource(URI.createURI("tests/test-save-1.json"));
assertNotNull(resource);
resource.getContents().add(user);
assertEquals(expected, mapper.valueToTree(resource));
}
@Test
public void testSaveTwoRootObjectsWithAttributesNoReferences() throws IOException {
JsonNode expected = mapper.createArrayNode()
.add(mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//User")
.put("userId", "1")
.put("name", "John"))
.add(mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//User")
.put("userId", "2")
.put("name", "Mary")
.put("sex", "FEMALE"));
User user1 = ModelFactory.eINSTANCE.createUser();
user1.setUserId("1");
user1.setName("John");
User user2 = ModelFactory.eINSTANCE.createUser();
user2.setUserId("2");
user2.setName("Mary");
user2.setSex(Sex.FEMALE);
Resource resource = resourceSet.createResource(URI.createURI("tests/test-save-2.json"));
resource.getContents().add(user1);
resource.getContents().add(user2);
assertEquals(expected, mapper.valueToTree(resource));
}
@Test
public void testSaveOneObjectWithOneChild() throws JsonProcessingException {
JsonNode expected = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//User")
.set("address", mapper.createObjectNode());
Resource resource = resourceSet.createResource(URI.createURI("test"));
User user = ModelFactory.eINSTANCE.createUser();
Address address = ModelFactory.eINSTANCE.createAddress();
user.setAddress(address);
resource.getContents().add(user);
assertEquals(expected, mapper.valueToTree(resource));
}
@Test
public void testLoadOneObjectWithOneChild() throws JsonProcessingException {
JsonNode data = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//User")
.set("address", mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Address"));
Resource resource = mapper.reader()
.withAttribute(RESOURCE_SET, resourceSet)
.treeToValue(data, Resource.class);
assertNotNull(resource);
assertEquals(1, resource.getContents().size());
User user = (User) resource.getContents().get(0);
assertNotNull(user.getAddress());
}
@Test
public void testSaveOneObjectWithManyChildren() throws JsonProcessingException {
JsonNode expected = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Node")
.set("child", mapper.createArrayNode()
.add(mapper.createObjectNode())
.add(mapper.createObjectNode())
.add(mapper.createObjectNode()));
Resource resource = resourceSet.createResource(URI.createURI("test"));
Node root = ModelFactory.eINSTANCE.createNode();
root.getChild().add(ModelFactory.eINSTANCE.createNode());
root.getChild().add(ModelFactory.eINSTANCE.createNode());
root.getChild().add(ModelFactory.eINSTANCE.createNode());
resource.getContents().add(root);
assertEquals(expected, mapper.valueToTree(resource));
}
@Test
public void testLoadOneObjectWithManyChildren() throws JsonProcessingException {
JsonNode data = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Node")
.set("child", mapper.createArrayNode()
.add(mapper.createObjectNode())
.add(mapper.createObjectNode())
.add(mapper.createObjectNode()));
Resource resource = mapper.reader()
.withAttribute(RESOURCE_SET, resourceSet)
.treeToValue(data, Resource.class);
assertNotNull(resource);
assertEquals(1, resource.getContents().size());
Node node = (Node) resource.getContents().get(0);
assertEquals(3, node.getChild().size());
}
@Test
public void testSaveProxyContainment() throws IOException {
// proxy.json
JsonNode expectedProxyResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Node")
.put("label", "1");
// proxyLink.json
JsonNode expectedProxyLinkResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Node")
.put("label", "2")
.set("child", mapper.createArrayNode()
.add(mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//Node")
.put("$ref", "proxy.json#/")));
Resource resourceProxy = resourceSet.createResource(URI.createURI("proxy.json"));
Resource resourceProxyLink = resourceSet.createResource(URI.createURI("proxyLink.json"));
Node linked = ModelFactory.eINSTANCE.createNode();
linked.setLabel("1");
resourceProxy.getContents().add(linked);
Node container = ModelFactory.eINSTANCE.createNode();
container.setLabel("2");
container.getChild().add(linked);
resourceProxyLink.getContents().add(container);
assertSame(resourceProxy, linked.eResource());
assertSame(container, linked.eContainer());
assertSame(ModelPackage.Literals.NODE__CHILD, linked.eContainmentFeature());
assertTrue(ModelPackage.Literals.NODE__CHILD.isContainment());
assertTrue(ModelPackage.Literals.NODE__CHILD.isResolveProxies());
assertSame(resourceProxyLink, container.eResource());
assertEquals(expectedProxyResource, mapper.valueToTree(resourceProxy));
assertEquals(expectedProxyLinkResource, mapper.valueToTree(resourceProxyLink));
}
@Test
public void testSaveProxyRootContainmentWithOppositeReference() throws IOException {
JsonNode expectedTargetResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//TargetObject")
.put("singleAttribute", "Foo");
JsonNode expectedSourceResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//PrimaryObject")
.put("name", "TheSource")
.set("singleContainmentReferenceProxies", mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//TargetObject")
.put("$ref", "target.json#/"));
Resource resourceTarget = resourceSet.createResource(URI.createURI("target.json"));
TargetObject target = ModelFactory.eINSTANCE.createTargetObject();
target.setSingleAttribute("Foo");
resourceTarget.getContents().add(target);
Resource resourceSource = resourceSet.createResource(URI.createURI("source.json"));
PrimaryObject source = ModelFactory.eINSTANCE.createPrimaryObject();
source.setName("TheSource");
resourceSource.getContents().add(source);
// setting the opposite reference will set the containment
target.setSingleReferenceNotResolveProxies(source);
assertSame(source, target.eContainer());
assertSame(ModelPackage.Literals.PRIMARY_OBJECT__SINGLE_CONTAINMENT_REFERENCE_PROXIES, target.eContainingFeature());
assertSame(resourceTarget, target.eResource());
assertEquals(expectedTargetResource, mapper.valueToTree(resourceTarget));
assertEquals(expectedSourceResource, mapper.valueToTree(resourceSource));
}
@Test
public void testSaveProxies() throws IOException {
JsonNode expectedTargetResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//TargetObject")
.set("manyReferences", mapper.createArrayNode()
.add(
mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//PrimaryObject")
.put("$ref", "source.json#/")));
JsonNode expectedSourceResource = mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//PrimaryObject")
.put("name", "TheSource")
.set("singleContainmentReferenceNoProxies", mapper.createObjectNode()
.put("eClass", "http://www.emfjson.org/jackson/model#//TargetObject")
.put("$ref", "target.json#/"));
Resource resourceTarget = resourceSet.createResource(URI.createURI("target.json"));
Resource resourceSource = resourceSet.createResource(URI.createURI("source.json"));
TargetObject target = ModelFactory.eINSTANCE.createTargetObject();
resourceTarget.getContents().add(target);
PrimaryObject source = ModelFactory.eINSTANCE.createPrimaryObject();
source.setName("TheSource");
resourceSource.getContents().add(source);
PrimaryObject sourceProxy = ModelFactory.eINSTANCE.createPrimaryObject();
((InternalEObject) sourceProxy).eSetProxyURI(EcoreUtil.getURI(source));
target.getManyReferences().add(sourceProxy);
TargetObject targetProxy = ModelFactory.eINSTANCE.createTargetObject();
((InternalEObject) targetProxy).eSetProxyURI(EcoreUtil.getURI(target));
source.setSingleContainmentReferenceNoProxies(targetProxy);
assertSame(source, targetProxy.eContainer());
assertSame(ModelPackage.Literals.PRIMARY_OBJECT__SINGLE_CONTAINMENT_REFERENCE_NO_PROXIES, targetProxy.eContainingFeature());
assertSame(resourceTarget, target.eResource());
assertEquals(expectedTargetResource, mapper.valueToTree(resourceTarget));
assertEquals(expectedSourceResource, mapper.valueToTree(resourceSource));
}
@Test
public void testLoadProxyRootContainmentWithOppositeReference() throws IOException {
Resource resource = resourceSet.getResource(URI.createURI("src/test/resources/tests/test-proxy-6.json"), true);
assertEquals(1, resource.getContents().size());
assertTrue(resource.getContents().get(0) instanceof PrimaryObject);
PrimaryObject source = (PrimaryObject) resource.getContents().get(0);
assertEquals("TheSource", source.getName());
assertTrue(source.eIsSet(ModelPackage.Literals.PRIMARY_OBJECT__SINGLE_CONTAINMENT_REFERENCE_PROXIES));
TargetObject target = source.getSingleContainmentReferenceProxies();
assertFalse(target.eIsProxy());
assertSame(source, target.getSingleReferenceNotResolveProxies());
assertSame(source, target.eContainer());
assertSame(ModelPackage.Literals.PRIMARY_OBJECT__SINGLE_CONTAINMENT_REFERENCE_PROXIES, target.eContainingFeature());
assertNotSame(source.eResource(), target.eResource());
}
@Test
public void testLoadResolvingProxyContainment() throws IOException {
Resource resource = resourceSet.getResource(
URI.createURI("src/test/resources/tests/test-proxy-5b.json"), true);
assertFalse(resource.getContents().isEmpty());
assertEquals(1, resource.getContents().size());
Node root = (Node) resource.getContents().get(0);
assertEquals("2", root.getLabel());
assertEquals(1, root.getChild().size());
Node child = root.getChild().get(0);
// Proxy is resolved because GenModel.ContainmentProxy is true
assertFalse(child.eIsProxy());
assertNotSame(root.eResource(), child.eResource());
assertEquals("1", child.getLabel());
}
@Test
public void testLoadResolvingProxyContainmentWithAbstract() throws IOException {
Resource resource = resourceSet.getResource(
URI.createURI("src/test/resources/tests/test-proxy-7b.json"), true);
assertFalse(resource.getContents().isEmpty());
assertEquals(1, resource.getContents().size());
PhysicalNodeImpl root = (PhysicalNodeImpl) resource.getContents().get(0);
assertEquals("2", root.getLabel());
assertEquals(1, root.getChild().size());
AbstractNode child = root.getChild().get(0);
assertTrue(child.eIsProxy());
assertSame(root.eResource(), child.eResource());
EObject resolve = EcoreUtil.resolve(child, resourceSet);
assertNotSame(resolve.eResource(), root.eResource());
}
@Test
public void testXmi1() throws IOException {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(ModelPackage.eNS_URI, ModelPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap()
.put("xmi", new XMIResourceFactoryImpl());
{
Resource x1 = resourceSet.createResource(URI.createURI("src/test/resources/xmi/test3.xmi"));
Node n1 = ModelFactory.eINSTANCE.createNode();
Node n2 = ModelFactory.eINSTANCE.createNode();
Node n3 = ModelFactory.eINSTANCE.createNode();
n1.getChild().add(n2);
n1.getChild().add(n3);
n2.setTarget(n3);
n2.getManyRef().add(n3);
x1.getContents().add(n1);
x1.save(null);
}
{
Resource x1 = resourceSet.createResource(URI.createFileURI("src/test/resources/xmi/test4.xmi"));
Resource x2 = resourceSet.createResource(URI.createFileURI("src/test/resources/xmi/test5.xmi"));
Resource x3 = resourceSet.createResource(URI.createFileURI("src/test/resources/xmi/test6.xmi"));
User n1 = ModelFactory.eINSTANCE.createUser();
n1.setUserId("1");
User n2 = ModelFactory.eINSTANCE.createUser();
n2.setUserId("2");
User n3 = ModelFactory.eINSTANCE.createUser();
n3.setUserId("3");
n1.setUniqueFriend(n2);
n1.getFriends().add(n2);
n1.getFriends().add(n3);
x1.getContents().add(n1);
x2.getContents().add(n2);
x3.getContents().add(n3);
x1.save(null);
x2.save(null);
x3.save(null);
}
}
// @Test
public void testXmi() throws IOException {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(ModelPackage.eNS_URI, ModelPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap()
.put("xmi", new XMIResourceFactoryImpl());
Resource x1 = resourceSet.createResource(URI.createURI("src/test/resources/xmi/test1.xmi"));
Resource x2 = resourceSet.createResource(URI.createURI("src/test/resources/xmi/test2.xmi"));
PhysicalNode p1 = ModelFactory.eINSTANCE.createPhysicalNode();
p1.setLabel("p1");
x1.getContents().add(p1);
PhysicalNode p2 = ModelFactory.eINSTANCE.createPhysicalNode();
p2.setLabel("p2");
x2.getContents().add(p2);
InternalEObject proxy = (InternalEObject) ModelFactory.eINSTANCE.createPhysicalNode();
proxy.eSetProxyURI(EcoreUtil.getURI(p2));
p1.getChild().add((AbstractNode) proxy);
x2.save(null);
x1.save(null);
}
// @Test
public void testLoadXmi() throws IOException {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(ModelPackage.eNS_URI, ModelPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap()
.put("xmi", new XMIResourceFactoryImpl());
Resource x1 = resourceSet.getResource(URI.createURI("src/test/resources/xmi/test1.xmi"), true);
assertEquals(1, x1.getContents().size());
PhysicalNode p1 = (PhysicalNode) x1.getContents().get(0);
AbstractNode p2 = p1.getChild().get(0);
assertTrue(p2.eIsProxy());
assertSame(p2.eResource(), p1.eResource());
EObject resolve = EcoreUtil.resolve(p2, resourceSet);
assertNotSame(resolve.eResource(), p1.eResource());
}
}