blob: 25ab3b976dececc38dbf1b5e876260a98c3b8eca [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 EclipseSource Muenchen GmbH 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:
* Stefan Dirix - initial API and implementation
*******************************************************************************/
package org.eclipse.papyrus.compare.diagram.ide.ui.internal.accessorfactory;
import com.google.common.collect.Sets;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor;
import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory;
import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement;
import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl.AbstractAccessorFactory;
import org.eclipse.papyrus.compare.diagram.ide.ui.internal.context.PapyrusContextUtil;
/**
* Returns a special PapyrusAccessor when the comparison took place in a Papyrus context, otherwise the call
* is delegated to a the normal CompareAccessorFactories.
*
* @author Stefan Dirix <sdirix@eclipsesource.com>
*/
@SuppressWarnings("restriction")
public class PapyrusAccessorFactoryWrapper extends AbstractAccessorFactory {
/**
* The types for which we return a special Papyrus CompareAccessor.
*/
private static final Set<String> OVERRIDE_TYPES = Sets.newHashSet(
"org.eclipse.emf.compare.rcp.ui.eTreeDiff", "org.eclipse.emf.compare.rcp.ui.eMatch", //$NON-NLS-1$ //$NON-NLS-2$
"org.eclipse.emf.compare.rcp.ui.eResourceDiff", "NODE_TYPE__EMF_EOBJECT", //$NON-NLS-1$ //$NON-NLS-2$
"NODE_TYPE__EMF_RESOURCE", "NODE_TYPE__EMF_RESOURCESET", "NODE_TYPE__EMF_COMPARISON"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/**
* {@inheritDoc}
*/
public boolean isFactoryFor(Object target) {
return true;
}
/**
* {@inheritDoc}
*/
public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) {
final IAccessorFactory highestRankingFactory = getHighestRankingFactory(target);
if (highestRankingFactory != null) {
final ITypedElement left = highestRankingFactory.createLeft(adapterFactory, target);
return wrapIfNecessary(left);
}
return null;
}
/**
* {@inheritDoc}
*/
public ITypedElement createRight(AdapterFactory adapterFactory, Object target) {
final IAccessorFactory highestRankingFactory = getHighestRankingFactory(target);
if (highestRankingFactory != null) {
final ITypedElement right = highestRankingFactory.createRight(adapterFactory, target);
return wrapIfNecessary(right);
}
return null;
}
/**
* {@inheritDoc}
*/
public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) {
final IAccessorFactory highestRankingFactory = getHighestRankingFactory(target);
if (highestRankingFactory != null) {
final ITypedElement ancestor = highestRankingFactory.createAncestor(adapterFactory, target);
return wrapIfNecessary(ancestor);
}
return null;
}
/**
* Checks the given {@link ITypedElement} and wraps it in a PapyrusAccessor if needed.
*
* @param element
* the {@linked ITypedElement} to check.
* @return the wrapped {@code element} if a PapyrusAccessor is needed, the original {@code element}
* otherwise.
*/
private ITypedElement wrapIfNecessary(ITypedElement element) {
if (element instanceof ICompareAccessor) {
final ICompareAccessor accessor = (ICompareAccessor)element;
if (PapyrusContextUtil.isPapyrusContext(accessor.getComparison())
&& isOverrideType(element.getType())) {
return new PapyrusAccessorWrapper(accessor);
}
}
return element;
}
/**
* Determines whether the given type is one of the types we override in a Papyrus context.
*
* @param type
* the type to check.
* @return {@code true} if the type is one of the types we override, {@code false} otherwise.
*/
private boolean isOverrideType(String type) {
return OVERRIDE_TYPES.contains(type);
}
/**
* Searches the highest ranking factory for the given target, disregarding {@code this} factory itself.
*
* @param target
* the target for which the highest ranking factory is to be determined.
* @return the highest ranking factory which is not this class itself, {@code null} if no other factory
* could be determined.
*/
private IAccessorFactory getHighestRankingFactory(Object target) {
IAccessorFactory.Registry factoryRegistry = EMFCompareRCPUIPlugin.getDefault()
.getAccessorFactoryRegistry();
Iterator<IAccessorFactory> factories = factoryRegistry.getFactories(target).iterator();
IAccessorFactory ret = null;
while (factories.hasNext()) {
IAccessorFactory factory = factories.next();
// Do not use this or another higher ranking factory to avoid endless loops
if (factory.getRanking() >= this.getRanking()) {
continue;
}
if (ret == null || factory.getRanking() > ret.getRanking()) {
ret = factory;
}
}
return ret;
}
}