/**
* <copyright>
*
* Copyright (c) 2006-2017 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.ui.sirius;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.diffmerge.api.IDiffPolicy;
import org.eclipse.emf.diffmerge.api.IMatchPolicy;
import org.eclipse.emf.diffmerge.api.IMergePolicy;
import org.eclipse.emf.diffmerge.api.Role;
import org.eclipse.emf.diffmerge.sirius.SiriusDiffPolicy;
import org.eclipse.emf.diffmerge.sirius.SiriusMatchPolicy;
import org.eclipse.emf.diffmerge.sirius.SiriusMergePolicy;
import org.eclipse.emf.diffmerge.ui.EMFDiffMergeUIPlugin;
import org.eclipse.emf.diffmerge.ui.gmf.GMFComparisonMethod;
import org.eclipse.emf.diffmerge.ui.specification.IModelScopeDefinition;
import org.eclipse.emf.diffmerge.ui.specification.ext.URIScopeDefinition;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* A Sirius comparison method.
*/
public class SiriusComparisonMethod extends GMFComparisonMethod {
/** A non-null map from roles to the corresponding Sirius sessions
* that may contain the model scope of the role */
protected final Map<Role, Session> _roleToSession;
/**
* Constructor
* @param leftScopeSpec a non-null scope specification
* @param rightScopeSpec a non-null scope specification
* @param ancestorScopeSpec an optional scope specification
*/
public SiriusComparisonMethod(IModelScopeDefinition leftScopeSpec,
IModelScopeDefinition rightScopeSpec, IModelScopeDefinition ancestorScopeSpec) {
super(leftScopeSpec, rightScopeSpec, ancestorScopeSpec);
_roleToSession = new HashMap<Role, Session>(3);
}
/**
* Return the Sirius session for the given role if possible
* (this method is only called once per role)
* @param role a non-null role
* @return a potentially null resource set
*/
protected Session checkSession(Role role) {
Session result = null;
if (role != Role.ANCESTOR || isThreeWay()) {
// Use session resource set if available
IModelScopeDefinition scopeDefinition = getModelScopeDefinition(role);
if (scopeDefinition instanceof URIScopeDefinition) {
URIScopeDefinition uriScopeDefinition = (URIScopeDefinition)scopeDefinition;
URI uri = uriScopeDefinition.getEntrypoint();
result = SessionManager.INSTANCE.getExistingSession(uri);
}
}
return result;
}
/**
* Look for Sirius sessions for the scope definitions of the different roles,
* see if they can be reused, and return the central editing domain in which
* the whole comparison can take place if any.
* This method is not supposed to be called more than once in a comparison method.
* @return a potentially null editing domain
*/
protected EditingDomain checkSessions() {
for (Role role : Role.values()) {
_roleToSession.put(role, checkSession(role));
}
Set<Session> sessions = new HashSet<Session>(_roleToSession.values());
sessions.remove(null);
int nbResourceSets = sessions.size();
EditingDomain result;
switch (nbResourceSets) {
case 0:
// No session found: use new editing domain
result = createEditingDomain();
_isDedicatedEditingDomain = true;
break;
case 1:
// One session found: use its editing domain
result = sessions.iterator().next().getTransactionalEditingDomain();
break;
case 2:
// Two sessions found
if (isThreeWay() && _roleToSession.get(Role.ANCESTOR) != null) {
// One of them is for the ancestor: use the other
Session sideSession = _roleToSession.get(Role.TARGET);
if (sideSession == null)
sideSession = _roleToSession.get(Role.REFERENCE);
result = sideSession.getTransactionalEditingDomain(); // sideSession cannot be null
} else {
// The two sessions are for the left and right sides:
// no central editing domain
result = null;
}
break;
default:
// Three sessions found: no central editing domain
result = null;
}
return result;
}
/**
* @see org.eclipse.emf.diffmerge.ui.gmf.GMFComparisonMethod#createDiffPolicy()
*/
@Override
protected IDiffPolicy createDiffPolicy() {
return new SiriusDiffPolicy();
}
/**
* @see org.eclipse.emf.diffmerge.ui.gmf.GMFComparisonMethod#createMatchPolicy()
*/
@Override
protected IMatchPolicy createMatchPolicy() {
return new SiriusMatchPolicy();
}
/**
* @see org.eclipse.emf.diffmerge.ui.gmf.GMFComparisonMethod#createMergePolicy()
*/
@Override
protected IMergePolicy createMergePolicy() {
return new SiriusMergePolicy();
}
/**
* @see org.eclipse.emf.diffmerge.ui.specification.ext.DefaultComparisonMethod#doGetEditingDomain()
*/
@Override
protected EditingDomain doGetEditingDomain() {
EditingDomain result = checkSessions();
if (result == null)
showNoEditingDomainWarning();
return result;
}
/**
* @see org.eclipse.emf.diffmerge.ui.gmf.GMFComparisonMethod#getCustomLabelProvider()
*/
@Override
protected ILabelProvider getCustomLabelProvider() {
return SiriusDiffMergeLabelProvider.getInstance();
}
/**
* @see org.eclipse.emf.diffmerge.ui.specification.ext.DefaultComparisonMethod#getResourceSet(org.eclipse.emf.diffmerge.api.Role)
*/
@Override
public ResourceSet getResourceSet(Role role_p) {
ResourceSet result = null;
EditingDomain centralDomain = getEditingDomain(); // Ensure initialization
if (centralDomain == null) {
// Only if no central editing domain
Session roleSession = _roleToSession.get(role_p);
if (roleSession != null) {
EditingDomain sessionDomain = roleSession.getTransactionalEditingDomain();
if (sessionDomain != null)
result = sessionDomain.getResourceSet();
}
}
return result;
}
/**
* Warn the user that no central editing domain will be used
*/
protected void showNoEditingDomainWarning() {
Display.getDefault().asyncExec(new Runnable() {
/**
* @see java.lang.Runnable#run()
*/
public void run() {
Shell shell = getShell();
if (shell != null) {
String message = Messages.SiriusComparisonMethod_UndoRedoWarning;
MessageDialog.openWarning(shell, EMFDiffMergeUIPlugin.LABEL, message);
}
}
});
}
}