blob: 9b95846b9a164ede51935016b40dceba61af7a1e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2018 The Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
* Yatta Solutions - error handling (bug 374105), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IBundleGroup;
import org.eclipse.core.runtime.IBundleGroupProvider;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
/**
* @author Steffen Pingel
* @author David Green
* @author Carsten Reckord
*/
public class MarketplaceClientUi {
private static final String DOT_FEATURE_DOT_GROUP = ".feature.group"; //$NON-NLS-1$
public static final String BUNDLE_ID = "org.eclipse.epp.mpc.ui"; //$NON-NLS-1$
public static ILog getLog() {
return Platform.getLog(Platform.getBundle(BUNDLE_ID));
}
public static void error(String message, Object... params) {
log(IStatus.ERROR, message, params);
}
public static void error(String message, Throwable exception) {
log(IStatus.ERROR, message, exception);
}
public static void error(Throwable exception) {
error(null, exception);
}
public static void log(int severity, String message) {
getLog().log(newStatus(severity, message, (Throwable) null));
}
public static void log(int severity, String message, Throwable exception) {
getLog().log(newStatus(severity, message, exception));
}
public static void log(int severity, String message, Object... params) {
getLog().log(newStatus(severity, message, params));
}
public static IStatus newStatus(int severity, String message, Object... params) {
String formattedMessage = message;
if (message != null && params != null && params.length > 0) {
formattedMessage = NLS.bind(message, params);
}
Throwable exception = findException(params);
return newStatus(severity, formattedMessage, exception);
}
public static IStatus newStatus(int severity, String message, Throwable exception) {
if (message == null) {
String exceptionMessage = exception.getMessage();
if (exceptionMessage == null) {
exceptionMessage = exception.getClass().getSimpleName();
}
message = NLS.bind(Messages.MarketplaceClientUi_unexpectedException_reason, exceptionMessage);
}
IStatus status = new Status(severity, BUNDLE_ID, message, exception);
return status;
}
private static Throwable findException(Object... params) {
Throwable exception = null;
for (int i = params.length - 1; i >= 0; i--) {
if (params[i] instanceof Throwable) {
exception = (Throwable) params[i];
break;
}
}
return exception;
}
/**
* @deprecated Moved to {@link MarketplaceClientCore#computeStatus(Exception, String)}
*/
@Deprecated
public static IStatus computeStatus(Exception e, String message) {
return MarketplaceClientCore.computeStatus(e, message);
}
/**
* @deprecated Moved to {@link MarketplaceClientCore#computeWellknownProblemStatus(Throwable)}
*/
@Deprecated
public static IStatus computeWellknownProblemStatus(Throwable exception) {
return MarketplaceClientCore.computeWellknownProblemStatus(exception);
}
public static BundleContext getBundleContext() {
return FrameworkUtil.getBundle(MarketplaceClientDebug.class).getBundleContext();
}
public static Map<String, IInstallableUnit> computeInstalledIUsById(IProgressMonitor monitor) {
Map<String, IInstallableUnit> iUs = new HashMap<>();
BundleContext bundleContext = MarketplaceClientUi.getBundleContext();
ServiceReference<IProvisioningAgent> serviceReference = bundleContext.getServiceReference(IProvisioningAgent.class);
if (serviceReference != null) {
IProvisioningAgent agent = bundleContext.getService(serviceReference);
try {
IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
if (profileRegistry != null) {
IProfile profile = profileRegistry.getProfile(ProvisioningUI.getDefaultUI().getProfileId());
if (profile != null) {
IQueryResult<IInstallableUnit> result = profile.available(QueryUtil.createIUGroupQuery(),
monitor);
for (IInstallableUnit unit : result) {
iUs.put(unit.getId(), unit);
}
}
}
} finally {
bundleContext.ungetService(serviceReference);
}
}
return iUs;
}
public static Set<String> computeInstalledFeatures(IProgressMonitor monitor) {
Map<String, IInstallableUnit> iusById = computeInstalledIUsById(monitor);
Set<String> features = new HashSet<>(iusById.keySet());
if (features.isEmpty()) {
// probably a self-hosted environment
IBundleGroupProvider[] bundleGroupProviders = Platform.getBundleGroupProviders();
for (IBundleGroupProvider provider : bundleGroupProviders) {
if (monitor.isCanceled()) {
break;
}
IBundleGroup[] bundleGroups = provider.getBundleGroups();
for (IBundleGroup group : bundleGroups) {
String identifier = group.getIdentifier();
if (!identifier.endsWith(DOT_FEATURE_DOT_GROUP)) {
identifier += DOT_FEATURE_DOT_GROUP;
}
features.add(identifier);
}
}
}
return features;
}
public static void setDefaultHelp(Control control) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(control, "org.eclipse.epp.mpc.help.ui.userGuide"); //$NON-NLS-1$
}
public static void handle(Throwable t, final int style) {
handle(new Status(IStatus.ERROR, MarketplaceClientUi.BUNDLE_ID, t.getLocalizedMessage(), t), style);
}
public static void handle(final IStatus status, final int style) {
if (PlatformUI.isWorkbenchRunning()) {
IWorkbench workbench = PlatformUI.getWorkbench();
if (workbench != null) {
final Display workbenchDisplay = workbench.getDisplay();
if (!workbenchDisplay.isDisposed()) {
Runnable logRunnable = () -> {
if (!workbenchDisplay.isDisposed() && PlatformUI.isWorkbenchRunning()) {
IWorkbench workbench1 = PlatformUI.getWorkbench();
if (workbench1 != null) {
try {
StatusManager.getManager().handle(status, style);
return;
} catch (Exception ex) {
// Display might get disposed during call to handle due to workspace shutdown or similar.
// In that case, just log...
}
}
}
ILog log = getLog();
if (log != null) {
log.log(status);
} else {
System.out.println(status);
}
};
if (runIn(workbenchDisplay, logRunnable)) {
return;
}
}
}
}
//else just log
ILog log = getLog();
if (log != null) {
log.log(status);
} else {
System.out.println(status);
}
}
private static boolean runIn(Display display, Runnable runnable) {
if (display == null || display.isDisposed()) {
return false;
} else if (display == Display.getCurrent()) {
if (display.isDisposed()) {
return false;
}
runnable.run();
return true;
} else {
try {
display.asyncExec(runnable);
return true;
} catch (SWTException e) {
if (e.code == SWT.ERROR_DEVICE_DISPOSED) {
return false;
}
throw e;
}
}
}
public static boolean useNativeBorders() {
IPreferencesService service = Platform.getPreferencesService();
return service.getBoolean(BUNDLE_ID, "native-borders", true,
new IScopeContext[] { InstanceScope.INSTANCE });
}
}