/*****************************************************************************
* 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.commands;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.papyrus.uml.diagram.common.groups.core.utils.Utils;
import org.eclipse.papyrus.uml.diagram.common.groups.groupcontainment.AbstractContainerNodeDescriptor;
/**
* Update all references of a parent group.
* This class will set or unset references of the parent from a given child list
*
* @author arthur daussy
*
*/
public class UpdateReferencesCommand extends AbstractTransactionalCommand {
/**
* Mode used to set references
*/
public final static boolean SET_MODE = true;
/**
* Mode used to unset references
*/
public final static boolean UNSET_MODE = false;
/**
* List of all {@link IGraphicalEditPart} of all children
*/
private List<IGraphicalEditPart> childrenPart;
/**
* {@link AbstractContainerNodeDescriptor} of the parent group
*/
private AbstractContainerNodeDescriptor descriptor;
/**
* {@link IAdaptable} of the parent (Used to find {@link EObject}
*/
private IAdaptable elementAdapter;
/**
* Current mode {@link UpdateReferencesCommand#UNSET_MODE} and {@link #SET_MODE}
*/
private boolean setMode = true;
/**
*
* Constructor.
*
* @param domain
* @see {@link AbstractTransactionalCommand}
* @param label
* @see {@link AbstractTransactionalCommand}
* @param children
* @see {@link #childrenPart}
* @param descriptor
* @see {@link #descriptor}
* @param adapter
* @see {@link #elementAdapter}
*/
public UpdateReferencesCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> children, AbstractContainerNodeDescriptor descriptor, IAdaptable adapter) {
super(domain, label, null);
this.descriptor = descriptor;
elementAdapter = adapter;
this.childrenPart = children;
}
/**
*
* Constructor.
*
* @param domain
* @see {@link AbstractTransactionalCommand}
* @param label
* @see {@link AbstractTransactionalCommand}
* @param children
* @see {@link #childrenPart}
* @param descriptor
* @see {@link #descriptor}
* @param adapter
* @see {@link #elementAdapter}
*/
public UpdateReferencesCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> children, AbstractContainerNodeDescriptor descriptor, IAdaptable adapter, boolean mode) {
super(domain, label, null);
this.descriptor = descriptor;
elementAdapter = adapter;
this.childrenPart = children;
this.setMode = mode;
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException {
Object createdElement = elementAdapter.getAdapter(EObject.class);
if(createdElement instanceof EObject) {
EObject eObjectCreatedElement = (EObject)createdElement;
for(IGraphicalEditPart part : childrenPart) {
EObject childElement = part.resolveSemanticElement();
List<EReference> refs = descriptor.getReferenceFor(childElement.eClass());
for(EReference ref : refs) {
//Add reference to the father
if(ref != null && ref.isMany()) {
//ref.getEOpposite()
Collection<EObject> collection = (Collection<EObject>)eObjectCreatedElement.eGet(ref);
if(setMode) {
if(!collection.contains(childElement)) {
collection.add(childElement);
}
} else {
if(collection.contains(childElement)) {
collection.remove(childElement);
}
}
//Remove all element which have a model sons in the collection
} else if(ref != null && !ref.isMany()) {
if(setMode) {
eObjectCreatedElement.eSet(ref, childElement);
} else {
eObjectCreatedElement.eUnset(ref);
}
}
}
Utils.withDrawRedundantElementReferenced(childElement);
}
}
return CommandResult.newOKCommandResult();
}
}