summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorTamas Szabo2013-02-14 03:34:14 (EST)
committer Istvan Rath2013-02-14 03:34:14 (EST)
commit465fe92d597a107b456f6e2a4dbe390055507419 (patch)
tree505faaf0cac009d664abb8eb8e41baa5bb4ff5bd
parent2e0407d22c82d7f99c3cd2bfcc96ff88dc482c2e (diff)
downloadorg.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.zip
org.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.tar.gz
org.eclipse.incquery-465fe92d597a107b456f6e2a4dbe390055507419.tar.bz2
[397893] apply Tamas Szabo's patch
-rw-r--r--plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/api/IncQueryBaseFactory.java2
-rw-r--r--plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/EMFDataSource.java140
-rw-r--r--plugins/org.eclipse.incquery.runtime.base/src/org/eclipse/incquery/runtime/base/core/TransitiveClosureHelperImpl.java211
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);
+ }
}