Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 250088 Details for
Bug 452681
Representation disappears from Model Explorer on session reload
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
Simple Junit test that focus on the problem of crossReference broke after a reloading
EMFReloadWithCrossReferenceTests.java (text/x-java), 19.98 KB, created by
Laurent Redor
on 2015-01-20 11:09:08 EST
(
hide
)
Description:
Simple Junit test that focus on the problem of crossReference broke after a reloading
Filename:
MIME Type:
Creator:
Laurent Redor
Created:
2015-01-20 11:09:08 EST
Size:
19.98 KB
patch
obsolete
>/******************************************************************************* > * Copyright (c) 2015 THALES GLOBAL SERVICES. > * 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: > * Obeo - initial API and implementation > *******************************************************************************/ >package org.eclipse.sirius.tests.unit.common; > >import java.io.File; >import java.io.IOException; >import java.util.ArrayList; >import java.util.Collection; >import java.util.Iterator; >import java.util.List; >import java.util.Map; >import java.util.Map.Entry; > >import junit.framework.TestCase; > >import org.eclipse.emf.common.util.URI; >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.EStructuralFeature.Setting; >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.util.ECrossReferenceAdapter; >import org.eclipse.emf.ecore.util.EcoreUtil; >import org.eclipse.emf.transaction.RecordingCommand; >import org.eclipse.emf.transaction.TransactionalEditingDomain; >import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.FactoryImpl; > >import com.google.common.collect.Maps; > >/** > * Class containing some tests to reveal the "problem" with EMF CrossReferencer > * after a unload/reload. > * > * A.ecore has a classA with a reference to the ClassB of B.ecore. The > * cross-referencer allows to retrieve the reference from B to A. If we reload > * B, the cross-referencer does not work. > * > * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> > */ >public class EMFReloadWithCrossReferenceTests extends TestCase { > > private TransactionalEditingDomain editingDomain; > > private class SpecificECrossReferenceAdapter3 extends ECrossReferenceAdapter { > @Override > protected boolean resolve() { > return false; > } > } > > private class SpecificECrossReferenceAdapter extends ECrossReferenceAdapter { > public void resolveProxyCrossReference(Resource resource) { > if (resource != null) { > final Iterator<EObject> it = resource.getAllContents(); > while (it.hasNext()) { > resolveAll(it.next()); > } > } > } > } > > private class SpecificECrossReferenceAdapter2 extends ECrossReferenceAdapter { > private class SpecificInverseCrossReferencer extends InverseCrossReferencer { > private static final long serialVersionUID = 1L; > > @Override > protected List<EObject> removeProxies(URI uri) { > return super.removeProxies(uri); > } > } > > public SpecificECrossReferenceAdapter2() { > inverseCrossReferencer = new SpecificInverseCrossReferencer(); > } > > /** > * A part of {@link #resolveAll(EObject)} has been duplicated to avoid > * the time consumption of accessing to resourceURI for each objects of > * the same resource. > * > * @param resource > * Each cross reference pointing to a proxy of this > * <code>resource</code> will be resolved. > */ > public void resolveProxyCrossReference(Resource resource) { > if (resource != null) { > URI resourceURI = resource.getURI(); > if (resourceURI != null) { > ResourceSet resourceSet = resource.getResourceSet(); > if (resourceSet != null) { > resourceURI = resourceSet.getURIConverter().normalize(resourceURI); > } > } > final Iterator<EObject> it = resource.getAllContents(); > while (it.hasNext()) { > EObject eObject = it.next(); > URI eObjectURI; > if (resourceURI != null) { > eObjectURI = resourceURI.appendFragment(resource.getURIFragment(eObject)); > } else { > eObjectURI = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject)); > } > List<EObject> proxies = ((SpecificInverseCrossReferencer) inverseCrossReferencer).removeProxies(eObjectURI); > if (proxies != null) { > for (int i = 0, size = proxies.size(); i < size; ++i) { > EObject proxy = proxies.get(i); > for (EStructuralFeature.Setting setting : getInverseReferences(proxy, false)) { > resolveProxy(resource, eObject, proxy, setting); > } > } > } > } > } > } > } > > private class SpecificECrossReferenceAdapter4 extends ECrossReferenceAdapter { > private class SpecificInverseCrossReferencer extends InverseCrossReferencer { > private static final long serialVersionUID = 1L; > > @Override > protected List<EObject> removeProxies(URI uri) { > return super.removeProxies(uri); > } > > public void resolveProxies(Resource resource, EObject eObject, URI uri) { > for (Iterator<Entry<EObject, Collection<Setting>>> iterator = entrySet().iterator(); iterator.hasNext();) { > Entry<EObject, Collection<Setting>> entry = iterator.next(); > if (entry.getKey().eIsProxy()) { > EObject currentKey = entry.getKey(); > URI keyURI = EcoreUtil.getURI(currentKey); > if (uri.equals(keyURI)) { > for (EStructuralFeature.Setting setting : entry.getValue()) { > resolveProxy(resource, eObject, currentKey, setting); > } > } > } > } > } > > public boolean isNullMapProxy() { > return proxyMap == null; > } > > /** > * Get all proxy {@link EObject EObjects} that have URI > * corresponding to the <code>resourceURI</code>. > * > * @param resourceURI > * The URI of the resource for which we want to get the > * proxy EObjects. > * @return map of proxies with the URI as key. > */ > public Map<URI, EObject> getProxiesOf(URI resourceURI) { > Map<URI, EObject> result = Maps.newHashMap(); > for (Iterator<EObject> iterator = keySet().iterator(); iterator.hasNext();) { > EObject eObject = iterator.next(); > if (eObject.eIsProxy()) { > URI keyURI = EcoreUtil.getURI(eObject); > if (resourceURI.equals(keyURI.trimFragment())) { > result.put(keyURI, eObject); > } > } > } > return result; > } > } > > public SpecificECrossReferenceAdapter4() { > inverseCrossReferencer = new SpecificInverseCrossReferencer(); > } > > /** > * A part of {@link #resolveAll(EObject)} has been duplicated to avoid > * the time consumption of accessing to resourceURI for each objects of > * the same resource. > * > * @param resource > * Each cross reference pointing to a proxy of this > * <code>resource</code> will be resolved. > */ > public void resolveProxyCrossReference(Resource resource) { > if (resource != null) { > URI resourceURI = resource.getURI(); > if (resourceURI != null) { > ResourceSet resourceSet = resource.getResourceSet(); > if (resourceSet != null) { > resourceURI = resourceSet.getURIConverter().normalize(resourceURI); > } > } > final Iterator<EObject> it = resource.getAllContents(); > // Since change in ECrossReferenceAdapter (bugzilla 400891), > // the proxyMap is no longer used if the resolve() method > // returns true. In this case, we must iterate on all > // crossReferences to retrieve corresponding proxies. > if (((SpecificInverseCrossReferencer) inverseCrossReferencer).isNullMapProxy()) { > Map<URI, EObject> proxies = ((SpecificInverseCrossReferencer) inverseCrossReferencer).getProxiesOf(resourceURI); > while (it.hasNext()) { > EObject eObject = it.next(); > URI eObjectURI; > if (resourceURI != null) { > eObjectURI = resourceURI.appendFragment(resource.getURIFragment(eObject)); > } else { > eObjectURI = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject)); > } > EObject correspondingProxy = proxies.get(eObjectURI); > if (correspondingProxy != null) { > for (EStructuralFeature.Setting setting : getInverseReferences(correspondingProxy, false)) { > resolveProxy(resource, eObject, correspondingProxy, setting); > } > } > } > } else { > // Code used for Juno > while (it.hasNext()) { > EObject eObject = it.next(); > URI eObjectURI; > if (resourceURI != null) { > eObjectURI = resourceURI.appendFragment(resource.getURIFragment(eObject)); > } else { > eObjectURI = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject)); > } > List<EObject> proxies = ((SpecificInverseCrossReferencer) inverseCrossReferencer).removeProxies(eObjectURI); > if (proxies != null) { > for (int i = 0, size = proxies.size(); i < size; ++i) { > EObject proxy = proxies.get(i); > for (EStructuralFeature.Setting setting : getInverseReferences(proxy, false)) { > resolveProxy(resource, eObject, proxy, setting); > } > } > } > } > } > } > } > } > > /** > * Without cross reference resolution, we have 0 cross reference after > * unload/reload. > */ > public void testCrossReferencerAfterReloadingWithoutCrossReferenceResolution() { > /* Create a standard cross referencer */ > ECrossReferenceAdapter crossRefencer = new ECrossReferenceAdapter(); > Resource reloadedResourceB = init(crossRefencer); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have 0 cross reference after unload/reload without cross reference resolution.", 0, getReferencesTo(reloadedEClassB, crossRefencer, false).size()); > } > > /** > * With cross reference resolution, we have 1 cross reference after > * unload/reload, as expected. But always having the cross reference > * resolution enabled can be time consuming. > */ > public void testCrossReferencerAfterReloadingWithCrossReferenceResolution() { > /* Create a standard cross referencer */ > ECrossReferenceAdapter crossRefencer = new ECrossReferenceAdapter(); > Resource reloadedResourceB = init(crossRefencer); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have one cross reference after unload/reload with cross reference resolution.", 1, getReferencesTo(reloadedEClassB, crossRefencer, true).size()); > } > > /** > * With cross reference resolution, we have 1 cross reference after > * unload/reload, as expected. But always having the cross reference > * resolution enabled can be time consuming. > */ > public void testCrossReferencerAfterReloadingWithCrossReferenceResolutionAndResolveFalse() { > /* Create a standard cross referencer */ > ECrossReferenceAdapter crossRefencer = new SpecificECrossReferenceAdapter3(); > Resource reloadedResourceB = init(crossRefencer); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have one cross reference after unload/reload with cross reference resolution.", 1, getReferencesTo(reloadedEClassB, crossRefencer, true).size()); > } > > /** > * This test use a first specific implementation of cross referencer that > * allows to resolve all proxy cross reference to a specific resource by > * calling @ {@link ECrossReferenceAdapter#resolveAll}. > */ > public void testCrossReferencerAfterReloadingWithoutCrossReferenceResolutionButWithSpecificCrossReferencer() { > /* Create a specific cross referencer */ > SpecificECrossReferenceAdapter specificCrossRefencer = new SpecificECrossReferenceAdapter(); > Resource reloadedResourceB = init(specificCrossRefencer); > specificCrossRefencer.resolveProxyCrossReference(reloadedResourceB); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have one cross reference after unload/reload with cross reference resolution.", 1, getReferencesTo(reloadedEClassB, specificCrossRefencer, false).size()); > } > > /** > * This test use a second specific implementation of cross referencer that > * allows to resolve all proxy cross reference to a specific resource. This > * implementation uses an adaptation of > * {@link ECrossReferenceAdapter#resolveAll} to avoid the time consumption > * of accessing to resourceURI for each objects of the same resource. > */ > public void testCrossReferencerAfterReloadingWithoutCrossReferenceResolutionButWithSpecificCrossReferencer2() { > /* Create a specific cross referencer */ > SpecificECrossReferenceAdapter2 specificCrossRefencer = new SpecificECrossReferenceAdapter2(); > Resource reloadedResourceB = init(specificCrossRefencer); > specificCrossRefencer.resolveProxyCrossReference(reloadedResourceB); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have one cross reference after unload/reload with cross reference resolution.", 1, getReferencesTo(reloadedEClassB, specificCrossRefencer, false).size()); > } > > /** > * This test use a second specific implementation of cross referencer that > * allows to resolve all proxy cross reference to a specific resource. This > * implementation uses an adaptation of > * {@link ECrossReferenceAdapter#resolveAll} to avoid the time consumption > * of accessing to resourceURI for each objects of the same resource. > */ > public void testCrossReferencerAfterReloadingWithoutCrossReferenceResolutionButWithSpecificCrossReferencer4() { > /* Create a specific cross referencer */ > SpecificECrossReferenceAdapter4 specificCrossRefencer = new SpecificECrossReferenceAdapter4(); > Resource reloadedResourceB = init(specificCrossRefencer); > specificCrossRefencer.resolveProxyCrossReference(reloadedResourceB); > EClass reloadedEClassB = (EClass) ((EPackage) reloadedResourceB.getContents().get(0)).getEClassifier("ClassB"); > assertEquals("We should have one cross reference after unload/reload with cross reference resolution.", 1, getReferencesTo(reloadedEClassB, specificCrossRefencer, false).size()); > } > > protected Resource init(ECrossReferenceAdapter crossRefencer) { > /* create a resource set and add the crossRefencer on it. */ > ResourceSet rset = new ResourceSetImpl(); > rset.eAdapters().add(crossRefencer); > /* create an editing domain */ > editingDomain = FactoryImpl.INSTANCE.createEditingDomain(rset); > > /* Initialize the model B */ > final EPackage ePackageB = EcoreFactory.eINSTANCE.createEPackage(); > ePackageB.setName("RootB"); > final EClass eClassB = EcoreFactory.eINSTANCE.createEClass(); > eClassB.setName("ClassB"); > ePackageB.getEClassifiers().add(eClassB); > > /* create resource and and add it initialized model */ > final URI fileBUri = URI.createFileURI(new File("B.ecore").getAbsolutePath()); > final Resource rsB = rset.createResource(fileBUri); > editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) { > > @Override > protected void doExecute() { > rsB.getContents().add(ePackageB); > } > > }); > try { > rsB.save(null); > } catch (IOException e) { > e.printStackTrace(); > } > > /* initialize the model A */ > final EPackage ePackageA = EcoreFactory.eINSTANCE.createEPackage(); > ePackageA.setName("RootA"); > final EClass eClassA = EcoreFactory.eINSTANCE.createEClass(); > eClassA.setName("ClassA"); > final EReference refToB = EcoreFactory.eINSTANCE.createEReference(); > refToB.setName("refToB"); > refToB.setEType(eClassB); > eClassA.getEStructuralFeatures().add(refToB); > ePackageA.getEClassifiers().add(eClassA); > > /* create resource and and add it initialized model */ > final URI fileAUri = URI.createFileURI(new File("A.ecore").getAbsolutePath()); > final Resource rsA = rset.createResource(fileAUri); > editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) { > > @Override > protected void doExecute() { > rsA.getContents().add(ePackageA); > } > > }); > try { > rsA.save(null); > } catch (IOException e) { > e.printStackTrace(); > } > assertEquals("We should have one cross reference before unload/reload.", 1, getReferencesTo(eClassB, crossRefencer, false).size()); > // Unload and reload the resource B > try { > rsB.unload(); > rsB.load(null); > return rsB; > } catch (IOException e) { > fail("Unload/reload of resource b failed: " + e.getMessage()); > } > return null; > } > > /** > * Get the {@link EReference eReferences} that have <code>type</code> as > * EType. > * > * @param type > * The searched EType > * @param crossReferencer > * The cross referencer to use. > * @param resolve > * Resolve proxy crossReference to this <code>type</code> > * > * @return The list of {@link EReference eReferences} that have > * <code>type</code> as EType. > */ > public Collection<EReference> getReferencesTo(EClass type, ECrossReferenceAdapter crossReferencer, boolean resolve) { > Collection<EReference> crossReferenceResult = new ArrayList<EReference>(); > for (EStructuralFeature.Setting setting : crossReferencer.getInverseReferences(type, resolve)) { > if (EcorePackage.Literals.EREFERENCE.isInstance(setting.getEObject()) && setting.getEStructuralFeature() == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE) { > crossReferenceResult.add((EReference) setting.getEObject()); > } > } > return crossReferenceResult; > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 452681
:
248829
|
249825
|
249857
|
249858
| 250088