/**
* <copyright>
*
* Copyright (c) 2010-2016 Thales Global Services S.A.S.
* 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:
* Thales Global Services S.A.S. - initial API and implementation
*
* </copyright>
*/
package org.eclipse.emf.diffmerge.gmf;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.diffmerge.api.scopes.IFeaturedModelScope;
import org.eclipse.emf.diffmerge.api.scopes.IModelScope;
import org.eclipse.emf.diffmerge.impl.policies.ConfigurableMatchPolicy;
import org.eclipse.emf.diffmerge.util.structures.comparable.ComparableTreeMap;
import org.eclipse.emf.diffmerge.util.structures.comparable.IComparableStructure;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
* A match policy for GMF elements.
* @author Olivier Constant
*/
public class GMFMatchPolicy extends ConfigurableMatchPolicy {
/** The set of GMF ViewTypes for which no semantic ID is supported */
protected static final Collection<String> __NO_SEMANTIC_VIEWTYPES = Arrays.asList(
"Note", "NoteAttachment"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Constructor
*/
public GMFMatchPolicy() {
// Nothing needed
}
/**
* @see org.eclipse.emf.diffmerge.impl.policies.ConfigurableMatchPolicy#getSemanticID(org.eclipse.emf.ecore.EObject, org.eclipse.emf.diffmerge.api.scopes.IModelScope, boolean)
*/
@Override
protected IComparableStructure<?> getSemanticID(EObject element_p, IModelScope scope_p,
boolean inScopeOnly_p) {
// Intended return types: ComparableLinkedList<String>,
// ComparableTreeMap<String, ComparableLinkedList<String>>
IComparableStructure<?> result = null;
if (element_p instanceof View && !(element_p instanceof Diagram))
result = getViewSemanticID((View)element_p, scope_p, inScopeOnly_p);
if (result == null)
result = super.getSemanticID(element_p, scope_p, inScopeOnly_p);
return result;
}
/**
* @see org.eclipse.emf.diffmerge.impl.policies.ConfigurableMatchPolicy#getUniqueName(org.eclipse.emf.ecore.EObject, org.eclipse.emf.diffmerge.api.scopes.IModelScope, boolean)
*/
@Override
protected String getUniqueName(EObject element_p, IModelScope scope_p, boolean inScopeOnly_p) {
String result;
if (element_p instanceof Diagram)
result = ((Diagram)element_p).getName();
else
result = super.getUniqueName(element_p, scope_p, inScopeOnly_p);
return result;
}
/**
* Return a semantic ID for the given View
* @param view_p a non-null view
* @param scope_p a non-null scope that covers element_p
* @param inScopeOnly_p whether only the scope may be considered, or the underlying EMF model
* @return a potentially null
*/
protected IComparableStructure<?> getViewSemanticID(View view_p,
IModelScope scope_p, boolean inScopeOnly_p) {
// The semantic ID is defined from the diagram and the represented element,
// the assumption being that an element cannot be represented more than once
// in the same diagram.
ComparableTreeMap<String, IComparableStructure<?>> result = null;
if (scope_p instanceof IFeaturedModelScope) {
IFeaturedModelScope scope = (IFeaturedModelScope)scope_p;
Diagram diagram = view_p.getDiagram();
String viewType = view_p.getType();
if (diagram != null && viewType != null && !__NO_SEMANTIC_VIEWTYPES.contains(viewType)) {
List<EObject> values = scope.get(view_p, NotationPackage.eINSTANCE.getView_Element());
IComparableStructure<String> typeID = getEncapsulateOrNull(view_p.eClass().getName());
if (values.size() == 1) {
// Represented element is present
EObject represented = values.get(0);
IComparableStructure<?> diagramID = getMatchID(diagram, scope_p);
if (diagramID != null) {
IComparableStructure<?> representedID = getMatchID(represented, scope_p);
if (representedID != null) {
result = new ComparableTreeMap<String, IComparableStructure<?>>();
result.put("SEMANTIC_ID_TYPE", typeID); //$NON-NLS-1$
result.put("SEMANTIC_ID_DIAGRAM", diagramID); //$NON-NLS-1$
result.put("SEMANTIC_ID_ELEMENT", representedID); //$NON-NLS-1$
result.put("SEMANTIC_ID_VIEWTYPE", getEncapsulateOrNull(viewType)); //$NON-NLS-1$
}
}
} else {
// Represented element is absent
EObject container = getContainer(view_p, scope_p, inScopeOnly_p);
if (container != null) {
IComparableStructure<?> containerID = getMatchID(container, scope_p);
if (containerID != null) {
result = new ComparableTreeMap<String, IComparableStructure<?>>();
result.put("SEMANTIC_ID_TYPE", typeID); //$NON-NLS-1$
result.put("SEMANTIC_ID_CONTAINER", containerID); //$NON-NLS-1$
result.put("SEMANTIC_ID_VIEWTYPE", getEncapsulateOrNull(viewType)); //$NON-NLS-1$
}
}
}
}
}
return result;
}
/**
* @see org.eclipse.emf.diffmerge.impl.policies.ConfigurableMatchPolicy#isDiscriminatingContainment(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EReference)
*/
@Override
protected boolean isDiscriminatingContainment(EObject element_p, EReference containment_p) {
return super.isDiscriminatingContainment(element_p, containment_p) ||
containment_p == NotationPackage.eINSTANCE.getView_Styles();
}
}