| author | Tamas Szabo | 2013-02-14 03:34:14 (EST) |
|---|---|---|
| committer | Istvan Rath | 2013-02-14 03:34:14 (EST) |
| commit | 465fe92d597a107b456f6e2a4dbe390055507419 (patch) (side-by-side diff) | |
| tree | 505faaf0cac009d664abb8eb8e41baa5bb4ff5bd | |
| parent | 2e0407d22c82d7f99c3cd2bfcc96ff88dc482c2e (diff) | |
| download | org.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.zip org.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.tar.gz org.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.tar.bz2 | |
[397893] apply Tamas Szabo's patch
3 files changed, 98 insertions, 255 deletions
diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java index a870f1b..39be8de 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java @@ -90,7 +90,7 @@ public class IncQueryBaseFactory { */ public TransitiveClosureHelper createTransitiveClosureHelper(Notifier emfRoot, Set<EReference> referencesToObserve) throws IncQueryBaseException { - return new TransitiveClosureHelperImpl(emfRoot, referencesToObserve); + return new TransitiveClosureHelperImpl(getInstance().createNavigationHelper(emfRoot, false, null), referencesToObserve); } } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java index ccf0d51..441ec37 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java @@ -13,117 +13,40 @@ package org.eclipse.incquery.runtime.base.core; import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; -import org.eclipse.emf.common.notify.Notifier; -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.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EObjectEList; +import org.eclipse.incquery.runtime.base.api.NavigationHelper; +import org.eclipse.incquery.runtime.base.exception.IncQueryBaseException; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource; import org.eclipse.incquery.runtime.base.itc.igraph.IGraphObserver; -public abstract class EMFDataSource implements IGraphDataSource<EObject> { - - private static abstract class ForNotifier extends EMFDataSource { - - private static final long serialVersionUID = -1156614160439765303L; - protected Notifier root; - - public ForNotifier(Notifier root, Set<EReference> _refToObserv) { - this.root = root; - refToObserv = _refToObserv; - } - - } - - public static class ForEObject extends ForNotifier { - - private static final long serialVersionUID = 5213298003205081695L; - - public ForEObject(EObject root, Set<EReference> _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set<EObject> getAllNodes() { - EObject rootObj = (EObject) root; - HashSet<EObject> set = new HashSet<EObject>(); - set.add(rootObj); - TreeIterator<EObject> iterator = rootObj.eAllContents(); - - while (iterator.hasNext()) { - set.add(iterator.next()); - } - - return set; - } - } - - public static class ForResource extends ForNotifier { - - private static final long serialVersionUID = 7372972311144593543L; - - public ForResource(Resource root, Set<EReference> _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set<EObject> getAllNodes() { - Resource rootResource = (Resource) root; - HashSet<EObject> set = new HashSet<EObject>(); - TreeIterator<EObject> iterator = rootResource.getAllContents(); - while (iterator.hasNext()) { - set.add(iterator.next()); - } - return set; - } - } - - public static class ForResourceSet extends ForNotifier { - - private static final long serialVersionUID = 4619478637173366088L; - - public ForResourceSet(ResourceSet root, Set<EReference> _refToObserv) { - super(root, _refToObserv); - } - - @Override - public Set<EObject> getAllNodes() { - ResourceSet rootResourceSet = (ResourceSet) root; - HashSet<EObject> set = new HashSet<EObject>(); - - for (Resource res : rootResourceSet.getResources()) { - TreeIterator<EObject> iterator = res.getAllContents(); - while (iterator.hasNext()) { - set.add(iterator.next()); - } - } - - return set; - } - } - - private static void collectContents(Object obj, List<EObject> contents) { - if (obj instanceof EObjectEList<?>) { - @SuppressWarnings("unchecked") - EObjectEList<EObject> list = (EObjectEList<EObject>) obj; - Iterator<EObject> it = list.iterator(); - - while (it.hasNext()) { - contents.add(it.next()); - } - } else if (obj instanceof EObject) { - contents.add((EObject) obj); - } - } - - ArrayList<IGraphObserver<EObject>> observers = new ArrayList<IGraphObserver<EObject>>();; - Set<EReference> refToObserv; +public class EMFDataSource implements IGraphDataSource<EObject> { + + private static final long serialVersionUID = 5404152895901306358L; + private List<IGraphObserver<EObject>> observers; + private Set<EReference> references; + private Set<EClass> classes; + private NavigationHelper navigationHelper; + + public EMFDataSource(NavigationHelper navigationHelper, Set<EReference> references, Set<EClass> classes) throws IncQueryBaseException { + this.references = references; + this.classes = classes; + this.observers = new ArrayList<IGraphObserver<EObject>>(); + this.navigationHelper = navigationHelper; + } + + @Override + public Set<EObject> getAllNodes() { + Set<EObject> nodes = new HashSet<EObject>(); + for (EClass clazz : classes) { + nodes.addAll(navigationHelper.getAllInstances(clazz)); + } + return nodes; + } @Override public void attachObserver(IGraphObserver<EObject> go) { @@ -160,14 +83,13 @@ public abstract class EMFDataSource implements IGraphDataSource<EObject> { } @Override - public ArrayList<EObject> getTargetNodes(EObject source) { - ArrayList<EObject> targetNodes = new ArrayList<EObject>(); + public List<EObject> getTargetNodes(EObject source) { + List<EObject> targetNodes = new ArrayList<EObject>(); - for (EReference ref : source.eClass().getEAllReferences()) { - if (refToObserv.contains(ref)) { - collectContents(source.eGet(ref), targetNodes); - } + for (EReference ref : references) { + targetNodes.addAll(navigationHelper.getReferenceValues(source, ref)); } + return targetNodes; } } diff --git a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java index 744dd82..e94fbf8 100644 --- a/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java +++ b/plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java @@ -12,177 +12,76 @@ package org.eclipse.incquery.runtime.base.core; import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.HashSet; import java.util.Set; -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClass; 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.EStructuralFeature; import org.eclipse.emf.ecore.util.EContentAdapter; -import org.eclipse.emf.ecore.util.EObjectEList; +import org.eclipse.incquery.runtime.base.api.FeatureListener; +import org.eclipse.incquery.runtime.base.api.InstanceListener; +import org.eclipse.incquery.runtime.base.api.NavigationHelper; import org.eclipse.incquery.runtime.base.api.TransitiveClosureHelper; import org.eclipse.incquery.runtime.base.exception.IncQueryBaseException; import org.eclipse.incquery.runtime.base.itc.alg.incscc.IncSCCAlg; import org.eclipse.incquery.runtime.base.itc.igraph.ITcObserver; /** - * Implementation class for the transitive closure. The class is a wrapper for the tc algorithms on an emf model. + * Implementation class for the {@link TransitiveClosureHelper}. + * It uses a {@link NavigationHelper} instance to wrap an EMF model + * and make it suitable for the {@link IncSCCAlg} algorithm. * * @author Tamas Szabo * */ public class TransitiveClosureHelperImpl extends EContentAdapter implements TransitiveClosureHelper, - ITcObserver<EObject> { + ITcObserver<EObject>, FeatureListener, InstanceListener { private IncSCCAlg<EObject> sccAlg; - private Set<EReference> refToObserv; + private Set<EStructuralFeature> features; + private Set<EClass> classes; private EMFDataSource dataSource; - private ArrayList<ITcObserver<EObject>> observers; - private Notifier notifier; - - public TransitiveClosureHelperImpl(Notifier emfRoot, Set<EReference> refToObserv) throws IncQueryBaseException { - this.refToObserv = refToObserv; - this.notifier = emfRoot; - this.observers = new ArrayList<ITcObserver<EObject>>(); - - if (emfRoot instanceof EObject) { - dataSource = new EMFDataSource.ForEObject((EObject) emfRoot, refToObserv); - } else if (emfRoot instanceof Resource) { - dataSource = new EMFDataSource.ForResource((Resource) emfRoot, refToObserv); - } else if (emfRoot instanceof ResourceSet) { - dataSource = new EMFDataSource.ForResourceSet((ResourceSet) emfRoot, refToObserv); - } else { - throw new IncQueryBaseException(IncQueryBaseException.INVALID_EMFROOT); - } - + private ArrayList<ITcObserver<EObject>> tcObservers; + private NavigationHelper navigationHelper; + + public TransitiveClosureHelperImpl(NavigationHelper navigationHelper, Set<EReference> references) throws IncQueryBaseException { + this.tcObservers = new ArrayList<ITcObserver<EObject>>(); + this.navigationHelper = navigationHelper; + + //NavigationHelper only accepts Set<EStructuralFeature> upon registration + this.features = new HashSet<EStructuralFeature>(references); + this.navigationHelper.registerEStructuralFeatures(features); + this.classes = collectEClasses(); + this.navigationHelper.registerEClasses(classes); + + this.navigationHelper.registerFeatureListener(features, this); + this.navigationHelper.registerInstanceListener(classes, this); + + this.dataSource = new EMFDataSource(navigationHelper, references, classes); + this.sccAlg = new IncSCCAlg<EObject>(dataSource); this.sccAlg.attachObserver(this); - emfRoot.eAdapters().add(this); - } - - /** - * The method visits an {@link EObject} for the registered references in order to explore the potential nodes and - * edges that should be inserted and deleted. - * - * Multiple node deletion and insertion must be avoided! - * - * @param source - * @param isInsert - */ - private void visitObjectForEReference(EObject source, boolean isInsert) { - for (EReference ref : source.eClass().getEReferences()) { - if (refToObserv.contains(ref)) { - Object o = source.eGet(ref); - - if (o instanceof EObjectEList<?>) { - @SuppressWarnings("unchecked") - List<EObject> list = (EObjectEList<EObject>) o; - Iterator<EObject> it = list.iterator(); - - while (it.hasNext()) { - EObject target = it.next(); - if (isInsert) { - if (!target.equals(source)) - nodeInserted(target); - edgeInserted(source, target); - } else { - edgeDeleted(source, target); - if (!target.equals(source)) - nodeDeleted(target); - } - } - } else { - EObject target = (EObject) o; - if (isInsert) { - if (!target.equals(source)) - nodeInserted(target); - edgeInserted(source, target); - } else { - edgeDeleted(source, target); - if (!target.equals(source)) - nodeDeleted(target); - } - } - } - } - } - - @Override - public void notifyChanged(Notification notification) { - super.notifyChanged(notification); - Object feature = notification.getFeature(); - Object oldValue = notification.getOldValue(); - Object newValue = notification.getNewValue(); - Object notifier = notification.getNotifier(); - - // System.out.println(notification); - if (feature instanceof EReference && (oldValue == null || oldValue instanceof EObject) - && (newValue == null || newValue instanceof EObject) - && (notifier == null || notifier instanceof EObject)) { - - EReference ref = (EReference) feature; - EObject oldValueObj = (EObject) oldValue; - EObject newValueObj = (EObject) newValue; - EObject notifierObj = (EObject) notifier; - - if (ref.isContainment()) { - // Inserting nodes - if (notification.getEventType() == Notification.ADD && oldValueObj == null && newValueObj != null) { - nodeInserted(newValueObj); - visitObjectForEReference(newValueObj, true); - } - if (notification.getEventType() == Notification.REMOVE && newValueObj == null && oldValueObj != null) { - visitObjectForEReference(oldValueObj, false); - nodeDeleted(oldValueObj); - } - } else // Inserting edges (excusively -> edge or node modification) - if (refToObserv.contains(ref)) { - - if (notification.getEventType() == Notification.ADD && newValueObj != null) { - edgeInserted(notifierObj, newValueObj); - } else if (notification.getEventType() == Notification.REMOVE && oldValueObj != null) { - edgeDeleted(notifierObj, oldValueObj); - } else if (notification.getEventType() == Notification.SET) { - if (oldValueObj != null) { - edgeDeleted(notifierObj, oldValueObj); - } - - if (newValueObj != null) { - edgeInserted(notifierObj, newValueObj); - } - } - } - } - } - - private void edgeInserted(EObject source, EObject target) { - dataSource.notifyEdgeInserted(source, target); - } - - private void edgeDeleted(EObject source, EObject target) { - dataSource.notifyEdgeDeleted(source, target); - } - - private void nodeInserted(EObject node) { - dataSource.notifyNodeInserted(node); - } - - private void nodeDeleted(EObject node) { - dataSource.notifyNodeDeleted(node); } + + private Set<EClass> collectEClasses() { + Set<EClass> classes = new HashSet<EClass>(); + for (EStructuralFeature ref : features) { + classes.add(ref.getEContainingClass()); + classes.add(((EReference) ref).getEReferenceType()); + } + return classes; + } @Override public void attachObserver(ITcObserver<EObject> to) { - this.observers.add(to); + this.tcObservers.add(to); } @Override public void detachObserver(ITcObserver<EObject> to) { - this.observers.remove(to); + this.tcObservers.remove(to); } @Override @@ -202,14 +101,14 @@ public class TransitiveClosureHelperImpl extends EContentAdapter implements Tran @Override public void tupleInserted(EObject source, EObject target) { - for (ITcObserver<EObject> to : observers) { + for (ITcObserver<EObject> to : tcObservers) { to.tupleInserted(source, target); } } @Override public void tupleDeleted(EObject source, EObject target) { - for (ITcObserver<EObject> to : observers) { + for (ITcObserver<EObject> to : tcObservers) { to.tupleDeleted(source, target); } } @@ -217,6 +116,28 @@ public class TransitiveClosureHelperImpl extends EContentAdapter implements Tran @Override public void dispose() { this.sccAlg.dispose(); - this.notifier.eAdapters().remove(this); + this.navigationHelper.unregisterInstanceListener(classes, this); + this.navigationHelper.unregisterFeatureListener(features, this); + this.navigationHelper.dispose(); } + + @Override + public void featureInserted(EObject host, EStructuralFeature feature, Object value) { + this.dataSource.notifyEdgeInserted(host, (EObject) value); + } + + @Override + public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { + this.dataSource.notifyEdgeDeleted(host, (EObject) value); + } + + @Override + public void instanceInserted(EClass clazz, EObject instance) { + this.dataSource.notifyNodeInserted(instance); + } + + @Override + public void instanceDeleted(EClass clazz, EObject instance) { + this.dataSource.notifyNodeDeleted(instance); + } } |

