diff options
Diffstat (limited to 'subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java')
-rw-r--r-- | subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java new file mode 100644 index 00000000..552696cb --- /dev/null +++ b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java | |||
@@ -0,0 +1,153 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | |||
10 | package tools.refinery.viatra.runtime.base.core; | ||
11 | |||
12 | import java.util.ArrayList; | ||
13 | import java.util.HashSet; | ||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
16 | |||
17 | import org.eclipse.emf.ecore.EClass; | ||
18 | import org.eclipse.emf.ecore.EObject; | ||
19 | import org.eclipse.emf.ecore.EReference; | ||
20 | import org.eclipse.emf.ecore.EStructuralFeature; | ||
21 | import org.eclipse.emf.ecore.util.EContentAdapter; | ||
22 | import tools.refinery.viatra.runtime.base.api.FeatureListener; | ||
23 | import tools.refinery.viatra.runtime.base.api.IndexingLevel; | ||
24 | import tools.refinery.viatra.runtime.base.api.InstanceListener; | ||
25 | import tools.refinery.viatra.runtime.base.api.NavigationHelper; | ||
26 | import tools.refinery.viatra.runtime.base.api.TransitiveClosureHelper; | ||
27 | import tools.refinery.viatra.runtime.base.itc.alg.incscc.IncSCCAlg; | ||
28 | import tools.refinery.viatra.runtime.base.itc.alg.misc.IGraphPathFinder; | ||
29 | import tools.refinery.viatra.runtime.base.itc.igraph.ITcObserver; | ||
30 | |||
31 | /** | ||
32 | * Implementation class for the {@link TransitiveClosureHelper}. | ||
33 | * It uses a {@link NavigationHelper} instance to wrap an EMF model | ||
34 | * and make it suitable for the {@link IncSCCAlg} algorithm. | ||
35 | * | ||
36 | * @author Tamas Szabo | ||
37 | * | ||
38 | */ | ||
39 | public class TransitiveClosureHelperImpl extends EContentAdapter implements TransitiveClosureHelper, | ||
40 | ITcObserver<EObject>, FeatureListener, InstanceListener { | ||
41 | |||
42 | private IncSCCAlg<EObject> sccAlg; | ||
43 | private Set<EStructuralFeature> features; | ||
44 | private Set<EClass> classes; | ||
45 | private EMFDataSource dataSource; | ||
46 | private List<ITcObserver<EObject>> tcObservers; | ||
47 | private NavigationHelper navigationHelper; | ||
48 | private boolean disposeBaseIndexWhenDisposed; | ||
49 | |||
50 | public TransitiveClosureHelperImpl(final NavigationHelper navigationHelper, boolean disposeBaseIndexWhenDisposed, Set<EReference> references) { | ||
51 | this.tcObservers = new ArrayList<ITcObserver<EObject>>(); | ||
52 | this.navigationHelper = navigationHelper; | ||
53 | this.disposeBaseIndexWhenDisposed = disposeBaseIndexWhenDisposed; | ||
54 | |||
55 | //NavigationHelper only accepts Set<EStructuralFeature> upon registration | ||
56 | this.features = new HashSet<EStructuralFeature>(references); | ||
57 | this.classes = collectEClasses(); | ||
58 | /*this.classes = Collections.emptySet();*/ | ||
59 | if (!navigationHelper.isInWildcardMode()) | ||
60 | navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL); | ||
61 | |||
62 | this.navigationHelper.addFeatureListener(features, this); | ||
63 | this.navigationHelper.addInstanceListener(classes, this); | ||
64 | |||
65 | this.dataSource = new EMFDataSource(navigationHelper, references, classes); | ||
66 | |||
67 | this.sccAlg = new IncSCCAlg<EObject>(dataSource); | ||
68 | this.sccAlg.attachObserver(this); | ||
69 | } | ||
70 | |||
71 | private Set<EClass> collectEClasses() { | ||
72 | Set<EClass> classes = new HashSet<EClass>(); | ||
73 | for (EStructuralFeature ref : features) { | ||
74 | classes.add(ref.getEContainingClass()); | ||
75 | classes.add(((EReference) ref).getEReferenceType()); | ||
76 | } | ||
77 | return classes; | ||
78 | } | ||
79 | |||
80 | @Override | ||
81 | public void attachObserver(ITcObserver<EObject> to) { | ||
82 | this.tcObservers.add(to); | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public void detachObserver(ITcObserver<EObject> to) { | ||
87 | this.tcObservers.remove(to); | ||
88 | } | ||
89 | |||
90 | @Override | ||
91 | public Set<EObject> getAllReachableTargets(EObject source) { | ||
92 | return this.sccAlg.getAllReachableTargets(source); | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public Set<EObject> getAllReachableSources(EObject target) { | ||
97 | return this.sccAlg.getAllReachableSources(target); | ||
98 | } | ||
99 | |||
100 | @Override | ||
101 | public boolean isReachable(EObject source, EObject target) { | ||
102 | return this.sccAlg.isReachable(source, target); | ||
103 | } | ||
104 | |||
105 | @Override | ||
106 | public void tupleInserted(EObject source, EObject target) { | ||
107 | for (ITcObserver<EObject> to : tcObservers) { | ||
108 | to.tupleInserted(source, target); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | @Override | ||
113 | public void tupleDeleted(EObject source, EObject target) { | ||
114 | for (ITcObserver<EObject> to : tcObservers) { | ||
115 | to.tupleDeleted(source, target); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | @Override | ||
120 | public void dispose() { | ||
121 | this.sccAlg.dispose(); | ||
122 | this.navigationHelper.removeInstanceListener(classes, this); | ||
123 | this.navigationHelper.removeFeatureListener(features, this); | ||
124 | |||
125 | if (disposeBaseIndexWhenDisposed) | ||
126 | this.navigationHelper.dispose(); | ||
127 | } | ||
128 | |||
129 | @Override | ||
130 | public void featureInserted(EObject host, EStructuralFeature feature, Object value) { | ||
131 | this.dataSource.notifyEdgeInserted(host, (EObject) value); | ||
132 | } | ||
133 | |||
134 | @Override | ||
135 | public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { | ||
136 | this.dataSource.notifyEdgeDeleted(host, (EObject) value); | ||
137 | } | ||
138 | |||
139 | @Override | ||
140 | public void instanceInserted(EClass clazz, EObject instance) { | ||
141 | this.dataSource.notifyNodeInserted(instance); | ||
142 | } | ||
143 | |||
144 | @Override | ||
145 | public void instanceDeleted(EClass clazz, EObject instance) { | ||
146 | this.dataSource.notifyNodeDeleted(instance); | ||
147 | } | ||
148 | |||
149 | @Override | ||
150 | public IGraphPathFinder<EObject> getPathFinder() { | ||
151 | return this.sccAlg.getPathFinder(); | ||
152 | } | ||
153 | } | ||