/******************************************************************************* * Copyright (c) 2013 RelationWare, Benno Luthiger * 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: * RelationWare, Benno Luthiger ******************************************************************************/ package org.ripla.rap.internal.menu; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Link; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.User; import org.ripla.interfaces.IRiplaEventDispatcher; import org.ripla.interfaces.IRiplaEventDispatcher.Event; import org.ripla.rap.Constants; import org.ripla.rap.interfaces.IContextMenuItem; import org.ripla.rap.interfaces.IMenuSet; import org.ripla.rap.interfaces.IPluggable; import org.ripla.rap.util.GridLayoutHelper; import org.ripla.rap.util.UseCaseHelper; import org.ripla.util.ParameterObject; /** * Helper class responsible for managing all context menu items. * <p> * The context menu is the menu displayed in the sidebar panel, i.e. the left * part of the main window. * </p> * * @author Luthiger */ public final class ContextMenuManager { private final transient Map<String, ContextMenuSet> contextMenus = Collections .synchronizedMap(new HashMap<String, ContextMenuManager.ContextMenuSet>()); /** * Private constructor. */ private ContextMenuManager() { } /** * Factory method, creates an initialized instance of * {@link ContextMenuManager}. * * @return {@link ContextMenuManager} */ public static ContextMenuManager createInstance() { final ContextMenuManager out = new ContextMenuManager(); // add empty menu out.addContextMenuSet(new IMenuSet() { @Override public String getSetID() { return Constants.MENU_SET_ID_EMPTY; } @Override public IContextMenuItem[] getContextMenuItems() { return new IContextMenuItem[] {}; } }); return out; } /** * Adds the configuration of a context menu set to the menu manager. * * @param inMenuSet * {@link IMenuSet} */ public void addContextMenuSet(final IMenuSet inMenuSet) { final String lSetID = UseCaseHelper.createFullyQualifiedID( inMenuSet.getSetID(), inMenuSet.getClass()); final ContextMenuSet lContextMenuSet = new ContextMenuSet(); for (final IContextMenuItem lContextMenuItem : inMenuSet .getContextMenuItems()) { lContextMenuSet.addContextMenuItem(new ContextMenuItem( // NOPMD lContextMenuItem)); } contextMenus.put(lSetID, lContextMenuSet); } /** * Removes the configuration of a context menu set from the menu manager. * * @param inMenuSet * {@link IMenuSet} */ public void removeContextMenuSet(final IMenuSet inMenuSet) { contextMenus.remove(UseCaseHelper.createFullyQualifiedID( inMenuSet.getSetID(), inMenuSet.getClass())); } /** * Method to render the context menu. * * @param inParent * {@link Composite} * @param inMenuSetName * String the fully qualified ID of the context menu * @param inUser * {@link User} the user instance, might be evaluated to check * the conditions * @param inAuthorization * {@link Authorization} the authorization instance, will be * evaluate to check the conditions * @param inParameters * {@link ParameterObject} the generic parameter object with * parameters that could be evaluated to check the conditions * @param inControllerClass * Class<? extends IPluggable> the active controller class * @return {@link Composite} the component that displays the rendered * context menu */ public Composite renderContextMenu(final Composite inParent, final String inMenuSetName, final User inUser, final Authorization inAuthorization, final ParameterObject inParameters, final Class<? extends IPluggable> inControllerClass) { final Composite outContextMenu = new Composite(inParent, SWT.NONE); outContextMenu.setData(RWT.CUSTOM_VARIANT, "ripla-contextmenu"); outContextMenu.setBackgroundMode(SWT.INHERIT_DEFAULT); final GridLayout lLayout = GridLayoutHelper.createGridLayout(); // lLayout.verticalSpacing = 7; outContextMenu.setLayout(lLayout); outContextMenu.setLayoutData(GridLayoutHelper.createFillLayoutData()); final ContextMenuSet lContextMenuSet = contextMenus.get(inMenuSetName); if (lContextMenuSet == null) { return outContextMenu; } for (final ContextMenuItem lItem : lContextMenuSet .getContextMenuItems()) { if (lItem.checkConditions(inUser, inAuthorization, inParameters)) { final Composite lContextMenuItem = GridLayoutHelper .createComposite(outContextMenu); lContextMenuItem.setData(RWT.CUSTOM_VARIANT, "ripla-contextmenu-item"); final Link lContextMenuLink = new Link(lContextMenuItem, SWT.NONE); // NOPMD lContextMenuLink.setText(String.format("<a href=\"\">%s</a>", lItem.getCaption())); lContextMenuLink.setData(RWT.CUSTOM_VARIANT, "ripla-contextmenu-item"); final Class<? extends IPluggable> lControllerClass = lItem .getControllerClass(); if (lControllerClass.equals(inControllerClass)) { lContextMenuLink.setData(RWT.CUSTOM_VARIANT, "ripla-contextmenu-item-active"); } lContextMenuLink.addSelectionListener(new ContextMenuListener( // NOPMD lControllerClass)); } } return outContextMenu; } // --- private classes --- @SuppressWarnings("serial") private static class ContextMenuListener extends SelectionAdapter { private final Class<? extends IPluggable> controllerClass; ContextMenuListener(final Class<? extends IPluggable> inControllerClass) { controllerClass = inControllerClass; } @Override public void widgetSelected(final SelectionEvent inEvent) { final Map<String, Object> lProperties = new HashMap<String, Object>(); lProperties .put(Constants.EVENT_PROPERTY_NEXT_CONTROLLER, UseCaseHelper .createFullyQualifiedControllerName(controllerClass)); ((IRiplaEventDispatcher) RWT.getUISession().getAttribute( Constants.RS_EVENT_DISPATCHER)).dispatch( Event.LOAD_CONTROLLER, lProperties); } } private static class ContextMenuSet { private final transient Collection<ContextMenuItem> items = new ArrayList<ContextMenuManager.ContextMenuItem>(); protected void addContextMenuItem(final ContextMenuItem inItem) { items.add(inItem); } protected Collection<ContextMenuItem> getContextMenuItems() { return items; } } /** * Wrapper class for context menu items provided by use case bundles. */ private static class ContextMenuItem { private final transient IContextMenuItem contextMenuItem; // NOPMD protected ContextMenuItem(final IContextMenuItem inContextMenuItem) { contextMenuItem = inContextMenuItem; } protected String getCaption() { return contextMenuItem.getTitleMsg(); } public Class<? extends IPluggable> getControllerClass() { return contextMenuItem.getControllerClass(); } /** * Check the conditions to display the context menu item. * * @param inUser * {@link User} the user instance, might be evaluated to * check the conditions * @param inAuthorization * {@link Authorization} the authorization instance, will be * evaluate to check the conditions * @param inParameters * {@link ParameterObject} the generic parameter object with * parameters that could be evaluated to check the conditions * @return boolean <code>true</code> if the conditions allow to * display/enable the context menu item, <code>false</code> if * not */ protected boolean checkConditions(final User inUser, final Authorization inAuthorization, final ParameterObject inParameters) { return contextMenuItem.checkConditions(inUser, inAuthorization, inParameters); } } }