/*****************************************************************************
* Copyright (c) 2011 Atos.
*
*
* 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 - Initial API and implementation
* Arthur Daussy Bug 366026 - [ActivityDiagram] Refactoring in order to try respect Generation Gap Pattern
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.activity.providers;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateNodeViewOperation;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ControlFlowInterruptibleIconEditPart;
import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ObjectFlowInterruptibleIconEditPart;
import org.eclipse.papyrus.uml.diagram.activity.part.UMLVisualIDRegistry;
import org.eclipse.papyrus.uml.diagram.common.helper.PreferenceInitializerForElementHelper;
import org.eclipse.uml2.uml.UMLPackage;
/**
* Extends UMLViewProvider in order to provide custom node creation.
* List of custom node (has to be updated):
* -> ControlFlow
* -> Object Flow
* -> Interruptible Edge Icon (for ControlFlow and ObjectFlow)
*
* @author arthur daussy
*
*/
public class CustomUMLViewProvider extends UMLViewProvider {
@Override
public Edge createControlFlow_4004(EObject domainElement, View containerView, int index, boolean persisted, PreferencesHint preferencesHint) {
Edge edge = super.createControlFlow_4004(domainElement, containerView, index, persisted, preferencesHint);
/*
* Withdraw the view create for ControlFlowInterruptibleFigure
* This implementation do the following:
* 1. (In super imp) Create View + InterruptibleIconView
* 2. (Here) Withdraw InterruptibleIconView
* This implementation was done in purpose to keep generated code intact and keep using the next generation code
*/
if(edge != null) {
EObject semanticElement = edge.getElement();
if(semanticElement != null) {
if(!semanticElement.eIsSet(UMLPackage.Literals.ACTIVITY_EDGE__INTERRUPTS)) {
deleteView(edge, ControlFlowInterruptibleIconEditPart.VISUAL_ID);
}
} else {
deleteView(edge, ControlFlowInterruptibleIconEditPart.VISUAL_ID);
}
}
return edge;
}
@Override
public Edge createObjectFlow_4003(EObject domainElement, View containerView, int index, boolean persisted, PreferencesHint preferencesHint) {
Edge edge = super.createObjectFlow_4003(domainElement, containerView, index, persisted, preferencesHint);
/*
* Withdraw the view create for ControlFlowInterruptibleFigure
* This implementation do the following:
* 1. (In super imp) Create View + InterruptibleIconView
* 2. (Here) Withdraw InterruptibleIconView
* This implementation was done in purpose to keep generated code intact and keep using the next generation code
*/
if(edge != null) {
EObject semanticElement = edge.getElement();
if(semanticElement != null) {
if(!semanticElement.eIsSet(UMLPackage.Literals.ACTIVITY_EDGE__INTERRUPTS)) {
deleteView(edge, ObjectFlowInterruptibleIconEditPart.VISUAL_ID);
}
} else {
deleteView(edge, ObjectFlowInterruptibleIconEditPart.VISUAL_ID);
}
}
return edge;
}
/**
*
* @param edge
* @param semanticHint
*/
private void deleteView(Edge edge, int semanticHint) {
View interruptibleIconView = ViewUtil.getChildBySemanticHint(edge, String.valueOf(semanticHint));
if(interruptibleIconView != null) {
ViewUtil.destroy(interruptibleIconView);
}
}
/**
* Create an Interruptible Edge icon on Control Flow
*
* @param edge
* @param prefStore
* @param InterruptibleEdgeVisualID
* @param elementName
*/
public Node createInterruptibleEdgeIconOnControlFlow(View edge, PreferencesHint preferencesHint) {
final IPreferenceStore prefStore = (IPreferenceStore)preferencesHint.getPreferenceStore();
Node label = createLabel(edge, UMLVisualIDRegistry.getType(ControlFlowInterruptibleIconEditPart.VISUAL_ID));
label.setLayoutConstraint(NotationFactory.eINSTANCE.createLocation());
PreferenceInitializerForElementHelper.initLabelVisibilityFromPrefs(edge, prefStore, "ControlFlow");
return label;
}
/**
* Create an Interruptible Edge icon on Object Flow
*
* @param edge
* @param prefStore
* @param InterruptibleEdgeVisualID
* @param elementName
*/
public Node createInterruptibleEdgeIconOnObjectlFlow(View containerView, PreferencesHint preferencesHint) {
final IPreferenceStore prefStore = (IPreferenceStore)preferencesHint.getPreferenceStore();
Node label = createLabel(containerView, UMLVisualIDRegistry.getType(ObjectFlowInterruptibleIconEditPart.VISUAL_ID));
label.setLayoutConstraint(NotationFactory.eINSTANCE.createLocation());
PreferenceInitializerForElementHelper.initLabelVisibilityFromPrefs(containerView, prefStore, "ObjectFlow");
return label;
}
/**
* Override in order to be able to accept custom node creation
*
* @see org.eclipse.papyrus.uml.diagram.activity.providers.UMLViewProvider#createNode(org.eclipse.core.runtime.IAdaptable,
* org.eclipse.gmf.runtime.notation.View, java.lang.String, int, boolean, org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint)
*
* @param semanticAdapter
* @param containerView
* @param semanticHint
* @param index
* @param persisted
* @param preferencesHint
* @return
*/
@Override
public Node createNode(IAdaptable semanticAdapter, View containerView, String semanticHint, int index, boolean persisted, PreferencesHint preferencesHint) {
final EObject domainElement = getSemanticElement(semanticAdapter);
final int visualID;
if(semanticHint == null) {
visualID = UMLVisualIDRegistry.getNodeVisualID(containerView, domainElement);
} else {
visualID = UMLVisualIDRegistry.getVisualID(semanticHint);
}
/**
* handle specific node creation
*/
Node node = createCustomNode(visualID, containerView, preferencesHint);
return (node != null) ? node : super.createNode(semanticAdapter, containerView, semanticHint, index, persisted, preferencesHint);
}
/**
* Override in order to handle custom node
*
* @see org.eclipse.papyrus.uml.diagram.activity.providers.UMLViewProvider#provides(org.eclipse.gmf.runtime.diagram.core.services.view.CreateNodeViewOperation)
*
* @param op
* @return
*/
@Override
protected boolean provides(CreateNodeViewOperation op) {
return super.provides(op) || isCustomNode(op);
}
/***
* return true if the operation asking a for custom node creation
*
* @param op
* @return
*/
protected boolean isCustomNode(CreateNodeViewOperation op) {
IElementType elementType = getSemanticElementType(op.getSemanticAdapter());
if(op.getContainerView() != null && op.getSemanticHint() != null && elementType == null) {
int visualID = UMLVisualIDRegistry.getVisualID(op.getSemanticHint());
return isCustomNode(visualID);
}
return false;
}
/**
* Return true if the node is a custom node
*
* @param visualID
* @return
*/
protected boolean isCustomNode(int visualID) {
switch(visualID) {
case ControlFlowInterruptibleIconEditPart.VISUAL_ID:
case ObjectFlowInterruptibleIconEditPart.VISUAL_ID:
return true;
}
return false;
}
/**
* Create specific node
*
* @param visualID
* @param containerView
* @param preferencesHint
* @return
*/
protected Node createCustomNode(int visualID, View containerView, PreferencesHint preferencesHint) {
switch(visualID) {
case ControlFlowInterruptibleIconEditPart.VISUAL_ID:
return createInterruptibleEdgeIconOnControlFlow(containerView, preferencesHint);
case ObjectFlowInterruptibleIconEditPart.VISUAL_ID:
return createInterruptibleEdgeIconOnObjectlFlow(containerView, preferencesHint);
}
return null;
}
}