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 33894 Details for
Bug 113892
Integration of the EMF dynamic references for reverse reference lookup
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
multi project patch
2006-01-31_bugzilla113892_multiProjectPatch.txt (text/plain), 108.41 KB, created by
Christian Vogt
on 2006-01-31 17:04:07 EST
(
hide
)
Description:
multi project patch
Filename:
MIME Type:
Creator:
Christian Vogt
Created:
2006-01-31 17:04:07 EST
Size:
108.41 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.gmf.tests.runtime.emf.core >Index: src/org/eclipse/gmf/tests/runtime/emf/core/EditingDomainExtensibilityTests.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/tests/org.eclipse.gmf.tests.runtime.emf.core/src/org/eclipse/gmf/tests/runtime/emf/core/EditingDomainExtensibilityTests.java,v >retrieving revision 1.1 >diff -u -r1.1 EditingDomainExtensibilityTests.java >--- src/org/eclipse/gmf/tests/runtime/emf/core/EditingDomainExtensibilityTests.java 14 Nov 2005 21:10:10 -0000 1.1 >+++ src/org/eclipse/gmf/tests/runtime/emf/core/EditingDomainExtensibilityTests.java 31 Jan 2006 22:02:43 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2005 IBM Corporation and others. >+ * Copyright (c) 2005, 2006 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 >@@ -653,7 +653,7 @@ > projectName); > > if (proj != null) { >- result = (MyResourceSet) getResourceSet(proj); >+ result = getResourceSet(proj); > } > } > >Index: src/org/eclipse/gmf/tests/runtime/emf/core/AllTests.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/tests/org.eclipse.gmf.tests.runtime.emf.core/src/org/eclipse/gmf/tests/runtime/emf/core/AllTests.java,v >retrieving revision 1.8 >diff -u -r1.8 AllTests.java >--- src/org/eclipse/gmf/tests/runtime/emf/core/AllTests.java 23 Dec 2005 20:18:58 -0000 1.8 >+++ src/org/eclipse/gmf/tests/runtime/emf/core/AllTests.java 31 Jan 2006 22:02:42 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2002, 2005 IBM Corporation and others. >+ * Copyright (c) 2002-2006 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 >@@ -88,6 +88,7 @@ > suite.addTestSuite(MSLEditingDomainTestCase.class); > suite.addTestSuite(MFilterTests.class); > suite.addTestSuite(MListenerTest.class); >+ suite.addTestSuite(CrossReferenceAdapterTests.class); > > return suite; > } >Index: src/org/eclipse/gmf/tests/runtime/emf/core/CrossReferenceAdapterTests.java >=================================================================== >RCS file: src/org/eclipse/gmf/tests/runtime/emf/core/CrossReferenceAdapterTests.java >diff -N src/org/eclipse/gmf/tests/runtime/emf/core/CrossReferenceAdapterTests.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/gmf/tests/runtime/emf/core/CrossReferenceAdapterTests.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,809 @@ >+/****************************************************************************** >+ * Copyright (c) 2006 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 Corporation - initial API and implementation >+ ****************************************************************************/ >+ >+package org.eclipse.gmf.tests.runtime.emf.core; >+ >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Iterator; >+import java.util.List; >+ >+import org.eclipse.emf.common.notify.Notifier; >+import org.eclipse.emf.common.util.TreeIterator; >+import org.eclipse.emf.ecore.EObject; >+import org.eclipse.emf.ecore.EReference; >+import org.eclipse.emf.ecore.resource.Resource; >+import org.eclipse.emf.ecore.resource.ResourceSet; >+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; >+import org.eclipse.emf.examples.extlibrary.Book; >+import org.eclipse.emf.examples.extlibrary.EXTLibraryFactory; >+import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage; >+import org.eclipse.emf.examples.extlibrary.Employee; >+import org.eclipse.emf.examples.extlibrary.Library; >+import org.eclipse.emf.examples.extlibrary.Writer; >+import org.eclipse.gmf.runtime.emf.core.edit.MRunnable; >+import org.eclipse.gmf.runtime.emf.core.edit.MUndoInterval; >+import org.eclipse.gmf.runtime.emf.core.exceptions.MSLActionAbandonedException; >+import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >+import org.eclipse.gmf.runtime.emf.core.internal.index.MSLCrossReferenceAdapter; >+import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil; >+import org.eclipse.gmf.runtime.emf.core.util.ResourceUtil; >+ >+/** >+ * Test cases for the MSLCrossReferenceAdapter. >+ * >+ * @author Christian Vogt (cvogt) >+ */ >+public class CrossReferenceAdapterTests extends BaseCoreTests { >+ >+ private Resource otherRes; >+ private Library otherRoot; >+ private Book otherBook; >+ private Writer otherWriter; >+ private Employee otherEmp; >+ >+ /** >+ * Tests to ensure that every object in the resource has >+ * an attached CrossReferenceAdapter >+ */ >+ public void test_hasCrossReferenceAdapter() { >+ checkHasCrossReferenceAdapter(testResource); >+ } >+ >+ /** >+ * Helper method to check that the notifier and all its contents >+ * have an attached CrossReferenceAdapter. >+ * >+ * @param notifier >+ */ >+ private void checkHasCrossReferenceAdapter(Notifier notifier) { >+ boolean result = hasCrossRefenenceAdapter(notifier); >+ if (result) { >+ TreeIterator iter = null; >+ if (notifier instanceof ResourceSet) { >+ iter = ((ResourceSet)notifier).getAllContents(); >+ } else if (notifier instanceof Resource) { >+ iter = ((Resource)notifier).getAllContents(); >+ } else if (notifier instanceof EObject) { >+ iter = ((EObject)notifier).eAllContents(); >+ } else { >+ fail("Invalid Object Type"); //$NON-NLS-1$ >+ } >+ >+ while (iter.hasNext()) { >+ if (!hasCrossRefenenceAdapter((Notifier)iter.next())) { >+ result = false; >+ break; >+ } >+ } >+ } >+ if (!result) { >+ fail("CrossReferenceAdapter is missing."); //$NON-NLS-1$ >+ } >+ } >+ >+ /** >+ * Returns true if the notifier has an attached CrossReferenceAdapter. >+ * >+ * @param notifier the notifier to check >+ * @return >+ */ >+ private boolean hasCrossRefenenceAdapter(Notifier notifier) { >+ boolean result = false; >+ for (Iterator i = notifier.eAdapters().iterator(); i.hasNext(); ) { >+ if (i.next() instanceof MSLCrossReferenceAdapter) { >+ result = true; >+ } >+ } >+ return result; >+ } >+ >+ /** >+ * Tests that resource import and exports information is properly >+ * maintained when many cross references are added and removed. >+ */ >+ public void test_importsExportsAddRemoveMany() { >+ Book rootBook = (Book)root.getBooks().get(0); >+ Book level1Book = (Book)((Library)root.getBranches().get(0)).getBooks().get(0); >+ final List books = new ArrayList(); >+ books.add(rootBook); >+ books.add(level1Book); >+ >+ MUndoInterval undo = domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().addAll(books); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection imports = domain.getImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ Collection exports = domain.getExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ // remove books by undo >+ undo.undo(); >+ >+ imports = domain.getImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ exports = domain.getExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ } >+ >+ /** >+ * Tests that resource import and exports information is properly >+ * maintained when many cross references are added and removed >+ * one at a time. >+ */ >+ public void test_importsExportsAddManyRemoveOneAtATime() { >+ final Book rootBook = (Book)root.getBooks().get(0); >+ final Book level1Book = (Book)((Library)root.getBranches().get(0)).getBooks().get(0); >+ final List books = new ArrayList(); >+ books.add(rootBook); >+ books.add(level1Book); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().addAll(books); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection imports = domain.getImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ Collection exports = domain.getExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().remove(rootBook); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ imports = domain.getImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ exports = domain.getExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ domain.runUnvalidated(new MRunnable() { >+ public Object run() { >+ return domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().remove(level1Book); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ } >+ }); >+ } >+ }); >+ >+ imports = domain.getImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ exports = domain.getExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ } >+ >+ /** >+ * Tests that resource import and exports information is properly >+ * maintained when a cross reference is set and unset. >+ */ >+ public void test_importsExportsSetUnset() { >+ final Writer rootWriter = (Writer)root.getWriters().get(0); >+ >+ >+ MUndoInterval undo = domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherBook.setAuthor(rootWriter); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection imports = domain.getImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ Collection exports = domain.getExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ // unset author by undo >+ undo.undo(); >+ >+ imports = domain.getImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ exports = domain.getExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ } >+ >+ /** >+ * Tests that resource import and exports information is properly >+ * maintained when a cross reference is added and removed. >+ */ >+ public void test_importsExportsAddRemove() { >+ final Book rootBook = (Book)root.getBooks().get(0); >+ >+ MUndoInterval undo = domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().add(rootBook); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection imports = domain.getImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertTrue(imports.contains(testResource)); >+ >+ Collection exports = domain.getExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertTrue(exports.contains(otherRes)); >+ >+ // remove book by undo >+ undo.undo(); >+ >+ imports = domain.getImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ imports = domain.getAllImports(otherRes); >+ assertFalse(imports.contains(testResource)); >+ >+ exports = domain.getExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ >+ exports = domain.getAllExports(testResource); >+ assertFalse(exports.contains(otherRes)); >+ } >+ >+ /** >+ * Tests that when a resource containing a cross reference is unload, >+ * the cross reference information is maintained and not accessible. >+ */ >+ public void test_unloadedCrossReference() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ // unload the resource containing the employee >+ otherRes.unload(); >+ >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ // cannot find references because resource was unloaded and are not returned >+ assertTrue(xrefs.isEmpty()); >+ } >+ >+ /** >+ * Tests when a resource containing a cross reference and the referencer >+ * is destroyed, that the cross reference information is updated. >+ */ >+ public void test_destroyReferencer() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ domain.getResourceSet().eAdapters().add(new ECrossReferenceAdapter()); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ EObjectUtil.destroy(otherEmp); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.isEmpty()); >+ } >+ >+ /** >+ * Tests when a resource containing a cross reference and the referencer >+ * is detached, that the cross reference information is maintained. >+ */ >+ public void test_detachReferencer() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherRoot.getEmployees().remove(otherEmp); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ } >+ >+ /** >+ * Tests when a resource containing a cross reference and the referenced object >+ * is detached, that the cross reference information is maintained. >+ */ >+ public void test_detachReferenced() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().remove(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ } >+ >+ /** >+ * Tests when a resource containing a bi-directional cross reference >+ * to an object and the reference is destroyed, that the cross >+ * reference information is updated correctly >+ */ >+ public void test_biDirectionalReference() { >+ final Book rootBook = (Book)root.getBooks().get(0); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ otherWriter.getBooks().add(rootBook); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ rootBook, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getWriter_Books()}); >+ >+ assertTrue(xrefs.contains(otherWriter)); >+ >+ domain.runUnvalidated(new MRunnable() { >+ public Object run() { >+ return domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ EObjectUtil.destroy(otherWriter); >+ otherWriter = null; >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ } >+ }); >+ } >+ }); >+ >+ xrefs = EObjectUtil.getReferencers( >+ rootBook, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getWriter_Books()}); >+ >+ assertTrue(xrefs.isEmpty()); >+ } >+ >+ /** >+ * Tests when a resource containing a uni-directional cross reference >+ * to an object in another resource and the reference is destroyed, >+ * that the cross reference information is updated correctly >+ */ >+ public void test_uniDirectionalReference() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ EObjectUtil.destroy(otherEmp); >+ otherEmp = null; >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.isEmpty()); >+ } >+ >+ /** >+ * Tests retrieving referencers of a specific type. >+ */ >+ public void test_getReferencersOfType() { >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ MSLCrossReferenceAdapter crossReferenceAdapter = >+ MSLCrossReferenceAdapter.getCrossReferenceAdapter(boss); >+ >+ // tests valid type >+ Collection xrefs = crossReferenceAdapter.getInverseReferencers(boss, >+ EXTLibraryPackage.eINSTANCE.getEmployee_Manager(), >+ EXTLibraryPackage.eINSTANCE.getEmployee()); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ // tests valid type >+ xrefs = crossReferenceAdapter.getInverseReferencers(boss, >+ null, >+ EXTLibraryPackage.eINSTANCE.getEmployee()); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ >+ // tests invalid type >+ xrefs = crossReferenceAdapter.getInverseReferencers(boss, >+ EXTLibraryPackage.eINSTANCE.getEmployee_Manager(), >+ EXTLibraryPackage.eINSTANCE.getLibrary()); >+ >+ assertTrue(xrefs.isEmpty()); >+ >+ // tests invalid type >+ xrefs = crossReferenceAdapter.getInverseReferencers(boss, >+ null, >+ EXTLibraryPackage.eINSTANCE.getLibrary()); >+ >+ assertTrue(xrefs.isEmpty()); >+ } >+ >+ /** >+ * Tests retrieving referencers when the cross reference adapter >+ * is not added to the ResourceSet when the domain is created, but rather >+ * added at a later point in time. >+ */ >+ public void test_addLateCrossReferenceAdapter() { >+ MSLEditingDomain mslDomain = (MSLEditingDomain)domain; >+ >+ // remove the cross reference adapter from the ResourceSet >+ mslDomain.getResourceSet().eAdapters().remove(mslDomain.getCrossReferenceAdapter()); >+ >+ final Employee boss = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ root.getEmployees().add(boss); >+ otherEmp.setManager(boss); >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to update model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ >+ Collection xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.isEmpty()); >+ >+ // add the cross reference adapter back to the ResourceSet >+ mslDomain.getResourceSet().eAdapters().add(mslDomain.getCrossReferenceAdapter()); >+ >+ // check that all children of the ResourceSet have a cross reference adapter >+ checkHasCrossReferenceAdapter(mslDomain.getResourceSet()); >+ >+ xrefs = EObjectUtil.getReferencers( >+ boss, >+ new EReference[] {EXTLibraryPackage.eINSTANCE.getEmployee_Manager()}); >+ >+ assertTrue(xrefs.contains(otherEmp)); >+ } >+ >+ /* >+ * Sets up a library test model: >+ * >+ * Library (otherRoot) >+ * - Book (otherBook) >+ * - Writer (otherWiter) >+ * - Employee (otherEmp) >+ */ >+ protected void setUp() throws Exception { >+ >+ super.setUp(); >+ >+ otherRes = ResourceUtil.create("/tmp/otherLibrary.extLibrary", //$NON-NLS-1$ >+ EXTLibraryPackage.eINSTANCE.getLibrary()); >+ >+ domain.getResourceSet().getResources().add(otherRes); >+ >+ otherRoot = (Library)otherRes.getContents().get(0); >+ otherBook = EXTLibraryFactory.eINSTANCE.createBook(); >+ otherWriter = EXTLibraryFactory.eINSTANCE.createWriter(); >+ otherEmp = EXTLibraryFactory.eINSTANCE.createEmployee(); >+ >+ domain.runInUndoInterval(new Runnable() { >+ public void run() { >+ try { >+ domain.runAsWrite(new MRunnable() { >+ >+ public Object run() { >+ >+ otherRoot.getBooks().add(otherBook); >+ otherRoot.getWriters().add(otherWriter); >+ otherRoot.getEmployees().add(otherEmp); >+ >+ return null; >+ }}); >+ } catch (MSLActionAbandonedException e) { >+ fail("Failed to setup test model: " + e.getLocalizedMessage()); //$NON-NLS-1$ >+ } >+ }}); >+ } >+ >+ protected void tearDown() throws Exception { >+ >+ try { >+ if (otherRes != null) { >+ if (otherRes.isLoaded()) { >+ otherRes.unload(); >+ } >+ >+ otherRes.getResourceSet().getResources().remove(otherRes); >+ } >+ } finally { >+ super.tearDown(); >+ } >+ } >+} >#P org.eclipse.gmf.runtime.emf.core >Index: src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLResourceListener.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLResourceListener.java,v >retrieving revision 1.3 >diff -u -r1.3 MSLResourceListener.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLResourceListener.java 25 Nov 2005 21:58:30 -0000 1.3 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLResourceListener.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2002, 2003 IBM Corporation and others. >+ * Copyright (c) 2002-2006 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 >@@ -182,9 +182,6 @@ > > loadedResources.remove(notifier); > >- domain.getResourceIndexer().deregisterReferences( >- notifier); >- > domain.getUndoStack().flushAll(); > > EObject root = null; >Index: src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLObjectListener.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLObjectListener.java,v >retrieving revision 1.5 >diff -u -r1.5 MSLObjectListener.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLObjectListener.java 16 Dec 2005 18:06:50 -0000 1.5 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/notifications/MSLObjectListener.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2002, 2004 IBM Corporation and others. >+ * Copyright (c) 2002-2006 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 >@@ -11,18 +11,11 @@ > > package org.eclipse.gmf.runtime.emf.core.internal.notifications; > >-import java.util.ArrayList; >-import java.util.Collection; >-import java.util.Iterator; >-import java.util.List; >- > import org.eclipse.emf.common.notify.Notification; > import org.eclipse.emf.ecore.EObject; >-import org.eclipse.emf.ecore.EReference; > import org.eclipse.emf.ecore.resource.Resource; > import org.eclipse.gmf.runtime.emf.core.EventTypes; > import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >-import org.eclipse.gmf.runtime.emf.core.internal.resources.MResource; > import org.eclipse.gmf.runtime.emf.core.internal.util.MSLUtil; > > /** >@@ -51,8 +44,6 @@ > > int eventType = notification.getEventType(); > >- Object feature = notification.getFeature(); >- > if (resource != null) { > > if (!domain.getResouceListener().resourceFinishedLoading(resource)) >@@ -96,75 +87,7 @@ > // populate undo stack. > domain.getCommandGenerator().generateCommand(notification); > >- // process references. >- processReferences(notifier, eventType, newValue, oldValue, feature, >- resource); >- > // forward event to broker. > domain.getEventBroker().addEvent(notification); > } >- >- /** >- * Process references and update reference maps. >- */ >- private void processReferences(EObject notifier, int eventType, >- Object newValue, Object oldValue, Object feature, Resource resource) { >- >- if (feature instanceof EReference) { >- >- // maintain the reverese reference map. >- EReference reference = (EReference) feature; >- >- List newObjects = new ArrayList(); >- List oldObjects = new ArrayList(); >- >- if ((eventType == Notification.SET) >- || (eventType == Notification.UNSET) >- || (eventType == Notification.ADD) >- || (eventType == Notification.REMOVE) >- || (eventType == Notification.ADD_MANY) >- || (eventType == Notification.REMOVE_MANY) >- || (eventType == Notification.RESOLVE)) { >- >- if (newValue instanceof EObject) >- newObjects.add(newValue); >- >- else if (newValue instanceof Collection) { >- >- Iterator i = ((Collection) newValue).iterator(); >- >- while (i.hasNext()) { >- >- Object newObject = i.next(); >- >- if (newObject instanceof EObject) >- newObjects.add(newObject); >- } >- } >- >- if (oldValue instanceof EObject) >- oldObjects.add(oldValue); >- >- else if (oldValue instanceof Collection) { >- >- Iterator i = ((Collection) oldValue).iterator(); >- >- while (i.hasNext()) { >- >- Object oldObject = i.next(); >- >- if (oldObject instanceof EObject) >- oldObjects.add(oldObject); >- } >- } >- } >- >- if (resource instanceof MResource) >- ((MResource) resource).getHelper().registerReferences(domain, >- notifier, reference, newObjects, oldObjects); >- else >- MSLUtil.registerReferences(domain, notifier, reference, >- newObjects, oldObjects); >- } >- } > } >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceVisitor.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceVisitor.java,v >retrieving revision 1.2 >diff -u -r1.2 MSLReferenceVisitor.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceVisitor.java 12 Sep 2005 21:25:13 -0000 1.2 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceVisitor.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2004 IBM Corporation and others. >+ * Copyright (c) 2004-2006 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 >@@ -11,13 +11,18 @@ > > package org.eclipse.gmf.runtime.emf.core.internal.index; > >-import java.lang.ref.WeakReference; >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Collections; >+import java.util.HashMap; >+import java.util.Iterator; > import java.util.List; > import java.util.Map; >+import java.util.Set; > > import org.eclipse.emf.ecore.EObject; > import org.eclipse.emf.ecore.EReference; >- >+import org.eclipse.emf.ecore.EStructuralFeature.Setting; > import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; > > /** >@@ -32,33 +37,21 @@ > > protected EObject referencedObject = null; > >- private boolean resolve = true; >- > /** > * Constructor. > */ > public MSLReferenceVisitor(MSLEditingDomain domain, EObject eObject) { >- this(domain, eObject, true); >- } >- >- /** >- * Constructor. >- */ >- public MSLReferenceVisitor(MSLEditingDomain domain, EObject eObject, >- boolean resolve) { >- > this.domain = domain; > this.referencedObject = eObject; >- this.resolve = resolve; > } > >+ > /** > * Visit all the referencers. > */ > public void visitReferencers() { > >- Map featureMap = domain.getObjectIndexer().getGroupedReferencers( >- referencedObject, resolve); >+ Map featureMap = getGroupedReferencers(referencedObject); > > // operate on a clone to prevent concurrent access exceptions. > Object[] references = featureMap.keySet().toArray(); >@@ -67,46 +60,85 @@ > > EReference reference = (EReference) references[i]; > >- Object value = featureMap.get(reference); >+ List referencerList = (List)featureMap.get(reference); > >- if (value instanceof List) { >+ // operate on a clone to prevent concurrent access exceptions. >+ Object[] referencers = referencerList.toArray(); > >- List referencerList = (List) value; >+ for (int j = 0; j < referencers.length; j++) { >+ EObject referencer = (EObject) referencerList.get(j); > >- // operate on a clone to prevent concurrent access exceptions. >- Object[] referencers = referencerList.toArray(); >+ visitedReferencer(reference, referencer); >+ } >+ } >+ } > >- for (int j = 0; j < referencers.length; j++) { >+ /** >+ * Override to implement processing the visit. >+ */ >+ protected abstract void visitedReferencer(EReference reference, >+ EObject referencer); > >- WeakReference r = (WeakReference) referencerList.get(j); >+ /** >+ * For the given referenced EObject, returns a Map whose keys are EReferences >+ * and values are EObjects that reference the referenced EObject with the key >+ * EReference. >+ * >+ * @param referenced the referenced EObject >+ * @return a Map of referencers >+ */ >+ private Map getGroupedReferencers(EObject referenced) { > >- if (r != null) { >+ Map newMap = new HashMap(); > >- EObject referencer = (EObject) r.get(); >+ MSLCrossReferenceAdapter crossReferenceAdapter = domain.getCrossReferenceAdapter(); > >- if (referencer != null) >- visitedReferencer(reference, referencer); >- } >+ // first group all the inverse referencers >+ Collection nonNavigableInverseReferences = >+ crossReferenceAdapter.getNonNavigableInverseReferences(referenced); >+ >+ if (nonNavigableInverseReferences != null && >+ !nonNavigableInverseReferences.isEmpty()) { >+ for (Iterator iter = nonNavigableInverseReferences.iterator(); iter >+ .hasNext();) { >+ Setting setting = (Setting) iter.next(); >+ List list = (List)newMap.get(setting.getEStructuralFeature()); >+ if (list == null) { >+ list = new ArrayList(); >+ list.add(setting.getEObject()); >+ newMap.put(setting.getEStructuralFeature(), list); >+ } else { >+ list.add(setting.getEObject()); > } >+ } >+ } >+ >+ // next loop through all the EReferences to find referencers >+ // for those EReferences with opposites >+ List features = referenced.eClass().getEAllReferences(); >+ >+ for (Iterator i = features.iterator(); i.hasNext();) { >+ >+ EReference reference = (EReference) i.next(); > >- } else if (value instanceof WeakReference) { >+ EReference opposite = reference.getEOpposite(); > >- WeakReference r = (WeakReference) value; >+ if (opposite != null && reference.isChangeable() >+ && !reference.isContainer() && !reference.isContainment()) { > >- if (r != null) { >+ Set referencers = crossReferenceAdapter.getInverseReferencers(referenced, opposite, null); > >- EObject referencer = (EObject) r.get(); >+ if (!referencers.isEmpty()) { > >- if (referencer != null) >- visitedReferencer(reference, referencer); >+ newMap.put(opposite, new ArrayList(referencers)); > } > } > } >- } > >- /** >- * Override to implement processing the visit. >- */ >- protected abstract void visitedReferencer(EReference reference, >- EObject referencer); >+ if (newMap != null) { >+ return Collections.unmodifiableMap(newMap); >+ } else { >+ return Collections.EMPTY_MAP; >+ } >+ } > } >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLObjectIndexer.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLObjectIndexer.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLObjectIndexer.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLObjectIndexer.java 12 Sep 2005 21:25:13 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,905 +0,0 @@ >-/****************************************************************************** >- * 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 Corporation - initial API and implementation >- ****************************************************************************/ >- >-package org.eclipse.gmf.runtime.emf.core.internal.index; >- >-import java.lang.ref.WeakReference; >-import java.util.ArrayList; >-import java.util.Collections; >-import java.util.HashMap; >-import java.util.HashSet; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map; >-import java.util.Set; >- >-import org.eclipse.emf.common.notify.Adapter; >-import org.eclipse.emf.common.util.EList; >-import org.eclipse.emf.common.util.URI; >-import org.eclipse.emf.ecore.EObject; >-import org.eclipse.emf.ecore.EReference; >-import org.eclipse.emf.ecore.resource.Resource; >-import org.eclipse.emf.ecore.util.EcoreUtil; >-import org.eclipse.emf.ecore.util.InternalEList; >- >-import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >-import org.eclipse.gmf.runtime.emf.core.internal.resources.MResourceFactory; >-import org.eclipse.gmf.runtime.emf.core.internal.util.MSLUtil; >-import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil; >- >-/** >- * This class manages the reverse reference map feature at the object level. >- * When resources are loaded the reverse map gets updated without causing more >- * resources to be loaded. >- * >- * @author rafikj >- */ >-public class MSLObjectIndexer { >- >- private MSLEditingDomain domain = null; >- >- /** >- * Constructor. >- */ >- public MSLObjectIndexer(MSLEditingDomain domain) { >- >- super(); >- >- this.domain = domain; >- } >- >- /** >- * Registers a reference in the reverse reference map. >- */ >- public boolean registerReference(EObject referencer, EObject referenced, >- EReference reference) { >- >- // ignore non changeable and container/containment features. >- if ((!reference.isChangeable()) || (reference.isContainer()) >- || (reference.isContainment())) >- return false; >- >- if (referencer.eIsProxy()) >- return false; >- >- // register resource reference. >- Resource referencerResource = referencer.eResource(); >- >- Resource referencedResource = MSLUtil.getResource(domain, referenced); >- >- if (referenced.eIsProxy()) { >- >- URI uri = EcoreUtil.getURI(referenced); >- >- Resource.Factory factory = Resource.Factory.Registry.INSTANCE >- .getFactory(uri); >- >- if (!(factory instanceof MResourceFactory)) { >- >- if ((referencerResource == referencedResource) >- || ((referencedResource != null) && (referencedResource >- .isLoaded()))) >- referenced = EcoreUtil.resolve(referenced, domain >- .getResourceSet()); >- } >- } >- >- domain.getResourceIndexer().registerReference(referencerResource, >- referencedResource); >- >- return doRegisterReference(referencer, referenced, reference); >- } >- >- /** >- * Registers a reference in the reverse reference map. >- */ >- private boolean doRegisterReference(EObject referencer, EObject referenced, >- EReference reference) { >- >- // ignore features that have opposites. >- if (reference.getEOpposite() != null) >- return false; >- >- // objects must be resolved. >- if (referenced.eIsProxy()) >- return false; >- >- Map featureMap = getFeatureMap(referenced); >- >- if (featureMap == null) >- featureMap = createFeatureMap(referenced); >- >- WeakReference ref = new WeakReference(referencer); >- >- Object value = featureMap.get(reference); >- >- // value is a list. >- if (value instanceof List) { >- >- int index = -1; >- >- List referencerList = (List) value; >- >- for (int i = 0, count = referencerList.size(); i < count; i++) { >- >- WeakReference r = (WeakReference) referencerList.get(i); >- >- if (r == null) { >- >- // found empty slot. >- if (index == -1) >- index = i; >- >- } else { >- >- Object current = r.get(); >- >- // object already there. >- if (current == referencer) >- ref = null; >- >- else if (current == null) { >- >- referencerList.set(i, null); >- >- // found empty slot. >- if (index == -1) >- index = i; >- } >- } >- } >- >- // if not already there add. >- if (ref != null) { >- >- // resuse slot if any. >- if (index != -1) >- referencerList.set(index, ref); >- else >- referencerList.add(ref); >- } >- >- } else if (value instanceof WeakReference) { >- >- // value is a weak reference. >- WeakReference r = (WeakReference) value; >- >- Object current = r.get(); >- >- if (current == referencer) { >- >- // already there. >- ref = null; >- >- } else if (current == null) { >- >- // put in empty slot. >- featureMap.put(reference, ref); >- >- } else { >- >- // create a new list if more than one. >- List referencerList = new ArrayList(2); >- >- referencerList.add(r); >- referencerList.add(ref); >- >- featureMap.put(reference, referencerList); >- } >- >- } else if (value == null) { >- >- // found empty slot. >- featureMap.put(reference, ref); >- } >- >- return true; >- } >- >- /** >- * Deregisters a reference in the reverse reference map. >- */ >- public void deregisterReference(EObject referencer, EObject referenced, >- EReference reference) { >- >- // ignore non changeable and container/containment features. >- if ((!reference.isChangeable()) || (reference.isContainer()) >- || (reference.isContainment())) >- return; >- >- if (referencer.eIsProxy()) >- return; >- >- // deregister resource reference. >- Resource referencerResource = referencer.eResource(); >- >- Resource referencedResource = MSLUtil.getResource(domain, referenced); >- >- domain.getResourceIndexer().deregisterReference(referencerResource, >- referencedResource); >- >- doDeregisterReference(referencer, referenced, reference); >- } >- >- /** >- * Deregisters a reference in the reverse reference map. >- */ >- private void doDeregisterReference(EObject referencer, EObject referenced, >- EReference reference) { >- >- Map featureMap = getFeatureMap(referenced); >- >- if (featureMap == null) >- return; >- >- Object value = featureMap.get(reference); >- >- if (value instanceof List) { >- >- // value is a list. >- List referencerList = (List) value; >- >- boolean empty = true; >- >- for (int i = 0, count = referencerList.size(); i < count; i++) { >- >- WeakReference r = (WeakReference) referencerList.get(i); >- >- if (r != null) { >- >- Object current = r.get(); >- >- if (current == referencer) >- referencerList.set(i, null); >- >- else if (current == null) >- referencerList.set(i, null); >- >- else if (empty) >- empty = false; >- } >- } >- >- if (empty) >- featureMap.remove(reference); >- >- } else if (value instanceof WeakReference) { >- >- // value is a weak reference. >- WeakReference r = (WeakReference) value; >- >- if (r.get() == referencer) >- featureMap.remove(reference); >- >- } else >- return; >- >- if (featureMap.isEmpty()) >- removeFeatureMap(referenced); >- } >- >- /** >- * Registers references by traversing the referencer object. Referencer is a >- * non proxy object. >- */ >- public void registerReferences(EObject container, EObject eObject) { >- >- if (eObject.eIsProxy()) >- return; >- >- EList features = eObject.eClass().getEAllReferences(); >- >- Iterator i = features.iterator(); >- >- while (i.hasNext()) { >- >- EReference reference = (EReference) i.next(); >- >- if ((reference.isChangeable()) && (!reference.isContainer()) >- && (eObject.eIsSet(reference))) { >- >- if (reference.isMany()) { >- >- if (reference.isContainment()) { >- >- EList objects = (EList) eObject.eGet(reference); >- >- for (Iterator j = objects.iterator(); j.hasNext();) { >- >- EObject contained = (EObject) j.next(); >- >- if (contained != null) >- registerReferences(container, contained); >- } >- >- } else { >- >- EList objects = (EList) eObject.eGet(reference, false); >- >- // ensure references are not resolved. >- boolean resolve = true; >- >- for (Iterator j = ((InternalEList) objects) >- .basicIterator(); j.hasNext();) { >- >- EObject referenced = (EObject) j.next(); >- >- if (referenced != null) { >- >- if (!registerReference(eObject, referenced, >- reference)) >- resolve = false; >- } >- } >- >- // if all references were resolveable resolve the whole >- // list. >- if (resolve) { >- >- for (Iterator k = objects.iterator(); k.hasNext();) >- k.next(); >- } >- } >- >- } else { >- >- if (reference.isContainment()) { >- >- EObject contained = (EObject) eObject.eGet(reference); >- >- if (contained != null) >- registerReferences(container, contained); >- >- } else { >- >- // ensure reference is not resolved. >- EObject referenced = (EObject) eObject.eGet(reference, >- false); >- >- if (referenced != null) { >- >- boolean resolve = registerReference(eObject, >- referenced, reference); >- >- // if reference was resolveable resolve it. >- if (resolve) >- eObject.eGet(reference); >- } >- } >- } >- } >- } >- >- // register referencer resources. >- final Resource containerResource = container.eResource(); >- >- MSLReferenceVisitor visitor = new MSLReferenceVisitor(domain, eObject, >- false) { >- >- protected void visitedReferencer(EReference reference, >- EObject referencer) { >- >- Resource referencerResource = referencer.eResource(); >- >- domain.getResourceIndexer().registerReference( >- referencerResource, containerResource); >- } >- }; >- >- visitor.visitReferencers(); >- } >- >- /** >- * Deregisters references by traversing the referencer object. >- */ >- public void deregisterReferences(EObject container, EObject eObject) { >- deregisterReferences(container, eObject, eObject); >- } >- >- /** >- * Deregisters references by traversing the referencer object. >- */ >- public void deregisterReferences(EObject container, final EObject detached, >- EObject eObject) { >- >- if (eObject.eIsProxy()) >- return; >- >- final Resource containerResource = container.eResource(); >- >- EList features = eObject.eClass().getEAllReferences(); >- >- Iterator i = features.iterator(); >- >- while (i.hasNext()) { >- >- EReference reference = (EReference) i.next(); >- >- if ((reference.isChangeable()) && (!reference.isContainer()) >- && (eObject.eIsSet(reference))) { >- >- if (reference.isMany()) { >- >- if (reference.isContainment()) { >- >- EList objects = (EList) eObject.eGet(reference); >- >- for (Iterator j = objects.iterator(); j.hasNext();) { >- >- EObject contained = (EObject) j.next(); >- >- if (contained != null) >- deregisterReferences(container, detached, >- contained); >- } >- >- } else { >- >- EList objects = (EList) eObject.eGet(reference, false); >- >- // ensure references are not resolved. >- for (Iterator j = ((InternalEList) objects) >- .basicIterator(); j.hasNext();) { >- >- EObject referenced = (EObject) j.next(); >- >- if ((referenced != null) >- && (!EObjectUtil.contains(detached, referenced))) { >- >- Resource referencedResource = MSLUtil >- .getResource(domain, referenced); >- >- domain.getResourceIndexer() >- .deregisterReference(containerResource, >- referencedResource); >- } >- } >- } >- >- } else { >- >- if (reference.isContainment()) { >- >- EObject contained = (EObject) eObject.eGet(reference); >- >- if (contained != null) >- deregisterReferences(container, detached, contained); >- >- } else { >- >- // ensure reference is not resolved. >- EObject referenced = (EObject) eObject.eGet(reference, >- false); >- >- if ((referenced != null) >- && (!EObjectUtil.contains(detached, referenced))) { >- >- Resource referencedResource = MSLUtil.getResource( >- domain, referenced); >- >- domain.getResourceIndexer().deregisterReference( >- containerResource, referencedResource); >- } >- } >- } >- } >- } >- >- // deregister referencer resources. >- MSLReferenceVisitor visitor = new MSLReferenceVisitor(domain, eObject) { >- >- protected void visitedReferencer(EReference reference, >- EObject referencer) { >- >- if (!EObjectUtil.contains(detached, referencer)) { >- >- Resource referencerResource = referencer.eResource(); >- >- domain.getResourceIndexer().deregisterReference( >- referencerResource, containerResource); >- } >- } >- }; >- >- visitor.visitReferencers(); >- } >- >- /** >- * Resolves references by traversing the referencer object. Referencer is a >- * non proxy object. >- */ >- public void resolveReferences(EObject container, EObject eObject) { >- >- if (eObject.eIsProxy()) >- return; >- >- EList features = eObject.eClass().getEAllReferences(); >- >- Iterator i = features.iterator(); >- >- while (i.hasNext()) { >- >- EReference reference = (EReference) i.next(); >- >- if ((reference.isChangeable()) && (!reference.isContainer()) >- && (eObject.eIsSet(reference))) { >- >- if (reference.isMany()) { >- >- if (reference.isContainment()) { >- >- EList objects = (EList) eObject.eGet(reference); >- >- for (Iterator j = objects.iterator(); j.hasNext();) { >- >- EObject contained = (EObject) j.next(); >- >- if (contained != null) >- resolveReferences(container, contained); >- } >- >- } else { >- >- EList objects = (EList) eObject.eGet(reference, false); >- >- // ensure references are not resolved. >- boolean resolve = true; >- >- for (Iterator j = ((InternalEList) objects) >- .basicIterator(); j.hasNext();) { >- >- EObject referenced = (EObject) j.next(); >- >- if (referenced != null) { >- >- if (!resolveReference(eObject, referenced, >- reference)) >- resolve = false; >- } >- } >- >- // if all references were resolveable resolve the whole >- // list. >- if (resolve) { >- >- for (Iterator k = objects.iterator(); k.hasNext();) >- k.next(); >- } >- } >- >- } else { >- >- if (reference.isContainment()) { >- >- EObject contained = (EObject) eObject.eGet(reference); >- >- if (contained != null) >- resolveReferences(container, contained); >- >- } else { >- >- // ensure reference is not resolved. >- EObject referenced = (EObject) eObject.eGet(reference, >- false); >- >- if (referenced != null) { >- >- boolean resolve = resolveReference(eObject, >- referenced, reference); >- >- // if reference was resolveable resolve it. >- if (resolve) >- eObject.eGet(reference); >- } >- } >- } >- } >- } >- } >- >- /** >- * Resolves a reference. >- */ >- public boolean resolveReference(EObject referencer, EObject referenced, >- EReference reference) { >- >- // ignore non changeable and container/containment features. >- if ((!reference.isChangeable()) || (reference.isContainer()) >- || (reference.isContainment())) >- return false; >- >- if (referencer.eIsProxy()) >- return false; >- >- if (referenced.eIsProxy()) { >- >- // register resource reference. >- Resource referencerResource = referencer.eResource(); >- >- Resource referencedResource = MSLUtil.getResource(domain, >- referenced); >- >- URI uri = EcoreUtil.getURI(referenced); >- >- Resource.Factory factory = Resource.Factory.Registry.INSTANCE >- .getFactory(uri); >- >- if (!(factory instanceof MResourceFactory)) { >- >- if ((referencerResource == referencedResource) >- || ((referencedResource != null) && (referencedResource >- .isLoaded()))) >- referenced = EcoreUtil.resolve(referenced, domain >- .getResourceSet()); >- } >- >- if (referenced.eIsProxy()) >- return false; >- else >- doRegisterReference(referencer, referenced, reference); >- } >- >- return true; >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Map getGroupedReferencers(EObject referenced) { >- return getGroupedReferencers(referenced, true); >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Map getGroupedReferencers(EObject referenced, boolean resolve) { >- >- Map map = getFeatureMap(referenced); >- >- Map newMap = null; >- >- List features = referenced.eClass().getEAllReferences(); >- >- for (Iterator i = features.iterator(); i.hasNext();) { >- >- EReference reference = (EReference) i.next(); >- >- EReference opposite = reference.getEOpposite(); >- >- if (opposite != null) { >- >- Set referencers = getReferencers(referenced, opposite, resolve); >- >- if (!referencers.isEmpty()) { >- >- if (newMap == null) >- newMap = (map == null) ? (new HashMap()) >- : (new HashMap(map)); >- >- List newReferencers = new ArrayList(referencers.size()); >- >- for (Iterator j = referencers.iterator(); j.hasNext();) >- newReferencers.add(new WeakReference(j.next())); >- >- newMap.put(opposite, newReferencers); >- } >- } >- } >- >- if (newMap != null) >- return Collections.unmodifiableMap(newMap); >- >- else if (map != null) >- return Collections.unmodifiableMap(map); >- >- else >- return Collections.EMPTY_MAP; >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Set getAllReferencers(EObject referenced) { >- return getAllReferencers(referenced, true); >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Set getAllReferencers(EObject referenced, boolean resolve) { >- >- if (referenced.eIsProxy()) >- return Collections.EMPTY_SET; >- >- final Set set = new HashSet(); >- >- MSLReferenceVisitor visitor = new MSLReferenceVisitor(domain, >- referenced, resolve) { >- >- protected void visitedReferencer(EReference reference, >- EObject referencer) { >- >- if (!referencer.eIsProxy()) >- set.add(referencer); >- } >- }; >- >- visitor.visitReferencers(); >- >- return Collections.unmodifiableSet(set); >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Set getReferencers(EObject referenced, EReference reference) { >- return getReferencers(referenced, reference, true); >- } >- >- /** >- * Retrieves reverse references. >- */ >- public Set getReferencers(EObject referenced, EReference reference, >- boolean resolve) { >- >- if (referenced.eIsProxy()) >- return Collections.EMPTY_SET; >- >- if ((reference.isChangeable()) && (!reference.isContainer()) >- && (!reference.isContainment())) { >- >- EReference opposite = reference.getEOpposite(); >- >- if (opposite == null) { >- >- Map featureMap = getFeatureMap(referenced); >- >- if (featureMap != null) { >- >- Object value = featureMap.get(reference); >- >- if (value instanceof List) { >- >- // value is a list. >- List referencerList = (List) value; >- >- Set set = new HashSet(); >- >- for (int i = 0, count = referencerList.size(); i < count; i++) { >- >- WeakReference r = (WeakReference) referencerList >- .get(i); >- >- if (r != null) { >- >- EObject referencer = (EObject) r.get(); >- >- if ((referencer != null) >- && (!referencer.eIsProxy())) >- set.add(referencer); >- } >- } >- >- return Collections.unmodifiableSet(set); >- >- } else if (value instanceof WeakReference) { >- >- // value is a weak reference. >- WeakReference r = (WeakReference) value; >- >- EObject referencer = (EObject) r.get(); >- >- if (referencer != null) >- return Collections.singleton(referencer); >- } >- } >- >- } else { >- >- if ((opposite.isChangeable()) && (!opposite.isContainer()) >- && (!opposite.isContainment()) >- && (referenced.eIsSet(opposite))) { >- >- if (opposite.isMany()) { >- >- List referencers = (List) referenced.eGet(opposite, >- resolve); >- >- if (!referencers.isEmpty()) { >- >- // try not to resolve if asked to. >- if (resolve) >- return Collections.unmodifiableSet(new HashSet( >- referencers)); >- else { >- >- Set nonProxyReferencers = new HashSet(); >- >- for (Iterator j = ((InternalEList) referencers) >- .basicIterator(); j.hasNext();) { >- >- EObject referencer = (EObject) j.next(); >- >- if ((referencer != null) >- && (!referencer.eIsProxy())) >- nonProxyReferencers.add(referencer); >- } >- >- return Collections >- .unmodifiableSet(nonProxyReferencers); >- } >- } >- >- } else { >- >- // try not to resolve if asked to. >- EObject referencer = (EObject) referenced.eGet( >- opposite, resolve); >- >- if ((referencer != null) && (!referencer.eIsProxy())) >- return Collections.singleton(referencer); >- } >- } >- } >- } >- >- return Collections.EMPTY_SET; >- } >- >- /** >- * Gets feature map of a given object. >- */ >- private Map getFeatureMap(EObject referenced) { >- >- for (int i = 0, count = referenced.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referenced.eAdapters().get(i); >- >- if (adapter instanceof MSLReferenceAdapter) >- return (Map) adapter; >- } >- >- return null; >- } >- >- /** >- * Creates feature map of a given object. >- */ >- private Map createFeatureMap(EObject referenced) { >- >- Map map = new MSLReferenceAdapter(); >- >- referenced.eAdapters().add(map); >- >- return map; >- } >- >- /** >- * Removes feature map of a given object. >- */ >- private Map removeFeatureMap(EObject referenced) { >- >- for (int i = 0, count = referenced.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referenced.eAdapters().get(i); >- >- if (adapter instanceof MSLReferenceAdapter) { >- >- referenced.eAdapters().remove(i); >- >- return (Map) adapter; >- } >- } >- >- return null; >- } >-} >- >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLExportsAdapter.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLExportsAdapter.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLExportsAdapter.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLExportsAdapter.java 29 Dec 2005 19:01:08 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,66 +0,0 @@ >-/****************************************************************************** >- * Copyright (c) 2002, 2003 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 Corporation - initial API and implementation >- ****************************************************************************/ >- >-package org.eclipse.gmf.runtime.emf.core.internal.index; >- >-import java.util.HashMap; >- >-import org.eclipse.emf.common.notify.Adapter; >-import org.eclipse.emf.common.notify.Notification; >-import org.eclipse.emf.common.notify.Notifier; >- >-/** >- * This class defines the reference adapter that will hold the exports for a >- * given resource. >- * >- * @author rafikj >- */ >-public class MSLExportsAdapter >- extends HashMap >- implements Adapter { >- >- private static final long serialVersionUID = -9110312883845863489L; >- >- /** >- * Constructor. >- */ >- public MSLExportsAdapter() { >- super(2); >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification) >- */ >- public void notifyChanged(Notification notification) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#getTarget() >- */ >- public Notifier getTarget() { >- return null; >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier) >- */ >- public void setTarget(Notifier newTarget) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object) >- */ >- public boolean isAdapterForType(Object type) { >- return false; >- } >-} >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLResourceIndexer.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLResourceIndexer.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLResourceIndexer.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLResourceIndexer.java 12 Sep 2005 21:25:13 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,388 +0,0 @@ >-/****************************************************************************** >- * Copyright (c) 2002, 2003 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 Corporation - initial API and implementation >- ****************************************************************************/ >- >-package org.eclipse.gmf.runtime.emf.core.internal.index; >- >-import java.util.Collections; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map; >-import java.util.Set; >- >-import org.eclipse.emf.common.notify.Adapter; >-import org.eclipse.emf.common.notify.impl.NotificationImpl; >-import org.eclipse.emf.ecore.EObject; >-import org.eclipse.emf.ecore.resource.Resource; >- >-import org.eclipse.gmf.runtime.emf.core.EventTypes; >-import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >- >-/** >- * This class manages the reverse reference map feature at the resource level. >- * When resources are loaded the reverse map gets updated without causing more >- * resources to be loaded. >- * >- * @author rafikj >- */ >-public class MSLResourceIndexer { >- >- private MSLEditingDomain domain = null; >- >- /** >- * Constructor. >- */ >- public MSLResourceIndexer(MSLEditingDomain domain) { >- >- super(); >- >- this.domain = domain; >- } >- >- /** >- * Registers a reference in the imports and exports maps. >- */ >- public void registerReference(final Resource referencer, >- final Resource referenced) { >- >- if ((referencer != null) && (referenced != null) >- && (referencer != referenced)) { >- >- Map importsMap = getImportsMap(referencer); >- >- if (importsMap == null) >- importsMap = createImportsMap(referencer); >- >- Integer importsCount = (Integer) importsMap.get(referenced); >- >- if (importsCount == null) { >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.IMPORT, (Object) null, referenced, -1) { >- >- public Object getNotifier() { >- return referencer; >- } >- }); >- >- importsCount = new Integer(1); >- >- } else >- importsCount = new Integer(importsCount.intValue() + 1); >- >- importsMap.put(referenced, importsCount); >- >- Map exportsMap = getExportsMap(referenced); >- >- if (exportsMap == null) >- exportsMap = createExportsMap(referenced); >- >- Integer exportsCount = (Integer) exportsMap.get(referencer); >- >- if (exportsCount == null) { >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.EXPORT, (Object) null, referencer, -1) { >- >- public Object getNotifier() { >- return referenced; >- } >- }); >- >- exportsCount = new Integer(1); >- >- } else >- exportsCount = new Integer(exportsCount.intValue() + 1); >- >- exportsMap.put(referencer, exportsCount); >- } >- } >- >- /** >- * Dregisters a reference in the imports and exports maps. >- */ >- public void deregisterReference(final Resource referencer, >- final Resource referenced) { >- >- if ((referencer != null) && (referenced != null) >- && (referencer != referenced)) { >- >- Map importsMap = getImportsMap(referencer); >- >- if (importsMap != null) { >- >- Integer importsCount = (Integer) importsMap.get(referenced); >- >- if (importsCount != null) { >- >- if (importsCount.intValue() < 2) { >- >- importsMap.remove(referenced); >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.IMPORT, referenced, (Object) null, -1) { >- >- public Object getNotifier() { >- return referencer; >- } >- }); >- } else >- importsMap.put(referenced, new Integer(importsCount >- .intValue() - 1)); >- } >- >- if (importsMap.isEmpty()) >- removeImportsMap(referencer); >- } >- >- Map exportsMap = getExportsMap(referenced); >- >- if (exportsMap != null) { >- >- Integer exportsCount = (Integer) exportsMap.get(referencer); >- >- if (exportsCount != null) { >- >- if (exportsCount.intValue() < 2) { >- >- exportsMap.remove(referencer); >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.EXPORT, referencer, (Object) null, -1) { >- >- public Object getNotifier() { >- return referenced; >- } >- }); >- } else >- exportsMap.put(referencer, new Integer(exportsCount >- .intValue() - 1)); >- } >- >- if (exportsMap.isEmpty()) >- removeExportsMap(referenced); >- } >- } >- } >- >- /** >- * Registers references by traversing the referencer resource. >- */ >- public void registerReferences(Resource referencer) { >- >- List referencerContents = referencer.getContents(); >- >- if (referencerContents == null) >- return; >- >- for (Iterator i = referencerContents.iterator(); i.hasNext();) { >- >- EObject referencerRoot = (EObject) i.next(); >- >- if (referencerRoot != null) { >- >- domain.getObjectIndexer().registerReferences(referencerRoot, >- referencerRoot); >- >- Object[] exports = getExports(referencer).toArray(); >- >- for (int j = 0; j < exports.length; j++) { >- >- Resource resource = (Resource) exports[j]; >- >- List resourceContents = resource.getContents(); >- >- if (resourceContents == null) >- continue; >- >- for (Iterator k = resourceContents.iterator(); k.hasNext();) { >- >- EObject resourceRoot = (EObject) k.next(); >- >- if (resourceRoot != null) >- domain.getObjectIndexer().resolveReferences( >- resourceRoot, resourceRoot); >- } >- } >- } >- } >- } >- >- /** >- * Cleans reference maps. >- */ >- public void deregisterReferences(final Resource referencer) { >- >- Object[] imports = getImports(referencer).toArray(); >- >- for (int i = 0; i < imports.length; i++) { >- >- final Resource referenced = (Resource) imports[i]; >- >- Map importsMap = getImportsMap(referencer); >- >- if (importsMap != null) { >- >- importsMap.remove(referenced); >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.IMPORT, referenced, (Object) null, -1) { >- >- public Object getNotifier() { >- return referencer; >- } >- }); >- >- if (importsMap.isEmpty()) >- removeImportsMap(referencer); >- } >- >- Map exportsMap = getExportsMap(referenced); >- >- if (exportsMap != null) { >- >- exportsMap.remove(referencer); >- >- domain.sendNotification(new NotificationImpl( >- EventTypes.EXPORT, referencer, (Object) null, -1) { >- >- public Object getNotifier() { >- return referenced; >- } >- }); >- >- if (exportsMap.isEmpty()) >- removeExportsMap(referenced); >- } >- } >- } >- >- /** >- * Gets the imports of a resource. >- */ >- public Set getImports(Resource referencer) { >- >- Map importsMap = getImportsMap(referencer); >- >- if (importsMap != null) >- return Collections.unmodifiableSet(importsMap.keySet()); >- else >- return Collections.EMPTY_SET; >- } >- >- /** >- * Gets the exports of a resource. >- */ >- public Set getExports(Resource referenced) { >- >- Map exportsMap = getExportsMap(referenced); >- >- if (exportsMap != null) >- return Collections.unmodifiableSet(exportsMap.keySet()); >- else >- return Collections.EMPTY_SET; >- } >- >- /** >- * Gets imports map of a given resource. >- */ >- private Map getImportsMap(Resource referencer) { >- >- for (int i = 0, count = referencer.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referencer.eAdapters().get(i); >- >- if (adapter instanceof MSLImportsAdapter) >- return (Map) adapter; >- } >- >- return null; >- } >- >- /** >- * Creates imports map of a given resource. >- */ >- private Map createImportsMap(Resource referencer) { >- >- Map map = new MSLImportsAdapter(); >- >- referencer.eAdapters().add(map); >- >- return map; >- } >- >- /** >- * Removes imports map of a given resource. >- */ >- private Map removeImportsMap(Resource referencer) { >- >- for (int i = 0, count = referencer.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referencer.eAdapters().get(i); >- >- if (adapter instanceof MSLImportsAdapter) { >- >- referencer.eAdapters().remove(i); >- >- return (Map) adapter; >- } >- } >- >- return null; >- } >- >- /** >- * Gets exports map of a given resource. >- */ >- private Map getExportsMap(Resource referenced) { >- >- for (int i = 0, count = referenced.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referenced.eAdapters().get(i); >- >- if (adapter instanceof MSLExportsAdapter) >- return (Map) adapter; >- } >- >- return null; >- } >- >- /** >- * Creates exports map of a given resource. >- */ >- private Map createExportsMap(Resource referenced) { >- >- Map map = new MSLExportsAdapter(); >- >- referenced.eAdapters().add(map); >- >- return map; >- } >- >- /** >- * Removes exports map of a given resource. >- */ >- private Map removeExportsMap(Resource referenced) { >- >- for (int i = 0, count = referenced.eAdapters().size(); i < count; i++) { >- >- Adapter adapter = (Adapter) referenced.eAdapters().get(i); >- >- if (adapter instanceof MSLExportsAdapter) { >- >- referenced.eAdapters().remove(i); >- >- return (Map) adapter; >- } >- } >- >- return null; >- } >-} >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceAdapter.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceAdapter.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceAdapter.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLReferenceAdapter.java 29 Dec 2005 19:01:08 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,66 +0,0 @@ >-/****************************************************************************** >- * Copyright (c) 2002, 2003 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 Corporation - initial API and implementation >- ****************************************************************************/ >- >-package org.eclipse.gmf.runtime.emf.core.internal.index; >- >-import java.util.HashMap; >- >-import org.eclipse.emf.common.notify.Adapter; >-import org.eclipse.emf.common.notify.Notification; >-import org.eclipse.emf.common.notify.Notifier; >- >-/** >- * This class defines the reference adapter that will hold the reverse map for a >- * given EObject. >- * >- * @author rafikj >- */ >-public class MSLReferenceAdapter >- extends HashMap >- implements Adapter { >- >- private static final long serialVersionUID = 1989964645244552123L; >- >- /** >- * Constructor. >- */ >- public MSLReferenceAdapter() { >- super(2); >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification) >- */ >- public void notifyChanged(Notification notification) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#getTarget() >- */ >- public Notifier getTarget() { >- return null; >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier) >- */ >- public void setTarget(Notifier newTarget) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object) >- */ >- public boolean isAdapterForType(Object type) { >- return false; >- } >-} >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLImportsAdapter.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLImportsAdapter.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLImportsAdapter.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLImportsAdapter.java 29 Dec 2005 19:01:08 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,66 +0,0 @@ >-/****************************************************************************** >- * Copyright (c) 2002, 2003 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 Corporation - initial API and implementation >- ****************************************************************************/ >- >-package org.eclipse.gmf.runtime.emf.core.internal.index; >- >-import java.util.HashMap; >- >-import org.eclipse.emf.common.notify.Adapter; >-import org.eclipse.emf.common.notify.Notification; >-import org.eclipse.emf.common.notify.Notifier; >- >-/** >- * This class defines the reference adapter that will hold the imports for a >- * given resource. >- * >- * @author rafikj >- */ >-public class MSLImportsAdapter >- extends HashMap >- implements Adapter { >- >- private static final long serialVersionUID = 7770242431763053066L; >- >- /** >- * Constructor. >- */ >- public MSLImportsAdapter() { >- super(2); >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification) >- */ >- public void notifyChanged(Notification notification) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#getTarget() >- */ >- public Notifier getTarget() { >- return null; >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier) >- */ >- public void setTarget(Notifier newTarget) { >- // do nothing. >- } >- >- /** >- * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object) >- */ >- public boolean isAdapterForType(Object type) { >- return false; >- } >-} >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/domain/MSLEditingDomain.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/domain/MSLEditingDomain.java,v >retrieving revision 1.12 >diff -u -r1.12 MSLEditingDomain.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/domain/MSLEditingDomain.java 26 Jan 2006 21:37:49 -0000 1.12 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/domain/MSLEditingDomain.java 31 Jan 2006 22:02:44 -0000 >@@ -70,8 +70,7 @@ > import org.eclipse.gmf.runtime.emf.core.exceptions.MSLRuntimeException; > import org.eclipse.gmf.runtime.emf.core.internal.commands.MSLCommandGenerator; > import org.eclipse.gmf.runtime.emf.core.internal.commands.MSLUndoStack; >-import org.eclipse.gmf.runtime.emf.core.internal.index.MSLObjectIndexer; >-import org.eclipse.gmf.runtime.emf.core.internal.index.MSLResourceIndexer; >+import org.eclipse.gmf.runtime.emf.core.internal.index.MSLCrossReferenceAdapter; > import org.eclipse.gmf.runtime.emf.core.internal.l10n.EMFCoreMessages; > import org.eclipse.gmf.runtime.emf.core.internal.notifications.MSLContentAdapter; > import org.eclipse.gmf.runtime.emf.core.internal.notifications.MSLEventBroker; >@@ -130,9 +129,7 @@ > > private MSLPathmap pathmap = null; > >- private MSLObjectIndexer objectIndexer = null; >- >- private MSLResourceIndexer resourceIndexer = null; >+ private MSLCrossReferenceAdapter crossReferenceAdapter = null; > > private static Map resourceSets = new WeakHashMap(); > >@@ -187,12 +184,12 @@ > > pathmap = new MSLPathmap(this); > >- objectIndexer = new MSLObjectIndexer(this); >- >- resourceIndexer = new MSLResourceIndexer(this); >+ crossReferenceAdapter = new MSLCrossReferenceAdapter(this); > > ResourceSet resourceSet = getResourceSet(); > >+ resourceSet.eAdapters().add(crossReferenceAdapter); >+ > extendedMetaData = new MSLExtendedMetaData(); > > contentAdapter.listenToModifications(resourceSet); >@@ -268,17 +265,10 @@ > } > > /** >- * Returns the object indexer. >+ * Returns the cross reference adapter. > */ >- public MSLObjectIndexer getObjectIndexer() { >- return objectIndexer; >- } >- >- /** >- * Returns the resource indexer. >- */ >- public MSLResourceIndexer getResourceIndexer() { >- return resourceIndexer; >+ public MSLCrossReferenceAdapter getCrossReferenceAdapter() { >+ return crossReferenceAdapter; > } > > /** >@@ -1672,14 +1662,14 @@ > * @see org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain#getImports(org.eclipse.emf.ecore.resource.Resource) > */ > public Collection getImports(Resource resource) { >- return resourceIndexer.getImports(resource); >+ return crossReferenceAdapter.getImports(resource); > } > > /** > * @see org.eclipse.gmf.runtime.emf.core.edit.MEditingDomain#getExports(org.eclipse.emf.ecore.resource.Resource) > */ > public Collection getExports(Resource resource) { >- return resourceIndexer.getExports(resource); >+ return crossReferenceAdapter.getExports(resource); > } > > /** >@@ -1789,7 +1779,7 @@ > > if (!exports.contains(directExport)) { > >- directExports.add(directExport); >+ exports.add(directExport); > > getAllExports(directExport, exports, unload); > } >@@ -1830,6 +1820,9 @@ > if (currentDomain instanceof MSLEditingDomain) { > // remove current content adapter > rset.eAdapters().remove(((MSLEditingDomain) currentDomain).getContentAdapter()); >+ >+ // remove cross reference adapter >+ rset.eAdapters().remove(((MSLEditingDomain) currentDomain).getCrossReferenceAdapter()); > } > > if (domain instanceof MSLEditingDomain) { >@@ -1838,6 +1831,9 @@ > // attach new content adapter > rset.eAdapters().add(newDomain.getContentAdapter()); > >+ // attach new cross reference adapter >+ rset.eAdapters().add(newDomain.getCrossReferenceAdapter()); >+ > // for each resource that is loaded, ensure that the new domain > // know that it has finished loading > for (Iterator iter = rset.getResources().iterator(); iter.hasNext();) { >Index: src/org/eclipse/gmf/runtime/emf/core/internal/util/MSLUtil.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/util/MSLUtil.java,v >retrieving revision 1.6 >diff -u -r1.6 MSLUtil.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/util/MSLUtil.java 26 Jan 2006 15:37:26 -0000 1.6 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/util/MSLUtil.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2002, 2004 IBM Corporation and others. >+ * Copyright (c) 2002-2006 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 >@@ -44,8 +44,6 @@ > import org.eclipse.emf.ecore.resource.ResourceSet; > import org.eclipse.emf.ecore.util.EcoreUtil; > import org.eclipse.emf.ecore.xmi.XMLResource; >-import org.osgi.framework.Bundle; >- > import org.eclipse.gmf.runtime.common.core.util.Trace; > import org.eclipse.gmf.runtime.emf.core.EventTypes; > import org.eclipse.gmf.runtime.emf.core.IValidationStatus; >@@ -65,6 +63,7 @@ > import org.eclipse.gmf.runtime.emf.core.services.metamodel.IMetamodelSupport; > import org.eclipse.gmf.runtime.emf.core.util.EObjectUtil; > import org.eclipse.gmf.runtime.emf.core.util.MetaModelUtil; >+import org.osgi.framework.Bundle; > > import com.ibm.icu.util.StringTokenizer; > >@@ -154,6 +153,8 @@ > eClass); > > domain.getContentAdapter().listenToModifications(eObject); >+ >+ eObject.eAdapters().add(domain.getCrossReferenceAdapter()); > > if (sendEvents) > sendCreateEvent(domain, eObject); >@@ -724,9 +725,6 @@ > } > } > >- domain.getResourceIndexer() >- .registerReferences(resource); >- > return null; > } > }); >@@ -735,74 +733,6 @@ > } > > /** >- * Process references and update reference maps. >- */ >- public static void registerReferences(MSLEditingDomain domain, >- EObject eObject, EReference reference, List newObjects, >- List oldObjects) { >- >- if (reference.isContainment()) { >- >- if (!newObjects.isEmpty()) { >- >- Iterator i = newObjects.iterator(); >- >- while (i.hasNext()) { >- >- EObject newObject = (EObject) i.next(); >- >- domain.getObjectIndexer().registerReferences(eObject, >- newObject); >- } >- } >- >- if (!oldObjects.isEmpty()) { >- >- Iterator i = oldObjects.iterator(); >- >- while (i.hasNext()) { >- >- EObject oldObject = (EObject) i.next(); >- >- domain.getObjectIndexer().deregisterReferences(eObject, >- oldObject); >- } >- } >- >- } else { >- >- if (!newObjects.isEmpty()) { >- >- Iterator i = newObjects.iterator(); >- >- while (i.hasNext()) { >- >- EObject newObject = (EObject) i.next(); >- >- // registers reference in reverse reference map. >- domain.getObjectIndexer().registerReference(eObject, >- newObject, reference); >- } >- } >- >- if (!oldObjects.isEmpty()) { >- >- Iterator i = oldObjects.iterator(); >- >- while (i.hasNext()) { >- >- EObject oldObject = (EObject) i.next(); >- >- // deregisters reference in reverse reference >- // map. >- domain.getObjectIndexer().deregisterReference(eObject, >- oldObject, reference); >- } >- } >- } >- } >- >- /** > * Returns all of the children of the validation <code>status</code> that > * indicate violated constraints (i.e., problems). These will be some > * combination of errors, warnings, and informational messages. No reports >Index: src/org/eclipse/gmf/runtime/emf/core/util/EObjectUtil.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/util/EObjectUtil.java,v >retrieving revision 1.3 >diff -u -r1.3 EObjectUtil.java >--- src/org/eclipse/gmf/runtime/emf/core/util/EObjectUtil.java 31 Oct 2005 19:43:48 -0000 1.3 >+++ src/org/eclipse/gmf/runtime/emf/core/util/EObjectUtil.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2004 IBM Corporation and others. >+ * Copyright (c) 2004-2006 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 >@@ -13,6 +13,7 @@ > > import java.util.ArrayList; > import java.util.Collection; >+import java.util.Collections; > import java.util.Iterator; > import java.util.List; > import java.util.Map; >@@ -30,6 +31,7 @@ > import org.eclipse.emf.ecore.EStructuralFeature; > 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.util.EcoreUtil; > import org.eclipse.gmf.runtime.common.core.util.Trace; > import org.eclipse.gmf.runtime.emf.clipboard.core.ClipboardUtil; >@@ -39,6 +41,7 @@ > import org.eclipse.gmf.runtime.emf.core.edit.MRunnable; > import org.eclipse.gmf.runtime.emf.core.exceptions.MSLRuntimeException; > import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >+import org.eclipse.gmf.runtime.emf.core.internal.index.MSLCrossReferenceAdapter; > import org.eclipse.gmf.runtime.emf.core.internal.index.MSLReferenceVisitor; > import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLDebugOptions; > import org.eclipse.gmf.runtime.emf.core.internal.plugin.MSLPlugin; >@@ -563,7 +566,7 @@ > > for (int j = 0; j < list.length; j++) { > >- Object object = (EObject) list[j]; >+ Object object = list[j]; > > newList.add(object); > } >@@ -636,6 +639,13 @@ > if (domain == null) > domain = (MSLEditingDomain) MEditingDomain.INSTANCE; > >+ MSLCrossReferenceAdapter crossReferenceAdapter = >+ MSLCrossReferenceAdapter.getCrossReferenceAdapter(eObject); >+ >+ if (crossReferenceAdapter == null) { >+ return Collections.EMPTY_LIST; >+ } >+ > if ((features != null) && (features.length != 0)) { > > Collection referencers = new ArrayList(); >@@ -644,8 +654,8 @@ > > EReference feature = features[i]; > >- Iterator j = domain.getObjectIndexer().getReferencers(eObject, >- feature).iterator(); >+ Iterator j = crossReferenceAdapter.getInverseReferencers(eObject, >+ feature, null).iterator(); > > while (j.hasNext()) { > >@@ -658,7 +668,7 @@ > return referencers; > > } else >- return domain.getObjectIndexer().getAllReferencers(eObject); >+ return crossReferenceAdapter.getInverseReferencers(eObject, null, null); > } > > /** >Index: src/org/eclipse/gmf/runtime/emf/core/internal/resources/MResource.java >=================================================================== >RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.emf.core/src/org/eclipse/gmf/runtime/emf/core/internal/resources/MResource.java,v >retrieving revision 1.2 >diff -u -r1.2 MResource.java >--- src/org/eclipse/gmf/runtime/emf/core/internal/resources/MResource.java 12 Sep 2005 21:25:12 -0000 1.2 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/resources/MResource.java 31 Jan 2006 22:02:44 -0000 >@@ -1,5 +1,5 @@ > /****************************************************************************** >- * Copyright (c) 2004 IBM Corporation and others. >+ * Copyright (c) 2004-2006 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 >@@ -76,10 +76,13 @@ > } > > // Override to alter the behavior of reference registration. >+ /** >+ * @deprecated No longer necessary to register references. The cross >+ * reference adapter takes care of this. >+ */ > public void registerReferences(MEditingDomain domain, EObject eObject, > EReference reference, List newObjects, List oldObjects) { >- MSLUtil.registerReferences((MSLEditingDomain) domain, eObject, >- reference, newObjects, oldObjects); >+ // empty > } > } > } >\ No newline at end of file >Index: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLCrossReferenceAdapter.java >=================================================================== >RCS file: src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLCrossReferenceAdapter.java >diff -N src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLCrossReferenceAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/gmf/runtime/emf/core/internal/index/MSLCrossReferenceAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,564 @@ >+/****************************************************************************** >+ * Copyright (c) 2006 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 Corporation - initial API and implementation >+ ****************************************************************************/ >+ >+package org.eclipse.gmf.runtime.emf.core.internal.index; >+ >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Collections; >+import java.util.HashMap; >+import java.util.HashSet; >+import java.util.Iterator; >+import java.util.List; >+import java.util.Map; >+import java.util.Set; >+ >+import org.eclipse.emf.common.notify.Adapter; >+import org.eclipse.emf.common.notify.Notification; >+import org.eclipse.emf.common.notify.Notifier; >+import org.eclipse.emf.common.notify.impl.NotificationImpl; >+import org.eclipse.emf.common.util.TreeIterator; >+import org.eclipse.emf.ecore.EClass; >+import org.eclipse.emf.ecore.EObject; >+import org.eclipse.emf.ecore.EReference; >+import org.eclipse.emf.ecore.InternalEObject; >+import org.eclipse.emf.ecore.EStructuralFeature.Setting; >+import org.eclipse.emf.ecore.resource.Resource; >+import org.eclipse.emf.ecore.resource.ResourceSet; >+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; >+import org.eclipse.gmf.runtime.emf.core.EventTypes; >+import org.eclipse.gmf.runtime.emf.core.internal.domain.MSLEditingDomain; >+ >+/** >+ * An adapter that maintains itself as an adapter for all contained objects. >+ * It can be installed for an {@link EObject}, a {@link Resource}, or a {@link ResourceSet}. >+ * <p> >+ * This adapter maintain information on inverse references, resource imports, and resource >+ * exports. >+ * >+ * @author Christian Vogt (cvogt) >+ */ >+public class MSLCrossReferenceAdapter extends ECrossReferenceAdapter { >+ >+ private MSLEditingDomain domain; >+ >+ private Map imports = new HashMap(); >+ >+ private Map exports = new HashMap(); >+ >+ /** >+ * Constructor. >+ * >+ * @param domain a (@link MSLEditingDomain} >+ */ >+ public MSLCrossReferenceAdapter(MSLEditingDomain domain) { >+ super(); >+ this.domain = domain; >+ } >+ >+ /** >+ * Updates imports and exports maps. >+ * >+ * @param notification the event notification >+ */ >+ public void selfAdapt(Notification notification) { >+ super.selfAdapt(notification); >+ Object notifier = notification.getNotifier(); >+ Object feature = notification.getFeature(); >+ >+ // update import / export information when a resource >+ // is unloaded >+ if (notifier instanceof Resource) { >+ if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED >+ && !notification.getNewBooleanValue()) { >+ deregisterReferences((Resource)notifier); >+ } >+ return; >+ } >+ >+ // interested in maintaining import / export information >+ // when the notifier is an EObject and the feature is a >+ // non-containment EReference >+ if (!(notifier instanceof EObject) >+ || !(feature instanceof EReference)) { >+ return; >+ } >+ >+ EReference reference = (EReference)feature; >+ if (reference.isContainment()) { >+ return; >+ } >+ >+ switch (notification.getEventType()) { >+ case Notification.RESOLVE: >+ case Notification.SET: >+ case Notification.UNSET: { >+ EObject oldValue = (EObject) notification.getOldValue(); >+ if (oldValue != null) { >+ deregisterReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ oldValue.eResource()); >+ } >+ EObject newValue = (EObject) notification.getNewValue(); >+ if (newValue != null) { >+ registerReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ newValue.eResource()); >+ } >+ break; >+ } >+ case Notification.ADD: { >+ EObject newValue = (EObject) notification.getNewValue(); >+ if (newValue != null) { >+ registerReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ newValue.eResource()); >+ } >+ break; >+ } >+ case Notification.ADD_MANY: { >+ Collection newValues = (Collection) notification.getNewValue(); >+ for (Iterator i = newValues.iterator(); i.hasNext();) { >+ EObject newValue = (EObject) i.next(); >+ registerReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ newValue.eResource()); >+ } >+ break; >+ } >+ case Notification.REMOVE: { >+ EObject oldValue = (EObject) notification.getOldValue(); >+ if (oldValue != null) { >+ deregisterReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ oldValue.eResource()); >+ } >+ break; >+ } >+ case Notification.REMOVE_MANY: { >+ Collection oldValues = (Collection) notification.getOldValue(); >+ for (Iterator i = oldValues.iterator(); i.hasNext();) { >+ EObject oldValue = (EObject) i.next(); >+ deregisterReference( >+ ((EObject)notification.getNotifier()).eResource(), >+ oldValue.eResource()); >+ } >+ break; >+ } >+ } >+ } >+ >+ /** >+ * @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#setTarget(org.eclipse.emf.common.notify.Notifier) >+ */ >+ public void setTarget(Notifier target) { >+ super.setTarget(target); >+ if (target instanceof Resource) { >+ Resource resource = (Resource)target; >+ for (TreeIterator conents = resource.getAllContents(); conents.hasNext(); ) { >+ EObject eObject = (EObject)conents.next(); >+ List allRefs = eObject.eClass().getEAllReferences(); >+ for (int i = 0; i < allRefs.size(); ++i) { >+ EReference eReference = (EReference)allRefs.get(i); >+ if (!eReference.isContainer() && !eReference.isContainment() && eObject.eIsSet(eReference)) { >+ if (eReference.isMany()) { >+ for (Iterator iter = ((Collection)eObject.eGet(eReference)).iterator(); iter.hasNext(); ) { >+ registerReference(resource, ((EObject)iter.next()).eResource()); >+ } >+ } else { >+ registerReference(resource, ((EObject)eObject.eGet(eReference)).eResource()); >+ } >+ } >+ } >+ } >+ } >+ } >+ >+ /** >+ * @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#unsetTarget(org.eclipse.emf.common.notify.Notifier) >+ */ >+ public void unsetTarget(Notifier target) { >+ super.unsetTarget(target); >+ if (target instanceof Resource) { >+ deregisterReferences((Resource)target); >+ } >+ } >+ >+ /** >+ * @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#isIncluded(org.eclipse.emf.ecore.EReference) >+ */ >+ protected boolean isIncluded(EReference eReference) { >+ return super.isIncluded(eReference) && eReference.isChangeable() >+ && !eReference.isContainer() && !eReference.isContainment(); >+ } >+ >+ /** >+ * @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#getInverseReferences(org.eclipse.emf.ecore.EObject) >+ */ >+ public Collection getInverseReferences(EObject eObject) { >+ Collection result = new ArrayList(); >+ >+ // removed the addition of eContainer from default behavior >+ >+ Collection nonNavigableInverseReferences = (Collection)inverseCrossReferencer.get(eObject); >+ if (nonNavigableInverseReferences != null) { >+ result.addAll(nonNavigableInverseReferences); >+ } >+ >+ for (Iterator i = eObject.eClass().getEAllReferences().iterator(); i.hasNext(); ) { >+ EReference eReference = (EReference)i.next(); >+ EReference eOpposite = eReference.getEOpposite(); >+ // added eReference.isChangeable() from default behavior >+ if (eOpposite != null && eReference.isChangeable() && !eReference.isContainer() && !eReference.isContainment() && eObject.eIsSet(eReference)) { >+ if (eReference.isMany()) { >+ for (Iterator j = ((Collection)eObject.eGet(eReference)).iterator(); j.hasNext(); ) { >+ InternalEObject referencingEObject = (InternalEObject)j.next(); >+ result.add(referencingEObject.eSetting(eOpposite)); >+ } >+ } else { >+ result.add(((InternalEObject)eObject.eGet(eReference)).eSetting(eOpposite)); >+ } >+ } >+ } >+ >+ return result; >+ } >+ >+ /** >+ * Gets the imports of a resource. >+ * >+ * @param referencer the resource to retrieve imports for >+ * @return a Set of resource imports >+ */ >+ public Set getImports(Resource referencer) { >+ >+ Map importsMap = getImportsMap(referencer); >+ >+ if (importsMap != null) { >+ return Collections.unmodifiableSet(importsMap.keySet()); >+ } else { >+ return Collections.EMPTY_SET; >+ } >+ } >+ >+ /** >+ * Gets the exports of a resource. >+ * >+ * @param referenced the resource to retrieve exports for >+ * @return a Set of resource exports >+ */ >+ public Set getExports(Resource referenced) { >+ >+ Map exportsMap = getExportsMap(referenced); >+ >+ if (exportsMap != null) { >+ return Collections.unmodifiableSet(exportsMap.keySet()); >+ } else { >+ return Collections.EMPTY_SET; >+ } >+ } >+ >+ /** >+ * Returns the imports map of the given resource. >+ * >+ * @param resource >+ * @return imports map of the given resource >+ */ >+ private Map getImportsMap(Resource resource) { >+ return (Map) imports.get(resource); >+ } >+ >+ /** >+ * Returns the exports map of the given resource. >+ * >+ * @param resource >+ * @return exports map of the given resource >+ */ >+ private Map getExportsMap(Resource resource) { >+ return (Map) exports.get(resource); >+ } >+ >+ /** >+ * Registers a reference updating the imports and exports maps >+ * accordingly. >+ * >+ * @param referencer the referencing resource >+ * @param referenced the referenced resouce >+ */ >+ private void registerReference(final Resource referencer, >+ final Resource referenced) { >+ >+ if ((referencer != null) && (referenced != null) >+ && (referencer != referenced)) { >+ >+ Map importsMap = getImportsMap(referencer); >+ >+ if (importsMap == null) { >+ importsMap = new HashMap(); >+ imports.put(referencer, importsMap); >+ } >+ >+ Integer importsCount = (Integer) importsMap.get(referenced); >+ >+ if (importsCount == null) { >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.IMPORT, (Object) null, referenced, -1) { >+ >+ public Object getNotifier() { >+ return referencer; >+ } >+ }); >+ >+ importsCount = new Integer(1); >+ >+ } else { >+ importsCount = new Integer(importsCount.intValue() + 1); >+ } >+ >+ importsMap.put(referenced, importsCount); >+ >+ Map exportsMap = getExportsMap(referenced); >+ >+ if (exportsMap == null) { >+ exportsMap = new HashMap(); >+ exports.put(referenced, exportsMap); >+ } >+ >+ Integer exportsCount = (Integer) exportsMap.get(referencer); >+ >+ if (exportsCount == null) { >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.EXPORT, (Object) null, referencer, -1) { >+ >+ public Object getNotifier() { >+ return referenced; >+ } >+ }); >+ >+ exportsCount = new Integer(1); >+ >+ } else { >+ exportsCount = new Integer(exportsCount.intValue() + 1); >+ } >+ >+ exportsMap.put(referencer, exportsCount); >+ } >+ } >+ >+ /** >+ * Deregisters a reference updating the imports and exports maps >+ * accordingly. >+ * >+ * @param referencer the referencing resource >+ * @param referenced the referenced resource >+ */ >+ private void deregisterReference(final Resource referencer, >+ final Resource referenced) { >+ >+ if ((referencer != null) && (referenced != null) >+ && (referencer != referenced)) { >+ >+ Map importsMap = getImportsMap(referencer); >+ >+ if (importsMap != null) { >+ >+ Integer importsCount = (Integer) importsMap.get(referenced); >+ >+ if (importsCount != null) { >+ >+ if (importsCount.intValue() < 2) { >+ >+ importsMap.remove(referenced); >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.IMPORT, referenced, (Object) null, -1) { >+ >+ public Object getNotifier() { >+ return referencer; >+ } >+ }); >+ } else { >+ importsMap.put(referenced, new Integer(importsCount >+ .intValue() - 1)); >+ } >+ } >+ >+ if (importsMap.isEmpty()) { >+ imports.remove(referencer); >+ } >+ } >+ >+ Map exportsMap = getExportsMap(referenced); >+ >+ if (exportsMap != null) { >+ >+ Integer exportsCount = (Integer) exportsMap.get(referencer); >+ >+ if (exportsCount != null) { >+ >+ if (exportsCount.intValue() < 2) { >+ >+ exportsMap.remove(referencer); >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.EXPORT, referencer, (Object) null, -1) { >+ >+ public Object getNotifier() { >+ return referenced; >+ } >+ }); >+ } else { >+ exportsMap.put(referencer, new Integer(exportsCount >+ .intValue() - 1)); >+ } >+ } >+ >+ if (exportsMap.isEmpty()) { >+ exports.remove(referenced); >+ } >+ } >+ } >+ } >+ >+ /** >+ * Cleans up a resource from the imports and exports maps. >+ * >+ * @param referencer the referencing resource >+ */ >+ private void deregisterReferences(final Resource referencer) { >+ >+ Object[] resImports = getImports(referencer).toArray(); >+ >+ for (int i = 0; i < resImports.length; i++) { >+ >+ final Resource referenced = (Resource) resImports[i]; >+ >+ Map importsMap = getImportsMap(referencer); >+ >+ if (importsMap != null) { >+ >+ importsMap.remove(referenced); >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.IMPORT, referenced, (Object) null, -1) { >+ >+ public Object getNotifier() { >+ return referencer; >+ } >+ }); >+ >+ if (importsMap.isEmpty()) { >+ imports.remove(referencer); >+ } >+ } >+ >+ Map exportsMap = getExportsMap(referenced); >+ >+ if (exportsMap != null) { >+ >+ exportsMap.remove(referencer); >+ >+ domain.sendNotification(new NotificationImpl( >+ EventTypes.EXPORT, referencer, (Object) null, -1) { >+ >+ public Object getNotifier() { >+ return referenced; >+ } >+ }); >+ >+ if (exportsMap.isEmpty()) { >+ exports.remove(referenced); >+ } >+ } >+ } >+ } >+ >+ >+ /** >+ * Returns a Set of EObjects that reference the given EObject. >+ * If an EReference is specified, the scope of the search is limited >+ * only to that EReference. To include all references specify a value of null. >+ * If an EClass type is specified, the returned Set will only include those >+ * referencers that match the given type. To include all types specify a value of null. >+ * >+ * @param referenced the referenced EObject >+ * @param reference the reference to find referencers on, null for any reference >+ * @param type the type of the referencers, use null for any type >+ * @return a Set of referencers >+ */ >+ public Set getInverseReferencers(EObject referenced, EReference reference, EClass type) { >+ return getReferencers(getInverseReferences(referenced), reference, type); >+ } >+ >+ /** >+ * Returns a Set of EObjects that reference the given EObject through a uni >+ * directional EReferences. If an EReference is specified, the scope of the >+ * search is limited only to that EReference. To include all references specify >+ * a value of null. If an EClass type is specified, the returned Set will only >+ * include those referencers that match the given type. To include all types >+ * specify a value of null. >+ * >+ * @param referenced the referenced EObject >+ * @param reference the reference to find referencers on, null for any reference >+ * @param type the type of the referencers, use null for any type >+ * @return a Set of referencers >+ */ >+ public Set getNonNavigableInverseReferencers(EObject referenced, EReference reference, EClass type) { >+ return getReferencers(getNonNavigableInverseReferences(referenced), reference, type); >+ } >+ >+ /** >+ * Extracts the EObjects from the EStructuralFeature.Setting references >+ * and returns a filtered Set based on the given reference and type. >+ * >+ * @param references a collection of EStructuralFeature.Setting >+ * @param reference the reference to find referencers on, null for any reference >+ * @param type the type of the referencers, use null for any type >+ * @return a Set of referencers >+ */ >+ private Set getReferencers(Collection references, EReference reference, EClass type) { >+ Set set = new HashSet(); >+ if (!references.isEmpty()) { >+ for (Iterator iter = references.iterator(); iter.hasNext(); ) { >+ Setting setting = (Setting) iter.next(); >+ if (reference == null || reference == setting.getEStructuralFeature()) { >+ EObject referencer = setting.getEObject(); >+ if (referencer != null && (type == null || type.isInstance(referencer))) { >+ set.add(referencer); >+ } >+ } >+ } >+ } >+ return set; >+ } >+ >+ /** >+ * Searches the adapter list of the given Notifier for an MSLCrossReferenceAdapter. >+ * If not found, returns null. >+ * >+ * @param notifier the notifier to search >+ * @return MSLCrossReferenceAdapter if found, otherwise null >+ */ >+ public static MSLCrossReferenceAdapter getCrossReferenceAdapter(Notifier notifier) { >+ List adapters = notifier.eAdapters(); >+ >+ for (int i = 0, size = adapters.size(); i < size; ++i) { >+ Adapter adapter = (Adapter)adapters.get(i); >+ if (adapter instanceof MSLCrossReferenceAdapter) { >+ return (MSLCrossReferenceAdapter)adapter; >+ } >+ } >+ return null; >+ } >+ >+}
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 Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 113892
: 33894