blob: aa53ccdf5e43e8dc3904884e8f60e33efa16e11c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Christian W. Damus and others.
*
* 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:
* Christian W. Damus - initial API and implementation
*******************************************************************************/
package org.eclipse.papyrus.compare.uml2.internal.postprocessor;
import static com.google.common.collect.Iterables.filter;
import static org.eclipse.emf.compare.DifferenceSource.LEFT;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceKind;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ResourceAttachmentChange;
import org.eclipse.emf.compare.utils.MatchUtil;
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;
/**
* An adapter for a {@link ResourceAttachmentChange} that represents a resource refactoring. It provides
* details of the resource's old and new {@link URI}s.
*
* @author Christian W. Damus
*/
public final class ResourceRefactoringChange implements Adapter {
private static final Object TYPE = new Object();
private final ResourceAttachmentChange rac;
private URI oldURI;
private URI newURI;
/**
* Initializes me with the RAC that I wrap.
*
* @param rac
* my wrapped diff
*/
private ResourceRefactoringChange(ResourceAttachmentChange rac) {
super();
this.rac = rac;
rac.eAdapters().add(this);
}
public static boolean isResourceRefactoringChange(Diff diff) {
return diff instanceof ResourceAttachmentChange && get(diff) != null;
}
public static Predicate<Diff> isResourceRefactoringChange() {
return new Predicate<Diff>() {
public boolean apply(Diff input) {
return isResourceRefactoringChange(input);
}
};
}
public static ResourceRefactoringChange get(Diff diff) {
if (diff instanceof ResourceAttachmentChange) {
return (ResourceRefactoringChange)EcoreUtil.getExistingAdapter(diff, TYPE);
}
return null;
}
public static Function<Diff, ResourceRefactoringChange> get() {
return new Function<Diff, ResourceRefactoringChange>() {
public ResourceRefactoringChange apply(Diff input) {
return get(input);
}
};
}
public static ResourceRefactoringChange demand(ResourceAttachmentChange rac) {
ResourceRefactoringChange result = get(rac);
if (result == null) {
result = new ResourceRefactoringChange(rac);
}
return result;
}
public static ResourceRefactoringChange demand(Match match, DifferenceSource side) {
return demand(getRAC(match, side));
}
private static ResourceAttachmentChange getRAC(Match match, DifferenceSource side) {
Iterable<ResourceAttachmentChange> racs = filter(match.getDifferences(),
ResourceAttachmentChange.class);
return Iterables.find(racs, fromSide(side));
}
public static Predicate<ResourceRefactoringChange> onSide(final DifferenceSource side) {
return new Predicate<ResourceRefactoringChange>() {
public boolean apply(ResourceRefactoringChange input) {
return (input != null) && input.getSource() == side;
}
};
}
public ResourceAttachmentChange toDiff() {
return rac;
}
/**
* @return the oldURI
*/
public URI getOldURI() {
return oldURI;
}
/**
* @param oldURI
* the oldURI to set
*/
public void setOldURI(URI oldURI) {
this.oldURI = oldURI;
}
/**
* @return the newURI
*/
public URI getNewURI() {
return newURI;
}
/**
* @param newURI
* the newURI to set
*/
public void setNewURI(URI newURI) {
this.newURI = newURI;
}
public Resource getNewResource() {
// Get the resource of the new URI on the left side
return demandResource(getNewURI(), LEFT, true);
}
public Resource getOldResource() {
// Get the resource of the old URI on the left side
return demandResource(getOldURI(), LEFT, false);
}
/**
* Obtains the specified resource on the given {@code side} of the match.
*
* @param uri
* the resource URI to get
* @param side
* the side of the comparison in which to get the refactored resource
* @param create
* whether to create the resource if it doesn't exist (e.g., for merging into it)
* @return the resource, or {@code null} if it doesn't exist and is not {@code create}d
*/
protected Resource demandResource(URI uri, DifferenceSource side, boolean create) {
EObject context = MatchUtil.getMatchedObject(getMatch(), side);
ResourceSet rset = context.eResource().getResourceSet();
Resource result = rset.getResource(uri, false);
if (result == null) {
if (rset.getURIConverter().exists(uri, null)) {
result = rset.getResource(uri, true);
} else if (create) {
result = rset.createResource(uri);
}
}
return result;
}
//
// Diff protocol delegation
//
public DifferenceSource getSource() {
return rac.getSource();
}
public DifferenceKind getKind() {
return rac.getKind();
}
public DifferenceState getState() {
return rac.getState();
}
public Match getMatch() {
return rac.getMatch();
}
public EList<Diff> getRequiredBy() {
return rac.getRequiredBy();
}
//
// Adapter protocol
//
public Notifier getTarget() {
return rac;
}
public void setTarget(Notifier newTarget) {
if (newTarget != null && newTarget != rac) {
throw new IllegalArgumentException("attempt to attach to another object"); //$NON-NLS-1$
}
}
public boolean isAdapterForType(Object type) {
return type == TYPE;
}
public void notifyChanged(Notification notification) {
// Pass
}
}