diff options
Diffstat (limited to 'subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java')
-rw-r--r-- | subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java | 885 |
1 files changed, 885 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java new file mode 100644 index 00000000..6a9f704b --- /dev/null +++ b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java | |||
@@ -0,0 +1,885 @@ | |||
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.api; | ||
11 | |||
12 | import org.eclipse.emf.common.notify.Notifier; | ||
13 | import org.eclipse.emf.common.util.EList; | ||
14 | import org.eclipse.emf.common.util.Enumerator; | ||
15 | import org.eclipse.emf.ecore.*; | ||
16 | import org.eclipse.emf.ecore.EStructuralFeature.Setting; | ||
17 | import org.eclipse.emf.ecore.resource.Resource; | ||
18 | import org.eclipse.emf.ecore.resource.ResourceSet; | ||
19 | import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEClassProcessor; | ||
20 | import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEDataTypeProcessor; | ||
21 | import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; | ||
22 | |||
23 | import java.lang.reflect.InvocationTargetException; | ||
24 | import java.util.Collection; | ||
25 | import java.util.ConcurrentModificationException; | ||
26 | import java.util.Set; | ||
27 | import java.util.concurrent.Callable; | ||
28 | |||
29 | /** | ||
30 | * | ||
31 | * Using an index of the EMF model, this interface exposes useful query functionality, such as: | ||
32 | * <ul> | ||
33 | * <li> | ||
34 | * Getting all the (direct or descendant) instances of a given {@link EClass} | ||
35 | * <li> | ||
36 | * Inverse navigation along arbitrary {@link EReference} instances (heterogenous paths too) | ||
37 | * <li> | ||
38 | * Finding model elements by attribute value (i.e. inverse navigation along {@link EAttribute}) | ||
39 | * <li> | ||
40 | * Querying instances of given data types, or structural features. | ||
41 | * </ul> | ||
42 | * As queries are served from an index, results are always instantaneous. | ||
43 | * | ||
44 | * <p> | ||
45 | * Such indices will be built on an EMF model rooted at an {@link EObject}, {@link Resource} or {@link ResourceSet}. | ||
46 | * The boundaries of the model are defined by the containment (sub)tree. | ||
47 | * The indices will be <strong>maintained incrementally</strong> on changes to the model; these updates can also be | ||
48 | * observed by registering listeners. | ||
49 | * </p> | ||
50 | * | ||
51 | * <p> | ||
52 | * One of the options is to build indices in <em>wildcard mode</em>, meaning that all EClasses, EDataTypes, EReferences | ||
53 | * and EAttributes are indexed. This is convenient, but comes at a high memory cost. To save memory, one can disable | ||
54 | * <em>wildcard mode</em> and manually register those EClasses, EDataTypes, EReferences and EAttributes that should be | ||
55 | * indexed. | ||
56 | * </p> | ||
57 | * | ||
58 | * <p> | ||
59 | * Another choice is whether to build indices in <em>dynamic EMF mode</em>, meaning that types are identified by the String IDs | ||
60 | * that are ultimately derived from the nsURI of the EPackage. Multiple types with the same ID are treated as the same. | ||
61 | * This is useful if dynamic EMF is used, where there can be multiple copies (instantiations) of the same EPackage, | ||
62 | * representing essentially the same metamodel. If one disables <em>dynamic EMF mode</em>, an error is logged if | ||
63 | * duplicate EPackages with the same nsURI are encountered. | ||
64 | * </p> | ||
65 | * | ||
66 | * <p> | ||
67 | * Note that none of the defined query methods return null upon empty result sets. All query methods return either a copy of | ||
68 | * the result sets (where {@link Setting} is instantiated) or an unmodifiable collection of the result view. | ||
69 | * | ||
70 | * <p> | ||
71 | * Instantiate using {@link ViatraBaseFactory} | ||
72 | * | ||
73 | * @author Tamas Szabo | ||
74 | * @noimplement This interface is not intended to be implemented by clients. | ||
75 | * | ||
76 | */ | ||
77 | public interface NavigationHelper { | ||
78 | |||
79 | /** | ||
80 | * Indicates whether indexing is performed in <em>wildcard mode</em>, where every aspect of the EMF model is | ||
81 | * automatically indexed. | ||
82 | * | ||
83 | * @return true if everything is indexed, false if manual registration of interesting EClassifiers and | ||
84 | * EStructuralFeatures is required. | ||
85 | */ | ||
86 | public boolean isInWildcardMode(); | ||
87 | |||
88 | /** | ||
89 | * Indicates whether indexing is performed in <em>wildcard mode</em> for a selected indexing level | ||
90 | * | ||
91 | * @return true if everything is indexed, false if manual registration of interesting EClassifiers and | ||
92 | * EStructuralFeatures is required. | ||
93 | * @since 1.5 | ||
94 | */ | ||
95 | public boolean isInWildcardMode(IndexingLevel level); | ||
96 | |||
97 | /** | ||
98 | * Returns the current {@link IndexingLevel} applied to all model elements. For specific types it is possible to request a higher indexing levels, but cannot be lowered. | ||
99 | * @return the current level of index specified | ||
100 | * @since 1.4 | ||
101 | */ | ||
102 | public IndexingLevel getWildcardLevel(); | ||
103 | |||
104 | /** | ||
105 | * Starts wildcard indexing at the given level. After this call, no registration is required for this {@link IndexingLevel}. | ||
106 | * a previously set wildcard level cannot be lowered, only extended. | ||
107 | * | ||
108 | * @since 1.4 | ||
109 | */ | ||
110 | public void setWildcardLevel(IndexingLevel level); | ||
111 | |||
112 | /** | ||
113 | * Indicates whether indexing is performed in <em>dynamic EMF mode</em>, i.e. EPackage nsURI collisions are | ||
114 | * tolerated and EPackages with the same URI are automatically considered as equal. | ||
115 | * | ||
116 | * @return true if multiple EPackages with the same nsURI are treated as the same, | ||
117 | * false if an error is logged instead in this case. | ||
118 | */ | ||
119 | public boolean isInDynamicEMFMode(); | ||
120 | |||
121 | /** | ||
122 | * For a given attribute value <code>value</code>, find each {@link EAttribute} and host {@link EObject} | ||
123 | * such that this attribute of the the host object takes the given value. The method will | ||
124 | * return a set of {@link Setting}s, one for each such host object - EAttribute - value triplet. | ||
125 | * | ||
126 | * <p> | ||
127 | * <strong>Precondition:</strong> Unset / null attribute values are not indexed, so <code>value!=null</code> | ||
128 | * | ||
129 | * <p> | ||
130 | * <strong>Precondition:</strong> Will only find those EAttributes that have already been registered using | ||
131 | * {@link #registerEStructuralFeatures(Set)}, unless running in <em>wildcard mode</em> (see | ||
132 | * {@link #isInWildcardMode()}). | ||
133 | * | ||
134 | * @param value | ||
135 | * the value of the attribute | ||
136 | * @return a set of {@link Setting}s, one for each EObject and EAttribute that have the given value | ||
137 | * @see #findByAttributeValue(Object) | ||
138 | */ | ||
139 | public Set<Setting> findByAttributeValue(Object value); | ||
140 | |||
141 | /** | ||
142 | * For given <code>attributes</code> and an attribute value <code>value</code>, find each host {@link EObject} | ||
143 | * such that any of these attributes of the the host object takes the given value. The method will | ||
144 | * return a set of {@link Setting}s, one for each such host object - EAttribute - value triplet. | ||
145 | * | ||
146 | * <p> | ||
147 | * <strong>Precondition:</strong> Unset / null attribute values are not indexed, so <code>value!=null</code> | ||
148 | * | ||
149 | * <p> | ||
150 | * <strong>Precondition:</strong> Will only find those EAttributes that have already been registered using | ||
151 | * {@link #registerEStructuralFeatures(Set)}, unless running in <em>wildcard mode</em> (see | ||
152 | * {@link #isInWildcardMode()}). | ||
153 | * | ||
154 | * @param value | ||
155 | * the value of the attribute | ||
156 | * @param attributes | ||
157 | * the collection of attributes that should take the given value | ||
158 | * @return a set of {@link Setting}s, one for each EObject and attribute that have the given value | ||
159 | */ | ||
160 | public Set<Setting> findByAttributeValue(Object value, Collection<EAttribute> attributes); | ||
161 | |||
162 | /** | ||
163 | * Find all {@link EObject}s for which the given <code>attribute</code> takes the given <code>value</code>. | ||
164 | * | ||
165 | * <p> | ||
166 | * <strong>Precondition:</strong> Unset / null attribute values are not indexed, so <code>value!=null</code> | ||
167 | * | ||
168 | * <p> | ||
169 | * <strong>Precondition:</strong> Results will be returned only if either (a) the EAttribute has already been | ||
170 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
171 | * {@link #isInWildcardMode()}). | ||
172 | * | ||
173 | * @param value | ||
174 | * the value of the attribute | ||
175 | * @param attribute | ||
176 | * the EAttribute that should take the given value | ||
177 | * @return the set of {@link EObject}s for which the given attribute has the given value | ||
178 | */ | ||
179 | public Set<EObject> findByAttributeValue(Object value, EAttribute attribute); | ||
180 | |||
181 | /** | ||
182 | * Returns the set of instances for the given {@link EDataType} that can be found in the model. | ||
183 | * | ||
184 | * <p> | ||
185 | * <strong>Precondition:</strong> Results will be returned only if either (a) the EDataType has already been | ||
186 | * registered using {@link #registerEDataTypes(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
187 | * {@link #isInWildcardMode()}). | ||
188 | * | ||
189 | * @param type | ||
190 | * the data type | ||
191 | * @return the set of all attribute values found in the model that are of the given data type | ||
192 | */ | ||
193 | public Set<Object> getDataTypeInstances(EDataType type); | ||
194 | |||
195 | /** | ||
196 | * Returns whether an object is an instance for the given {@link EDataType} that can be found in the current scope. | ||
197 | * <p> | ||
198 | * <strong>Precondition:</strong> Result will be true only if either (a) the EDataType has already been registered | ||
199 | * using {@link #registerEDataTypes(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
200 | * {@link #isInWildcardMode()}). | ||
201 | * | ||
202 | * @param value a non-null value to decide whether it is available as an EDataType instance | ||
203 | * @param type a non-null EDataType | ||
204 | * @return true, if a corresponding instance was found | ||
205 | * @since 1.7 | ||
206 | */ | ||
207 | public boolean isInstanceOfDatatype(Object value, EDataType type); | ||
208 | |||
209 | /** | ||
210 | * Find all {@link EObject}s that are the target of the EReference <code>reference</code> from the given | ||
211 | * <code>source</code> {@link EObject}. | ||
212 | * | ||
213 | * <p> | ||
214 | * Unset / null-valued references are not indexed, and will not be included in the results. | ||
215 | * | ||
216 | * <p> | ||
217 | * <strong>Precondition:</strong> Results will be returned only if either (a) the reference has already been | ||
218 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
219 | * {@link #isInWildcardMode()}). | ||
220 | * | ||
221 | * @param source the host object | ||
222 | * @param reference an EReference of the host object | ||
223 | * @return the set of {@link EObject}s that the given reference points to, from the given source object | ||
224 | */ | ||
225 | public Set<EObject> getReferenceValues(EObject source, EReference reference); | ||
226 | |||
227 | /** | ||
228 | * Find all {@link Object}s that are the target of the EStructuralFeature <code>feature</code> from the given | ||
229 | * <code>source</code> {@link EObject}. | ||
230 | * | ||
231 | * <p> | ||
232 | * Unset / null-valued features are not indexed, and will not be included in the results. | ||
233 | * | ||
234 | * <p> | ||
235 | * <strong>Precondition:</strong> Results will be returned only if either (a) the feature has already been | ||
236 | * registered, or (b) running in <em>wildcard mode</em> (see | ||
237 | * {@link #isInWildcardMode()}). | ||
238 | * | ||
239 | * @param source the host object | ||
240 | * @param feature an EStructuralFeature of the host object | ||
241 | * @return the set of values that the given feature takes at the given source object | ||
242 | * | ||
243 | * @see #getReferenceValues(EObject, EReference) | ||
244 | */ | ||
245 | public Set<Object> getFeatureTargets(EObject source, EStructuralFeature feature); | ||
246 | |||
247 | /** | ||
248 | * Decides whether the given non-null source and target objects are connected via a specific, indexed EStructuralFeature instance. | ||
249 | * | ||
250 | * <p> | ||
251 | * Unset / null-valued features are not indexed, and will not be included in the results. | ||
252 | * | ||
253 | * <p> | ||
254 | * <strong>Precondition:</strong> Result will be true only if either (a) the feature has already been | ||
255 | * registered, or (b) running in <em>wildcard mode</em> (see | ||
256 | * {@link #isInWildcardMode()}). | ||
257 | * @since 1.7 | ||
258 | */ | ||
259 | public boolean isFeatureInstance(EObject source, Object target, EStructuralFeature feature); | ||
260 | |||
261 | /** | ||
262 | * For a given {@link EObject} <code>target</code>, find each {@link EReference} and source {@link EObject} | ||
263 | * such that this reference (list) of the the host object points to the given target object. The method will | ||
264 | * return a set of {@link Setting}s, one for each such source object - EReference - target triplet. | ||
265 | * | ||
266 | * <p> | ||
267 | * <strong>Precondition:</strong> Unset / null reference values are not indexed, so <code>target!=null</code> | ||
268 | * | ||
269 | * <p> | ||
270 | * <strong>Precondition:</strong> Results will be returned only for those references that have already been | ||
271 | * registered using {@link #registerEStructuralFeatures(Set)}, or all references if running in | ||
272 | * <em>wildcard mode</em> (see {@link #isInWildcardMode()}). | ||
273 | * | ||
274 | * @param target | ||
275 | * the EObject pointed to by the references | ||
276 | * @return a set of {@link Setting}s, one for each source EObject and reference that point to the given target | ||
277 | */ | ||
278 | public Set<Setting> getInverseReferences(EObject target); | ||
279 | |||
280 | /** | ||
281 | * For given <code>references</code> and an {@link EObject} <code>target</code>, find each source {@link EObject} | ||
282 | * such that any of these references of the the source object points to the given target object. The method will | ||
283 | * return a set of {@link Setting}s, one for each such source object - EReference - target triplet. | ||
284 | * | ||
285 | * <p> | ||
286 | * <strong>Precondition:</strong> Unset / null reference values are not indexed, so <code>target!=null</code> | ||
287 | * | ||
288 | * <p> | ||
289 | * <strong>Precondition:</strong> Will only find those EReferences that have already been registered using | ||
290 | * {@link #registerEStructuralFeatures(Set)}, unless running in <em>wildcard mode</em> (see | ||
291 | * {@link #isInWildcardMode()}). | ||
292 | * | ||
293 | * @param target | ||
294 | * the EObject pointed to by the references | ||
295 | * @param references a set of EReferences pointing to the target | ||
296 | * @return a set of {@link Setting}s, one for each source EObject and reference that point to the given target | ||
297 | */ | ||
298 | public Set<Setting> getInverseReferences(EObject target, Collection<EReference> references); | ||
299 | |||
300 | /** | ||
301 | * Find all source {@link EObject}s for which the given <code>reference</code> points to the given <code>target</code> object. | ||
302 | * | ||
303 | * <p> | ||
304 | * <strong>Precondition:</strong> Unset / null reference values are not indexed, so <code>target!=null</code> | ||
305 | * | ||
306 | * <p> | ||
307 | * <strong>Precondition:</strong> Results will be returned only if either (a) the reference has already been | ||
308 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
309 | * {@link #isInWildcardMode()}). | ||
310 | * | ||
311 | * @param target | ||
312 | * the EObject pointed to by the references | ||
313 | * @param reference | ||
314 | * an EReference pointing to the target | ||
315 | * @return the collection of {@link EObject}s for which the given reference points to the given target object | ||
316 | */ | ||
317 | public Set<EObject> getInverseReferences(EObject target, EReference reference); | ||
318 | |||
319 | /** | ||
320 | * Get the direct {@link EObject} instances of the given {@link EClass}. Instances of subclasses will be excluded. | ||
321 | * | ||
322 | * <p> | ||
323 | * <strong>Precondition:</strong> Results will be returned only if either (a) the EClass (or any superclass) has | ||
324 | * already been registered using {@link #registerEClasses(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
325 | * {@link #isInWildcardMode()}). | ||
326 | * | ||
327 | * @param clazz | ||
328 | * an EClass | ||
329 | * @return the collection of {@link EObject} direct instances of the given EClass (not of subclasses) | ||
330 | * | ||
331 | * @see #getAllInstances(EClass) | ||
332 | */ | ||
333 | public Set<EObject> getDirectInstances(EClass clazz); | ||
334 | |||
335 | /** | ||
336 | * Get the all {@link EObject} instances of the given {@link EClass}. | ||
337 | * This includes instances of subclasses. | ||
338 | * | ||
339 | * <p> | ||
340 | * <strong>Precondition:</strong> Results will be returned only if either (a) the EClass (or any superclass) has | ||
341 | * already been registered using {@link #registerEClasses(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
342 | * {@link #isInWildcardMode()}). | ||
343 | * | ||
344 | * @param clazz | ||
345 | * an EClass | ||
346 | * @return the collection of {@link EObject} instances of the given EClass and any of its subclasses | ||
347 | * | ||
348 | * @see #getDirectInstances(EClass) | ||
349 | */ | ||
350 | public Set<EObject> getAllInstances(EClass clazz); | ||
351 | |||
352 | /** | ||
353 | * Checks whether the given {@link EObject} is an instance of the given {@link EClass}. | ||
354 | * This includes instances of subclasses. | ||
355 | * <p> Special note: this method does not check whether the object is indexed in the scope, | ||
356 | * and will return true for out-of-scope objects as well (as long as they are instances of the class). | ||
357 | * <p> The given class does not have to be indexed. | ||
358 | * <p> The difference between this method and {@link EClassifier#isInstance(Object)} is that in dynamic EMF mode, EPackage equivalence is taken into account. | ||
359 | * @since 1.6 | ||
360 | */ | ||
361 | public boolean isInstanceOfUnscoped(EObject object, EClass clazz); | ||
362 | |||
363 | /** | ||
364 | * Checks whether the given {@link EObject} is an instance of the given {@link EClass}. | ||
365 | * This includes instances of subclasses. | ||
366 | * <p> Special note: this method does check whether the object is indexed in the scope, | ||
367 | * and will return false for out-of-scope objects as well (as long as they are instances of the class). | ||
368 | * <p> The given class does have to be indexed. | ||
369 | * @since 1.7 | ||
370 | */ | ||
371 | public boolean isInstanceOfScoped(EObject object, EClass clazz); | ||
372 | |||
373 | /** | ||
374 | * Get the total number of instances of the given {@link EClass} and all of its subclasses. | ||
375 | * | ||
376 | * @since 1.4 | ||
377 | */ | ||
378 | public int countAllInstances(EClass clazz); | ||
379 | |||
380 | /** | ||
381 | * Find all source {@link EObject}s for which the given <code>feature</code> points to / takes the given <code>value</code>. | ||
382 | * | ||
383 | * <p> | ||
384 | * <strong>Precondition:</strong> Unset / null-valued features are not indexed, so <code>value!=null</code> | ||
385 | * | ||
386 | * <p> | ||
387 | * <strong>Precondition:</strong> Results will be returned only if either (a) the feature has already been | ||
388 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
389 | * {@link #isInWildcardMode()}). | ||
390 | * | ||
391 | * @param value | ||
392 | * the value of the feature | ||
393 | * @param feature | ||
394 | * the feature instance | ||
395 | * @return the collection of {@link EObject} instances | ||
396 | */ | ||
397 | public Set<EObject> findByFeatureValue(Object value, EStructuralFeature feature); | ||
398 | |||
399 | /** | ||
400 | * Returns those host {@link EObject}s that have a non-null value for the given feature | ||
401 | * (at least one, in case of multi-valued references). | ||
402 | * | ||
403 | * <p> | ||
404 | * Unset / null-valued features are not indexed, and will not be included in the results. | ||
405 | * | ||
406 | * <p> | ||
407 | * <strong>Precondition:</strong> Results will be returned only if either (a) the feature has already been | ||
408 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
409 | * {@link #isInWildcardMode()}). | ||
410 | * | ||
411 | * @param feature | ||
412 | * a structural feature | ||
413 | * @return the collection of {@link EObject}s that have some value for the given structural feature | ||
414 | */ | ||
415 | public Set<EObject> getHoldersOfFeature(EStructuralFeature feature); | ||
416 | /** | ||
417 | * Returns all non-null values that the given feature takes at least once for any {@link EObject} in the scope | ||
418 | * | ||
419 | * <p> | ||
420 | * Unset / null-valued features are not indexed, and will not be included in the results. | ||
421 | * | ||
422 | * <p> | ||
423 | * <strong>Precondition:</strong> Results will be returned only if either (a) the feature has already been | ||
424 | * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in <em>wildcard mode</em> (see | ||
425 | * {@link #isInWildcardMode()}). | ||
426 | * | ||
427 | * @param feature | ||
428 | * a structural feature | ||
429 | * @return the collection of values that the given structural feature takes | ||
430 | * @since 2.1 | ||
431 | */ | ||
432 | public Set<Object> getValuesOfFeature(EStructuralFeature feature); | ||
433 | |||
434 | /** | ||
435 | * Call this method to dispose the NavigationHelper. | ||
436 | * | ||
437 | * <p>After its disposal, the NavigationHelper will no longer listen to EMF change notifications, | ||
438 | * and it will be possible to GC it even if the model is retained in memory. | ||
439 | * | ||
440 | * <dt><b>Precondition:</b><dd> no listeners can be registered at all. | ||
441 | * @throws IllegalStateException if there are any active listeners | ||
442 | * | ||
443 | */ | ||
444 | public void dispose(); | ||
445 | |||
446 | /** | ||
447 | * The given <code>listener</code> will be notified from now on whenever instances the given {@link EClass}es | ||
448 | * (and any of their subtypes) are added to or removed from the model. | ||
449 | * | ||
450 | * <br/> | ||
451 | * <b>Important</b>: Do not call this method from {@link InstanceListener} methods as it may cause a | ||
452 | * {@link ConcurrentModificationException}, if you want to add a listener | ||
453 | * at that point, wrap the call with {@link #executeAfterTraversal(Runnable)}. | ||
454 | * | ||
455 | * @param classes | ||
456 | * the collection of classes whose instances the listener should be notified of | ||
457 | * @param listener | ||
458 | * the listener instance | ||
459 | */ | ||
460 | public void addInstanceListener(Collection<EClass> classes, InstanceListener listener); | ||
461 | |||
462 | /** | ||
463 | * Unregisters an instance listener for the given classes. | ||
464 | * | ||
465 | * <br/> | ||
466 | * <b>Important</b>: Do not call this method from {@link InstanceListener} methods as it may cause a | ||
467 | * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with | ||
468 | * {@link #executeAfterTraversal(Runnable)}. | ||
469 | * | ||
470 | * @param classes | ||
471 | * the collection of classes | ||
472 | * @param listener | ||
473 | * the listener instance | ||
474 | */ | ||
475 | public void removeInstanceListener(Collection<EClass> classes, InstanceListener listener); | ||
476 | |||
477 | /** | ||
478 | * The given <code>listener</code> will be notified from now on whenever instances the given {@link EDataType}s are | ||
479 | * added to or removed from the model. | ||
480 | * | ||
481 | * <br/> | ||
482 | * <b>Important</b>: Do not call this method from {@link DataTypeListener} methods as it may cause a | ||
483 | * {@link ConcurrentModificationException}, if you want to add a listener at that point, wrap the call with | ||
484 | * {@link #executeAfterTraversal(Runnable)}. | ||
485 | * | ||
486 | * @param types | ||
487 | * the collection of types associated to the listener | ||
488 | * @param listener | ||
489 | * the listener instance | ||
490 | */ | ||
491 | public void addDataTypeListener(Collection<EDataType> types, DataTypeListener listener); | ||
492 | |||
493 | /** | ||
494 | * Unregisters a data type listener for the given types. | ||
495 | * | ||
496 | * <br/> | ||
497 | * <b>Important</b>: Do not call this method from {@link DataTypeListener} methods as it may cause a | ||
498 | * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with | ||
499 | * {@link #executeAfterTraversal(Runnable)}. | ||
500 | * | ||
501 | * @param types | ||
502 | * the collection of data types | ||
503 | * @param listener | ||
504 | * the listener instance | ||
505 | */ | ||
506 | public void removeDataTypeListener(Collection<EDataType> types, DataTypeListener listener); | ||
507 | |||
508 | /** | ||
509 | * The given <code>listener</code> will be notified from now on whenever instances the given | ||
510 | * {@link EStructuralFeature}s are added to or removed from the model. | ||
511 | * | ||
512 | * <br/> | ||
513 | * <b>Important</b>: Do not call this method from {@link FeatureListener} methods as it may cause a | ||
514 | * {@link ConcurrentModificationException}, if you want to add a listener at that point, wrap the call with | ||
515 | * {@link #executeAfterTraversal(Runnable)}. | ||
516 | * | ||
517 | * @param features | ||
518 | * the collection of features associated to the listener | ||
519 | * @param listener | ||
520 | * the listener instance | ||
521 | */ | ||
522 | public void addFeatureListener(Collection<? extends EStructuralFeature> features, FeatureListener listener); | ||
523 | |||
524 | /** | ||
525 | * Unregisters a feature listener for the given features. | ||
526 | * | ||
527 | * <br/> | ||
528 | * <b>Important</b>: Do not call this method from {@link FeatureListener} methods as it may cause a | ||
529 | * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with | ||
530 | * {@link #executeAfterTraversal(Runnable)}. | ||
531 | * | ||
532 | * @param listener | ||
533 | * the listener instance | ||
534 | * @param features | ||
535 | * the collection of features | ||
536 | */ | ||
537 | public void removeFeatureListener(Collection<? extends EStructuralFeature> features, FeatureListener listener); | ||
538 | |||
539 | /** | ||
540 | * Register a lightweight observer that is notified if the value of any feature of the given EObject changes. | ||
541 | * | ||
542 | * <br/> | ||
543 | * <b>Important</b>: Do not call this method from {@link LightweightEObjectObserver} methods as it may cause a | ||
544 | * {@link ConcurrentModificationException}, if you want to add an observer at that point, wrap the call with | ||
545 | * {@link #executeAfterTraversal(Runnable)}. | ||
546 | * | ||
547 | * @param observer | ||
548 | * the listener instance | ||
549 | * @param observedObject | ||
550 | * the observed EObject | ||
551 | * @return false if the observer was already attached to the object (call has no effect), true otherwise | ||
552 | */ | ||
553 | public boolean addLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject); | ||
554 | |||
555 | /** | ||
556 | * Unregisters a lightweight observer for the given EObject. | ||
557 | * | ||
558 | * <br/> | ||
559 | * <b>Important</b>: Do not call this method from {@link LightweightEObjectObserver} methods as it may cause a | ||
560 | * {@link ConcurrentModificationException}, if you want to remove an observer at that point, wrap the call with | ||
561 | * {@link #executeAfterTraversal(Runnable)}. | ||
562 | * | ||
563 | * @param observer | ||
564 | * the listener instance | ||
565 | * @param observedObject | ||
566 | * the observed EObject | ||
567 | * @return false if the observer has not been previously attached to the object (call has no effect), true otherwise | ||
568 | */ | ||
569 | public boolean removeLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject); | ||
570 | |||
571 | /** | ||
572 | * Manually turns on indexing for the given types (indexing of others are unaffected). Note that | ||
573 | * registering new types will result in a single iteration through the whole attached model. | ||
574 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
575 | * | ||
576 | * @param classes | ||
577 | * the set of classes to observe (null okay) | ||
578 | * @param dataTypes | ||
579 | * the set of data types to observe (null okay) | ||
580 | * @param features | ||
581 | * the set of features to observe (null okay) | ||
582 | * @throws IllegalStateException if in wildcard mode | ||
583 | * @since 1.4 | ||
584 | */ | ||
585 | public void registerObservedTypes(Set<EClass> classes, Set<EDataType> dataTypes, Set<? extends EStructuralFeature> features, IndexingLevel level); | ||
586 | |||
587 | /** | ||
588 | * Manually turns off indexing for the given types (indexing of others are unaffected). Note that if the | ||
589 | * unregistered types are re-registered later, the whole attached model needs to be visited again. | ||
590 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
591 | * | ||
592 | * <dt><b>Precondition:</b><dd> no listeners can be registered for the given types. | ||
593 | * @param classes | ||
594 | * the set of classes that will be ignored again from now on (null okay) | ||
595 | * @param dataTypes | ||
596 | * the set of data types that will be ignored again from now on (null okay) | ||
597 | * @param features | ||
598 | * the set of features that will be ignored again from now on (null okay) | ||
599 | * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types | ||
600 | */ | ||
601 | public void unregisterObservedTypes(Set<EClass> classes, Set<EDataType> dataTypes, Set<? extends EStructuralFeature> features); | ||
602 | |||
603 | /** | ||
604 | * Manually turns on indexing for the given features (indexing of other features are unaffected). Note that | ||
605 | * registering new features will result in a single iteration through the whole attached model. | ||
606 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
607 | * | ||
608 | * @param features | ||
609 | * the set of features to observe | ||
610 | * @throws IllegalStateException if in wildcard mode | ||
611 | * @since 1.4 | ||
612 | */ | ||
613 | public void registerEStructuralFeatures(Set<? extends EStructuralFeature> features, IndexingLevel level); | ||
614 | |||
615 | /** | ||
616 | * Manually turns off indexing for the given features (indexing of other features are unaffected). Note that if the | ||
617 | * unregistered features are re-registered later, the whole attached model needs to be visited again. | ||
618 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
619 | * | ||
620 | * <dt><b>Precondition:</b><dd> no listeners can be registered for the given features. | ||
621 | * | ||
622 | * @param features | ||
623 | * the set of features that will be ignored again from now on | ||
624 | * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types | ||
625 | */ | ||
626 | public void unregisterEStructuralFeatures(Set<? extends EStructuralFeature> features); | ||
627 | |||
628 | /** | ||
629 | * Manually turns on indexing for the given classes (indexing of other classes are unaffected). Instances of | ||
630 | * subclasses will also be indexed. Note that registering new classes will result in a single iteration through the whole | ||
631 | * attached model. | ||
632 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
633 | * | ||
634 | * @param classes | ||
635 | * the set of classes to observe | ||
636 | * @throws IllegalStateException if in wildcard mode | ||
637 | * @since 1.4 | ||
638 | */ | ||
639 | public void registerEClasses(Set<EClass> classes, IndexingLevel level); | ||
640 | |||
641 | /** | ||
642 | * Manually turns off indexing for the given classes (indexing of other classes are unaffected). Note that if the | ||
643 | * unregistered classes are re-registered later, the whole attached model needs to be visited again. | ||
644 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
645 | * | ||
646 | * <dt><b>Precondition:</b><dd> no listeners can be registered for the given classes. | ||
647 | * @param classes | ||
648 | * the set of classes that will be ignored again from now on | ||
649 | * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types | ||
650 | */ | ||
651 | public void unregisterEClasses(Set<EClass> classes); | ||
652 | |||
653 | /** | ||
654 | * Manually turns on indexing for the given data types (indexing of other features are unaffected). Note that | ||
655 | * registering new data types will result in a single iteration through the whole attached model. | ||
656 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
657 | * | ||
658 | * @param dataTypes | ||
659 | * the set of data types to observe | ||
660 | * @throws IllegalStateException if in wildcard mode | ||
661 | * @since 1.4 | ||
662 | */ | ||
663 | public void registerEDataTypes(Set<EDataType> dataTypes, IndexingLevel level); | ||
664 | |||
665 | /** | ||
666 | * Manually turns off indexing for the given data types (indexing of other data types are unaffected). Note that if | ||
667 | * the unregistered data types are re-registered later, the whole attached model needs to be visited again. | ||
668 | * <b> Not usable in <em>wildcard mode</em>.</b> | ||
669 | * | ||
670 | * <dt><b>Precondition:</b><dd> no listeners can be registered for the given datatypes. | ||
671 | * | ||
672 | * @param dataTypes | ||
673 | * the set of data types that will be ignored again from now on | ||
674 | * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types | ||
675 | */ | ||
676 | public void unregisterEDataTypes(Set<EDataType> dataTypes); | ||
677 | |||
678 | /** | ||
679 | * The given callback will be executed, and all model traversals and index registrations will be delayed until the | ||
680 | * execution is done. If there are any outstanding feature, class or datatype registrations, a single coalesced model | ||
681 | * traversal will initialize the caches and deliver the notifications. | ||
682 | * | ||
683 | * @param callable | ||
684 | */ | ||
685 | public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException; | ||
686 | |||
687 | /** | ||
688 | * Execute the given runnable after traversal. It is guaranteed that the runnable is executed as soon as | ||
689 | * the indexing is finished. The callback is executed only once, then is removed from the callback queue. | ||
690 | * @param traversalCallback | ||
691 | * @throws InvocationTargetException | ||
692 | * @since 1.4 | ||
693 | */ | ||
694 | public void executeAfterTraversal(Runnable traversalCallback) throws InvocationTargetException; | ||
695 | |||
696 | /** | ||
697 | * Examines whether execution is currently in the callable | ||
698 | * block of an invocation of {#link {@link #coalesceTraversals(Callable)}}. | ||
699 | */ | ||
700 | public boolean isCoalescing(); | ||
701 | |||
702 | /** | ||
703 | * Adds a coarse-grained listener that will be invoked after the NavigationHelper index or the underlying model is changed. Can be used | ||
704 | * e.g. to check model contents. Not intended for general use. | ||
705 | * | ||
706 | * <p/> See {@link #removeBaseIndexChangeListener(EMFBaseIndexChangeListener)} | ||
707 | * @param listener | ||
708 | */ | ||
709 | public void addBaseIndexChangeListener(EMFBaseIndexChangeListener listener); | ||
710 | |||
711 | /** | ||
712 | * Removes a registered listener. | ||
713 | * | ||
714 | * <p/> See {@link #addBaseIndexChangeListener(EMFBaseIndexChangeListener)} | ||
715 | * | ||
716 | * @param listener | ||
717 | */ | ||
718 | public void removeBaseIndexChangeListener(EMFBaseIndexChangeListener listener); | ||
719 | |||
720 | /** | ||
721 | * Adds an additional EMF model root. | ||
722 | * | ||
723 | * @param emfRoot | ||
724 | * @throws ViatraQueryRuntimeException | ||
725 | */ | ||
726 | public void addRoot(Notifier emfRoot); | ||
727 | |||
728 | /** | ||
729 | * Moves an EObject (along with its entire containment subtree) within the containment hierarchy of the EMF model. | ||
730 | * The object will be relocated from the original parent object to a different parent, or a different containment | ||
731 | * list of the same parent. | ||
732 | * | ||
733 | * <p> When indexing is enabled, such a relocation is costly if performed through normal getters/setters, as the index | ||
734 | * for the entire subtree is pruned at the old location and reconstructed at the new one. | ||
735 | * This method provides a workaround to keep the operation cheap. | ||
736 | * | ||
737 | * <p> This method is experimental. Re-entrancy not supported. | ||
738 | * | ||
739 | * @param element the eObject to be moved | ||
740 | * @param targetContainmentReferenceList containment list of the new parent object into which the element has to be moved | ||
741 | * | ||
742 | */ | ||
743 | public <T extends EObject> void cheapMoveTo(T element, EList<T> targetContainmentReferenceList); | ||
744 | |||
745 | /** | ||
746 | * Moves an EObject (along with its entire containment subtree) within the containment hierarchy of the EMF model. | ||
747 | * The object will be relocated from the original parent object to a different parent, or a different containment | ||
748 | * list of the same parent. | ||
749 | * | ||
750 | * <p> When indexing is enabled, such a relocation is costly if performed through normal getters/setters, as the index | ||
751 | * for the entire subtree is pruned at the old location and reconstructed at the new one. | ||
752 | * This method provides a workaround to keep the operation cheap. | ||
753 | * | ||
754 | * <p> This method is experimental. Re-entrancy not supported. | ||
755 | * | ||
756 | * @param element the eObject to be moved | ||
757 | * @param parent the new parent object under which the element has to be moved | ||
758 | * @param containmentFeature the kind of containment reference that should be established between the new parent and the element | ||
759 | * | ||
760 | */ | ||
761 | public void cheapMoveTo(EObject element, EObject parent, EReference containmentFeature); | ||
762 | |||
763 | |||
764 | /** | ||
765 | * Traverses all instances of a selected data type stored in the base index, and allows executing a custom function on | ||
766 | * it. There is no guaranteed order in which the processor will be called with the selected features. | ||
767 | * | ||
768 | * @param type | ||
769 | * @param processor | ||
770 | * @since 0.8 | ||
771 | */ | ||
772 | void processDataTypeInstances(EDataType type, IEDataTypeProcessor processor); | ||
773 | |||
774 | /** | ||
775 | * Traverses all direct instances of a selected class stored in the base index, and allows executing a custom function on | ||
776 | * it. There is no guaranteed order in which the processor will be called with the selected features. | ||
777 | * | ||
778 | * @param type | ||
779 | * @param processor | ||
780 | * @since 0.8 | ||
781 | */ | ||
782 | void processAllInstances(EClass type, IEClassProcessor processor); | ||
783 | |||
784 | /** | ||
785 | * Traverses all direct instances of a selected class stored in the base index, and allows executing a custom function on | ||
786 | * it. There is no guaranteed order in which the processor will be called with the selected features. | ||
787 | * | ||
788 | * @param type | ||
789 | * @param processor | ||
790 | * @since 0.8 | ||
791 | */ | ||
792 | void processDirectInstances(EClass type, IEClassProcessor processor); | ||
793 | |||
794 | /** | ||
795 | * Traverses all instances of a selected feature stored in the base index, and allows executing a custom function on | ||
796 | * it. There is no guaranteed order in which the processor will be called with the selected features. | ||
797 | * | ||
798 | * <p> | ||
799 | * <strong>Precondition:</strong> Will only find those {@link EStructuralFeature}s that have already been registered using | ||
800 | * {@link #registerEStructuralFeatures(Set)}, unless running in <em>wildcard mode</em> (see | ||
801 | * {@link #isInWildcardMode()}). | ||
802 | * | ||
803 | * @since 1.7 | ||
804 | */ | ||
805 | void processAllFeatureInstances(EStructuralFeature feature, IStructuralFeatureInstanceProcessor processor); | ||
806 | /** | ||
807 | * Returns all EClasses that currently have direct instances cached by the index. <ul> | ||
808 | * <li> Supertypes will not be returned, unless they have direct instances in the model as well. | ||
809 | * <li> If not in <em>wildcard mode</em>, only registered EClasses and their subtypes will be considered. | ||
810 | * <li> Note for advanced users: if a type is represented by multiple EClass objects, one of them is chosen as representative and returned. | ||
811 | * </ul> | ||
812 | */ | ||
813 | public Set<EClass> getAllCurrentClasses(); | ||
814 | |||
815 | /** | ||
816 | * Updates the value of indexed derived features that are not well-behaving. | ||
817 | */ | ||
818 | void resampleDerivedFeatures(); | ||
819 | |||
820 | /** | ||
821 | * Adds a listener for internal errors in the index. A listener can only be added once. | ||
822 | * | ||
823 | * @param listener | ||
824 | * @returns true if the listener was not already added | ||
825 | * @since 0.8 | ||
826 | */ | ||
827 | boolean addIndexingErrorListener(IEMFIndexingErrorListener listener); | ||
828 | |||
829 | /** | ||
830 | * Removes a listener for internal errors in the index. | ||
831 | * | ||
832 | * @param listener | ||
833 | * @returns true if the listener was successfully removed (e.g. it did exist) | ||
834 | * @since 0.8 | ||
835 | */ | ||
836 | boolean removeIndexingErrorListener(IEMFIndexingErrorListener listener); | ||
837 | |||
838 | /** | ||
839 | * Returns the internal, canonicalized implementation of an attribute value. | ||
840 | * | ||
841 | * <p> Behaviour: when in dynamic EMF mode, substitutes enum literals with a canonical version of the enum literal. | ||
842 | * Otherwise, returns the input. | ||
843 | * | ||
844 | * <p> The canonical enum literal will be guaranteed to be a valid EMF enum literal ({@link Enumerator}), | ||
845 | * and the best effort is made to ensure that it will be the same for all versions of the {@link EEnum}, | ||
846 | * including {@link EEnumLiteral}s in different versions of ecore packages, as well as Java enums generated from them.. | ||
847 | * | ||
848 | * <p> Usage is not required when simply querying the indexed model through the {@link NavigationHelper} API, | ||
849 | * as both method inputs and the results returned are automatically canonicalized in dynamic EMF mode. | ||
850 | * Using this method is required only if the client wants to do querying/filtering on the results returned, and wants to know what to look for. | ||
851 | */ | ||
852 | Object toCanonicalValueRepresentation(Object value); | ||
853 | |||
854 | /** | ||
855 | * @since 1.4 | ||
856 | */ | ||
857 | IndexingLevel getIndexingLevel(EClass type); | ||
858 | |||
859 | /** | ||
860 | * @since 1.4 | ||
861 | */ | ||
862 | IndexingLevel getIndexingLevel(EDataType type); | ||
863 | |||
864 | /** | ||
865 | * @since 1.4 | ||
866 | */ | ||
867 | IndexingLevel getIndexingLevel(EStructuralFeature feature); | ||
868 | |||
869 | /** | ||
870 | * @since 1.4 | ||
871 | */ | ||
872 | public int countDataTypeInstances(EDataType dataType); | ||
873 | |||
874 | /** | ||
875 | * @since 1.4 | ||
876 | */ | ||
877 | public int countFeatureTargets(EObject seedSource, EStructuralFeature feature); | ||
878 | |||
879 | /** | ||
880 | * @since 1.4 | ||
881 | */ | ||
882 | public int countFeatures(EStructuralFeature feature); | ||
883 | |||
884 | |||
885 | } | ||