aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java')
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java191
1 files changed, 0 insertions, 191 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java
deleted file mode 100644
index 4a256aea..00000000
--- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java
+++ /dev/null
@@ -1,191 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2008 Gabor Bergmann 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
10package tools.refinery.viatra.runtime.api;
11
12import tools.refinery.viatra.runtime.api.scope.QueryScope;
13import tools.refinery.viatra.runtime.internal.apiimpl.ViatraQueryEngineImpl;
14import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil;
15
16import java.lang.ref.WeakReference;
17import java.util.*;
18
19import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument;
20
21/**
22 * Global registry of active VIATRA Query Engines.
23 *
24 * <p>
25 * Manages an {@link ViatraQueryEngine} for each model (more precisely scope), that is created on demand. Managed engines are shared between
26 * clients querying the same model.
27 *
28 * <p>
29 * It is also possible to create private, unmanaged engines that are not shared between clients.
30 *
31 * <p>
32 * Only weak references are retained on the managed engines. So if there are no other references to the matchers or the
33 * engine, they can eventually be GC'ed, and they won't block the model from being GC'ed either.
34 *
35 *
36 * @author Bergmann Gabor
37 *
38 */
39public class ViatraQueryEngineManager {
40 private static ViatraQueryEngineManager instance = new ViatraQueryEngineManager();
41
42
43 /**
44 * @return the singleton instance
45 */
46 public static ViatraQueryEngineManager getInstance() {
47 return instance;
48 }
49
50 /**
51 * The engine manager keeps track of the managed engines via weak references only, so it will not keep unused
52 * managed engines from being garbage collected. Still, as long as the user keeps the model in memory, the
53 * associated managed engine will not be garbage collected, as it is expected to be strongly reachable from the
54 * model via the scope-specific base index or change notification listeners (see
55 * {@link BaseIndexListener#iqEngine}).
56 */
57 Map<QueryScope, WeakReference<ViatraQueryEngineImpl>> engines;
58
59 ViatraQueryEngineManager() {
60 super();
61 engines = new WeakHashMap<QueryScope, WeakReference<ViatraQueryEngineImpl>>();
62 initializationListeners = new HashSet<ViatraQueryEngineInitializationListener>();
63 }
64
65 /**
66 * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope})
67 * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine.
68 * Consequently, the engine will be reused between different clients querying the same model, providing performance benefits.
69 *
70 * <p>
71 * The match set of any patterns will be incrementally refreshed upon updates from this scope.
72 *
73 * @param scope
74 * the scope of query evaluation; the definition of the set of model elements that this engine is operates on.
75 * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model.
76 * @return a new or previously existing engine
77 */
78 public ViatraQueryEngine getQueryEngine(QueryScope scope) {
79 return getQueryEngine(scope, ViatraQueryEngineOptions.getDefault());
80 }
81
82 /**
83 * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope})
84 * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine.
85 * Consequently, the engine will be reused between different clients querying the same model, providing performance benefits.
86 *
87 * <p>
88 * The match set of any patterns will be incrementally refreshed upon updates from this scope.
89 *
90 * @param scope
91 * the scope of query evaluation; the definition of the set of model elements that this engine is operates on.
92 * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model.
93 * @return a new or previously existing engine
94 * @since 1.4
95 */
96 public ViatraQueryEngine getQueryEngine(QueryScope scope, ViatraQueryEngineOptions options) {
97 ViatraQueryEngineImpl engine = getEngineInternal(scope);
98 if (engine == null) {
99 engine = new ViatraQueryEngineImpl(this, scope, options);
100 engines.put(scope, new WeakReference<ViatraQueryEngineImpl>(engine));
101 notifyInitializationListeners(engine);
102 }
103 return engine;
104 }
105
106 /**
107 * Retrieves an already existing managed VIATRA Query Engine.
108 *
109 * @param scope
110 * the scope of query evaluation; the definition of the set of model elements that this engine is operates on.
111 * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model.
112 * @return a previously existing engine, or null if no engine is active for the given EMF model root
113 */
114 public ViatraQueryEngine getQueryEngineIfExists(QueryScope scope) {
115 return getEngineInternal(scope);
116 }
117
118 /**
119 * Collects all {@link ViatraQueryEngine} instances that still exist.
120 *
121 * @return set of engines if there is any, otherwise EMTPY_SET
122 */
123 public Set<ViatraQueryEngine> getExistingQueryEngines(){
124 Set<ViatraQueryEngine> existingEngines = null;
125 for (WeakReference<ViatraQueryEngineImpl> engineRef : engines.values()) {
126 AdvancedViatraQueryEngine engine = engineRef == null ? null : engineRef.get();
127 if(existingEngines == null) {
128 existingEngines = new HashSet<>();
129 }
130 existingEngines.add(engine);
131 }
132 if(existingEngines == null) {
133 existingEngines = Collections.emptySet();
134 }
135 return existingEngines;
136 }
137
138 private final Set<ViatraQueryEngineInitializationListener> initializationListeners;
139
140 /**
141 * Registers a listener for new engine initialization.
142 *
143 * <p/> For removal, use {@link #removeQueryEngineInitializationListener}
144 *
145 * @param listener the listener to register
146 */
147 public void addQueryEngineInitializationListener(ViatraQueryEngineInitializationListener listener) {
148 checkArgument(listener != null, "Cannot add null listener!");
149 initializationListeners.add(listener);
150 }
151
152 /**
153 * Removes a registered listener added with {@link #addQueryEngineInitializationListener}
154 *
155 * @param listener
156 */
157 public void removeQueryEngineInitializationListener(ViatraQueryEngineInitializationListener listener) {
158 checkArgument(listener != null, "Cannot remove null listener!");
159 initializationListeners.remove(listener);
160 }
161
162 /**
163 * Notifies listeners that a new engine has been initialized.
164 *
165 * @param engine the initialized engine
166 */
167 protected void notifyInitializationListeners(AdvancedViatraQueryEngine engine) {
168 try {
169 if (!initializationListeners.isEmpty()) {
170 for (ViatraQueryEngineInitializationListener listener : new HashSet<>(initializationListeners)) {
171 listener.engineInitialized(engine);
172 }
173 }
174 } catch (Exception ex) {
175 ViatraQueryLoggingUtil.getLogger(getClass()).fatal(
176 "VIATRA Query Engine Manager encountered an error in delivering notifications"
177 + " about engine initialization. ", ex);
178 }
179 }
180
181 /**
182 * @param emfRoot
183 * @return
184 */
185 private ViatraQueryEngineImpl getEngineInternal(QueryScope scope) {
186 final WeakReference<ViatraQueryEngineImpl> engineRef = engines.get(scope);
187 ViatraQueryEngineImpl engine = engineRef == null ? null : engineRef.get();
188 return engine;
189 }
190
191}