blob: 3b6ebfeb01b216c68b8382204dfcd5c1d9ee4da7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Sonatype, Inc.
* All rights reserved. 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:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.m2e.internal.discovery.wizards;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogConfiguration;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogViewer;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.m2e.core.internal.lifecyclemapping.model.LifecycleMappingMetadata;
import org.eclipse.m2e.core.internal.lifecyclemapping.model.LifecycleMappingMetadataSource;
import org.eclipse.m2e.core.internal.lifecyclemapping.model.PluginExecutionMetadata;
import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
import org.eclipse.m2e.internal.discovery.DiscoveryActivator;
import org.eclipse.m2e.internal.discovery.MavenDiscovery;
import org.eclipse.m2e.internal.discovery.Messages;
@SuppressWarnings("restriction")
public class MavenCatalogViewer extends CatalogViewer {
public static final Logger log = LoggerFactory.getLogger(MavenCatalogViewer.class);
private Set<String> installedFeatures;
private boolean noneApplicable;
/*
* Outside of tests the shellProvider should generally be a WizardPage which allows setting the header.
*/
public MavenCatalogViewer(Catalog catalog, IShellProvider shellProvider, IRunnableContext context,
CatalogConfiguration configuration) {
super(catalog, shellProvider, context, configuration);
}
protected void postDiscovery(IProgressMonitor monitor) {
final SubMonitor subMon = SubMonitor.convert(monitor, getCatalog().getItems().size() * 3);
try {
for(CatalogItem connector : getCatalog().getItems()) {
connector
.setInstalled(installedFeatures != null && installedFeatures.containsAll(connector.getInstallableUnits()));
subMon.worked(1);
}
if(getCatalog().getItems().size() == installedFeatures.size()) {
handleStatus(new Status(IStatus.ERROR, DiscoveryActivator.PLUGIN_ID, Messages.MavenCatalogViewer_allInstalled));
} else {
final MavenCatalogConfiguration config = (MavenCatalogConfiguration) getConfiguration();
final Collection<String> selectedPackagingTypes = config.getSelectedPackagingTypes();
final Collection<MojoExecutionKey> selectedMojos = config.getSelectedMojos();
final Collection<String> selectedLifecycleIds = config.getSelectedLifecycleIds();
final Collection<String> selectedConfiguratorIds = config.getSelectedConfiguratorIds();
if(!selectedConfiguratorIds.isEmpty() || !selectedLifecycleIds.isEmpty() || !selectedMojos.isEmpty()
|| !selectedPackagingTypes.isEmpty()) {
noneApplicable = true;
shellProvider.getShell().getDisplay().syncExec(() -> {
for(CatalogItem ci : getCatalog().getItems()) {
boolean selected = false;
subMon.worked(2);
LifecycleMappingMetadataSource src = MavenDiscovery.getLifecycleMappingMetadataSource(ci);
if(src != null) {
for(String packagingType : selectedPackagingTypes) {
if(hasPackaging(src, packagingType)) {
selected = true;
select(ci);
break;
}
}
if(selected) {
continue;
}
for(MojoExecutionKey mojoExecution : selectedMojos) {
if(matchesFilter(src, mojoExecution)) {
selected = true;
select(ci);
break;
}
}
if(selected) {
continue;
}
}
List<String> projectConfigurators = new ArrayList<String>();
List<String> mappingStrategies = new ArrayList<String>();
MavenDiscovery.getProvidedProjectConfigurators(ci, projectConfigurators, mappingStrategies);
for(String configuratorId : selectedConfiguratorIds) {
if(projectConfigurators.contains(configuratorId)) {
selected = true;
select(ci);
break;
}
}
if(selected) {
continue;
}
for(String lifecycleId : selectedLifecycleIds) {
if(mappingStrategies.contains(lifecycleId)) {
select(ci);
break;
}
}
}
if(noneApplicable) {
handleStatus(new Status(IStatus.ERROR, DiscoveryActivator.PLUGIN_ID,
Messages.MavenCatalogViewer_noApplicableCatalogItems));
}
});
}
}
} finally {
subMon.done();
}
}
@Override
public void updateCatalog() {
boolean wasCancelled = false;
boolean wasError = false;
final IStatus[] result = new IStatus[1];
try {
context.run(true, true, new IRunnableWithProgress() {
@SuppressWarnings("synthetic-access")
public void run(IProgressMonitor monitor) throws InterruptedException {
SubMonitor submon = SubMonitor.convert(monitor, 100);
try {
if(installedFeatures == null) {
installedFeatures = getInstalledFeatures(submon.newChild(10));
}
result[0] = getCatalog().performDiscovery(submon.newChild(80));
if(monitor.isCanceled()) {
throw new InterruptedException();
}
if(!getCatalog().getItems().isEmpty()) {
postDiscovery(submon.newChild(10));
}
} finally {
submon.done();
}
}
});
} catch(InvocationTargetException e) {
result[0] = computeStatus(e, Messages.MavenCatalogViewer_unexpectedException);
} catch(InterruptedException e) {
// cancelled by user so nothing to do here.
wasCancelled = true;
}
if(result[0] != null && !result[0].isOK()) {
handleStatus(result[0]);
wasError = true;
}
if(getCatalog() != null) {
catalogUpdated(wasCancelled, wasError);
verifyUpdateSiteAvailability();
}
// help UI tests
viewer.setData("discoveryComplete", Boolean.TRUE); //$NON-NLS-1$
}
private void select(CatalogItem ci) {
modifySelection(ci, true);
ci.addTag(MavenDiscovery.APPLICABLE_TAG);
noneApplicable = false;
}
private void handleStatus(final IStatus status) {
if(status.isOK()) {
return;
}
if(shellProvider instanceof WizardPage) {
shellProvider.getShell().getDisplay().asyncExec(() -> {
// Display the error in the wizard header
int messageType = IMessageProvider.INFORMATION;
if(status.matches(IStatus.ERROR)) {
messageType = IMessageProvider.ERROR;
} else if(status.matches(IStatus.WARNING)) {
messageType = IMessageProvider.WARNING;
}
((WizardPage) shellProvider).setMessage(status.getMessage(), messageType);
StatusManager.getManager().handle(status);
});
} else {
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
}
}
private static boolean matchesFilter(LifecycleMappingMetadataSource src, MojoExecutionKey mojoExecution) {
for(PluginExecutionMetadata p : src.getPluginExecutions()) {
if(p.getFilter().match(mojoExecution)) {
return true;
}
}
return false;
}
private static boolean hasPackaging(LifecycleMappingMetadataSource lifecycleMappingMetadataSource,
String packagingType) {
for(LifecycleMappingMetadata lifecycleMappingMetadata : lifecycleMappingMetadataSource.getLifecycleMappings()) {
if(packagingType.equals(lifecycleMappingMetadata.getPackagingType())) {
return true;
}
}
return false;
}
}