/******************************************************************************* * 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.Iterator; import java.util.List; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.osgi.framework.FrameworkUtil; import org.osgi.service.useradmin.Authorization; import org.ripla.interfaces.IMenuExtendible; import org.ripla.services.IExtendibleMenuContribution; import org.ripla.util.ExtendibleMenuMarker; import org.ripla.util.ExtendibleMenuMarker.Position; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Menu factory for an extendible menu. * * @author Luthiger */ public final class ExtendibleMenuFactory extends MenuFactory { private static final Logger LOG = LoggerFactory .getLogger(ExtendibleMenuFactory.class); private final transient IMenuExtendible menu; private final transient List<IExtMenuItem> contributions = new ArrayList<ExtendibleMenuFactory.IExtMenuItem>(); /** * ExtendibleMenuFactory constructor. * * @param inMenu * {@link IVIFMenuExtendible} the extendible menu to process * @param inContributions * Collection of {@link IExtendibleMenuContribution}s the set of * contributions to the extendible menu */ public ExtendibleMenuFactory(final IMenuExtendible inMenu, final Collection<IExtendibleMenuContribution> inContributions) { super(inMenu); menu = inMenu; initializePositions(inMenu.getMarkers(), inContributions); } private void initializePositions(final ExtendibleMenuMarker[] inMarkers, final Collection<IExtendibleMenuContribution> inContributions) { for (final ExtendibleMenuMarker lMarker : inMarkers) { contributions.add(new MarkerItem(lMarker.getMarkerID())); // NOPMD } for (final IExtendibleMenuContribution lContribution : inContributions) { final Position lPosition = lContribution.getPosition(); switch (lPosition.getType()) { case APPEND: appendTo(lPosition.getMarkerID(), lContribution); break; case INSERT_BEFORE: insert(lPosition.getMarkerID(), lContribution, 0); break; case INSERT_AFTER: insert(lPosition.getMarkerID(), lContribution, 1); break; default: // append appendTo(lPosition.getMarkerID(), lContribution); } } } private void insert(final String inMarkerID, final IExtendibleMenuContribution inContribution, final int inInsertOffset) { final IExtMenuItem lItem = find(inMarkerID); if (lItem == null) { LOG.error("Can't find ID {}!", inMarkerID); //$NON-NLS-1$ throw new IllegalArgumentException("Can't find ID " + inMarkerID); //$NON-NLS-1$ } final int lIndex = contributions.indexOf(lItem); if (lIndex >= 0) { contributions.add(lIndex + inInsertOffset, new ContributionAdapter( inContribution)); } } private IExtMenuItem find(final String inMarkerID) { for (final IExtMenuItem lItem : contributions) { final String lItemID = lItem.getMarkerID(); if (lItemID.equalsIgnoreCase(inMarkerID)) { return lItem; } } return null; } private void appendTo(final String inMarkerID, final IExtendibleMenuContribution inContribution) { int i; // NOPMD by Luthiger on 09.09.12 23:37 final Iterator<IExtMenuItem> lItems = contributions.iterator(); for (i = 0; lItems.hasNext(); i++) { final IExtMenuItem lItem = lItems.next(); if (lItem.isMarker()) { final String lID = lItem.getMarkerID(); if (lID.equalsIgnoreCase(inMarkerID)) { i++; for (; lItems.hasNext(); i++) { final IExtMenuItem lNextItem = lItems.next(); if (lNextItem.isMarker()) { // NOPMD by Luthiger break; } } contributions.add(i - 1, new ContributionAdapter( // NOPMD inContribution)); return; } } } } @Override public DropDownMenu createMenu(final Composite inMenuBar, final Image inIcon, final SelectionListener inListener, final Authorization inAuthorization) { if (checkPermissions(menu.getPermission(), inAuthorization)) { return new DropDownMenuExt(inMenuBar, DropDownMenuExt.getItemsCreator(menu, contributions, inListener, inAuthorization)); } return null; } // --- inner classes --- public interface IExtMenuItem { boolean isMarker(); String getMarkerID(); IExtendibleMenuContribution getContribution(); } private static class MarkerItem implements IExtMenuItem { private final transient String markerID; public MarkerItem(final String inMarkerID) { markerID = inMarkerID; } @Override public boolean isMarker() { return true; } @Override public String getMarkerID() { return markerID; } @Override public IExtendibleMenuContribution getContribution() { return null; } } private static class ContributionAdapter implements IExtMenuItem { private final transient IExtendibleMenuContribution contribution; public ContributionAdapter( final IExtendibleMenuContribution inContribution) { contribution = inContribution; } @Override public boolean isMarker() { return false; } @Override public String getMarkerID() { return ""; //$NON-NLS-1$ } @Override public IExtendibleMenuContribution getContribution() { return contribution; } } @Override public String getProviderSymbolicName() { return FrameworkUtil.getBundle( contributions.get(0).getContribution().getClass()) .getSymbolicName(); } }