/* * 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.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.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.emfjson.jackson.junit.model.*; import org.emfjson.jackson.junit.model.impl.PrimaryObjectImpl; import org.emfjson.jackson.support.StandardFixture; import org.junit.ClassRule; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Paths; import static org.assertj.core.api.Assertions.assertThat; import static org.emfjson.jackson.databind.EMFContext.Attributes.RESOURCE_SET; import static org.emfjson.jackson.databind.EMFContext.Attributes.ROOT_ELEMENT; import static org.junit.Assert.*; public class ReferenceTest { @ClassRule public static StandardFixture fixture = new StandardFixture(); private ObjectMapper mapper = fixture.mapper(); private ResourceSet resourceSet = fixture.getResourceSet(); @Test public void testSaveTwoObjectsWithAttributesOneReference() throws IOException { JsonNode expected = mapper.createArrayNode() .add(mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "1") .put("name", "John") .set("uniqueFriend", mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("$ref", "2") )) .add(mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "2") .put("name", "Mary") .put("sex", "FEMALE")); Resource resource = resourceSet.createResource(URI.createURI("test")); 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); user1.setUniqueFriend(user2); resource.getContents().add(user1); resource.getContents().add(user2); assertEquals(expected, mapper.valueToTree(resource)); } @Test public void testSaveObjectWithManyReferences() throws IOException { Resource resource = resourceSet.createResource(URI.createURI("test")); User u1 = ModelFactory.eINSTANCE.createUser(); u1.setUserId("1"); u1.setName("Paul"); User u2 = ModelFactory.eINSTANCE.createUser(); u2.setUserId("2"); u2.setName("Pierre"); User u3 = ModelFactory.eINSTANCE.createUser(); u3.setUserId("3"); u3.setName("Victor"); u1.getFriends().add(u2); u1.getFriends().add(u3); resource.getContents().add(u1); resource.getContents().add(u2); resource.getContents().add(u3); assertThat(mapper.valueToTree(resource)) .isEqualTo(mapper.readTree(Paths.get("src/test/resources/tests/test-load-2.json").toFile())); } @Test public void testLoadTwoObjectsWithAttributesOneReference() throws IOException { JsonNode data = mapper.createArrayNode() .add(mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "1") .put("name", "John") .put("sex", "MALE") .set("uniqueFriend", mapper.createObjectNode() .put("$ref", "2") )) .add(mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "2") .put("name", "Mary") .put("sex", "FEMALE")); Resource resource = resourceSet.createResource(URI.createURI("tests/test-save-3.json")); resource.load(new ByteArrayInputStream(mapper.writeValueAsBytes(data)), null); assertEquals(2, resource.getContents().size()); User first = (User) resource.getContents().get(0); User second = (User) resource.getContents().get(1); assertSame(second, first.getUniqueFriend()); } @Test public void testLoadWithExternalReferenceFromFile() throws IOException { JsonNode data = mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "2") .set("uniqueFriend", mapper.createObjectNode() .put("$ref", "http://eclipselabs.org/emfjson/tests/test-load-1.json#1")); Resource resource = resourceSet.createResource(URI.createURI("http://resources/second")); resource.load(new ByteArrayInputStream(mapper.writeValueAsBytes(data)), null); assertFalse(resource.getContents().isEmpty()); User u2 = (User) resource.getContents().get(0); assertNotNull(u2.getUniqueFriend()); assertFalse(u2.getUniqueFriend().eIsProxy()); } @Test public void testLoadWithExternalReference() throws IOException { JsonNode firstResource = mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "1"); JsonNode secondResource = mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("userId", "2") .set("uniqueFriend", mapper.createObjectNode() .put("eClass", "http://www.emfjson.org/jackson/model#//User") .put("$ref", "http://resources/first#1")); Resource first = resourceSet.createResource(URI.createURI("http://resources/first")); Resource second = resourceSet.createResource(URI.createURI("http://resources/second")); first.load(new ByteArrayInputStream(mapper.writeValueAsBytes(firstResource)), null); second.load(new ByteArrayInputStream(mapper.writeValueAsBytes(secondResource)), null); assertFalse(first.getContents().isEmpty()); assertFalse(second.getContents().isEmpty()); User u1 = (User) first.getContents().get(0); User u2 = (User) second.getContents().get(0); assertSame(u1, u2.getUniqueFriend()); } @Test public void testLoadThreeObjectsTwoReferences() throws IOException { Resource resource = mapper .reader() .withAttribute(RESOURCE_SET, resourceSet) .withAttribute(ROOT_ELEMENT, ModelPackage.Literals.USER) .forType(Resource.class) .readValue(Paths.get("src/test/resources/tests/test-load-2.json").toFile()); assertFalse(resource.getContents().isEmpty()); assertEquals(3, resource.getContents().size()); EObject obj1 = resource.getContents().get(0); assertTrue(obj1 instanceof User); assertEquals("1", ((User) obj1).getUserId()); EObject obj2 = resource.getContents().get(1); assertTrue(obj2 instanceof User); assertEquals("2", ((User) obj2).getUserId()); EObject obj3 = resource.getContents().get(2); assertTrue(obj3 instanceof User); assertEquals("3", ((User) obj3).getUserId()); assertFalse(((User) obj1).getFriends().isEmpty()); assertEquals(2, ((User) obj1).getFriends().size()); User friend1 = ((User) obj1).getFriends().get(0); assertNotNull(friend1); User friend2 = ((User) obj1).getFriends().get(1); assertNotNull(friend2); assertFalse(friend1.eIsProxy()); assertFalse(friend2.eIsProxy()); assertEquals(obj2, friend1); assertEquals(obj3, friend2); } // @Test // public void testSaveReferenceAsValue() { // ObjectMapper mapper = fixture.mapper(OPTION_SERIALIZE_REF_AS_VALUE, true); // // JsonNode expected = mapper.createArrayNode() // .add(mapper.createObjectNode() // .put("eClass", "http://www.emfjson.org/jackson/model#//User") // .put("userId", "1") // .put("name", "John") // .put("uniqueFriend", "2")) // .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); // // user1.setUniqueFriend(user2); // // Resource resource = resourceSet.createResource(URI.createURI("test")); // resource.getContents().add(user1); // resource.getContents().add(user2); // // assertEquals(expected, mapper.valueToTree(resource)); // } // // @Test // public void testLoadReferenceAsValue() throws JsonProcessingException { // ObjectMapper mapper = fixture.mapper(OPTION_SERIALIZE_REF_AS_VALUE, true); // // JsonNode data = mapper.createArrayNode() // .add(mapper.createObjectNode() // .put("eClass", "http://www.emfjson.org/jackson/model#//User") // .put("userId", "1") // .put("name", "John") // .put("sex", "MALE") // .put("uniqueFriend", "2")) // .add(mapper.createObjectNode() // .put("eClass", "http://www.emfjson.org/jackson/model#//User") // .put("userId", "2") // .put("name", "Mary") // .put("sex", "FEMALE")); // // Resource resource = mapper // .reader() // .withAttribute(RESOURCE_SET, resourceSet) // .treeToValue(data, Resource.class); // // assertEquals(2, resource.getContents().size()); // // User first = (User) resource.getContents().get(0); // User second = (User) resource.getContents().get(1); // // assertSame(second, first.getUniqueFriend()); // } @Test public void testLoadShouldNotResolveProxiesIfIsNonResolve() throws IOException { Resource resource = resourceSet.getResource(URI.createURI("src/test/resources/tests/test-non-resolve-1.json"), true); assertEquals(1, resource.getContents().size()); assertTrue(resource.getContents().get(0) instanceof PrimaryObject); PrimaryObjectImpl source = (PrimaryObjectImpl) resource.getContents().get(0); assertTrue(source.eIsSet(ModelPackage.Literals.PRIMARY_OBJECT__SINGLE_REFERENCE)); assertTrue(source.basicGetSingleReference().eIsProxy()); assertFalse(source.getSingleReference().eIsProxy()); assertEquals("Foo", source.getSingleReference().getSingleAttribute()); assertTrue(source.eIsSet(ModelPackage.Literals.PRIMARY_OBJECT__MANY_REFERENCES)); assertEquals(1, source.getManyReferences().size()); } @Test public void testLoadObjectWithDeepHierarchy() throws IOException { Resource resource = resourceSet.getResource(URI.createURI("src/test/resources/tests/test-load-3.json"), true); assertThat(resource.getContents()) .hasSize(1) .hasOnlyElementsOfType(PrimaryObject.class); PrimaryObject p1 = (PrimaryObject) resource.getContents().get(0); assertThat(p1.getName()) .isEqualTo("p1"); // p1 assertThat(p1.getMultipleContainmentReferenceNoProxies()) .hasSize(2); assertThat(p1.getMultipleContainmentReferenceNoProxies().get(0).getSingleAttribute()) .isEqualTo("t1"); assertThat(p1.getMultipleContainmentReferenceNoProxies().get(1).getSingleAttribute()) .isEqualTo("t2"); assertThat(p1.getContainmentReferenceSameCollection()) .isNotNull(); // p2 PrimaryObject p2 = p1.getContainmentReferenceSameCollection(); assertThat(p2.getMultipleContainmentReferenceNoProxies()) .hasSize(2); assertThat(p2.getMultipleContainmentReferenceNoProxies().get(0).getSingleAttribute()) .isEqualTo("t3"); assertThat(p2.getMultipleContainmentReferenceNoProxies().get(1).getSingleAttribute()) .isEqualTo("t4"); // p3 PrimaryObject p3 = p2.getContainmentReferenceSameCollection(); assertThat(p3.getMultipleContainmentReferenceNoProxies()) .hasSize(2); assertThat(p3.getMultipleContainmentReferenceNoProxies().get(0).getSingleAttribute()) .isEqualTo("t5"); assertThat(p3.getMultipleContainmentReferenceNoProxies().get(1).getSingleAttribute()) .isEqualTo("t6"); } }