Skip to main content
summaryrefslogtreecommitdiffstats
blob: 3acdad920580781032af2e2622f204f8177b3437 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*******************************************************************************
 * 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.emf.compare.diagram.ide.ui.papyrus.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.diagram.ide.ui.papyrus.internal.context.PapyrusContextUtil;
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;

/**
 * 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;
	}

}

Back to the top