/******************************************************************************* * Copyright (c) 2004, 2010 Tasktop Technologies and others. * 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: * 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; } }