package org.eclipse.uml2.diagram.clazz.part;
import java.util.Arrays;
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.draw2d.geometry.Point;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest.ConnectionViewDescriptor;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor;
import org.eclipse.gmf.runtime.diagram.ui.tools.UnspecifiedTypeConnectionTool;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.diagram.clazz.edit.helpers.GeneralizationSetEditHelper;
import org.eclipse.uml2.diagram.clazz.edit.parts.Generalization2EditPart;
import org.eclipse.uml2.diagram.clazz.edit.parts.GeneralizationEditPart;
import org.eclipse.uml2.diagram.clazz.edit.parts.GeneralizationGeneralEditPart;
import org.eclipse.uml2.diagram.clazz.edit.parts.GeneralizationSetEditPart;
import org.eclipse.uml2.diagram.clazz.providers.UMLElementTypes;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.UMLPackage;
public class CreateGeneralizationLinkTool extends UnspecifiedTypeConnectionTool {
public CreateGeneralizationLinkTool() {
super(GENERALISATION_TYPES);
}
@Override
protected Command getCommand() {
if (getTargetEditPart() == null) {
return null;
}
if (getTargetEditPart() instanceof GeneralizationEditPart) {
return getCreateSetAndThenGeneralizationCommand();
}
if (getTargetEditPart() instanceof Generalization2EditPart) {
Generalization2EditPart generalization2EditPart = (Generalization2EditPart) getTargetEditPart();
EditPart generalizationSetEditPart = generalization2EditPart.getTarget();
return generalizationSetEditPart.getCommand(getTargetRequest());
}
if (getTargetEditPart() instanceof GeneralizationGeneralEditPart) {
GeneralizationGeneralEditPart generalizationGeneralEditPart = (GeneralizationGeneralEditPart) getTargetEditPart();
EditPart generalizationSetEditPart = generalizationGeneralEditPart.getSource();
return generalizationSetEditPart.getCommand(getTargetRequest());
}
return super.getCommand();
}
private Command getCreateSetAndThenGeneralizationCommand() {
GeneralizationEditPart generalizationEditPart = (GeneralizationEditPart) getTargetEditPart();
GraphicalEditPart packageEditPart = (GraphicalEditPart) generalizationEditPart.getRoot().getContents();
View generalizationView = generalizationEditPart.getNotationView();
Generalization generalization = (Generalization) generalizationView.getElement();
View container = packageEditPart.getNotationView();
CreateViewAndElementRequest createGeneralizationSetRequest = getCreateGeneralizationSetRequest(container, generalizationView);
Command createGeneralizationSetCommand = packageEditPart.getCommand(createGeneralizationSetRequest);
final ViewAndElementDescriptor created = getCreatedElement(createGeneralizationSetRequest);
if (created == null) {
return UnexecutableCommand.INSTANCE;
}
EditPart generalizationSource = generalizationEditPart.getSource();
EditPart generalizationTarget = generalizationEditPart.getTarget();
CompoundCommand result = new CompoundCommand();
result.add(createGeneralizationSetCommand);
result.add(getDeleteViewCommand(generalizationEditPart));
result.add(getCreateGeneralizationCommand(packageEditPart, created));
// restore existing generalization EditPart
result.add(getCompleteCreateGeneralizationCommand(generalization, packageEditPart, generalizationSource, created));
// result.add(getCreateGeneralizationGeneralCommand(packageEditPart, created, generalizationTarget));
return result;
}
private ViewAndElementDescriptor getCreatedElement(CreateViewAndElementRequest createGeneralizationSetRequest) {
List newObject = (List) createGeneralizationSetRequest.getNewObject();
return (ViewAndElementDescriptor) ((List) newObject).get(0);
}
private Command getCreateGeneralizationGeneralCommand(GraphicalEditPart packageEditPart, final ViewAndElementDescriptor created, final EditPart targetEditPart) {
AbstractTransactionalCommand createGeneralizationGeneral = new AbstractTransactionalCommand(packageEditPart.getEditingDomain(),
CustomMessages.CreateGeneralizationLinkTool_change_generalization_notation_command, null) {
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
View view = (View) created.getAdapter(View.class);
EditPart sourceEditPart = (EditPart) getCurrentViewer().getEditPartRegistry().get(view);
CreateConnectionRequest connectionRequest = getCreateConnectionViewRequest(UMLElementTypes.GeneralizationGeneral_4012, String.valueOf(GeneralizationGeneralEditPart.VISUAL_ID));
createConnection(sourceEditPart, targetEditPart, connectionRequest);
return CommandResult.newOKCommandResult();
}
};
return new ICommandProxy(createGeneralizationGeneral);
}
private Command getCompleteCreateGeneralizationCommand(final EObject element, GraphicalEditPart packageEditPart, final EditPart sourceEditPart, final ViewAndElementDescriptor created) {
AbstractTransactionalCommand createGeneralization = new AbstractTransactionalCommand(packageEditPart.getEditingDomain(),
CustomMessages.CreateGeneralizationLinkTool_change_generalization_notation_command_2, null) {
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
View view = (View) created.getAdapter(View.class);
EditPart targetEditPart = (EditPart) getCurrentViewer().getEditPartRegistry().get(view);
CreateConnectionRequest connectionRequest = getCreateConnectionWithClassViewRequest(element, String.valueOf(Generalization2EditPart.VISUAL_ID));
createConnection(sourceEditPart, targetEditPart, connectionRequest);
return CommandResult.newOKCommandResult();
}
};
return new ICommandProxy(createGeneralization);
}
private CreateConnectionRequest getCreateConnectionViewRequest(final IElementType elementType, String hint) {
IAdaptable semanticAdapter = new IAdaptable() {
public Object getAdapter(Class adapter) {
if (IElementType.class.equals(adapter)) {
return elementType;
}
return null;
}
};
ConnectionViewDescriptor viewDescriptor = new ConnectionViewDescriptor(semanticAdapter, hint, getPreferencesHint());
return new CreateConnectionViewRequest(viewDescriptor);
}
private CreateConnectionRequest getCreateConnectionWithClassViewRequest(EObject element, String hint) {
ConnectionViewDescriptor viewDescriptor = new ConnectionViewDescriptor(new EObjectAdapter(element), hint, getPreferencesHint());
return new CreateConnectionViewRequest(viewDescriptor);
}
private void createConnection(EditPart sourceEditPart, EditPart targetEditPart, CreateConnectionRequest connectionRequest) {
connectionRequest.setTargetEditPart(sourceEditPart);
connectionRequest.setType(RequestConstants.REQ_CONNECTION_START);
connectionRequest.setLocation(new Point(0, 0));
if (sourceEditPart.getCommand(connectionRequest) == null) {
return;
}
connectionRequest.setSourceEditPart(sourceEditPart);
connectionRequest.setTargetEditPart(targetEditPart);
connectionRequest.setType(RequestConstants.REQ_CONNECTION_END);
connectionRequest.setLocation(new Point(0, 0));
Command createConnectionCmd = targetEditPart.getCommand(connectionRequest);
if (createConnectionCmd.canExecute()) {
createConnectionCmd.execute();
}
}
private Command getCreateGeneralizationCommand(GraphicalEditPart packageEditPart, final ViewAndElementDescriptor created) {
AbstractTransactionalCommand createGeneralization = new AbstractTransactionalCommand(packageEditPart.getEditingDomain(),
CustomMessages.CreateGeneralizationLinkTool_change_generalization_notation_command_3, null) {
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
View view = (View) created.getAdapter(View.class);
EditPart editPart = (EditPart) getCurrentViewer().getEditPartRegistry().get(view);
Command createConnectionCmd = editPart.getCommand(getTargetRequest());
if (createConnectionCmd.canExecute()) {
createConnectionCmd.execute();
}
return CommandResult.newOKCommandResult();
}
};
return new ICommandProxy(createGeneralization);
}
private CreateViewAndElementRequest getCreateGeneralizationSetRequest(View container, View generalization) {
CreateElementRequest createElementRequest = new CreateElementRequest(container.getElement(), UMLElementTypes.GeneralizationSet_2012, UMLPackage.eINSTANCE.getPackage_PackagedElement());
ViewAndElementDescriptor descriptor = new ViewAndElementDescriptor(new CreateElementRequestAdapter(createElementRequest), Node.class, Integer.toString(GeneralizationSetEditPart.VISUAL_ID),
getPreferencesHint());
CreateViewAndElementRequest createGeneralizationSetRequest = new CreateViewAndElementRequest(descriptor);
createGeneralizationSetRequest.getExtendedData().put(GeneralizationSetEditHelper.PARAMETER_SET_GENERALIZATION, generalization.getElement());
createGeneralizationSetRequest.setLocation(getLocation());
return createGeneralizationSetRequest;
}
private Command getDeleteViewCommand(GeneralizationEditPart editPart) {
View view = editPart.getNotationView();
return new ICommandProxy(new DeleteCommand(view));
}
private static List<IElementType> GENERALISATION_TYPES = Arrays.asList(new IElementType[] { UMLElementTypes.Generalization_4001, UMLElementTypes.Generalization_4011, });
}