/** * Copyright (c) 2004 IBM Corporation 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: * IBM - Initial API and implementation */ package org.eclipse.emf.test.core.ecore; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.List; import java.util.Map; 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.ETypedElement; 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.ResourceImpl; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl; import org.junit.Before; import org.junit.Test; public class ResourceCacheMechanismTest { private EAttribute id; private EAttribute name; private EObject john; private EObject mary; private EObject johnDoe; @Before public void setUp() throws Exception { EPackage pack = EcoreFactory.eINSTANCE.createEPackage(); EClass employee = EcoreFactory.eINSTANCE.createEClass(); employee.setName("Employee"); pack.getEClassifiers().add(employee); id = EcoreFactory.eINSTANCE.createEAttribute(); id.setName("id"); id.setID(true); id.setEType(EcorePackage.Literals.ESTRING); employee.getEStructuralFeatures().add(id); name = EcoreFactory.eINSTANCE.createEAttribute(); name.setName("name"); name.setEType(EcorePackage.Literals.ESTRING); employee.getEStructuralFeatures().add(name); john = pack.getEFactoryInstance().create(employee); john.eSet(id, "1"); john.eSet(name, "John"); mary = pack.getEFactoryInstance().create(employee); mary.eSet(id, "2"); mary.eSet(name, "mary"); johnDoe = pack.getEFactoryInstance().create(employee); johnDoe.eSet(name, "John"); } /* * Bugzilla 62885 */ @Test public void testResourceImplIntrinsicIDCache() throws Exception { Resource resource = new ResourceImpl(); //Setting the map before adding the objects Map<String, EObject> map = new HashMap<String, EObject>(); ((ResourceImpl)resource).setIntrinsicIDToEObjectMap(map); resource.getContents().add(john); resource.getContents().add(mary); resource.getContents().add(johnDoe); //The map should have all the objects with ID (john and mary) assertEquals(2, map.size()); assertEquals(john, map.get(john.eGet(id))); assertEquals(mary, map.get("2")); resource.getContents().remove(mary); //Mary should have been removed from the map. assertEquals(1, map.size()); assertEquals(john, map.get(john.eGet(id))); //Setting johnDoe's ID johnDoe.eSet(id, "newId"); //The map should be the same as before assertEquals(1, map.size()); assertEquals(john, map.get(john.eGet(id))); //Since john was added before johnDoe, retrieving john should not //add johnDoe to the map assertEquals(john, resource.getEObject("1")); assertEquals(1, map.size()); assertEquals(john, map.get(john.eGet(id))); //Adding mary again but removing her ID first so she is not added to the map mary.eSet(id, null); resource.getContents().add(mary); assertEquals(1, map.size()); assertEquals(john, map.get(john.eGet(id))); //Setting mary's ID mary.eSet(id, "2"); //Now mary was added after johnDoe so retrieving Mary should add //johnDoe to the map assertEquals(mary, resource.getEObject("2")); assertEquals(3, map.size()); assertEquals(john, map.get(john.eGet(id))); assertEquals(mary, map.get("2")); assertEquals(johnDoe, map.get(johnDoe.eGet(id))); } @Test public void testXMLResourceIDCache() throws Exception { XMLResource xmlResource = new XMLResourceImpl(); //Setting an external ID for john xmlResource.setID(john, "externalIDForJohn"); assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals("externalIDForJohn", xmlResource.getID(john)); //Setting the id doesn't add the object to the resource assertTrue(xmlResource.getContents().isEmpty()); xmlResource.getContents().add(john); xmlResource.getContents().add(mary); //Only john can be retrieved by an external ID assertEquals(john, xmlResource.getEObject("externalIDForJohn")); //Everybody can be retrieved by their IDs (XMLResource inherits this from Resource) assertEquals(john, xmlResource.getEObject((String)john.eGet(id))); assertEquals(mary, xmlResource.getEObject((String)mary.eGet(id))); //Setting mary's external ID xmlResource.setID(mary, "MARY"); assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals(mary, xmlResource.getEObject("MARY")); assertEquals("externalIDForJohn", xmlResource.getID(john)); assertEquals("MARY", xmlResource.getID(mary)); //john and mary can be retrieved by their external IDs assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals(mary, xmlResource.getEObject("MARY")); //Removing mary's external id xmlResource.setID(mary, null); assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertNull(xmlResource.getEObject("MARY")); assertEquals("externalIDForJohn", xmlResource.getID(john)); assertNull(xmlResource.getID(mary)); //Setting mary's external ID again xmlResource.setID(mary, "MARY"); //john and mary can be retrieved by their external IDs assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals(mary, xmlResource.getEObject("MARY")); //Removing mary from the resource xmlResource.getContents().remove(mary); assertEquals(1, xmlResource.getContents().size()); //Mary should not be in the maps. assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals("externalIDForJohn", xmlResource.getID(john)); assertNull(xmlResource.getEObject("MARY")); assertNull(xmlResource.getID(mary)); } /* * IMPORTANT: This is a test!! The maps IDToEObject and EObjectToID should never * be used directly. The get methods may be removed in future versions of EMF. */ @Test public void testXMLResourceImplIDCache() throws Exception { XMLResource xmlResource = new XMLResourceImpl(); //Setting an external ID for john xmlResource.setID(john, "externalIDForJohn"); assertEquals(1, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().size()); assertEquals(john, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("externalIDForJohn")); assertEquals(1, ((XMLResourceImpl)xmlResource).getEObjectToIDMap().size()); assertEquals("externalIDForJohn", ((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(john)); //Setting the id doesn't add the object to the resource assertTrue(xmlResource.getContents().isEmpty()); xmlResource.getContents().add(john); xmlResource.getContents().add(mary); xmlResource.getContents().add(johnDoe); //Only john can be retrieved by an external ID assertEquals(john, xmlResource.getEObject("externalIDForJohn")); //Everybody can be retrieved by their IDs (XMLResource inherits this from Resource) assertEquals(john, xmlResource.getEObject((String)john.eGet(id))); assertEquals(mary, xmlResource.getEObject((String)mary.eGet(id))); //Setting mary's external ID xmlResource.setID(mary, "MARY"); assertEquals(2, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().size()); assertEquals(john, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("externalIDForJohn")); assertEquals(mary, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("MARY")); assertEquals(2, ((XMLResourceImpl)xmlResource).getEObjectToIDMap().size()); assertEquals("externalIDForJohn", ((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(john)); assertEquals("MARY", ((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(mary)); //john and mary can be retrieved by their external IDs assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals(mary, xmlResource.getEObject("MARY")); //Removing mary's external id xmlResource.setID(mary, null); assertEquals(1, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().size()); assertEquals(john, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("externalIDForJohn")); assertNull(((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("MARY")); assertEquals(1, ((XMLResourceImpl)xmlResource).getEObjectToIDMap().size()); assertEquals("externalIDForJohn", ((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(john)); assertNull(((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(mary)); //Setting mary's external ID again xmlResource.setID(mary, "MARY"); //john and mary can be retrieved by their external IDs assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals(mary, xmlResource.getEObject("MARY")); //Removing mary xmlResource.getContents().remove(mary); assertEquals(2, xmlResource.getContents().size()); //Mary should not be in the maps. assertEquals(1, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().size()); assertEquals(john, ((XMLResourceImpl)xmlResource).getIDToEObjectMap().get("externalIDForJohn")); assertEquals(1, ((XMLResourceImpl)xmlResource).getEObjectToIDMap().size()); assertEquals("externalIDForJohn", ((XMLResourceImpl)xmlResource).getEObjectToIDMap().get(john)); } @Test public void testAllIDCaches() throws Exception { XMLResource xmlResource = new XMLResourceImpl(); //Setting an external ID for john xmlResource.setID(john, "externalIDForJohn"); //Setting the map before adding the objects Map<String, EObject> map = new HashMap<String, EObject>(); ((ResourceImpl)xmlResource).setIntrinsicIDToEObjectMap(map); xmlResource.getContents().add(john); xmlResource.getContents().add(mary); //Unsetting johnDoe's id johnDoe.eSet(id, null); xmlResource.getContents().add(johnDoe); //john with external ID, mary with instrinsic ID, johnDoe without any ID assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals("externalIDForJohn", xmlResource.getID(john)); assertEquals(mary, xmlResource.getEObject((String)mary.eGet(id))); assertNull(xmlResource.getID(mary)); assertNull(xmlResource.getID(johnDoe)); assertEquals(2, map.size()); assertEquals(john, map.get(john.eGet(id))); assertEquals(mary, map.get(mary.eGet(id))); // Unsetting john's ID xmlResource.setID(john, null); // john and mary with instrinsic IDs, johnDoe without any ID assertNull(xmlResource.getEObject("externalIDForJohn")); assertNull(xmlResource.getID(john)); assertEquals(john, xmlResource.getEObject((String)john.eGet(id))); assertEquals(2, map.size()); assertEquals(john, map.get(john.eGet(id))); assertEquals(mary, map.get(mary.eGet(id))); xmlResource.setID(john, "externalIDForJohn"); //john with external ID, mary with instrinsic ID, johnDoe without any ID assertEquals(john, xmlResource.getEObject("externalIDForJohn")); assertEquals("externalIDForJohn", xmlResource.getID(john)); assertEquals(mary, xmlResource.getEObject((String)mary.eGet(id))); assertNull(xmlResource.getID(mary)); assertNull(xmlResource.getID(johnDoe)); assertEquals(2, map.size()); assertEquals(john, map.get(john.eGet(id))); assertEquals(mary, map.get(mary.eGet(id))); xmlResource.getContents().remove(john); assertNull(xmlResource.getEObject("externalIDForJohn")); assertNull(xmlResource.getID(john)); assertNull(xmlResource.getEObject((String)john.eGet(id))); assertEquals(mary, xmlResource.getEObject((String)mary.eGet(id))); assertEquals(1, map.size()); assertEquals(mary, map.get(mary.eGet(id))); } @Test public void testResourceSetURICache() throws Exception { ResourceSet resourceSet = new ResourceSetImpl(); Resource resource1 = new ResourceImpl(); resource1.setURI(URI.createFileURI("f1")); resource1.getContents().add(john); resource1.getContents().add(mary); Resource resource2 = new ResourceImpl(); resource2.setURI(URI.createURI("http://www.eclipse.org/emf")); resource2.getContents().add(johnDoe); Map<URI, Resource> map = new HashMap<URI, Resource>(); ((ResourceSetImpl)resourceSet).setURIResourceMap(map); resourceSet.getResources().add(resource1); resourceSet.getResources().add(resource2); assertTrue(map.isEmpty()); assertEquals(resource1, resourceSet.getResource(URI.createFileURI("f1"), false)); assertEquals(1, map.size()); assertEquals(resource1, map.get(URI.createFileURI("f1"))); assertEquals(john, resourceSet.getEObject(URI.createFileURI("f1").appendFragment(resource1.getURIFragment(john)), false)); assertEquals(1, map.size()); assertEquals(resource1, map.get(URI.createFileURI("f1"))); assertEquals(johnDoe, resourceSet.getEObject(resource2.getURI().appendFragment(resource2.getURIFragment(johnDoe)), false)); assertEquals(2, map.size()); assertEquals(resource1, map.get(URI.createFileURI("f1"))); assertEquals(resource2, map.get(resource2.getURI())); resourceSet.getResources().remove(resource1); assertEquals(1, map.size()); assertEquals(resource2, map.get(resource2.getURI())); resourceSet.getResources().clear(); assertTrue(map.isEmpty()); } @Test public void testXMLResourceIDCacheWithContainment() throws Exception { EClass person = john.eClass(); EPackage pack = person.getEPackage(); EClass company = EcoreFactory.eINSTANCE.createEClass(); company.setName("company"); pack.getEClassifiers().add(company); EReference employees = EcoreFactory.eINSTANCE.createEReference(); company.getEStructuralFeatures().add(employees); employees.setName("employees"); employees.setContainment(true); employees.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY); employees.setEType(person); EObject company1 = pack.getEFactoryInstance().create(company); @SuppressWarnings("unchecked") List<EObject> company1Employees = ((List<EObject>)company1.eGet(employees)); company1Employees.add(john); assertEquals(company1, john.eContainer()); XMLResource xmlResource = new XMLResourceImpl(); xmlResource.getContents().add(company1); assertEquals(xmlResource, company1.eResource()); assertEquals(john, xmlResource.getEObject((String)john.eGet(id))); xmlResource.setID(john, "JOHN"); assertEquals(john, xmlResource.getEObject("JOHN")); EObject company2 = pack.getEFactoryInstance().create(company); @SuppressWarnings("unchecked") List<EObject> company2Employees = ((List<EObject>)company2.eGet(employees)); company2Employees.add(john); assertEquals(company2, john.eContainer()); assertTrue(((List<?>)company1.eGet(employees)).isEmpty()); assertTrue(((XMLResourceImpl)xmlResource).getEObjectToIDMap().isEmpty()); assertTrue(((XMLResourceImpl)xmlResource).getIDToEObjectMap().isEmpty()); assertNull(xmlResource.getEObject("JOHN")); } }