summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorMatthew Piggott2011-02-24 09:55:55 (EST)
committer Igor Fedorenko2011-02-24 10:42:24 (EST)
commit638a96afa71d94d281e92cc4dd8ae838e12cd176 (patch)
treeaa1d0ebce65ca23e29a6cba63f1120c608738c3b
parent7c6d6279b9f0fed0c93e557247d5fcc6bd721f89 (diff)
downloadm2e-core-638a96afa71d94d281e92cc4dd8ae838e12cd176.zip
m2e-core-638a96afa71d94d281e92cc4dd8ae838e12cd176.tar.gz
m2e-core-638a96afa71d94d281e92cc4dd8ae838e12cd176.tar.bz2
bug 337604 - Support installation of non-feature IUs and specific versions
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
-rw-r--r--org.eclipse.m2e.discovery/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java9
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/Messages.java26
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/messages.properties11
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/operation/MavenDiscoveryInstallOperation.java166
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2EConnectorDiscoveryExtensionReader.java136
-rw-r--r--org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2ERemoteBundleDiscoveryStrategy.java83
7 files changed, 418 insertions, 18 deletions
diff --git a/org.eclipse.m2e.discovery/META-INF/MANIFEST.MF b/org.eclipse.m2e.discovery/META-INF/MANIFEST.MF
index 6210952..6b26e94 100644
--- a/org.eclipse.m2e.discovery/META-INF/MANIFEST.MF
+++ b/org.eclipse.m2e.discovery/META-INF/MANIFEST.MF
@@ -21,15 +21,18 @@ Require-Bundle: org.eclipse.equinox.p2.ui.discovery,
org.eclipse.equinox.p2.metadata,
org.eclipse.m2e.core.ui;bundle-version="[0.13.0,0.14.0)",
org.slf4j.api;bundle-version="1.5.11",
- org.eclipse.m2e.maven.runtime;bundle-version="[0.13.0,0.14.0)"
+ org.eclipse.m2e.maven.runtime;bundle-version="[0.13.0,0.14.0)",
+ org.eclipse.equinox.p2.repository
Export-Package: org.eclipse.m2e.internal.discovery;x-internal:=true,
org.eclipse.m2e.internal.discovery.handlers;x-internal:=true,
org.eclipse.m2e.internal.discovery.markers;x-internal:=true,
org.eclipse.m2e.internal.discovery.operation;x-internal:=true,
org.eclipse.m2e.internal.discovery.startup;x-internal:=true,
+ org.eclipse.m2e.internal.discovery.strategy;x-internal:=true,
org.eclipse.m2e.internal.discovery.wizards;x-internal:=true
Import-Package: org.apache.maven.model,
org.apache.maven.plugin,
+ org.eclipse.equinox.internal.p2.discovery.compatibility,
org.eclipse.equinox.internal.p2.ui,
org.eclipse.equinox.internal.p2.ui.dialogs,
org.eclipse.equinox.internal.p2.ui.model,
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java
index daf834d..7f7e30b 100644
--- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java
@@ -22,13 +22,13 @@ import java.util.List;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
-import org.eclipse.equinox.internal.p2.discovery.compatibility.RemoteBundleDiscoveryStrategy;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.discovery.model.Tag;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.m2e.core.internal.lifecyclemapping.LifecycleMappingFactory;
import org.eclipse.m2e.core.internal.lifecyclemapping.model.LifecycleMappingMetadataSource;
import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.internal.discovery.strategy.M2ERemoteBundleDiscoveryStrategy;
import org.eclipse.m2e.internal.discovery.wizards.MavenCatalogConfiguration;
import org.eclipse.m2e.internal.discovery.wizards.MavenCatalogViewer;
import org.eclipse.m2e.internal.discovery.wizards.MavenDiscoveryWizard;
@@ -54,7 +54,7 @@ public class MavenDiscovery {
private static final Tag MAVEN_TAG = new Tag("maven", Messages.MavenDiscovery_Wizard_MavenTag); //$NON-NLS-1$
- private static final String PATH = "http://desktop.ifedorenko.com/discovery.xml"; //$NON-NLS-1$
+ private static final String PATH = "http://download.eclipse.org/technology/m2e/discovery/directory.xml"; //$NON-NLS-1$
public static void launchWizard(Shell shell) {
launchWizard(shell, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
@@ -111,7 +111,7 @@ public class MavenDiscovery {
catalog.setVerifyUpdateSiteAvailability(false);
// look for remote descriptor
- RemoteBundleDiscoveryStrategy remoteDiscoveryStrategy = new RemoteBundleDiscoveryStrategy();
+ M2ERemoteBundleDiscoveryStrategy remoteDiscoveryStrategy = new M2ERemoteBundleDiscoveryStrategy();
remoteDiscoveryStrategy.setDirectoryUrl(PATH);
catalog.getDiscoveryStrategies().add(remoteDiscoveryStrategy);
return catalog;
@@ -120,6 +120,9 @@ public class MavenDiscovery {
public static LifecycleMappingMetadataSource getLifecycleMappingMetadataSource(CatalogItem ci) {
try {
URL url = MavenCatalogViewer.getLifecycleMappingMetadataSourceURL(ci);
+ if(url == null) {
+ return null;
+ }
InputStream is = url.openStream();
try {
return LifecycleMappingFactory.createLifecycleMappingMetadataSource(is);
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/Messages.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/Messages.java
index 5a130c0..846f80e 100644
--- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/Messages.java
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/Messages.java
@@ -18,11 +18,26 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.m2e.internal.discovery.messages"; //$NON-NLS-1$
- public static String DiscoveryWizardProposal_description;
+ public static String BundleDiscoveryStrategy_3;
+
+ public static String BundleDiscoveryStrategy_categoryDisallowed;
+
+ public static String BundleDiscoveryStrategy_task_loading_local_extensions;
+
+ public static String BundleDiscoveryStrategy_task_processing_extensions;
+ public static String BundleDiscoveryStrategy_unexpected_element;
+
+ public static String DiscoveryWizardProposal_description;
public static String DiscoveryWizardProposal_Label;
+ public static String ConnectorDiscoveryExtensionReader_unexpected_element_icon;
+
+ public static String ConnectorDiscoveryExtensionReader_unexpected_element_overview;
+
+ public static String ConnectorDiscoveryExtensionReader_unexpected_value_kind;
+
public static String MavenCatalogPage_Descripton;
public static String MavenCatalogPage_Title;
@@ -41,6 +56,15 @@ public class Messages extends NLS {
public static String MavenDiscoveryInstallOperation_Configuring;
+
+ public static String MavenDiscoveryInstallOperation_ErrorMessage;
+
+ public static String MavenDiscoveryInstallOperation_missingIU;
+
+
+ public static String MavenDiscoveryInstallOperation_missingRepository;
+
+
public static String UpdateConfigurationStartup_MarkerError;
static {
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/messages.properties b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/messages.properties
index c4d7967..4f650e4 100644
--- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/messages.properties
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/messages.properties
@@ -5,6 +5,14 @@
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
+BundleDiscoveryStrategy_3={0}: {1}
+BundleDiscoveryStrategy_categoryDisallowed=Cannot create category ''{0}'' with id ''{1}'' from {2}: disallowed
+BundleDiscoveryStrategy_task_loading_local_extensions=Loading local extensions
+BundleDiscoveryStrategy_task_processing_extensions=Processing extensions
+BundleDiscoveryStrategy_unexpected_element=unexpected element ''{0}''
+ConnectorDiscoveryExtensionReader_unexpected_element_icon=Unexpected element icon
+ConnectorDiscoveryExtensionReader_unexpected_element_overview=Unexpected element overview
+ConnectorDiscoveryExtensionReader_unexpected_value_kind=Unexpected value for kind
DiscoveryWizardProposal_description=Opens the m2e Marketplace dialog and lets you find the appropriate m2e connectors
DiscoveryWizardProposal_Label=Discover new m2e connectors
MavenCatalogPage_Descripton=Select updates and extensions to install. Press Finish to proceed with installation.\nPress the information button to see a detailed overview and a link to more information.
@@ -16,4 +24,7 @@ MavenDiscovery_Wizard_ExtrasTag=Extras
MavenDiscovery_Wizard_LifecyclesTag=Lifecycles
MavenDiscovery_Wizard_MavenTag=Maven
MavenDiscoveryInstallOperation_Configuring=Configuring installation selection
+MavenDiscoveryInstallOperation_ErrorMessage=Error(s) occurred gathering items for installation
+MavenDiscoveryInstallOperation_missingIU=Error installing {0} unable to locate installable unit {1}
+MavenDiscoveryInstallOperation_missingRepository=Error installing {0} contacting repository {1}
UpdateConfigurationStartup_MarkerError=Error(s) collecting projects
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/operation/MavenDiscoveryInstallOperation.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/operation/MavenDiscoveryInstallOperation.java
index fca2409..4c6d80b 100644
--- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/operation/MavenDiscoveryInstallOperation.java
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/operation/MavenDiscoveryInstallOperation.java
@@ -12,25 +12,38 @@ package org.eclipse.m2e.internal.discovery.operation;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
-import org.eclipse.equinox.internal.p2.ui.discovery.operations.DiscoveryInstallOperation;
+import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IVersionedId;
+import org.eclipse.equinox.p2.metadata.VersionedId;
import org.eclipse.equinox.p2.operations.ProvisioningJob;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
-import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.operations.RepositoryTracker;
+import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.m2e.internal.discovery.DiscoveryActivator;
import org.eclipse.m2e.internal.discovery.MavenDiscovery;
import org.eclipse.m2e.internal.discovery.Messages;
import org.eclipse.m2e.internal.discovery.wizards.MavenDiscoveryUi;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
@@ -39,24 +52,27 @@ import org.eclipse.swt.widgets.Display;
* to support changing the restart policy for the subsequent ProvisioningJob.
*/
@SuppressWarnings("restriction")
-public class MavenDiscoveryInstallOperation extends DiscoveryInstallOperation {
+public class MavenDiscoveryInstallOperation implements IRunnableWithProgress {
private List<CatalogItem> installableConnectors;
private ProvisioningSession session;
+ private Set<URI> repositoryLocations;
+
private final boolean restart;
+ private List<IStatus> statuses = new ArrayList<IStatus>();
+
public MavenDiscoveryInstallOperation(List<CatalogItem> installableConnectors, boolean restart) {
- super(installableConnectors);
this.installableConnectors = installableConnectors;
this.restart = restart;
this.session = ProvisioningUI.getDefaultUI().getSession();
}
- @Override
public void run(IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
try {
- SubMonitor monitor = SubMonitor.convert(progressMonitor, Messages.MavenDiscoveryInstallOperation_Configuring, 100);
+ SubMonitor monitor = SubMonitor
+ .convert(progressMonitor, Messages.MavenDiscoveryInstallOperation_Configuring, 100);
try {
final IInstallableUnit[] ius = computeInstallableUnits(monitor.newChild(50));
@@ -83,11 +99,140 @@ public class MavenDiscoveryInstallOperation extends DiscoveryInstallOperation {
}
/*
+ * Compute the InstallableUnits & IMetadataRepository
+ */
+ public IInstallableUnit[] computeInstallableUnits(IProgressMonitor progressMonitor) throws CoreException {
+ SubMonitor monitor = SubMonitor.convert(progressMonitor);
+ try {
+
+ List<IMetadataRepository> repositories = addRepositories(monitor.newChild(50));
+ final List<IInstallableUnit> installableUnits = queryInstallableUnits(monitor.newChild(50), repositories);
+
+ if(!statuses.isEmpty()) {
+ throw new CoreException(new MultiStatus(DiscoveryActivator.PLUGIN_ID, 0, statuses.toArray(new IStatus[statuses
+ .size()]), Messages.MavenDiscoveryInstallOperation_ErrorMessage, null));
+ }
+ return installableUnits.toArray(new IInstallableUnit[installableUnits.size()]);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /*
+ * Get IUs to install from the specified repository
+ */
+ private List<IInstallableUnit> queryInstallableUnits(IProgressMonitor progressMonitor,
+ List<IMetadataRepository> repositories) {
+ final List<IInstallableUnit> installableUnits = new ArrayList<IInstallableUnit>(installableConnectors.size());
+
+ SubMonitor monitor = SubMonitor.convert(progressMonitor, installableConnectors.size());
+ try {
+ for(CatalogItem item : installableConnectors) {
+ SubMonitor subMon = monitor.newChild(1);
+ checkCancelled(monitor);
+ URI address = URI.create(item.getSiteUrl());
+ // get repository
+ IMetadataRepository repository = null;
+ for(IMetadataRepository candidate : repositories) {
+ if(address.equals(candidate.getLocation())) {
+ repository = candidate;
+ break;
+ }
+ }
+ if(repository == null) {
+ statuses.add(new Status(IStatus.ERROR, DiscoveryActivator.PLUGIN_ID, NLS.bind(
+ Messages.MavenDiscoveryInstallOperation_missingRepository, item.getName(), item.getSiteUrl())));
+ // Continue so we gather all the problems before telling the user
+ continue;
+ }
+ // get IUs
+ checkCancelled(monitor);
+
+ Set<IVersionedId> ids = getDescriptorIds(repository);
+ for(IVersionedId versionedId : ids) {
+ IQueryResult<IInstallableUnit> result = repository.query(QueryUtil.createIUQuery(versionedId),
+ subMon.newChild(1));
+ Set<IInstallableUnit> matches = result.toSet();
+ if(matches.size() == 1) {
+ installableUnits.addAll(matches);
+ } else if(matches.size() == 0) {
+ statuses.add(new Status(IStatus.ERROR, DiscoveryActivator.PLUGIN_ID, NLS.bind(
+ Messages.MavenDiscoveryInstallOperation_missingIU, item.getName(), versionedId.toString())));
+ } else {
+ // Choose the highest available version
+ IInstallableUnit match = null;
+ for(IInstallableUnit iu : matches) {
+ if(match == null || iu.getVersion().compareTo(match.getVersion()) > 0) {
+ match = iu;
+ }
+ }
+ if(match != null) {
+ installableUnits.add(match);
+ }
+ }
+ }
+ }
+ return installableUnits;
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /*
+ * Get the IVersionedId expected to be in the repository
+ */
+ protected Set<IVersionedId> getDescriptorIds(IMetadataRepository repository) {
+ Set<IVersionedId> ids = new HashSet<IVersionedId>();
+ for(CatalogItem item : installableConnectors) {
+ if(repository.getLocation().equals(URI.create(item.getSiteUrl()))) {
+ for(String id : item.getInstallableUnits()) {
+ ids.add(VersionedId.parse(id));
+ }
+ }
+ }
+ return ids;
+ }
+
+ /*
+ * Add the necessary repositories
+ */
+ protected List<IMetadataRepository> addRepositories(SubMonitor monitor) {
+ // TODO this isn't right
+ // tell p2 that it's okay to use these repositories
+ RepositoryTracker repositoryTracker = ProvisioningUI.getDefaultUI().getRepositoryTracker();
+ repositoryLocations = new HashSet<URI>();
+ monitor.setWorkRemaining(installableConnectors.size() * 5);
+ for(CatalogItem descriptor : installableConnectors) {
+ URI uri = URI.create(descriptor.getSiteUrl());
+ if(repositoryLocations.add(uri)) {
+ checkCancelled(monitor);
+ repositoryTracker.addRepository(uri, null, session);
+ }
+ monitor.worked(1);
+ }
+
+ // fetch meta-data for these repositories
+ ArrayList<IMetadataRepository> repositories = new ArrayList<IMetadataRepository>();
+ monitor.setWorkRemaining(repositories.size());
+ IMetadataRepositoryManager manager = (IMetadataRepositoryManager) session.getProvisioningAgent().getService(
+ IMetadataRepositoryManager.SERVICE_NAME);
+ for(URI uri : repositoryLocations) {
+ checkCancelled(monitor);
+ try {
+ IMetadataRepository repository = manager.loadRepository(uri, monitor.newChild(1));
+ repositories.add(repository);
+ } catch(ProvisionException e) {
+ statuses.add(e.getStatus());
+ }
+ }
+ return repositories;
+ }
+
+ /*
* Create a RestartInstallOperation and resolve
*/
private RestartInstallOperation createAndResolve(IProgressMonitor monitor, final IInstallableUnit[] ius,
- URI[] repositories,
- boolean requireRestart) throws CoreException {
+ URI[] repositories, boolean requireRestart) throws CoreException {
SubMonitor mon = SubMonitor.convert(monitor, ius.length);
try {
RestartInstallOperation op = new RestartInstallOperation(session, Arrays.asList(ius));
@@ -107,9 +252,4 @@ public class MavenDiscoveryInstallOperation extends DiscoveryInstallOperation {
throw new OperationCanceledException();
}
}
-
- @Override
- protected IQuery<IInstallableUnit> createInstalledIUsQuery() {
- return QueryUtil.createIUAnyQuery();
- }
}
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2EConnectorDiscoveryExtensionReader.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2EConnectorDiscoveryExtensionReader.java
new file mode 100644
index 0000000..ef6fd25
--- /dev/null
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2EConnectorDiscoveryExtensionReader.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * Sonatype, Inc. - support for versioned IUs
+ *******************************************************************************/
+package org.eclipse.m2e.internal.discovery.strategy;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.ConnectorDiscoveryExtensionReader;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.FeatureFilter;
+import org.eclipse.equinox.internal.p2.discovery.model.Icon;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+import org.eclipse.equinox.internal.p2.discovery.model.ValidationException;
+import org.eclipse.m2e.internal.discovery.Messages;
+
+
+/*
+ * ConnectorDiscoveryExtensionReader assumes that IUs installed will be features and that the user
+ * always wants the latest version.
+ *
+ * In the m2e use case the user may need a specific version of the IU which need not be a feature.
+ */
+@SuppressWarnings("restriction")
+public class M2EConnectorDiscoveryExtensionReader extends ConnectorDiscoveryExtensionReader {
+
+ private Map<String, Tag> tagById = new HashMap<String, Tag>();
+
+ public Set<Tag> getTags() {
+ return new HashSet<Tag>(tagById.values());
+ }
+
+ private Tag getTag(String id) {
+ if(id == null) {
+ return null;
+ }
+ // first, look for known tag
+ Tag result = tagById.get(id);
+ if(result != null) {
+ return result;
+ }
+ // second, search default tags
+ for(Tag tag : DEFAULT_TAGS) {
+ if(tag.getValue().equals(id)) {
+ tagById.put(id, tag);
+ return tag;
+ }
+ }
+ // third, create new tag
+ result = new Tag(id, id);
+ tagById.put(id, result);
+ return result;
+ }
+
+ public <T extends CatalogItem> T readConnectorDescriptor(IConfigurationElement element, Class<T> clazz)
+ throws ValidationException {
+ T connectorDescriptor;
+ try {
+ connectorDescriptor = clazz.newInstance();
+ } catch(Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ try {
+ String kinds = element.getAttribute("kind"); //$NON-NLS-1$
+ if(kinds != null) {
+ String[] akinds = kinds.split("\\s*,\\s*"); //$NON-NLS-1$
+ for(String kind : akinds) {
+ Tag tag = getTag(kind);
+ if(tag != null) {
+ connectorDescriptor.addTag(tag);
+ }
+ }
+ }
+ } catch(IllegalArgumentException e) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_value_kind);
+ }
+ connectorDescriptor.setName(element.getAttribute("name")); //$NON-NLS-1$
+ connectorDescriptor.setProvider(element.getAttribute("provider")); //$NON-NLS-1$
+ connectorDescriptor.setLicense(element.getAttribute("license")); //$NON-NLS-1$
+ connectorDescriptor.setDescription(element.getAttribute("description")); //$NON-NLS-1$
+ connectorDescriptor.setSiteUrl(element.getAttribute("siteUrl")); //$NON-NLS-1$
+ connectorDescriptor.setId(element.getAttribute("id")); //$NON-NLS-1$
+ connectorDescriptor.setCategoryId(element.getAttribute("categoryId")); //$NON-NLS-1$
+ connectorDescriptor.setCertificationId(element.getAttribute("certificationId")); //$NON-NLS-1$
+ connectorDescriptor.setPlatformFilter(element.getAttribute("platformFilter")); //$NON-NLS-1$
+ connectorDescriptor.setGroupId(element.getAttribute("groupId")); //$NON-NLS-1$
+
+ IConfigurationElement[] children = element.getChildren("iu"); //$NON-NLS-1$
+ if(children.length > 0) {
+ for(IConfigurationElement child : children) {
+ connectorDescriptor.getInstallableUnits().add(child.getAttribute("id")); //$NON-NLS-1$
+ }
+ } else {
+ // TODO Should an exception be thrown here?
+ // no particular iu specified, use connector id
+ connectorDescriptor.getInstallableUnits().add(connectorDescriptor.getId());
+ }
+ for(IConfigurationElement child : element.getChildren("featureFilter")) { //$NON-NLS-1$
+ FeatureFilter featureFilterItem = readFeatureFilter(child);
+ featureFilterItem.setItem(connectorDescriptor);
+ connectorDescriptor.getFeatureFilter().add(featureFilterItem);
+ }
+ for(IConfigurationElement child : element.getChildren("icon")) { //$NON-NLS-1$
+ Icon iconItem = readIcon(child);
+ if(connectorDescriptor.getIcon() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_icon);
+ }
+ connectorDescriptor.setIcon(iconItem);
+ }
+ for(IConfigurationElement child : element.getChildren("overview")) { //$NON-NLS-1$
+ Overview overviewItem = readOverview(child);
+ overviewItem.setItem(connectorDescriptor);
+ if(connectorDescriptor.getOverview() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_overview);
+ }
+ connectorDescriptor.setOverview(overviewItem);
+ }
+
+ connectorDescriptor.validate();
+
+ return connectorDescriptor;
+ }
+}
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2ERemoteBundleDiscoveryStrategy.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2ERemoteBundleDiscoveryStrategy.java
new file mode 100644
index 0000000..d801d7d
--- /dev/null
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/strategy/M2ERemoteBundleDiscoveryStrategy.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * Sonatype, Inc. - modified to support versioned IUs
+ *******************************************************************************/
+package org.eclipse.m2e.internal.discovery.strategy;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.ConnectorDiscoveryExtensionReader;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.RemoteBundleDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.internal.p2.discovery.model.ValidationException;
+import org.eclipse.m2e.internal.discovery.Messages;
+import org.eclipse.osgi.util.NLS;
+
+@SuppressWarnings("restriction")
+public class M2ERemoteBundleDiscoveryStrategy extends RemoteBundleDiscoveryStrategy {
+
+ protected void processExtensions(IProgressMonitor monitor, IExtension[] extensions) {
+ monitor.beginTask(Messages.BundleDiscoveryStrategy_task_processing_extensions, extensions.length == 0 ? 1
+ : extensions.length);
+ try {
+ M2EConnectorDiscoveryExtensionReader extensionReader = new M2EConnectorDiscoveryExtensionReader();
+
+ for(IExtension extension : extensions) {
+ AbstractCatalogSource discoverySource = computeDiscoverySource(extension.getContributor());
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for(IConfigurationElement element : elements) {
+ if(monitor.isCanceled()) {
+ return;
+ }
+ try {
+ if(ConnectorDiscoveryExtensionReader.CONNECTOR_DESCRIPTOR.equals(element.getName())) {
+ CatalogItem descriptor = extensionReader.readConnectorDescriptor(element, CatalogItem.class);
+ descriptor.setSource(discoverySource);
+ items.add(descriptor);
+ } else if(ConnectorDiscoveryExtensionReader.CONNECTOR_CATEGORY.equals(element.getName())) {
+ CatalogCategory category = extensionReader.readConnectorCategory(element, CatalogCategory.class);
+ category.setSource(discoverySource);
+ if(!discoverySource.getPolicy().isPermitCategories()) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.BundleDiscoveryStrategy_categoryDisallowed,
+ new Object[] {category.getName(), category.getId(), element.getContributor().getName()}), null));
+ } else {
+ categories.add(category);
+ }
+ } else if(ConnectorDiscoveryExtensionReader.CERTIFICATION.equals(element.getName())) {
+ Certification certification = extensionReader.readCertification(element, Certification.class);
+ certification.setSource(discoverySource);
+ certifications.add(certification);
+ } else {
+ throw new ValidationException(NLS.bind(Messages.BundleDiscoveryStrategy_unexpected_element,
+ element.getName()));
+ }
+ } catch(ValidationException e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.BundleDiscoveryStrategy_3, element.getContributor().getName(), e.getMessage()), e));
+ }
+ }
+ monitor.worked(1);
+ }
+
+ tags.addAll(extensionReader.getTags());
+ } finally {
+ monitor.done();
+ }
+ }
+}