blob: ffbfacb4f051b5f8c0e6d0837a92e85008e23964 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2013 Sonatype, Inc. 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:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.m2e.internal.discovery;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
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.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.internal.Workbench;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
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.MavenDiscoveryWizard;
@SuppressWarnings("restriction")
public class MavenDiscovery {
private static final Logger log = LoggerFactory.getLogger(MavenDiscovery.class);
public static final Tag NO_RESTART_TAG = new Tag("norestart", "norestart"); //$NON-NLS-1$//$NON-NLS-2$
public static final Tag APPLICABLE_TAG = new Tag("applicable", Messages.MavenDiscovery_Wizard_Applicable_Tag); //$NON-NLS-1$
private static final Tag EXTRAS_TAG = new Tag("extras", Messages.MavenDiscovery_Wizard_ExtrasTag); //$NON-NLS-1$
private static final Tag LIFECYCLES_TAG = new Tag("lifecycles", Messages.MavenDiscovery_Wizard_LifecyclesTag); //$NON-NLS-1$
private static final Tag MAVEN_TAG = new Tag("maven", Messages.MavenDiscovery_Wizard_MavenTag); //$NON-NLS-1$
private static final String DEFAULT_BASEURL = "http://download.eclipse.org/technology/m2e/discovery/"; //$NON-NLS-1$
private static final String DEFAULT_FILENAME = "directory-1.7.xml"; //$NON-NLS-1$
public static final String DEFAULT_URL = DEFAULT_BASEURL + DEFAULT_FILENAME;
private static final String CONFIGURED_URL = System.getProperty("m2e.discovery.url"); //$NON-NLS-1$
private static final String BASEURL = System.getProperty("m2e.discovery.baseurl", DEFAULT_BASEURL); //$NON-NLS-1$
public static final String PATH;
public static final String LIFECYCLE_PATH = "lifecycle/"; //$NON-NLS-1$
public static final String LIFECYCLE_EXT = ".xml"; //$NON-NLS-1$
public static final String PLUGINXML_EXT = ".pluginxml"; //$NON-NLS-1$
static {
PATH = CONFIGURED_URL != null ? CONFIGURED_URL : BASEURL + DEFAULT_FILENAME;
}
@SuppressWarnings("unchecked")
public static void launchWizard(Shell shell) {
launchWizard(shell, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
}
public static void launchWizard(final Collection<String> packagingTypes, final Collection<MojoExecutionKey> mojos,
final Collection<String> lifecycleIds, final Collection<String> configuratorIds) {
final Display display = Workbench.getInstance().getDisplay();
display.asyncExec(new Runnable() {
public void run() {
launchWizard(display.getActiveShell(), packagingTypes, mojos, lifecycleIds, configuratorIds);
}
});
}
public static void launchWizard(Shell shell, Collection<String> packagingTypes, Collection<MojoExecutionKey> mojos,
Collection<String> lifecycleIds, Collection<String> configuratorIds) {
Catalog catalog = getCatalog();
// Build the list of tags to show in the Wizard header
List<Tag> tags = new ArrayList<Tag>(3);
if(!packagingTypes.isEmpty() || !mojos.isEmpty() || !configuratorIds.isEmpty() || !lifecycleIds.isEmpty()) {
tags.add(APPLICABLE_TAG);
}
tags.add(EXTRAS_TAG);
tags.add(LIFECYCLES_TAG);
tags.add(MAVEN_TAG);
catalog.setTags(tags);
// Create configuration for the catalog
MavenCatalogConfiguration configuration = new MavenCatalogConfiguration();
configuration.setShowTagFilter(true);
if(!packagingTypes.isEmpty() || !mojos.isEmpty() || !configuratorIds.isEmpty() || !lifecycleIds.isEmpty()) {
tags = new ArrayList<Tag>(1);
tags.add(APPLICABLE_TAG);
configuration.setSelectedTags(tags);
} else {
configuration.setSelectedTags(tags);
}
configuration.setShowInstalledFilter(false);
configuration.setSelectedPackagingTypes(packagingTypes);
configuration.setSelectedMojos(mojos);
configuration.setSelectedLifecycleIds(lifecycleIds);
configuration.setSelectedConfigurators(configuratorIds);
MavenDiscoveryWizard wizard = new MavenDiscoveryWizard(catalog, configuration);
WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.open();
}
public static Catalog getCatalog() {
Catalog catalog = new Catalog();
catalog.setEnvironment(DiscoveryCore.createEnvironment());
catalog.setVerifyUpdateSiteAvailability(false);
// look for remote descriptor
M2ERemoteBundleDiscoveryStrategy remoteDiscoveryStrategy = new M2ERemoteBundleDiscoveryStrategy();
remoteDiscoveryStrategy.setDirectoryUrl(PATH);
catalog.getDiscoveryStrategies().add(remoteDiscoveryStrategy);
return catalog;
}
public static LifecycleMappingMetadataSource getLifecycleMappingMetadataSource(CatalogItem ci) {
URL url = null;
try {
url = getLifecycleMappingMetadataSourceURL(ci);
if(url == null) {
return null;
}
// To ensure we can delete the temporary file we need to prevent caching, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4386865
URLConnection conn = url.openConnection();
if(conn instanceof JarURLConnection) {
((JarURLConnection) conn).setDefaultUseCaches(false);
}
InputStream is = conn.getInputStream();
try {
return LifecycleMappingFactory.createLifecycleMappingMetadataSource(is);
} finally {
IOUtil.close(is);
}
} catch(FileNotFoundException e) {
// CatalogItem does not contain lifecycle mapping
log.info("No lifecyle mapping found at " + url);
} catch(Exception e) {
log.warn(NLS.bind(Messages.MavenCatalogViewer_Error_loading_lifecycle, ci.getId()), e);
}
return null;
}
/*
* Restart is required when one or more CatalogItem lacks the norestart tag.
*/
public static boolean requireRestart(Iterable<CatalogItem> catalogItems) {
for(CatalogItem item : catalogItems) {
if(!item.hasTag(NO_RESTART_TAG)) {
return true;
}
}
return false;
}
public static void getProvidedProjectConfigurators(CatalogItem ci, List<String> projectConfigurators,
List<String> mappingStrategies) {
try {
URL url = ci.getSource().getResource(LIFECYCLE_PATH + ci.getId() + PLUGINXML_EXT);
if(url != null) {
InputStream is = url.openStream();
parsePluginXml(is, projectConfigurators, mappingStrategies);
}
} catch(FileNotFoundException e) {
log.warn("CatalogItem {} does not contain lifecycle mapping metadata", ci.getId()); //$NON-NLS-1$
} catch(Exception e) {
log.warn(NLS.bind(Messages.MavenCatalogViewer_Error_loading_lifecycle, ci.getId()), e);
}
}
public static void parsePluginXml(InputStream is, List<String> configurators, List<String> mappingStrategies)
throws XmlPullParserException, IOException {
Xpp3Dom plugin = Xpp3DomBuilder.build(is, "UTF-8"); //$NON-NLS-1$
Xpp3Dom[] extensions = plugin.getChildren("extension"); //$NON-NLS-1$
for(Xpp3Dom extension : extensions) {
String extensionPoint = extension.getAttribute("point"); //$NON-NLS-1$
if(LifecycleMappingFactory.EXTENSION_PROJECT_CONFIGURATORS.equals(extensionPoint)) {
Xpp3Dom[] configuratorsDom = extension.getChildren("configurator"); //$NON-NLS-1$
for(Xpp3Dom configurator : configuratorsDom) {
String id = configurator.getAttribute("id"); //$NON-NLS-1$
if(id != null) {
configurators.add(id);
}
}
} else if(LifecycleMappingFactory.EXTENSION_LIFECYCLE_MAPPINGS.equals(extensionPoint)) {
Xpp3Dom[] lifecycleMappingsDom = extension.getChildren("lifecycleMapping"); //$NON-NLS-1$
for(Xpp3Dom lifecycleMapping : lifecycleMappingsDom) {
String id = lifecycleMapping.getAttribute("id"); //$NON-NLS-1$
if(id != null) {
mappingStrategies.add(id);
}
}
}
}
}
public static URL getLifecycleMappingMetadataSourceURL(CatalogItem ci) {
return ci.getSource().getResource(LIFECYCLE_PATH + ci.getId() + LIFECYCLE_EXT);
}
}