/*****************************************************************************
* Copyright (c) 2011 Atos Origin.
*
*
* 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:
* Atos Origin - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.groups.utils;
import java.util.Comparator;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.papyrus.uml.diagram.common.groups.core.groupcontainment.GroupContainmentRegistry;
/**
* This comparator give a way to have compare two IgraphicalEditParts by their parental link.
* If A is an ancestor of B in the graphical model or in the model then A<B
* If B is an ancestor of A in the graphical model or in the model then A<B
* else A=B (there is no parent link between them)
*
* @author adaussy
*
*/
public class GraphicalAndModelElementComparator implements Comparator<IGraphicalEditPart> {
/**
*
* @author adaussy
*/
public static enum Mode {
/** Define the model comparison mode */
MODEL,
/** Define the graphical comparison mode */
GRAPHICAL_AND_MODEL;
}
/**
* Current mode of the comparator
*
* @see {@link GraphicalAndModelElementComparator.Mode}
*/
private Mode mode;
private Map registery;
public GraphicalAndModelElementComparator(IGraphicalEditPart anypart) {
mode = Mode.GRAPHICAL_AND_MODEL;
this.registery = anypart.getViewer().getEditPartRegistry();
}
public GraphicalAndModelElementComparator(Mode mode, IGraphicalEditPart anypart) {
this.mode = mode;
this.registery = anypart.getViewer().getEditPartRegistry();
}
/**
* Get the current mode
*
* @return Current Mode
*/
public Mode getMode() {
return mode;
}
/**
* Set the current mode
*
* @param mode
* we want to set @see {@link GraphicalAndModelElementComparator.Mode}
*/
public void setMode(Mode mode) {
this.mode = mode;
}
/**
* Compare two IGraphicalEditPart.
* If o1 is an ancestor of o2 in the graphical model or in the model then o2>o1
* If o2 is an ancestor of o1 in the graphical model or in the model then o2<o1
* else o2 = o1
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*
* @param o1
* @param o2
* @return
*/
public int compare(IGraphicalEditPart o1, IGraphicalEditPart o2) {
if(o1.equals(o2)) {
return 0;
} else {
if(Mode.GRAPHICAL_AND_MODEL.equals(mode)) {
/*
* Compute the Graphic comparison
*/
EditPart o1Graphic = o1;
EditPart o2Graphic = o2;
/*
* Look if o1 is an ancestor of o2 (graphical model)
*/
EditPart graphicalParent = o2Graphic.getParent();
while(graphicalParent != null) {
if(graphicalParent.equals(o1Graphic)) {
return -1;
}
graphicalParent = graphicalParent.getParent();
}
/*
* Look if o2 is an ancestor of o1 (graphical model)
*/
graphicalParent = o1Graphic.getParent();
while(graphicalParent != null) {
if(graphicalParent == o2Graphic) {
return 1;
}
graphicalParent = graphicalParent.getParent();
}
}
/*
* Compute the Model comparison
*/
EObject o1model = o1.resolveSemanticElement();
EObject o2model = o2.resolveSemanticElement();
return compare(o1model, o2model);
}
}
public int compare(EObject o1model, EObject o2model) {
/*
* Look if o1 is an ancestor on the model of o2
*/
EObject modelParent = o2model.eContainer();
/*
* Find the edit part of the modelParent
*/
IGraphicalEditPart modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
while(modelParent != null || GroupContainmentRegistry.isContainerConcerned(modelParentEditPart)) {
if(modelParent == o1model) {
return -1;
}
modelParent = modelParent.eContainer();
modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
}
/*
* Look if o2 is an ancestor on the model of o2
*/
modelParent = o2model.eContainer();
/*
* Find the edit part of the modelParent
*/
modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
while(modelParent != null) {
if(modelParent == o2model || GroupContainmentRegistry.isContainerConcerned(modelParentEditPart)) {
return -1;
}
modelParent = modelParent.eContainer();
modelParentEditPart = (IGraphicalEditPart)registery.get(modelParent);
}
return 0;
}
}