package org.eclipse.uml2.diagram.sequence.part;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.uml2.diagram.sequence.edit.parts.BehaviorExecutionSpecificationEditPart;
import org.eclipse.uml2.diagram.sequence.edit.parts.InteractionEditPart;
import org.eclipse.uml2.diagram.sequence.edit.parts.LifelineEditPart;
import org.eclipse.uml2.diagram.sequence.edit.parts.MessageEditPart;
import org.eclipse.uml2.diagram.sequence.edit.policies.InteractionNestedLayoutRequest;
import org.eclipse.uml2.diagram.sequence.model.SDModelAccess;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDBehaviorSpec;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDBracket;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDExecution;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDModel;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDLifeLine;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDMessage;
import org.eclipse.uml2.diagram.sequence.model.sequenced.SDTrace;
import org.eclipse.uml2.uml.ExecutionSpecification;
import org.eclipse.uml2.uml.MessageSort;
import org.eclipse.uml2.uml.UMLPackage;
public class MessageCreationAction implements IObjectActionDelegate {
private Context myContext;
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
action.setText("Creation");
}
public void selectionChanged(IAction action, ISelection selection) {
myContext = null;
action.setEnabled(false);
if (selection instanceof IStructuredSelection == false || selection.isEmpty()) {
return;
}
MessageEditPart messageEP = (MessageEditPart) ((IStructuredSelection) selection).getFirstElement();
myContext = createCreationContext(messageEP);
action.setEnabled(myContext != null && (myContext.isCreation() || myContext.canBeCreation()));
action.setChecked(myContext != null && myContext.isCreation());
}
public void run(IAction action) {
if (myContext == null){
return;
}
TransactionalEditingDomain domain = myContext.getMessageEP().getEditingDomain();
CompositeTransactionalCommand cc = new CompositeTransactionalCommand(domain, "Toggle Destruction");
SetRequest request = new SetRequest(myContext.getSdMessage().getUmlMessage(), UMLPackage.eINSTANCE.getMessage_MessageSort(), //
myContext.isCreation() ? MessageSort.SYNCH_CALL_LITERAL : MessageSort.CREATE_MESSAGE_LITERAL);
cc.compose(new SetValueCommand(request));
InteractionNestedLayoutRequest layoutRequest = new InteractionNestedLayoutRequest();
layoutRequest.requestTotalLayout();
Command geflayout = myContext.findInteractionEditPart().getCommand(layoutRequest);
if (geflayout != null){
cc.compose(new CommandProxy(geflayout));
}
if (cc.canExecute()){
myContext.getMessageEP().getDiagramEditDomain().getDiagramCommandStack().execute(new ICommandProxy(cc.reduce()));
}
}
private Context createCreationContext(MessageEditPart messageEP){
if (false == messageEP.getTarget() instanceof BehaviorExecutionSpecificationEditPart){
return null;
}
BehaviorExecutionSpecificationEditPart targetEP = (BehaviorExecutionSpecificationEditPart)messageEP.getTarget();
View specView = targetEP.getNotationView();
EObject entity = specView.getElement();
if (false == entity instanceof ExecutionSpecification){
return null;
}
SDModel sdModel = SDModelAccess.findSDModel(specView);
if (sdModel == null){
return null;
}
SDTrace tracing = sdModel.getUMLTracing();
SDBehaviorSpec sdSpec = tracing.findBehaviorSpec((ExecutionSpecification)entity);
if (false == sdSpec instanceof SDExecution){
return null;
}
SDExecution sdExecution = (SDExecution)sdSpec;
if (false == sdExecution.getBracketContainer() instanceof SDLifeLine){
return null;
}
SDMessage incomingMessage = sdExecution.getIncomingMessage();
if (incomingMessage == null){
return null;
}
return new Context(messageEP, incomingMessage, sdExecution);
}
private static class Context {
private final SDExecution mySdExecution;
private final MessageEditPart myMessageEP;
private final SDMessage mySdMessage;
public Context(MessageEditPart messageEP, SDMessage sdMessage, SDExecution sdExecution){
myMessageEP = messageEP;
mySdMessage = sdMessage;
mySdExecution = sdExecution;
}
public MessageEditPart getMessageEP() {
return myMessageEP;
}
public SDExecution getSdExecution() {
return mySdExecution;
}
public SDMessage getSdMessage() {
return mySdMessage;
}
public boolean canBeCreation(){
List<SDBracket> brackets = mySdExecution.getBracketContainer().getBrackets();
return brackets.indexOf(mySdExecution) == 0;
}
public boolean isCreation(){
return mySdMessage.getUmlMessage().getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL;
}
public InteractionEditPart findInteractionEditPart(){
EditPart ep = myMessageEP.getTarget();
RootEditPart root = ep.getRoot();
while (ep != root && ep != null){
if (ep instanceof InteractionEditPart){
return (InteractionEditPart)ep;
}
ep = ep.getParent();
}
return null;
}
public LifelineEditPart findLifeLineEditpart(){
EditPart ep = myMessageEP.getTarget();
RootEditPart root = ep.getRoot();
while (ep != root && ep != null){
if (ep instanceof LifelineEditPart){
return (LifelineEditPart)ep;
}
ep = ep.getParent();
}
return null;
}
}
}