[578422] Extend subscriber retrieval through extension points
[EMFCompare2.git] / plugins / org.eclipse.emf.compare.ide.ui / src / org / eclipse / emf / compare / ide / ui / internal / logical / ComparisonScopeBuilder.java
blob934c0f0fdc9130460c7f143d5b363a318f88dca1
1 /*******************************************************************************
2 * Copyright (c) 2013, 2022 Obeo and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Obeo - initial API and implementation
10 * Stefan Dirix - bug 466607
11 * Philip Langer - add support for setting initial file URIs to scope
12 * Martin Fleck - bug 512562
13 * Martin Fleck - bug 578422
14 *******************************************************************************/
15 package org.eclipse.emf.compare.ide.ui.internal.logical;
17 import static com.google.common.base.Preconditions.checkNotNull;
18 import static com.google.common.collect.Collections2.transform;
19 import static org.eclipse.emf.compare.ide.ui.internal.util.PlatformElementUtil.findFile;
20 import static org.eclipse.emf.compare.ide.utils.ResourceUtil.createURIFor;
22 import com.google.common.base.Function;
23 import com.google.common.base.Predicate;
24 import com.google.common.collect.Sets;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.LinkedHashSet;
29 import java.util.Set;
31 import org.apache.log4j.Logger;
32 import org.eclipse.compare.ICompareContainer;
33 import org.eclipse.compare.IStreamContentAccessor;
34 import org.eclipse.compare.ITypedElement;
35 import org.eclipse.core.resources.IFile;
36 import org.eclipse.core.resources.IResource;
37 import org.eclipse.core.resources.IStorage;
38 import org.eclipse.core.runtime.Assert;
39 import org.eclipse.core.runtime.IProgressMonitor;
40 import org.eclipse.core.runtime.OperationCanceledException;
41 import org.eclipse.core.runtime.SubMonitor;
42 import org.eclipse.emf.common.util.BasicDiagnostic;
43 import org.eclipse.emf.common.util.Diagnostic;
44 import org.eclipse.emf.common.util.URI;
45 import org.eclipse.emf.compare.DifferenceSource;
46 import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
47 import org.eclipse.emf.compare.ide.internal.hook.ResourceSetHookRegistry;
48 import org.eclipse.emf.compare.ide.internal.utils.NotLoadingResourceSet;
49 import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
50 import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
51 import org.eclipse.emf.compare.ide.ui.internal.util.PlatformElementUtil;
52 import org.eclipse.emf.compare.ide.ui.logical.IModelMinimizer;
53 import org.eclipse.emf.compare.ide.ui.logical.IModelResolver;
54 import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor;
55 import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
56 import org.eclipse.emf.compare.ide.utils.ResourceUtil;
57 import org.eclipse.emf.compare.ide.utils.StorageTraversal;
58 import org.eclipse.emf.compare.scope.DefaultComparisonScope;
59 import org.eclipse.emf.compare.scope.FilterComparisonScope;
60 import org.eclipse.emf.compare.scope.IComparisonScope;
61 import org.eclipse.emf.ecore.resource.Resource;
62 import org.eclipse.emf.ecore.resource.ResourceSet;
63 import org.eclipse.emf.ecore.resource.URIConverter;
64 import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
65 import org.eclipse.emf.ecore.util.EcoreUtil;
66 import org.eclipse.team.core.subscribers.Subscriber;
68 /**
69 * This will be used by EMF Compare in order to construct its comparison scope given a "starting point".
70 * <p>
71 * A single file is not always a single EMF model, nor is an EMF model always stored in a single file. This
72 * will be used to resolve all physical resources composing the logical model we are to compare, minimize this
73 * set to the potential changed candidates, and construct the actual comparison scope.
74 * </p>
76 * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
78 public final class ComparisonScopeBuilder {
79 /** The instance that will be in charge of resolving our logical models. */
80 private final IModelResolver resolver;
82 /** The instance that will be in charge of reducing the comparison scope. */
83 private final IModelMinimizer minimizer;
85 /** The accessor that can be used to retrieve synchronization information between our resources. */
86 private final IStorageProviderAccessor storageAccessor;
88 /** The logger. */
89 private static final Logger LOGGER = Logger.getLogger(ComparisonScopeBuilder.class);
91 /** Function transforming an IResource into its URI. */
92 private static final Function<IResource, URI> TO_FILE_URIS = new Function<IResource, URI>() {
93 public URI apply(IResource input) {
94 URI uri;
95 if (input instanceof IStorage) {
96 uri = ResourceUtil.asURI().apply((IStorage)input);
97 } else {
98 uri = URI.createPlatformResourceURI(input.getFullPath().toString(), true);
100 return uri;
105 * Constructs a builder given its model resolver and minimizer.
107 * @param resolver
108 * The resolver we'll use to resolve the logical models of this scope.
109 * @param minimizer
110 * The minimizer that will be use to reduce the comparison scope before construction.
112 public ComparisonScopeBuilder(IModelResolver resolver, IModelMinimizer minimizer) {
113 this(resolver, minimizer, null);
117 * Constructs a builder given its model resolver and minimizer, along with the storage accessor for remote
118 * data.
120 * @param resolver
121 * The resolver we'll use to resolve the logical models of this scope.
122 * @param minimizer
123 * The minimizer that will be use to reduce the comparison scope before construction.
124 * @param storageAccessor
125 * The storage accessor we'll use to access remote resource variants. May be <code>null</code>,
126 * in which case we'll only use local content.
128 public ComparisonScopeBuilder(IModelResolver resolver, IModelMinimizer minimizer,
129 IStorageProviderAccessor storageAccessor) {
130 this.resolver = checkNotNull(resolver);
131 this.minimizer = checkNotNull(minimizer);
132 this.storageAccessor = storageAccessor;
136 * Builds a comparison scope from the given two starting elements.
138 * @param left
139 * The element that will be used as the starting point to resolve the left logical model.
140 * @param right
141 * Element that will be used as the starting point to resolve the left logical model.
142 * @param monitor
143 * The monitor on which to report progress information to the user.
144 * @return The newly created comparison scope.
146 public IComparisonScope build(ITypedElement left, ITypedElement right, IProgressMonitor monitor) {
147 return build(left, right, null, monitor);
151 * Builds a comparison scope from the given starting elements.
153 * @param left
154 * The element that will be used as the starting point to resolve the left logical model.
155 * @param right
156 * Element that will be used as the starting point to resolve the left logical model.
157 * @param origin
158 * The origin resource, starting point of the logical model we are to resolve as the origin
159 * one. Can be <code>null</code>.
160 * @param monitor
161 * The monitor on which to report progress information to the user.
162 * @return The newly created comparison scope.
164 public IComparisonScope build(ITypedElement left, ITypedElement right, ITypedElement origin,
165 IProgressMonitor monitor) {
166 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
167 subMonitor.subTask(EMFCompareIDEUIMessages.getString("EMFSynchronizationModel.resolving")); //$NON-NLS-1$
168 try {
169 final SynchronizationModel syncModel;
170 if (storageAccessor != null) {
171 syncModel = createSynchronizationModel(storageAccessor, left, right, origin,
172 subMonitor.newChild(60));
173 } else {
174 syncModel = createSynchronizationModel(left, right, origin, subMonitor.newChild(60));
177 return createMinimizedScope(left, syncModel, subMonitor.newChild(40));
178 } catch (InterruptedException e) {
179 Thread.currentThread().interrupt();
180 EmptyComparisonScope scope = new EmptyComparisonScope();
181 scope.setDiagnostic(BasicDiagnostic.toDiagnostic(e));
182 return scope;
187 * Resolves and minimizes the logical model for the given three typed element as would be done by
188 * {@link #build(ITypedElement, ITypedElement, ITypedElement, IProgressMonitor)}, but returns directly the
189 * SynchronizationModel DTO instead of the actual IComparisonScope.
190 * <p>
191 * This internal API is only intended for use by the resource mapping mergers.
192 * </p>
194 * @param left
195 * The element that will be used as the starting point to resolve the left logical model.
196 * @param right
197 * Element that will be used as the starting point to resolve the left logical model.
198 * @param origin
199 * The origin resource, starting point of the logical model we are to resolve as the origin
200 * one. Can be <code>null</code>.
201 * @param monitor
202 * The monitor on which to report progress information to the user.
203 * @return The newly created SynchronizationModel.
204 * @throws InterruptedException
205 * In case of user interruption.
207 /* package */SynchronizationModel buildSynchronizationModel(ITypedElement left, ITypedElement right,
208 ITypedElement origin, IProgressMonitor monitor) throws InterruptedException {
209 if (LOGGER.isDebugEnabled()) {
210 LOGGER.debug("buildSynchronizationModel - START"); //$NON-NLS-1$
212 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
213 subMonitor.subTask(EMFCompareIDEUIMessages.getString("EMFSynchronizationModel.resolving")); //$NON-NLS-1$
215 final SynchronizationModel syncModel;
216 if (LOGGER.isDebugEnabled()) {
217 LOGGER.debug("buildSynchronizationModel - Creating sync model"); //$NON-NLS-1$
219 if (storageAccessor != null) {
220 syncModel = createSynchronizationModel(storageAccessor, left, right, origin,
221 subMonitor.newChild(90));
222 } else {
223 syncModel = createSynchronizationModel(left, right, origin, subMonitor.newChild(90));
225 if (LOGGER.isDebugEnabled()) {
226 LOGGER.debug("buildSynchronizationModel - Minimizing model"); //$NON-NLS-1$
228 minimizer.minimize(PlatformElementUtil.findFile(left), syncModel, subMonitor.newChild(10));
229 if (LOGGER.isDebugEnabled()) {
230 LOGGER.debug("buildSynchronizationModel - FINISH NORMALLY"); //$NON-NLS-1$
232 return syncModel;
236 * Constructs the comparison scope corresponding to the given typed elements.
238 * @param left
239 * Left of the compared elements.
240 * @param right
241 * Right of the compared elements.
242 * @param origin
243 * Common ancestor of the <code>left</code> and <code>right</code> compared elements.
244 * @param monitor
245 * Monitor to report progress on.
246 * @return The created comparison scope.
248 public static IComparisonScope create(ICompareContainer container, ITypedElement left,
249 ITypedElement right, ITypedElement origin, IProgressMonitor monitor) {
250 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
251 Subscriber subscriber = EMFCompareIDEUIPlugin.getDefault().getSubscriberProviderRegistry()
252 .getSubscriber(container, left, right, origin, subMonitor.split(10));
253 IStorageProviderAccessor storageAccessor = null;
254 if (subscriber != null) {
255 storageAccessor = new SubscriberStorageAccessor(subscriber);
257 IStorage leftStorage = PlatformElementUtil.findFile(left);
258 if (leftStorage == null) {
259 leftStorage = StreamAccessorStorage.fromTypedElement(left);
261 IModelResolver resolver = EMFCompareIDEUIPlugin.getDefault().getModelResolverRegistry()
262 .getBestResolverFor(leftStorage);
263 final ComparisonScopeBuilder scopeBuilder = new ComparisonScopeBuilder(resolver,
264 EMFCompareIDEUIPlugin.getDefault().getModelMinimizerRegistry().getCompoundMinimizer(),
265 storageAccessor);
266 return scopeBuilder.build(left, right, origin, subMonitor.split(90));
270 * Creates the comparison scope corresponding to the given synchronization model, with no further
271 * operation on it.
272 * <p>
273 * This internal API is only intended for use by the resource mapping mergers and is not meant to be
274 * referenced.
275 * </p>
277 * @param synchronizationModel
278 * The synchronization model describing the traversals for which a comparison scope is needed.
279 * @param monitor
280 * Monitor on which to report progress information to the user.
281 * @return The created comparison scope.
282 * @throws OperationCanceledException
283 * if the user cancels (or has already canceled) the operation through the given
284 * {@code monitor}.
285 * @noreference This method is not intended to be referenced by clients.
287 public static IComparisonScope create(SynchronizationModel synchronizationModel, IProgressMonitor monitor)
288 throws OperationCanceledException {
289 if (monitor.isCanceled()) {
290 throw new OperationCanceledException();
293 return createScope(synchronizationModel, monitor);
297 * Creates the synchronization model for the given three elements (left, right, and the common ancestor of
298 * the two). Since this comparison may concern either local or remote resources, all I/O operations should
299 * go through the given storage accessor.
301 * @param accessor
302 * The accessor that can be used to retrieve synchronization information between our resources.
303 * @param left
304 * Typed element used as the left side of this comparison.
305 * @param right
306 * Typed element used as the right side of this comparison.
307 * @param origin
308 * Common ancestor of <code>left</code> and <code>right</code>.
309 * @param monitor
310 * Monitor to report progress information on.
311 * @return The created synchronization model.
313 private SynchronizationModel createSynchronizationModel(IStorageProviderAccessor accessor,
314 ITypedElement left, ITypedElement right, ITypedElement origin, IProgressMonitor monitor)
315 throws InterruptedException {
317 // Can we find a local file to associate a proper path to our storages?
318 final IFile localFile = findFile(left);
319 String path = null;
320 if (localFile != null) {
321 path = localFile.getFullPath().toString();
324 final IStorage leftStorage = StreamAccessorStorage.fromTypedElement(path, left);
325 final IStorage rightStorage;
326 if (right instanceof IStreamContentAccessor) {
327 rightStorage = StreamAccessorStorage.fromTypedElement(path, right);
328 } else {
329 rightStorage = null;
331 final IStorage originStorage;
332 if (origin instanceof IStreamContentAccessor) {
333 originStorage = StreamAccessorStorage.fromTypedElement(path, origin);
334 } else {
335 originStorage = null;
338 return resolver.resolveModels(accessor, leftStorage, rightStorage, originStorage, monitor);
342 * Creates the synchronization model for the given three elements (left, right, and their common
343 * ancestor). Since we have no remote data available, we'll consider that the three given files are either
344 * locally available, or that they have no logical model.
346 * @param left
347 * Typed element used as the left side of this comparison.
348 * @param right
349 * Typed element used as the right side of this comparison.
350 * @param origin
351 * Common ancestor of <code>left</code> and <code>right</code>.
352 * @param monitor
353 * Monitor to report progress information on.
354 * @return The created synchronization model.
356 private SynchronizationModel createSynchronizationModel(ITypedElement left, ITypedElement right,
357 ITypedElement origin, IProgressMonitor monitor) throws InterruptedException {
358 // Is this a local comparison?
359 final IFile leftFile = findFile(left);
360 final IFile rightFile = findFile(right);
361 if (leftFile != null && rightFile != null) {
362 // assume origin is local or null
363 return resolver.resolveLocalModels(leftFile, rightFile, findFile(origin), monitor);
366 // This is not a local comparison, and we've got no info on how to load remote revisions.
367 final IStorage leftStorage = StreamAccessorStorage.fromTypedElement(left);
368 Assert.isNotNull(leftStorage);
369 final IStorage rightStorage;
370 if (right instanceof IStreamContentAccessor) {
371 rightStorage = StreamAccessorStorage.fromTypedElement(right);
372 } else {
373 rightStorage = null;
375 final IStorage originStorage;
376 if (origin instanceof IStreamContentAccessor) {
377 originStorage = StreamAccessorStorage.fromTypedElement(origin);
378 } else {
379 originStorage = null;
382 return loadSingleResource(leftStorage, rightStorage, originStorage);
386 * We cannot resolve the logical model of these elements. Load them as single resources.
388 * @param left
389 * Storage to be loaded as left.
390 * @param right
391 * Storage to be loaded as right.
392 * @param origin
393 * Common ancestor of left and right, if any.
394 * @return The resolved synchronization model.
396 private SynchronizationModel loadSingleResource(IStorage left, IStorage right, IStorage origin) {
397 final StorageTraversal leftTraversal = new StorageTraversal(
398 new LinkedHashSet<IStorage>(Arrays.asList(left)));
399 final StorageTraversal rightTraversal;
400 if (right != null) {
401 rightTraversal = new StorageTraversal(new LinkedHashSet<IStorage>(Arrays.asList(right)));
402 } else {
403 rightTraversal = new StorageTraversal(Sets.<IStorage> newLinkedHashSet());
405 final StorageTraversal originTraversal;
406 if (origin != null) {
407 originTraversal = new StorageTraversal(new LinkedHashSet<IStorage>(Arrays.asList(origin)));
408 } else {
409 originTraversal = new StorageTraversal(Sets.<IStorage> newLinkedHashSet());
412 return new SynchronizationModel(leftTraversal, rightTraversal, originTraversal);
416 * Prepare the given synchronization model for use, then create the corresponding comparison scope.
418 * @param left
419 * The element that has been used as the starting point to resolve the left logical model.
420 * @param syncModel
421 * The synchronization model describing our resource traversals.
422 * @param monitor
423 * Monitor on which to report progress information to the user.
424 * @return The created comparison scope.
426 private IComparisonScope createMinimizedScope(ITypedElement left, SynchronizationModel syncModel,
427 IProgressMonitor monitor) {
428 if (monitor.isCanceled()) {
429 throw new OperationCanceledException();
432 SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
433 // Minimize the traversals to non-read-only resources with no binary identical counterparts.
434 minimizer.minimize(PlatformElementUtil.findFile(left), syncModel, subMonitor.newChild(10));
435 return createScope(syncModel, subMonitor.newChild(90));
439 * Constructs the actual comparison scope given the storage traversals from which to load the resources.
441 * @param syncModel
442 * The synchronization model describing our resource traversals.
443 * @param monitor
444 * Monitor on which to report progress information to the user.
445 * @return The created comparison scope.
447 private static IComparisonScope createScope(SynchronizationModel syncModel, IProgressMonitor monitor) {
448 SubMonitor progress = SubMonitor.convert(monitor, 3);
449 progress.subTask(EMFCompareIDEUIMessages.getString("EMFSynchronizationModel.creatingScope")); //$NON-NLS-1$
451 final StorageTraversal leftTraversal = syncModel.getLeftTraversal();
452 final StorageTraversal rightTraversal = syncModel.getRightTraversal();
453 final StorageTraversal originTraversal = syncModel.getOriginTraversal();
455 final ResourceSet originResourceSet;
456 ResourceSetHookRegistry resourceSetHookRegistry = EMFCompareIDEPlugin.getDefault()
457 .getResourceSetHookRegistry();
458 if (originTraversal == null || originTraversal.getStorages().isEmpty()) {
459 originResourceSet = null;
460 progress.setWorkRemaining(2);
461 } else {
462 originResourceSet = NotLoadingResourceSet.create(originTraversal, progress.newChild(1),
463 resourceSetHookRegistry);
465 final ResourceSet leftResourceSet = NotLoadingResourceSet.create(leftTraversal, progress.newChild(1),
466 resourceSetHookRegistry);
467 final ResourceSet rightResourceSet = NotLoadingResourceSet.create(rightTraversal,
468 progress.newChild(1), resourceSetHookRegistry);
470 final URIConverter converter = new ExtensibleURIConverterImpl();
471 final Set<URI> urisInScope = Sets.newLinkedHashSet();
472 for (IStorage left : leftTraversal.getStorages()) {
473 urisInScope.add(converter.normalize(createURIFor(left)));
475 for (IStorage right : rightTraversal.getStorages()) {
476 urisInScope.add(converter.normalize(createURIFor(right)));
478 if (originTraversal != null) {
479 for (IStorage origin : originTraversal.getStorages()) {
480 urisInScope.add(converter.normalize(createURIFor(origin)));
484 final FilterComparisonScope scope = new DefaultComparisonScope(leftResourceSet, rightResourceSet,
485 originResourceSet);
486 scope.setResourceSetContentFilter(isInScope(urisInScope));
488 final Set<IResource> involvedResources = syncModel.getAllInvolvedResources();
489 final Collection<URI> involvedResourceURIs = transform(involvedResources, TO_FILE_URIS);
490 scope.getAllInvolvedResourceURIs().addAll(involvedResourceURIs);
492 Diagnostic syncModelDiagnostic = syncModel.getDiagnostic();
493 Diagnostic scopeDiagnostic = computeDiagnostics(originResourceSet, leftResourceSet, rightResourceSet);
495 BasicDiagnostic basicDiagnostic = new BasicDiagnostic(Diagnostic.OK, EMFCompareIDEUIPlugin.PLUGIN_ID,
496 0, null, new Object[0]);
498 basicDiagnostic.add(syncModelDiagnostic);
499 basicDiagnostic.add(scopeDiagnostic);
501 scope.setDiagnostic(basicDiagnostic);
502 return scope;
505 private static Diagnostic computeDiagnostics(final ResourceSet originResourceSet,
506 final ResourceSet leftResourceSet, final ResourceSet rightResourceSet) {
507 final BasicDiagnostic originDiagnostic;
508 if (originResourceSet != null) {
509 originDiagnostic = getResourceSetDiagnostic(originResourceSet, null, true);
510 } else {
511 originDiagnostic = null;
513 BasicDiagnostic leftDiagnostic = getResourceSetDiagnostic(leftResourceSet, DifferenceSource.LEFT,
514 true);
515 BasicDiagnostic rightDiagnostic = getResourceSetDiagnostic(rightResourceSet, DifferenceSource.RIGHT,
516 true);
518 BasicDiagnostic diagnostic = new BasicDiagnostic(Diagnostic.OK, EMFCompareIDEUIPlugin.PLUGIN_ID, 0,
519 EMFCompareIDEUIMessages.getString("ComparisonScopeBuilder.comparisonScopeDiagnostic"), //$NON-NLS-1$
520 new Object[0]);
522 if (originDiagnostic != null) {
523 diagnostic.add(originDiagnostic);
525 diagnostic.add(leftDiagnostic);
526 diagnostic.add(rightDiagnostic);
528 return diagnostic;
532 * Compute the diagnotic on each resource of the given resource set and return a diagnostic composed of
534 * @param resourceSet
535 * the resource set
536 * @param side
537 * the resource set's side. null means origin
538 * @param includeWarning
539 * @return the composite diagnostic
541 private static BasicDiagnostic getResourceSetDiagnostic(final ResourceSet resourceSet,
542 DifferenceSource side, boolean includeWarning) {
543 final String sideStr;
544 if (side == DifferenceSource.LEFT) {
545 sideStr = EMFCompareIDEUIMessages.getString("ComparisonScopeBuilder.left"); //$NON-NLS-1$
546 } else if (side == DifferenceSource.RIGHT) {
547 sideStr = EMFCompareIDEUIMessages.getString("ComparisonScopeBuilder.right"); //$NON-NLS-1$
548 } else {
549 sideStr = EMFCompareIDEUIMessages.getString("ComparisonScopeBuilder.ancestor"); //$NON-NLS-1$
551 BasicDiagnostic diagnostic = new BasicDiagnostic(EMFCompareIDEUIPlugin.PLUGIN_ID, 0,
552 EMFCompareIDEUIMessages.getString("ComparisonScopeBuilder.resourceSetDiagnostic", sideStr), //$NON-NLS-1$
553 new Object[0]);
554 for (Resource resource : resourceSet.getResources()) {
555 Diagnostic resourceDiagnostic = EcoreUtil.computeDiagnostic(resource, includeWarning);
556 diagnostic.merge(resourceDiagnostic);
558 return diagnostic;
562 * Returns a predicate that can be applied to {@link Resource}s in order to check if their URI is
563 * contained in the given set.
565 * @param uris
566 * URIs that we consider to be in this scope.
567 * @return A useable Predicate.
569 private static Predicate<Resource> isInScope(final Set<URI> uris) {
570 return new Predicate<Resource>() {
571 public boolean apply(Resource input) {
572 final boolean result;
573 if (input != null) {
574 URI inputUri = input.getURI();
575 if (uris.contains(inputUri)) {
576 result = true;
577 } else if (input.getResourceSet() != null
578 && input.getResourceSet().getURIConverter() != null) {
579 // Tries to normalize the URI in case it is a pathmap uri that needs to be resolved
580 URI normalizedInputUri = input.getResourceSet().getURIConverter().normalize(inputUri);
581 result = uris.contains(normalizedInputUri);
582 } else {
583 result = false;
585 } else {
586 result = false;
588 return result;