blob: f53697a4c0513491db552753b0f4f34de076797a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012-2014 SAP SE.
* 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:
* SAP SE - initial API and implementation and/or initial documentation
*
*******************************************************************************/
package org.eclipse.ogee.designer.providers;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IPrintFeature;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.context.impl.CustomContext;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
import org.eclipse.graphiti.ui.editor.DiagramEditorContextMenuProvider;
import org.eclipse.graphiti.ui.platform.IConfigurationProvider;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.ogee.designer.Activator;
import org.eclipse.ogee.designer.actions.ODataArtifactsCollapseAllAction;
import org.eclipse.ogee.designer.actions.ODataArtifactsExpandAllAction;
import org.eclipse.ogee.designer.actions.ODataContextMenuAction;
import org.eclipse.ogee.designer.actions.ODataLayoutAction;
import org.eclipse.ogee.designer.actions.ODataLinkUsageContextAction;
import org.eclipse.ogee.designer.contextmenu.UIElementType;
import org.eclipse.ogee.designer.features.ODataContextMenuFeature;
import org.eclipse.ogee.designer.features.ODataLayoutFeature;
import org.eclipse.ogee.designer.features.ODataLinkUsageFeature;
import org.eclipse.ogee.designer.messages.Messages;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.IODataEditorConstants;
import org.eclipse.ogee.designer.utils.ODataContextMenuUtil;
import org.eclipse.ogee.designer.utils.ODataLayoutUtil;
import org.eclipse.ogee.designer.utils.ODataShapeUtil;
import org.eclipse.ogee.utils.logger.Logger;
import org.eclipse.swt.SWTException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.plugin.AbstractUIPlugin;
public class ODataDiagramContextMenuProvider extends
DiagramEditorContextMenuProvider {
private IDiagramTypeProvider diagramTypeProvider;
private ActionRegistry registry;
private MenuManager contextMenu;
private IAction contextMenuFeatureAction;
private ICustomContext contextMenuContext;
private ArrayList<String> parent_menuNameSet;
/**
* @param viewer
* @param registry
* @param diagramTypeProvider
*/
public ODataDiagramContextMenuProvider(EditPartViewer viewer,
ActionRegistry registry,
IConfigurationProvider configurationProvider,
IDiagramTypeProvider diagramTypeProvider) {
super(viewer, registry, configurationProvider);
this.registry = registry;
this.diagramTypeProvider = diagramTypeProvider;
}
@Override
public void buildContextMenu(IMenuManager manager) {
GEFActionConstants.addStandardActionGroups(manager);
addDefaultMenuGroupUndo(manager);
addDefaultMenuGroupSave(manager);
addDefaultMenuGroupEdit(manager);
addDefaultMenuGroupRest(manager);
addDefaultMenuGroupPrint(manager);
}
/**
* Adds the default menu group print.
*
* @param manager
* the manager
*/
@Override
protected void addDefaultMenuGroupPrint(IMenuManager manager) {
IFeatureProvider fp = getDiagramTypeProvider().getFeatureProvider();
if (fp != null) {
IPrintFeature pf = fp.getPrintFeature();
if (pf != null) {
addActionToMenu(manager, ActionFactory.PRINT.getId(),
GEFActionConstants.GROUP_SAVE);
}
}
}
/**
* Adds the default menu group rest.
*
* @param manager
* the manager
*/
@Override
protected void addDefaultMenuGroupRest(IMenuManager manager) {
super.addDefaultMenuGroupRest(manager);
addLinkUsageAction(manager);
IAction deleteAction = this.registry.getAction(ActionFactory.DELETE
.getId());
manager.appendToGroup(GEFActionConstants.GROUP_REST, deleteAction);
addExpandCollapseEntries(manager, null);
}
/**
* This method is responsible to add Show Usage Action.
*
* @param manager
*/
private void addLinkUsageAction(IMenuManager manager) {
PictogramElement[] pictogramElements = getEditor()
.getSelectedPictogramElements();
if (pictogramElements != null && pictogramElements.length > 0) {
ODataFeatureProvider fp = (ODataFeatureProvider) this.diagramTypeProvider
.getFeatureProvider();
ICustomContext context = null;
if (pictogramElements.length == 1) {
PictogramElement pe = pictogramElements[0];
EObject businessObject = (EObject) fp
.getBusinessObjectForPictogramElement(pe);
if (ArtifactUtil.isComplexType(businessObject)
|| ArtifactUtil.isEnumType(businessObject)
|| ArtifactUtil.isEntityType(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
context = new CustomContext(new PictogramElement[] { pe });
}
} else {
context = new CustomContext(pictogramElements);
}
if (context != null) {
ODataLinkUsageFeature linkUsageFeature = new ODataLinkUsageFeature(
fp, fp.getArtifactFactory(), fp.getShapesFactory());
IAction linkUsageAction = new ODataLinkUsageContextAction(
getEditor(), linkUsageFeature, context);
manager.appendToGroup(GEFActionConstants.GROUP_REST,
linkUsageAction);
}
}
}
/**
* Adds the action to menu if available.
*
* @param manager
* the manager
* @param actionId
* the action id
* @param menuGroup
* the menu group
*/
@Override
protected void addActionToMenuIfAvailable(IMenuManager manager,
String actionId, String menuGroup) {
if (IODataEditorConstants.REMOVE_ACTION_ID.equalsIgnoreCase(actionId)
|| IODataEditorConstants.UPDATE_ACTION_ID
.equalsIgnoreCase(actionId)
|| ActionFactory.DELETE.getId().equalsIgnoreCase(actionId)) {
return;
}
super.addActionToMenuIfAvailable(manager, actionId, menuGroup);
}
/**
*
* @param manager
* @param groupID
*/
private void addExpandCollapseEntries(IMenuManager manager, String groupID) {
appendContributionItem(manager, groupID, new Separator());
MenuManager subMenu = new MenuManager(
Messages.ODATAEDITOR_CONTEXTMENU_DIAGRAMMENU,
"org.eclipse.ogee.designer.context"); //$NON-NLS-1$
IAction action = new ODataArtifactsExpandAllAction(getEditor());
action.setText(Messages.ODATAEDITOR_CONTEXTMENU_EXPMENU);
action.setDescription(Messages.ODATAEDITOR_CONTEXTMENU_EXPMENU);
appendContributionItem(subMenu, groupID, new ActionContributionItem(
action));
IAction action1 = new ODataArtifactsCollapseAllAction(getEditor());
action1.setText(Messages.ODATAEDITOR_CONTEXTMENU_COLLMENU);
action1.setDescription(Messages.ODATAEDITOR_CONTEXTMENU_COLLMENU);
appendContributionItem(subMenu, groupID, new ActionContributionItem(
action1));
appendContributionItem(manager, groupID, subMenu);
appendContributionItem(manager, groupID, new Separator());
// Layout related Menu Provision
ODataLayoutFeature layoutFeature;
String[][] layoutOptions = ODataLayoutUtil
.getContextMenuLayoutOptions();
IAction layoutAction;
CustomContext layoutContext = new CustomContext();
layoutContext
.setPictogramElements(new PictogramElement[] { this.diagramTypeProvider
.getDiagram() });
if (layoutOptions.length > 1) {
MenuManager layoutMenu = new MenuManager(
Messages.ODATAEDITOR_CONTEXTMENU_LAYOUTMENU,
IODataEditorConstants.LAYOUT_MENU_ID);
for (int i = 0; i < layoutOptions.length; i++) {
String layoutName = layoutOptions[i][0];
String layoutId = layoutOptions[i][1];
layoutFeature = new ODataLayoutFeature(getEditor()
.getDiagramTypeProvider().getFeatureProvider(),
ODataLayoutUtil.getCurrentLayout(layoutId));
layoutAction = new ODataLayoutAction(getEditor(),
layoutFeature, layoutContext, layoutId);
layoutAction.setText(layoutName);
appendContributionItem(layoutMenu, groupID,
new ActionContributionItem(layoutAction));
}
appendContributionItem(manager, groupID, layoutMenu);
appendContributionItem(manager, groupID, new Separator());
} else {
layoutFeature = new ODataLayoutFeature(
getEditor().getDiagramTypeProvider().getFeatureProvider(),
ODataLayoutUtil
.getCurrentLayout(IODataEditorConstants.DEFAULT_LAYOUT_ID));
layoutAction = new ODataLayoutAction(getEditor(), layoutFeature,
layoutContext, IODataEditorConstants.DEFAULT_LAYOUT_ID);
layoutAction.setText(Messages.ODATAEDITOR_LAYOUT_NAME);
appendContributionItem(manager, groupID,
new ActionContributionItem(layoutAction));
}
// Custom Context Menu Implementation
try {
addCustomContextMenuAction(manager);
} catch (SWTException swte) {
Logger.getLogger(Activator.PLUGIN_ID).logError(swte);
} catch (Exception e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
}
}
/**
* This method is responsible to add Custom Context Menu.
*
* @param manager
*/
private void addCustomContextMenuAction(IMenuManager manager) {
ODataContextMenuFeature contextMenuFeature;
EObject businessObject = null;
String contextMenuName = null;
String contextMenuId = null;
String parent_name = null;
String icon = null;
String plugin_id = null;
String key_binding = null;
String[][] contextMenuOptions = ODataContextMenuUtil
.getContextMenuOptions();
parent_menuNameSet = new ArrayList<String>();
PictogramElement[] pictogramElements = getEditor()
.getSelectedPictogramElements();
PictogramElement pe = null;
if (pictogramElements != null && pictogramElements.length > 0) {
ODataFeatureProvider fp = (ODataFeatureProvider) this.diagramTypeProvider
.getFeatureProvider();
if (pictogramElements.length == 1) {
pe = pictogramElements[0];
businessObject = (EObject) fp
.getBusinessObjectForPictogramElement(pe);
}
}
if (contextMenuOptions.length > 0) {
for (int i = 0; i < contextMenuOptions.length; i++) {
contextMenuName = contextMenuOptions[i][0];
contextMenuId = contextMenuOptions[i][1];
parent_name = contextMenuOptions[i][2];
icon = contextMenuOptions[i][3];
plugin_id = contextMenuOptions[i][4];
key_binding = contextMenuOptions[i][5];
contextMenuFeature = new ODataContextMenuFeature(getEditor(),ODataContextMenuUtil
.getCurrentContextMenu(contextMenuId),
businessObject);
EnumSet<UIElementType> uiElementTypeSet = contextMenuFeature
.getElements();
// to iterate through each uielement from uielementset
if (null != uiElementTypeSet) {
for (UIElementType uiElementType : uiElementTypeSet) {
contextMenuContext = getCustomContextMenu(
uiElementType, pictogramElements);
contextMenuFeatureAction = new ODataContextMenuAction(
getEditor(), contextMenuFeature,
contextMenuContext, contextMenuId);
if (null != contextMenuContext && null != uiElementType) {
if (null != parent_name) {
if (parent_menuNameSet.size() != 0) {
for (int k = 0; k < parent_menuNameSet
.size(); k++) {
if (parent_menuNameSet.get(k).equals(
parent_name)) {
contextMenuFeatureAction
.setText(contextMenuName);
appendContributionItem(
contextMenu,
null,
new ActionContributionItem(
contextMenuFeatureAction));
} else {
contextMenu = new MenuManager(
parent_name,
IODataEditorConstants.CONTEXT_MENU_ID);
appendContributionItem(
contextMenu,
null,
new ActionContributionItem(
contextMenuFeatureAction));
appendContributionItem(manager,
null, contextMenu);
contextMenuFeatureAction
.setText(contextMenuName);
}
}
} else {
contextMenu = new MenuManager(
parent_name,
IODataEditorConstants.CONTEXT_MENU_ID);
appendContributionItem(contextMenu, null,
new ActionContributionItem(
contextMenuFeatureAction));
appendContributionItem(manager, null,
contextMenu);
contextMenuFeatureAction
.setText(contextMenuName);
parent_menuNameSet.add(parent_name);
}
parent_name = null;
} else {
contextMenuFeatureAction
.setText(contextMenuName);
appendContributionItem(manager, null,
new ActionContributionItem(
contextMenuFeatureAction));
}
if (null != icon && null != plugin_id) {
if (validateIcon(icon)) {
contextMenuFeatureAction
.setImageDescriptor((AbstractUIPlugin
.imageDescriptorFromPlugin(
plugin_id, icon)));
} else {
Logger.getLogger(Activator.PLUGIN_ID)
.logError(
"Unsupported or unrecognized icon format"); //$NON-NLS-1$
}
}
if (null != key_binding) {
contextMenuFeatureAction
.setActionDefinitionId(key_binding);
}
contextMenuContext = null;
}
}
}
}
}
appendContributionItem(manager, null, new Separator());
}
/**
* This method is responsible to add the custom context menu according to
* the diagram types like
* EntityType,ComplexType,EnumType,Association,Function Import and All(which
* comprises all the above mentioned diagram types.
*
* @param uiElementType
* @param pictogramElements
* @return
*/
private ICustomContext getCustomContextMenu(UIElementType uiElementType,
PictogramElement[] pictogramElements) {
Object businessObject = null;
PictogramElement pe = null;
if (pictogramElements != null && pictogramElements.length > 0) {
ODataFeatureProvider fp = (ODataFeatureProvider) this.diagramTypeProvider
.getFeatureProvider();
if (pictogramElements.length == 1) {
pe = pictogramElements[0];
businessObject = fp.getBusinessObjectForPictogramElement(pe);
if (null != uiElementType) {
switch (uiElementType) {
case ENTITY_TYPE:
if (ArtifactUtil.isEntityType(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
case COMPLEX_TYPE:
if (ArtifactUtil.isComplexType(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
case FUNCTION_IMPORT:
if (ArtifactUtil.isFunctionImport(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
// TODO :will be enabled once OData v4 is supported
/*
* case ENUMTYPE: if
* (ArtifactUtil.isEnumType(businessObject)) { pe =
* ODataShapeUtil.getTopContainer(pe); contextMenuContext =
* new CustomContext( new PictogramElement[] { pe });
*
* } break;
*/
case ASSOCIATION:
if (ArtifactUtil.isAssociation(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
case ALL:
if (ArtifactUtil.isComplexType(businessObject)
|| ArtifactUtil.isEntityType(businessObject)
|| ArtifactUtil.isAssociation(businessObject)
|| ArtifactUtil
.isFunctionImport(businessObject)) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
case ENTITY_SET:
if (ArtifactUtil.isEntitySet(businessObject)
) {
pe = ODataShapeUtil.getTopContainer(pe);
contextMenuContext = new CustomContext(
new PictogramElement[] { pe });
}
break;
default:
break;
}
} else {
contextMenuContext = null;
}
} else {
contextMenuContext = new CustomContext(pictogramElements);
}
}
return contextMenuContext;
}
/**
* To validate whether the icon provided is valid and does not throw SWT
* Exception on load
*
* @param icon
* @return
*/
private boolean validateIcon(String icon) {
Pattern patternIcon;
Matcher matcherIcon;
String icon_pattern = "([^\\s]+(\\.(?i)(jpg|png|gif|dib|jfif|jpe|jpeg|tif|tiff|bmp))$)"; //$NON-NLS-1$
patternIcon = Pattern.compile(icon_pattern);
matcherIcon = patternIcon.matcher(icon);
return matcherIcon.matches();
}
private void appendContributionItem(IMenuManager manager, String groupID,
IContributionItem contributionItem) {
if (groupID != null) {
manager.appendToGroup(groupID, contributionItem);
} else {
manager.add(contributionItem);
}
}
private IDiagramTypeProvider getDiagramTypeProvider() {
return this.diagramTypeProvider;
}
private DiagramEditor getEditor() {
return (DiagramEditor) getDiagramTypeProvider().getDiagramBehavior()
.getDiagramContainer();
}
}