| /******************************************************************************* |
| * Copyright (c) 2012 Obeo. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| * Eike Stepper - (390845) Make the URIInitializingIterator a little more extensible |
| *******************************************************************************/ |
| package org.eclipse.emf.compare.scope; |
| |
| import static java.util.Collections.emptyIterator; |
| |
| import com.google.common.base.Predicate; |
| import com.google.common.base.Predicates; |
| import com.google.common.collect.ForwardingIterator; |
| import com.google.common.collect.Iterators; |
| |
| import java.util.Iterator; |
| |
| import org.eclipse.emf.common.notify.Notifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| |
| /** |
| * This implementation of an {@link IComparisonScope} can be provided specific filters to filter out parts of |
| * the Notifiers' content lists. |
| * |
| * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a> |
| */ |
| public class FilterComparisonScope extends AbstractComparisonScope { |
| /** |
| * This will be used in order to determine the filter that should be used to filter the EObjects' content |
| * list of unnecessary values. |
| */ |
| protected Predicate<? super EObject> eObjectContentFilter = Predicates.alwaysTrue(); |
| |
| /** |
| * This will be used in order to determine the filter that should be used to filter the Resources' content |
| * list of unnecessary values. |
| */ |
| protected Predicate<? super EObject> resourceContentFilter = Predicates.alwaysTrue(); |
| |
| /** |
| * This will be used in order to determine the filter that should be used to filter the ResourceSets' |
| * content list of unnecessary values. |
| */ |
| protected Predicate<? super Resource> resourceSetContentFilter = Predicates.alwaysTrue(); |
| |
| /** |
| * This will instantiate a scope with left, right and origin Notifiers defined. |
| * |
| * @param left |
| * The left root of this comparison. |
| * @param right |
| * The right root of this comparison. |
| * @param origin |
| * The common ancestor of <code>left</code> and <code>right</code>. May be <code>null</code>. |
| */ |
| public FilterComparisonScope(Notifier left, Notifier right, Notifier origin) { |
| super(left, right, origin); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * This default implementation will only return the {@link Resource}s directly contained by |
| * {@link ResourceSet} which match the {@link #resourceSetContentFilter} predicate. |
| * </p> |
| * |
| * @see org.eclipse.emf.compare.scope.IComparisonScope#getCoveredResources(org.eclipse.emf.ecore.resource.ResourceSet) |
| */ |
| public Iterator<? extends Resource> getCoveredResources(ResourceSet resourceSet) { |
| if (resourceSet == null) { |
| return emptyIterator(); |
| } |
| |
| final Iterator<Resource> allResources = resourceSet.getResources().iterator(); |
| final Iterator<Resource> filter = Iterators.filter(allResources, resourceSetContentFilter); |
| |
| final Iterator<Resource> uriInitializingIt = new URIInitializingIterator<Resource>(filter); |
| |
| return Iterators.unmodifiableIterator(uriInitializingIt); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * This default implementation will return all direct and indirect content of the given {@link Resource}, |
| * filtering out those {@link EObject}s that do not match {@link #resourceContentFilter}. |
| * </p> |
| * |
| * @see org.eclipse.emf.compare.scope.IComparisonScope#getCoveredEObjects(org.eclipse.emf.ecore.resource.Resource) |
| */ |
| public Iterator<? extends EObject> getCoveredEObjects(Resource resource) { |
| if (resource == null) { |
| return emptyIterator(); |
| } |
| |
| final Iterator<EObject> properContent = EcoreUtil.getAllProperContents(resource, false); |
| final Iterator<EObject> filter = Iterators.filter(properContent, resourceContentFilter); |
| |
| final Iterator<EObject> uriInitializingIt = new URIInitializingIterator<EObject>(resource, filter); |
| |
| return Iterators.unmodifiableIterator(uriInitializingIt); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * This default implementation will return all direct and indirect content of the given {@link EObject}, |
| * filtering out those {@link EObject}s that do not match {@link #eObjectContentFilter}. |
| * </p> |
| * |
| * @see org.eclipse.emf.compare.scope.IComparisonScope#getChildren(org.eclipse.emf.ecore.EObject) |
| */ |
| public Iterator<? extends EObject> getChildren(EObject eObject) { |
| if (eObject == null) { |
| return emptyIterator(); |
| } |
| |
| final Iterator<EObject> properContent = EcoreUtil.getAllProperContents(eObject, false); |
| final Iterator<EObject> filter = Iterators.filter(properContent, eObjectContentFilter); |
| |
| final Iterator<EObject> uriInitializingIt = new URIInitializingIterator<EObject>(eObject, filter); |
| |
| return Iterators.unmodifiableIterator(uriInitializingIt); |
| } |
| |
| /** |
| * This can be used to set the filter that should be used to filter the EObjects' content list of |
| * unnecessary values. By default, we will use an "always true" predicate : the list won't be filtered out |
| * unless this is called with a new filter. |
| * |
| * @param newContentFilter |
| * The filter that should be used for EObject content filtering. |
| */ |
| public void setEObjectContentFilter(Predicate<? super EObject> newContentFilter) { |
| this.eObjectContentFilter = newContentFilter; |
| } |
| |
| /** |
| * This can be used to set the filter that should be used to filter the Resources' content list of |
| * unnecessary values. By default, we will return an "always true" predicate : the list won't be filtered |
| * out unless this is called with a new filter. |
| * |
| * @param resourceContentFilter |
| * The filter that should be used for Resource content filtering. |
| */ |
| public void setResourceContentFilter(Predicate<? super EObject> resourceContentFilter) { |
| this.resourceContentFilter = resourceContentFilter; |
| } |
| |
| /** |
| * This can be used to set the filter that should be used to filter the ResourceSets' content list of |
| * unnecessary values. By default, we will return an "always true" predicate : the list won't be filtered |
| * out unless this called with a new filter. |
| * |
| * @param resourceSetContentFilter |
| * The filter that should be used for ResourceSet content filtering. |
| */ |
| public void setResourceSetContentFilter(Predicate<? super Resource> resourceSetContentFilter) { |
| this.resourceSetContentFilter = resourceSetContentFilter; |
| } |
| |
| /** |
| * Tries and register the URI of the given object as one of this scope's resources. Note that we only |
| * consider EObjects and Resources. |
| * |
| * @param <T> |
| * Type of this object. |
| * @param obj |
| * eObject for which we |
| */ |
| protected <T> void addUri(T obj) { |
| if (obj instanceof Resource) { |
| addUri((Resource)obj); |
| } else if (obj instanceof EObject) { |
| addUri((EObject)obj); |
| } |
| } |
| |
| /** |
| * Registers the namespace and resource URI from the given <code>eObject</code>. |
| * |
| * @param eObject |
| * The given <code>eObject</code>. |
| */ |
| protected void addUri(EObject eObject) { |
| final Resource res = eObject.eResource(); |
| if (res != null) { |
| getResourceURIs().add(res.getURI().toString()); |
| } |
| getNsURIs().add(eObject.eClass().getEPackage().getNsURI()); |
| } |
| |
| /** |
| * Registers the resource URI from the given <code>resource</code>. |
| * |
| * @param resource |
| * The given <code>resource</code>. |
| */ |
| protected void addUri(Resource resource) { |
| getResourceURIs().add(resource.getURI().toString()); |
| } |
| |
| /** |
| * This iterator enables to add in the iteration the initialization of the namespace and resource uris |
| * set. |
| * |
| * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a> |
| * @param <T> |
| * The kind of object to iterate on. |
| */ |
| private class URIInitializingIterator<T> extends ForwardingIterator<T> { |
| |
| /** The origin iterator. */ |
| private Iterator<T> delegate; |
| |
| /** |
| * Constructor. |
| * |
| * @param delegate |
| * The origin iterator. |
| */ |
| URIInitializingIterator(Iterator<T> delegate) { |
| this.delegate = delegate; |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param resource |
| * The resource containing the elements to iterate on. |
| * @param delegate |
| * The origin iterator. |
| */ |
| URIInitializingIterator(Resource resource, Iterator<T> delegate) { |
| this.delegate = delegate; |
| addUri(resource); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param eObject |
| * The EObject containing the elements to iterate on. |
| * @param delegate |
| * The origin iterator. |
| */ |
| URIInitializingIterator(EObject eObject, Iterator<T> delegate) { |
| this.delegate = delegate; |
| addUri(eObject); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see com.google.common.collect.ForwardingIterator#delegate() |
| */ |
| @Override |
| protected Iterator<T> delegate() { |
| return delegate; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see com.google.common.collect.ForwardingIterator#next() |
| */ |
| @Override |
| public T next() { |
| T obj = super.next(); |
| addUri(obj); |
| return obj; |
| } |
| } |
| } |