| /******************************************************************************* |
| * Copyright (c) 2019, 2020 Red Hat Inc. 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: |
| * - Mickael Istria (Red Hat Inc.) |
| ******************************************************************************/ |
| package org.eclipse.ui.internal.quickaccess; |
| |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.stream.Collectors; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.WorkbenchPlugin; |
| import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; |
| import org.eclipse.ui.quickaccess.IQuickAccessComputer; |
| import org.eclipse.ui.quickaccess.IQuickAccessComputerExtension; |
| import org.eclipse.ui.quickaccess.QuickAccessElement; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleException; |
| |
| /** |
| * |
| */ |
| public class QuickAccessExtensionManager { |
| |
| private static final String EXTENSION_POINT_ID = PlatformUI.PLUGIN_ID + '.' |
| + IWorkbenchRegistryConstants.PL_QUICK_ACCESS; |
| private static final String COMPUTER_TAG = "computer"; //$NON-NLS-1$ |
| |
| private static class QuickAccessProviderExtensionProxy extends QuickAccessProvider { |
| private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ |
| private static final String REQUIRES_UI_ACCESS_ATTRIBUTE = "requiresUIAccess"; //$NON-NLS-1$ |
| |
| private final Bundle bundle; |
| private final IConfigurationElement extension; |
| private final QuickAccessElement[] activateElement; |
| private IQuickAccessComputer computer; |
| |
| public QuickAccessProviderExtensionProxy(IConfigurationElement extension, Runnable onActivate) { |
| this.bundle = Platform.getBundle(extension.getContributor().getName()); |
| this.extension = extension; |
| this.activateElement = new QuickAccessElement[] { new QuickAccessElement() { |
| @Override |
| public String getLabel() { |
| return NLS.bind(QuickAccessMessages.QuickAccessContents_activate, |
| QuickAccessProviderExtensionProxy.this.getName()); |
| } |
| |
| @Override |
| public ImageDescriptor getImageDescriptor() { |
| return null; |
| } |
| |
| @Override |
| public String getId() { |
| return "activate-" + QuickAccessProviderExtensionProxy.this.getId(); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void execute() { |
| try { |
| bundle.start(Bundle.START_ACTIVATION_POLICY); |
| reset(); |
| if (onActivate != null) { |
| onActivate.run(); |
| } |
| } catch (BundleException e) { |
| WorkbenchPlugin.log(e); |
| } |
| } |
| } }; |
| } |
| |
| private boolean canDelegate() { |
| if (bundle != null && bundle.getState() == Bundle.ACTIVE) { |
| if (computer == null) { |
| try { |
| computer = (IQuickAccessComputer) extension |
| .createExecutableExtension(IWorkbenchRegistryConstants.ATT_CLASS); |
| } catch (CoreException e) { |
| WorkbenchPlugin.log(e); |
| } |
| } |
| return computer != null; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean requiresUiAccess() { |
| return Boolean.parseBoolean(extension.getAttribute(REQUIRES_UI_ACCESS_ATTRIBUTE)); |
| } |
| |
| @Override |
| public String getName() { |
| return extension.getAttribute(NAME_ATTRIBUTE); |
| } |
| |
| @Override |
| public String getId() { |
| return bundle.getSymbolicName() + '/' + extension.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS); |
| } |
| |
| @Override |
| public ImageDescriptor getImageDescriptor() { |
| return null; |
| } |
| |
| @Override |
| public QuickAccessElement[] getElementsSorted(String filter, IProgressMonitor monitor) { |
| if (canDelegate()) { |
| boolean[] needsRefresh = new boolean[1]; |
| SafeRunner.run(() -> needsRefresh[0] = computer.needsRefresh()); |
| if (needsRefresh[0]) { |
| reset(); |
| } |
| return super.getElementsSorted(filter, monitor); |
| } |
| return activateElement; |
| } |
| |
| @Override |
| public QuickAccessElement[] getElements() { |
| if (canDelegate()) { |
| QuickAccessElement[][] elements = new QuickAccessElement[1][]; |
| SafeRunner.run(() -> elements[0] = computer.computeElements()); |
| return elements[0]; |
| } |
| return activateElement; |
| } |
| |
| @Override |
| public QuickAccessElement[] getElements(String filter, IProgressMonitor monitor) { |
| if (canDelegate()) { |
| if (computer instanceof IQuickAccessComputerExtension) { |
| QuickAccessElement[][] elements = new QuickAccessElement[1][]; |
| SafeRunner.run(() -> elements[0] = ((IQuickAccessComputerExtension) computer) |
| .computeElements(filter, monitor)); |
| return elements[0]; |
| } |
| return new QuickAccessElement[0]; |
| } |
| return activateElement; |
| } |
| |
| @Override |
| protected void doReset() { |
| if (canDelegate()) { |
| SafeRunner.run(computer::resetState); |
| } |
| } |
| |
| @Override |
| public QuickAccessElement findElement(String id, String filterText) { |
| QuickAccessElement[] elementsSorted = getElementsSorted(filterText, new NullProgressMonitor()); |
| return Arrays.stream(elementsSorted) |
| .filter(element -> element.getId().equals(id)) |
| .findAny() |
| .orElse(null); |
| } |
| |
| } |
| |
| public static Collection<QuickAccessProvider> getProviders(Runnable onActivate) { |
| return Arrays.stream(Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID)) |
| .filter(element -> COMPUTER_TAG.equals(element.getName())) |
| .map(element -> new QuickAccessProviderExtensionProxy(element, onActivate)) |
| .collect(Collectors.toList()); |
| } |
| } |