Java tutorial
/****************************************************************************** * Copyright (c) 2002, 2009 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.diagram.ui.editpolicies; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.editpolicies.AbstractEditPolicy; import org.eclipse.gef.requests.ReconnectRequest; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ITreeBranchEditPart; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants; import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper; import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants; import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand; import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry; import org.eclipse.gmf.runtime.emf.type.core.IElementType; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyReferenceRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientReferenceRelationshipRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientRelationshipRequest; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.widgets.Display; /** * An editpolicy to handle creation and updating of semantic model elements * * @author melaasar */ public class SemanticEditPolicy extends AbstractEditPolicy { private static final String DELETE_FROM_MODEL_DLG_TITLE = DiagramUIMessages.PromptingDeleteFromModelAction_DeleteFromModelDialog_Title; private static final String DELETE_FROM_MODEL_DLG_MESSAGE = DiagramUIMessages.PromptingDeleteFromModelAction_DeleteFromModelDialog_Message; private static final String DELETE_FROM_MODEL_DLG_TOGGLE_LABEL = DiagramUIMessages.MessageDialogWithToggle_DoNotPromptAgainToggle_label; /** * @see org.eclipse.gef.EditPolicy#getCommand(Request) */ public Command getCommand(Request request) { if (RequestConstants.REQ_SEMANTIC_WRAPPER.equals(request.getType())) { return getSemanticCommand(((EditCommandRequestWrapper) request).getEditCommandRequest()); } else if (REQ_RECONNECT_SOURCE.equals(request.getType()) && relationshipSourceHasChanged((ReconnectRequest) request)) { EditPart connectionEP = ((ReconnectRequest) request).getConnectionEditPart(); if (ViewUtil.resolveSemanticElement((View) connectionEP.getModel()) == null) { return getReorientRefRelationshipSourceCommand((ReconnectRequest) request); } else { return getReorientRelationshipSourceCommand((ReconnectRequest) request); } } else if (REQ_RECONNECT_TARGET.equals(request.getType()) && relationshipTargetHasChanged((ReconnectRequest) request)) { EditPart connectionEP = ((ReconnectRequest) request).getConnectionEditPart(); if (ViewUtil.resolveSemanticElement((View) connectionEP.getModel()) == null) { return getReorientRefRelationshipTargetCommand((ReconnectRequest) request); } else { return getReorientRelationshipTargetCommand((ReconnectRequest) request); } } return super.getCommand(request); } /** * Has the relationship target changed? If not, then it is not necessary to * return a command that will change the relationship's target. * * @param request * the request to reconnect the target of a relationship * @return true if the target has changed; false otherwise */ private boolean relationshipTargetHasChanged(ReconnectRequest request) { return !request.getConnectionEditPart().getTarget().equals(request.getTarget()); } /** * Has the relationship source changed? If not, then it is not necessary to * return a command that will change the relationship's source. * * @param request * the request to reconnect the source of a relationship * @return true if the source has changed; false otherwise */ private boolean relationshipSourceHasChanged(ReconnectRequest request) { return !request.getConnectionEditPart().getSource().equals(request.getTarget()); } /** * Method getSemanticCommand. * * @param request * @return Command */ protected Command getSemanticCommand(IEditCommandRequest request) { if ((request instanceof DestroyRequest) && (getHost() instanceof ConnectionEditPart) && !((ConnectionEditPart) getHost()).isSemanticConnection()) { // no semantic meaning to the connection being destroyed return null; } IEditCommandRequest completedRequest = completeRequest(request); boolean shouldPromptOnDestroy = false; if (completedRequest instanceof DestroyRequest && !isParentCanonical(getHost())) { shouldPromptOnDestroy = ((DestroyRequest) completedRequest).isConfirmationRequired(); ((DestroyRequest) completedRequest).setConfirm(false); } ICommand semanticCommand = null; Object editHelperContext = completedRequest.getEditHelperContext(); IElementType elementType = ElementTypeRegistry.getInstance().getElementType(editHelperContext); if (elementType == null && editHelperContext instanceof ICommand) { semanticCommand = (ICommand) editHelperContext; } else { semanticCommand = (elementType != null) ? elementType.getEditCommand(completedRequest) : null; } if (semanticCommand == null) { return null; } if (completedRequest instanceof DestroyRequest) { ((DestroyRequest) completedRequest).setConfirm(shouldPromptOnDestroy); } boolean shouldProceed = true; if (completedRequest instanceof DestroyRequest) { shouldProceed = shouldProceed((DestroyRequest) completedRequest); } if (shouldProceed) { Command c = new ICommandProxy(semanticCommand); if (completedRequest instanceof DestroyRequest) { TransactionalEditingDomain domain = ((IGraphicalEditPart) getHost()).getEditingDomain(); ICommand ic = new DeleteCommand(domain, (View) getHost().getModel()); CompositeTransactionalCommand cc = new CompositeTransactionalCommand(domain, semanticCommand.getLabel()); cc.setTransactionNestingEnabled(true); cc.compose(semanticCommand); cc.compose(ic); c = new ICommandProxy(cc); } return c; } return null; } /** * @see org.eclipse.gef.EditPolicy#understandsRequest(Request) */ public boolean understandsRequest(Request request) { if (request instanceof EditCommandRequestWrapper) return true; if (REQ_RECONNECT_SOURCE.equals(request.getType()) || REQ_RECONNECT_TARGET.equals(request.getType())) { EObject parentElement = null; if (getHost().getParent() instanceof IGraphicalEditPart) { parentElement = ViewUtil.resolveSemanticElement((View) getHost().getParent().getModel()); } if (getHostElement() != parentElement) return true; } return false; } private EObject getHostElement() { return ViewUtil.resolveSemanticElement((View) getHost().getModel()); } /** * Returns a new completed version of the <code>request</code>, mainly * based on targetting the host of this edit policy. * * @param request * the request to be completed * @return the completed version of the request. This may or may not be a * new instance. */ protected IEditCommandRequest completeRequest(IEditCommandRequest request) { IEditCommandRequest result = request; if (result instanceof DestroyRequest) { DestroyRequest destroyRequest = (DestroyRequest) result; if (getHostElement() != null) { // Destroy element request if (destroyRequest instanceof DestroyElementRequest) { ((DestroyElementRequest) destroyRequest).setElementToDestroy(getHostElement()); ((DestroyElementRequest) destroyRequest).getParameters().clear(); } else { result = new DestroyElementRequest(request.getEditingDomain(), getHostElement(), destroyRequest.isConfirmationRequired()); result.addParameters(request.getParameters()); } } else if (getHost() instanceof ConnectionEditPart) { // Destroy reference request EObject container = ViewUtil.resolveSemanticElement(((Edge) getHost().getModel()).getSource()); EObject referenceObject = ViewUtil .resolveSemanticElement(((Edge) getHost().getModel()).getTarget()); if (destroyRequest instanceof DestroyReferenceRequest) { DestroyReferenceRequest destroyReferenceRequest = (DestroyReferenceRequest) result; destroyReferenceRequest.setContainer(container); destroyReferenceRequest.setReferencedObject(referenceObject); } else { result = new DestroyReferenceRequest(((IGraphicalEditPart) getHost()).getEditingDomain(), container, null, referenceObject, destroyRequest.isConfirmationRequired()); result.addParameters(request.getParameters()); } } } return result; } /** * Method getReorientRelationshipSourceCommand. * * @param request * @return Command */ protected Command getReorientRelationshipSourceCommand(ReconnectRequest request) { EObject connectionSemElement = ViewUtil .resolveSemanticElement(((View) request.getConnectionEditPart().getModel())); EObject targetSemElement = ViewUtil.resolveSemanticElement(((View) request.getTarget().getModel())); EObject oldSemElement = ViewUtil .resolveSemanticElement(((View) request.getConnectionEditPart().getSource().getModel())); TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); ReorientRelationshipRequest semRequest = new ReorientRelationshipRequest(editingDomain, connectionSemElement, targetSemElement, oldSemElement, ReorientRelationshipRequest.REORIENT_SOURCE); semRequest.addParameters(request.getExtendedData()); return getSemanticCommand(semRequest); } /** * Method getReorientRelationshipTargetCommand. * * @param request * @return Command */ protected Command getReorientRelationshipTargetCommand(ReconnectRequest request) { EObject connectionSemElement = ViewUtil .resolveSemanticElement((View) request.getConnectionEditPart().getModel()); EObject targetSemElement = ViewUtil.resolveSemanticElement((View) request.getTarget().getModel()); EObject oldSemElement = ViewUtil .resolveSemanticElement((View) request.getConnectionEditPart().getTarget().getModel()); // check if we need to redirect the semantic request because of a tree // gesture. String connectionHint = ViewUtil .getSemanticElementClassId((View) request.getConnectionEditPart().getModel()); if (((View) request.getTarget().getModel()).getElement() != null) { String targetHint = ViewUtil.getSemanticElementClassId((View) request.getTarget().getModel()); if (request.getConnectionEditPart() instanceof ITreeBranchEditPart && request.getTarget() instanceof ITreeBranchEditPart && connectionHint.equals(targetHint)) { ITreeBranchEditPart targetBranch = (ITreeBranchEditPart) request.getTarget(); targetSemElement = ViewUtil.resolveSemanticElement((View) targetBranch.getTarget().getModel()); } } TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); ReorientRelationshipRequest semRequest = new ReorientRelationshipRequest(editingDomain, connectionSemElement, targetSemElement, oldSemElement, ReorientRelationshipRequest.REORIENT_TARGET); semRequest.addParameters(request.getExtendedData()); return getSemanticCommand(semRequest); } /* * Returns the getHost() if the policy understands the request. * * @see org.eclipse.gef.EditPolicy#getTargetEditPart(org.eclipse.gef.Request) */ public EditPart getTargetEditPart(Request request) { if (understandsRequest(request)) { return getHost(); } else { return super.getTargetEditPart(request); } } /** * Method getReorientRelationshipSourceCommand. * * @param request * @return Command */ protected Command getReorientRefRelationshipSourceCommand(ReconnectRequest request) { org.eclipse.gef.ConnectionEditPart connectionEP = (request).getConnectionEditPart(); if (connectionEP instanceof ConnectionEditPart) { if (!((ConnectionEditPart) connectionEP).isSemanticConnection()) { return null; } } EditPart sourceEditPart = connectionEP.getSource(); EditPart targetEditPart = connectionEP.getTarget(); EObject referenceOwner = ViewUtil.resolveSemanticElement((View) sourceEditPart.getModel()); EObject oldTarget = ViewUtil.resolveSemanticElement((View) targetEditPart.getModel()); EObject newTarget = ViewUtil.resolveSemanticElement((View) request.getTarget().getModel()); TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); ReorientReferenceRelationshipRequest semRequest = new ReorientReferenceRelationshipRequest(editingDomain, referenceOwner, newTarget, oldTarget, ReorientReferenceRelationshipRequest.REORIENT_SOURCE); semRequest.addParameters(request.getExtendedData()); return getSemanticCommand(semRequest); } /** * Method getReorientRefRelationshipTargetCommand. Removes the reference the * ConnectionEditPart current has an add the new TargetEditPart * * @param request * @return Command */ protected Command getReorientRefRelationshipTargetCommand(ReconnectRequest request) { org.eclipse.gef.ConnectionEditPart connectionEP = (request).getConnectionEditPart(); if (connectionEP instanceof ConnectionEditPart) { if (!((ConnectionEditPart) connectionEP).isSemanticConnection()) { return null; } } EditPart sourceEditPart = connectionEP.getSource(); EditPart targetEditPart = connectionEP.getTarget(); EObject referenceOwner = ViewUtil.resolveSemanticElement((View) sourceEditPart.getModel()); EObject oldTarget = ViewUtil.resolveSemanticElement((View) targetEditPart.getModel()); EObject newTarget = ViewUtil.resolveSemanticElement((View) request.getTarget().getModel()); TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain(); ReorientReferenceRelationshipRequest semRequest = new ReorientReferenceRelationshipRequest(editingDomain, referenceOwner, newTarget, oldTarget, ReorientReferenceRelationshipRequest.REORIENT_TARGET); semRequest.addParameters(request.getExtendedData()); return getSemanticCommand(semRequest); } /** * should proceed * @param destroyRequest the destroy request * @return true or false */ protected boolean shouldProceed(DestroyRequest destroyRequest) { if (isParentCanonical(getHost())) { return true; } if (!(destroyRequest.isConfirmationRequired())) { return true; } else { destroyRequest.setConfirm(false); return showMessageDialog(); } } /** * Checks if the parent container is canonical * * @param editpart the editpart in question * @return true if the parent shape is canonical */ private static boolean isParentCanonical(EditPart editpart) { EditPart parent = null; if ((editpart instanceof ConnectionEditPart) && (((ConnectionEditPart) editpart).getSource() != null)) { parent = ((ConnectionEditPart) editpart).getSource().getParent(); } else { parent = editpart.getParent(); } while (parent instanceof GroupEditPart) { parent = parent.getParent(); } return ((parent instanceof GraphicalEditPart) && ((GraphicalEditPart) parent).isCanonical()); } /** * launches the prompting dialogBox on deletion of elements from the model * for the end user. * * @return boolean true if user pressed YES; false otherwise */ private boolean showMessageDialog() { MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion( Display.getCurrent().getActiveShell(), DELETE_FROM_MODEL_DLG_TITLE, DELETE_FROM_MODEL_DLG_MESSAGE, DELETE_FROM_MODEL_DLG_TOGGLE_LABEL, false, (IPreferenceStore) ((IGraphicalEditPart) getHost()) .getDiagramPreferencesHint().getPreferenceStore(), IPreferenceConstants.PREF_PROMPT_ON_DEL_FROM_MODEL); if (dialog.getReturnCode() == IDialogConstants.YES_ID) return true; else return false; } }