| /******************************************************************************* |
| * Copyright (c) 2013, 2018 Remain BV, Industrial-TSI BV and others. |
| * |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Wim Jongmam <wim.jongman@remainsoftware.com> - initial API and implementation |
| * Steven Spungin <steven@spungin.tv> - Ongoing Maintenance |
| ******************************************************************************/ |
| package org.eclipse.e4.tools.emf.ui.internal.imp; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.eclipse.e4.tools.emf.ui.common.IExtensionLookup; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| import org.eclipse.e4.ui.model.application.MApplicationElement; |
| import org.eclipse.e4.ui.model.application.commands.MCategory; |
| import org.eclipse.e4.ui.model.application.commands.MCommand; |
| import org.eclipse.e4.ui.model.application.commands.MCommandsFactory; |
| import org.eclipse.e4.ui.model.application.commands.MHandler; |
| import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MAdvancedFactory; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicPackageImpl; |
| import org.eclipse.e4.ui.model.application.ui.menu.MMenu; |
| import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; |
| import org.eclipse.e4.ui.workbench.UIEvents.ApplicationElement; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.FrameworkUtil; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceReference; |
| |
| @SuppressWarnings("deprecation") |
| public class RegistryUtil { |
| |
| private static final String PLATFORM = "platform:"; //$NON-NLS-1$ |
| private static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
| private static final String COMMAND_ID = "commandId"; //$NON-NLS-1$ |
| private static final String CATEGORY_ID = "categoryId"; //$NON-NLS-1$ |
| private static final String COMPATIBILITY_VIEW = "bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView"; //$NON-NLS-1$ |
| private static final String VIEW_MENU = "ViewMenu"; //$NON-NLS-1$ |
| private static final String LAUNCHER = "launcher"; //$NON-NLS-1$ |
| private static final String EDITOR = "editor"; //$NON-NLS-1$ |
| private static final String VIEW = "View"; //$NON-NLS-1$ |
| private static final String CATEGORY_TAG = "categoryTag:"; //$NON-NLS-1$ |
| private static final String CATEGORY = "category"; //$NON-NLS-1$ |
| private static final String CLASS = "class"; //$NON-NLS-1$ |
| private static final String DESCRIPTION = "description"; //$NON-NLS-1$ |
| private static final String ICON = "icon"; //$NON-NLS-1$ |
| private static final String NAME = "name"; //$NON-NLS-1$ |
| private static final String ID = "id"; //$NON-NLS-1$ |
| public final static String HINT_VIEW = "view"; //$NON-NLS-1$ |
| public final static String HINT_EDITOR = EDITOR; |
| public final static String HINT_COMPAT_VIEW = "compatibilityView"; //$NON-NLS-1$ |
| |
| /** |
| * |
| * @param t |
| * @param application |
| * @param elements |
| */ |
| public static MApplicationElement[] getModelElements(Class<? extends MApplicationElement> t, String hint, |
| MApplication application, IConfigurationElement... elements) { |
| |
| Assert.isNotNull(t); |
| Assert.isNotNull(elements); |
| Assert.isTrue(elements.length > 0); |
| |
| if (t.equals(MCommand.class)) { |
| return getCommands(elements, application); |
| } else if (t.equals(MCategory.class)) { |
| return getCategories(elements); |
| } else if (t.equals(MPerspective.class)) { |
| return getPerspectives(elements); |
| } else if (t.equals(MPart.class) && HINT_COMPAT_VIEW.equals(hint)) { |
| return getViewsAsCompatibilityViews(elements); |
| } else if (t.equals(MPart.class)) { |
| return getViews(elements); |
| } else if (t.equals(MHandler.class)) { |
| return getHandlers(elements, application); |
| } else if (t.equals(MPartDescriptor.class) && HINT_EDITOR.equals(hint)) { |
| return getEditorPartDescriptors(elements); |
| } else if (t.equals(MPartDescriptor.class) && HINT_VIEW.equals(hint)) { |
| return getViewPartDescriptors(elements); |
| } else if (t.equals(MPartDescriptor.class) && HINT_COMPAT_VIEW.equals(hint)) { |
| return getPartDescriptorsAsCompatibilyViews(elements); |
| } |
| return new MApplicationElement[0]; |
| } |
| |
| private static MCommand[] getCommands(IConfigurationElement[] elements, MApplication application) { |
| |
| final ArrayList<MCommand> result = new ArrayList<>(); |
| |
| final MCommandsFactory commandsFactory = MCommandsFactory.INSTANCE; |
| |
| for (final IConfigurationElement element : elements) { |
| |
| final MCommand command = commandsFactory.createCommand(); |
| command.setCommandName(element.getAttribute(NAME)); |
| command.setDescription(element.getAttribute(DESCRIPTION)); |
| command.setElementId(element.getAttribute(ID)); |
| final String catId = element.getAttribute(CATEGORY_ID); |
| |
| if (catId != null && catId.trim().length() > 0) { |
| final List<MCategory> categories = application.getCategories(); |
| for (final MCategory category : categories) { |
| if (category.getElementId().equals(catId)) { |
| command.setCategory(category); |
| break; |
| } |
| } |
| } |
| |
| result.add(command); |
| } |
| |
| return result.toArray(new MCommand[0]); |
| } |
| |
| private static MPerspective[] getPerspectives(IConfigurationElement[] elements) { |
| |
| final ArrayList<MPerspective> result = new ArrayList<>(); |
| |
| final MAdvancedFactory factory = MAdvancedFactory.INSTANCE; |
| |
| for (final IConfigurationElement element : elements) { |
| final MPerspective perspective = factory.createPerspective(); |
| perspective.setLabel(element.getAttribute(NAME)); |
| perspective.setIconURI(getIconURI(element, ICON)); |
| perspective.setElementId(element.getAttribute(ID)); |
| perspective.setToBeRendered(true); |
| perspective.setVisible(true); |
| result.add(perspective); |
| } |
| |
| return result.toArray(new MPerspective[0]); |
| } |
| |
| private static MCategory[] getCategories(IConfigurationElement[] elements) { |
| |
| final ArrayList<MCategory> result = new ArrayList<>(); |
| |
| final MCommandsFactory commandsFactory = MCommandsFactory.INSTANCE; |
| |
| for (final IConfigurationElement element : elements) { |
| |
| final MCategory category = commandsFactory.createCategory(); |
| category.setDescription(element.getAttribute(DESCRIPTION)); |
| category.setElementId(element.getAttribute(ID)); |
| category.setName(element.getAttribute(NAME)); |
| |
| result.add(category); |
| } |
| |
| return result.toArray(new MCategory[0]); |
| } |
| |
| private static MPart[] getViews(IConfigurationElement[] elements) { |
| |
| final ArrayList<MPart> result = new ArrayList<>(); |
| for (final IConfigurationElement element : elements) { |
| final MPart part = (MPart) EcoreUtil.create(BasicPackageImpl.Literals.PART); |
| part.setElementId(element.getAttribute(ID)); |
| part.setLabel(element.getAttribute(NAME)); |
| part.setIconURI(getIconURI(element, ICON)); |
| part.setContributionURI(getContributionURI(element, CLASS)); |
| part.setToBeRendered(true); |
| part.setVisible(true); |
| part.setToolbar(createToolBar(part)); |
| part.getMenus().add(createViewMenu(part)); |
| part.setCloseable(true); |
| part.getTags().add(VIEW); |
| if (element.getAttribute(CATEGORY) != null) { |
| part.getTags().add(CATEGORY_TAG + element.getAttribute(CATEGORY)); |
| } |
| |
| result.add(part); |
| } |
| return result.toArray(new MPart[0]); |
| } |
| |
| private static MToolBar createToolBar(MPart part) { |
| final MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar(); |
| toolBar.setElementId(part.getElementId()); |
| return toolBar; |
| } |
| |
| private static MMenu createViewMenu(MPart part) { |
| final MMenu menu = MMenuFactory.INSTANCE.createMenu(); |
| menu.setElementId(part.getElementId()); |
| menu.getTags().add(VIEW_MENU); |
| return menu; |
| } |
| |
| private static MPart[] getViewsAsCompatibilityViews(IConfigurationElement[] elements) { |
| final ArrayList<MPart> result = new ArrayList<>(); |
| final MPart[] parts = getViews(elements); |
| for (final MPart part : parts) { |
| part.setContributionURI(COMPATIBILITY_VIEW); |
| result.add(part); |
| } |
| return result.toArray(new MPart[0]); |
| } |
| |
| private static MPartDescriptor[] getPartDescriptorsAsCompatibilyViews(IConfigurationElement[] elements) { |
| final ArrayList<MPartDescriptor> result = new ArrayList<>(); |
| final MPartDescriptor[] parts = getViewPartDescriptors(elements); |
| for (final MPartDescriptor part : parts) { |
| part.setContributionURI(COMPATIBILITY_VIEW); |
| result.add(part); |
| } |
| return result.toArray(new MPartDescriptor[0]); |
| } |
| |
| private static MPartDescriptor[] getEditorPartDescriptors(IConfigurationElement[] elements) { |
| |
| final ArrayList<MPartDescriptor> result = new ArrayList<>(); |
| for (final IConfigurationElement element : elements) { |
| final MPartDescriptor part = (MPartDescriptor) EcoreUtil |
| .create(org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.Literals.PART_DESCRIPTOR); |
| part.setElementId(element.getAttribute(ID)); |
| part.setLabel(element.getAttribute(NAME)); |
| part.setIconURI(getIconURI(element, ICON)); |
| if (element.getAttribute(CLASS) != null) { |
| part.setContributionURI(getContributionURI(element, CLASS)); |
| } else { |
| part.setContributionURI(getContributionURI(element, LAUNCHER)); |
| } |
| part.setDirtyable(true); |
| part.setAllowMultiple(true); |
| |
| final MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar(); |
| toolBar.setElementId(part.getElementId()); |
| part.setToolbar(toolBar); |
| |
| final MMenu menu = MMenuFactory.INSTANCE.createMenu(); |
| menu.setElementId(part.getElementId()); |
| menu.getTags().add(VIEW_MENU); |
| part.getMenus().add(menu); |
| |
| part.setCloseable(true); |
| result.add(part); |
| } |
| |
| return result.toArray(new MPartDescriptor[0]); |
| } |
| |
| private static MPartDescriptor[] getViewPartDescriptors(IConfigurationElement[] elements) { |
| |
| final ArrayList<MPartDescriptor> result = new ArrayList<>(); |
| for (final IConfigurationElement element : elements) { |
| final MPartDescriptor part = (MPartDescriptor) EcoreUtil |
| .create(org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.Literals.PART_DESCRIPTOR); |
| part.setElementId(element.getAttribute(ID)); |
| part.setLabel(element.getAttribute(NAME)); |
| part.setIconURI(getIconURI(element, ICON)); |
| |
| final MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar(); |
| toolBar.setElementId(part.getElementId()); |
| part.setToolbar(toolBar); |
| |
| final MMenu menu = MMenuFactory.INSTANCE.createMenu(); |
| menu.setElementId(part.getElementId()); |
| menu.getTags().add(VIEW_MENU); |
| part.getMenus().add(menu); |
| |
| part.setCloseable(true); |
| result.add(part); |
| } |
| |
| return result.toArray(new MPartDescriptor[0]); |
| } |
| |
| private static MHandler[] getHandlers(IConfigurationElement[] elements, MApplication application) { |
| |
| final ArrayList<MHandler> result = new ArrayList<>(); |
| for (final IConfigurationElement element : elements) { |
| final MHandler hand = MCommandsFactory.INSTANCE.createHandler(); |
| hand.setElementId(element.getAttribute(ID)); |
| hand.setContributionURI(getContributionURI(element, CLASS)); |
| |
| final String cmdId = element.getAttribute(COMMAND_ID); |
| |
| if (cmdId != null && cmdId.trim().length() > 0) { |
| final List<MCommand> categories = application.getCommands(); |
| for (final MCommand command : categories) { |
| if (command.getElementId().equals(cmdId)) { |
| hand.setCommand(command); |
| break; |
| } |
| } |
| } |
| result.add(hand); |
| } |
| return result.toArray(new MHandler[0]); |
| } |
| |
| private static String getIconURI(IConfigurationElement element, String attribute) { |
| if (element.getAttribute(attribute) == null) { |
| return EMPTY_STRING; |
| } |
| // FIXME any other cases? |
| if (element.getAttribute(attribute).startsWith(PLATFORM)) { |
| return element.getAttribute(attribute); |
| } |
| return "platform:/plugin/" + element.getContributor().getName() + "/" + element.getAttribute(attribute); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| private static String getContributionURI(IConfigurationElement element, String attribute) { |
| return "bundleclass://" + element.getContributor().getName() + "/" + element.getAttribute(attribute); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Returns a list of bundle id's that have extension to the passed extension |
| * point. |
| * |
| * @param registry |
| * @param extensionPoint |
| * @return the bundle ids as an array of Strings |
| */ |
| public static String[] getProvidingBundles(IExtensionRegistry registry, String extensionPoint, boolean isLive) { |
| |
| final IExtensionLookup service = getService(IExtensionLookup.class, null); |
| |
| if (service == null) { |
| return new String[] { "No " + IExtensionLookup.class.getName() + " service found." }; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| final ArrayList<String> result = new ArrayList<>(); |
| |
| final IExtension[] extensions = service.findExtensions(extensionPoint, isLive); |
| for (final IExtension extension : extensions) { |
| final IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (final IConfigurationElement element : elements) { |
| if (!result.contains(element.getContributor().getName())) { |
| result.add(element.getContributor().getName()); |
| } |
| } |
| } |
| |
| final String[] resultArray = result.toArray(new String[0]); |
| Arrays.sort(resultArray); |
| return resultArray; |
| } |
| |
| /** |
| * |
| * @param registry |
| * @param struct |
| * @return the array of {@link IConfigurationElement} objects that meets the |
| * passed criteria. |
| */ |
| public static IConfigurationElement[] getExtensions(IExtensionRegistry registry, RegistryStruct struct, |
| boolean isLive) { |
| |
| final IExtensionLookup service = getService(IExtensionLookup.class, null); |
| if (struct == null || service == null) { |
| return new IConfigurationElement[0]; |
| } |
| |
| final ArrayList<IConfigurationElement> result = new ArrayList<>(); |
| |
| final IExtension[] extensions = service.findExtensions(struct.getExtensionPoint(), isLive); |
| for (final IExtension extension : extensions) { |
| final IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (final IConfigurationElement element : elements) { |
| if (element.getContributor().getName().equals(struct.getBundle())) { |
| if (element.getName().equals(struct.getExtensionPointName())) { |
| result.add(element); |
| } |
| } |
| } |
| } |
| |
| return result.toArray(new IConfigurationElement[0]); |
| } |
| |
| /** |
| * This will return a structure that contains the registry information we |
| * are looking for. |
| * |
| * @param applicationElement |
| * @return the structure that matches the extension registry to the passed {@link ApplicationElement} |
| */ |
| public static RegistryStruct getStruct(Class<? extends MApplicationElement> applicationElement, String hint) { |
| |
| if (applicationElement == MCommand.class) { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.commands", "command", NAME); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else if (applicationElement == MCategory.class) { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.commands", CATEGORY, NAME); //$NON-NLS-1$ |
| } else if (applicationElement == MPerspective.class) { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.perspectives", "perspective", NAME); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else if (applicationElement == MPart.class) { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.views", "view", NAME); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else if (applicationElement == MHandler.class) { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.handlers", "handler", COMMAND_ID); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else if (applicationElement == MPartDescriptor.class) { |
| if (hint == HINT_EDITOR) |
| { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.editors", EDITOR, NAME); //$NON-NLS-1$ |
| } |
| if (hint == HINT_VIEW || hint == HINT_COMPAT_VIEW) |
| { |
| return new RegistryStruct(EMPTY_STRING, "org.eclipse.ui.views", "view", NAME); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| return null; |
| } |
| |
| private static <T> T getService(Class<T> clazz, String filter) { |
| |
| try { |
| final BundleContext context = FrameworkUtil.getBundle(RegistryUtil.class).getBundleContext(); |
| Collection<ServiceReference<T>> references; |
| references = context.getServiceReferences(clazz, filter); |
| for (final ServiceReference<T> reference : references) { |
| return context.getService(reference); |
| } |
| } catch (final InvalidSyntaxException e) { |
| // FIXME log |
| } |
| return null; |
| } |
| } |