| /******************************************************************************* |
| * Copyright (c) 2004, 2010 Tasktop Technologies and others. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * https://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Tasktop Technologies - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.tasks.bugs; |
| |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.IBundleGroup; |
| import org.eclipse.core.runtime.IBundleGroupProvider; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.mylyn.commons.core.StatusHandler; |
| import org.eclipse.mylyn.tasks.bugs.IProvider; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.branding.IBundleGroupConstants; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| |
| /** |
| * @author Steffen Pingel |
| */ |
| public class SupportProviderManager { |
| |
| private static final String ATTRIBUTE_CATEGORY_ID = "categoryId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_DESCRIPTION = "description"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_FEATURE_ID = "featureId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_ICON = "icon"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_ID = "id"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_NAMESPACE = "namespace"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_PLUGIN_ID = "pluginId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_VERSION_PLUGIN_ID = "versionPluginId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_PRODUCT_ID = "productId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_PROVIDER_ID = "providerId"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_REPOSITORY_KIND = "kind"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_REPOSITORY_URL = "url"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_URL = "url"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$ |
| |
| private static final String ATTRIBUTE_WEIGHT = "weight"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_CATEGORY = "category"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_MAPPING = "mapping"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_PRODUCT = "product"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_PROPERTY = "property"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_PROVIDER = "provider"; //$NON-NLS-1$ |
| |
| private static final String ELEMENT_REPOSITORY = "repository"; //$NON-NLS-1$ |
| |
| private static final String EXTENSION_ID_PLUGIN_SUPPORT = "org.eclipse.mylyn.tasks.bugs.support"; //$NON-NLS-1$ |
| |
| private HashMap<String, IBundleGroup> bundleGroupById; |
| |
| private List<SupportCategory> categories; |
| |
| private SupportProduct defaultProduct; |
| |
| private Map<String, SupportProduct> productById; |
| |
| private Map<String, SupportProvider> providerById; |
| |
| public SupportProviderManager() { |
| readExtensions(); |
| } |
| |
| public void addCategory(SupportCategory category) { |
| categories.add(category); |
| } |
| |
| public boolean addProduct(SupportProduct product) { |
| if (providerById.containsKey(product.getId())) { |
| return false; |
| } |
| productById.put(product.getId(), product); |
| return true; |
| } |
| |
| public boolean addProvider(SupportProvider provider) { |
| if (providerById.containsKey(provider.getId())) { |
| return false; |
| } |
| providerById.put(provider.getId(), provider); |
| return true; |
| } |
| |
| private IBundleGroup getBundleGroup(String featureId) { |
| if (bundleGroupById == null) { |
| bundleGroupById = new HashMap<String, IBundleGroup>(); |
| IBundleGroupProvider[] providers = Platform.getBundleGroupProviders(); |
| if (providers != null) { |
| for (IBundleGroupProvider provider : providers) { |
| for (IBundleGroup bundleGroup : provider.getBundleGroups()) { |
| bundleGroupById.put(bundleGroup.getIdentifier(), bundleGroup); |
| } |
| } |
| } |
| } |
| return bundleGroupById.get(featureId); |
| } |
| |
| public Collection<SupportCategory> getCategories() { |
| return Collections.unmodifiableList(categories); |
| } |
| |
| public SupportCategory getCategory(String categoryId) { |
| for (SupportCategory category : categories) { |
| if (category.getId().equals(categoryId)) { |
| return category; |
| } |
| } |
| return null; |
| } |
| |
| public SupportProduct getDefaultProduct() { |
| return defaultProduct; |
| } |
| |
| public SupportProduct getProduct(String productId) { |
| return productById.get(productId); |
| } |
| |
| public Collection<SupportProduct> getProducts() { |
| return Collections.unmodifiableCollection(productById.values()); |
| } |
| |
| public SupportProvider getProvider(String providerId) { |
| return providerById.get(providerId); |
| } |
| |
| public Collection<SupportProvider> getProviders() { |
| return Collections.unmodifiableCollection(providerById.values()); |
| } |
| |
| private boolean readAttributes(IConfigurationElement element, AbstractSupportElement item) { |
| item.setId(element.getAttribute(ATTRIBUTE_ID)); |
| item.setName(element.getAttribute(ATTRIBUTE_NAME)); |
| item.setDescription(element.getAttribute(ATTRIBUTE_DESCRIPTION)); |
| item.setUrl(element.getAttribute(ATTRIBUTE_URL)); |
| String iconPath = element.getAttribute(ATTRIBUTE_ICON); |
| if (iconPath != null) { |
| ImageDescriptor descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(element.getContributor().getName(), |
| iconPath); |
| if (descriptor != null) { |
| item.setIcon(descriptor); |
| } |
| } |
| |
| // optionally complement data from referenced feature |
| boolean available = true; |
| String featureId = element.getAttribute(ATTRIBUTE_FEATURE_ID); |
| if (featureId != null) { |
| IBundleGroup bundleGroup = getBundleGroup(featureId); |
| if (bundleGroup == null) { |
| // indicate that the specified feature was not found |
| available = false; |
| } else { |
| if (item.getName() == null) { |
| item.setName(bundleGroup.getName()); |
| } |
| if (item.getDescription() == null) { |
| item.setDescription(bundleGroup.getDescription()); |
| } |
| if (item.getIcon() == null) { |
| String imageUrl = bundleGroup.getProperty(IBundleGroupConstants.FEATURE_IMAGE); |
| if (imageUrl != null) { |
| try { |
| item.setIcon(ImageDescriptor.createFromURL(new URL(imageUrl))); |
| } catch (MalformedURLException e) { |
| // ignore |
| } |
| } |
| } |
| if (item instanceof SupportProduct) { |
| ((SupportProduct) item).setBundleGroup(bundleGroup); |
| } |
| } |
| } |
| String versionPluginId = element.getAttribute(ATTRIBUTE_VERSION_PLUGIN_ID); |
| if (versionPluginId != null) { |
| IBundleGroup bundleVersionPlugin = getBundleGroup(versionPluginId); |
| if (bundleVersionPlugin != null) { |
| if (item instanceof SupportProduct) { |
| ((SupportProduct) item).setVersioningBundleGroup(bundleVersionPlugin); |
| } |
| } |
| |
| } |
| |
| if (item.getName() == null) { |
| item.setName(Messages.SupportProviderManager_Product_Unknown); |
| } |
| |
| return available; |
| } |
| |
| private void readCategory(IConfigurationElement element) { |
| SupportCategory category = new SupportCategory(); |
| readAttributes(element, category); |
| String weight = element.getAttribute(ATTRIBUTE_WEIGHT); |
| if (weight != null) { |
| try { |
| category.setWeight(Integer.parseInt(weight)); |
| } catch (NumberFormatException e) { |
| // ignore |
| } |
| } |
| categories.add(category); |
| } |
| |
| private void readExtensions() { |
| categories = new ArrayList<SupportCategory>(); |
| productById = new HashMap<String, SupportProduct>(); |
| providerById = new HashMap<String, SupportProvider>(); |
| defaultProduct = new SupportProduct(); |
| |
| IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_ID_PLUGIN_SUPPORT); |
| IExtension[] extensions = extensionPoint.getExtensions(); |
| for (IExtension extension : extensions) { |
| IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (IConfigurationElement element : elements) { |
| if (element.getName().equals(ELEMENT_CATEGORY)) { |
| readCategory(element); |
| } |
| } |
| } |
| for (IExtension extension : extensions) { |
| IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (IConfigurationElement element : elements) { |
| if (element.getName().equals(ELEMENT_PROVIDER)) { |
| readProvider(element); |
| } |
| } |
| } |
| for (IExtension extension : extensions) { |
| IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (IConfigurationElement element : elements) { |
| if (element.getName().equals(ELEMENT_PRODUCT)) { |
| readProduct(element); |
| } |
| } |
| } |
| for (IExtension extension : extensions) { |
| IConfigurationElement[] elements = extension.getConfigurationElements(); |
| for (IConfigurationElement element : elements) { |
| if (element.getName().equals(ELEMENT_MAPPING)) { |
| readMapping(element); |
| } |
| } |
| } |
| |
| // clear cache |
| bundleGroupById = null; |
| } |
| |
| private ProductRepositoryMapping readMapping(IConfigurationElement element) { |
| String namespace = element.getAttribute(ATTRIBUTE_NAMESPACE); |
| String productId = element.getAttribute(ATTRIBUTE_PRODUCT_ID); |
| Map<String, String> attributes = new HashMap<String, String>(); |
| // repository |
| for (IConfigurationElement attributeElement : element.getChildren(ELEMENT_REPOSITORY)) { |
| String repositoryUrl = attributeElement.getAttribute(ATTRIBUTE_REPOSITORY_URL); |
| attributes.put(IRepositoryConstants.REPOSITORY_URL, repositoryUrl); |
| String connectorKind = attributeElement.getAttribute(ATTRIBUTE_REPOSITORY_KIND); |
| attributes.put(IRepositoryConstants.CONNECTOR_KIND, connectorKind); |
| } |
| // attributes |
| for (IConfigurationElement attributeElement : element.getChildren(ELEMENT_PROPERTY)) { |
| String name = attributeElement.getAttribute(ATTRIBUTE_NAME); |
| String value = attributeElement.getAttribute(ATTRIBUTE_VALUE); |
| attributes.put(name, value); |
| } |
| |
| if (!attributes.isEmpty()) { |
| ProductRepositoryMapping mapping = new ProductRepositoryMapping(namespace); |
| mapping.addAttributes(attributes); |
| |
| final SupportProduct product; |
| if (productId == null) { |
| product = defaultProduct; |
| } else { |
| product = getProduct(productId); |
| if (product == null) { |
| StatusHandler.log(new Status( |
| IStatus.WARNING, |
| TasksBugsPlugin.ID_PLUGIN, |
| NLS.bind( |
| "Mapping contributed by {0} with namespace ''{1}'' ignored, unkown product id ''{1}'' specified", //$NON-NLS-1$ |
| new String[] { element.getNamespaceIdentifier(), namespace, productId }))); |
| return null; |
| } |
| } |
| product.addRepositoryMapping(mapping); |
| return mapping; |
| } else { |
| StatusHandler.log(new Status(IStatus.WARNING, TasksBugsPlugin.ID_PLUGIN, NLS.bind( |
| "Mapping contributed by {0} with namespace ''{1}'' ignored, no attributes specified", //$NON-NLS-1$ |
| new String[] { element.getNamespaceIdentifier(), namespace }))); |
| return null; |
| } |
| } |
| |
| private SupportProduct readProduct(IConfigurationElement element) { |
| String id = element.getAttribute(ATTRIBUTE_ID); |
| String providerId = element.getAttribute(ATTRIBUTE_PROVIDER_ID); |
| IProvider provider = getProvider(providerId); |
| if (provider == null) { |
| StatusHandler.log(new Status(IStatus.WARNING, TasksBugsPlugin.ID_PLUGIN, NLS.bind( |
| "Product contributed by {0} with id ''{1}'' ignored, unknown provider id ''{2}'' specified", //$NON-NLS-1$ |
| new String[] { element.getNamespaceIdentifier(), id, providerId }))); |
| return null; |
| } |
| boolean enabled = true; |
| String pluginId = element.getAttribute(ATTRIBUTE_PLUGIN_ID); |
| if (pluginId != null) { |
| enabled &= Platform.getBundle(pluginId) != null; |
| } |
| SupportProduct product = new SupportProduct(); |
| enabled &= readAttributes(element, product); |
| // disable products that do not have a corresponding plug-in or feature installed |
| product.setInstalled(enabled); |
| product.setProvider(provider); |
| if (!addProduct(product)) { |
| StatusHandler.log(new Status(IStatus.WARNING, TasksBugsPlugin.ID_PLUGIN, NLS.bind( |
| "Product contributed by {0} ignored, id ''{1}'' already present", //$NON-NLS-1$ |
| element.getNamespaceIdentifier(), id))); |
| return null; |
| } |
| ((SupportProvider) provider).add(product); |
| productById.put(id, product); |
| return product; |
| } |
| |
| private SupportProvider readProvider(IConfigurationElement element) { |
| String id = element.getAttribute(ATTRIBUTE_ID); |
| SupportProvider provider = new SupportProvider(); |
| readAttributes(element, provider); |
| if (!addProvider(provider)) { |
| StatusHandler.log(new Status(IStatus.WARNING, TasksBugsPlugin.ID_PLUGIN, NLS.bind( |
| "Provider contributed by {0} ignored, id ''{1}'' already present", //$NON-NLS-1$ |
| element.getNamespaceIdentifier(), id))); |
| return null; |
| } |
| String categoryId = element.getAttribute(ATTRIBUTE_CATEGORY_ID); |
| SupportCategory category = getCategory(categoryId); |
| if (category == null) { |
| StatusHandler.log(new Status(IStatus.WARNING, TasksBugsPlugin.ID_PLUGIN, NLS.bind( |
| "Provider contributed by {0} ignored with id ''{1}'' ignored, category id ''{2}'' is invalid", //$NON-NLS-1$ |
| new String[] { element.getNamespaceIdentifier(), id, categoryId }))); |
| return null; |
| } |
| providerById.put(id, provider); |
| category.add(provider); |
| provider.setCategory(category); |
| return provider; |
| } |
| |
| } |