blob: ceb4cb23e1ff0db9c92143b43ac23a56631fb639 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2020 IBM Corporation and others.
*
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.p2.operations;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.internal.p2.operations.Constants;
import org.eclipse.equinox.internal.p2.operations.Messages;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.osgi.util.NLS;
/**
* Abstract class representing provisioning jobs. Provisioning jobs
* can be run in the background by scheduling them, or they can
* be run by a client in a modal context. An additional progress monitor
* can be set into the job for progress reporting.
*
* @since 2.0
*/
public abstract class ProvisioningJob extends Job {
/**
* Class for multiplexing progress across multiple progress monitors.
*/
private static class DoubleProgressMonitor extends ProgressMonitorWrapper {
IProgressMonitor additionalMonitor;
protected DoubleProgressMonitor(IProgressMonitor monitor1, IProgressMonitor monitor2) {
super(monitor1);
additionalMonitor = monitor2;
}
@Override
public void beginTask(String name, int totalWork) {
super.beginTask(name, totalWork);
additionalMonitor.beginTask(name, totalWork);
}
@Override
public void clearBlocked() {
super.clearBlocked();
additionalMonitor.clearBlocked();
}
@Override
public void done() {
super.done();
additionalMonitor.done();
}
@Override
public void internalWorked(double work) {
super.internalWorked(work);
additionalMonitor.internalWorked(work);
}
@Override
public boolean isCanceled() {
if (super.isCanceled())
return true;
return additionalMonitor.isCanceled();
}
@Override
public void setBlocked(IStatus reason) {
super.setBlocked(reason);
additionalMonitor.setBlocked(reason);
}
@Override
public void setCanceled(boolean b) {
super.setCanceled(b);
additionalMonitor.setCanceled(b);
}
@Override
public void setTaskName(String name) {
super.setTaskName(name);
additionalMonitor.setTaskName(name);
}
@Override
public void subTask(String name) {
super.subTask(name);
additionalMonitor.subTask(name);
}
@Override
public void worked(int work) {
super.worked(work);
additionalMonitor.worked(work);
}
}
/**
* Constant which indicates that the job does not require a restart
* upon completion. This constant is typically used for operations that
* do not modify the running profile.
*
* @since 2.0
*/
public static final int RESTART_NONE = 1;
/**
* Constant which indicates that the job requires the user to either
* restart or apply the configuration changes in order to pick up the
* changes performed by the job. This constant is typically used for
* operations that modify the running profile.
*
* @since 2.0
*/
public static final int RESTART_OR_APPLY = 2;
/**
* Constant which indicates that the job requires the user to restart
* in order to pick up the changes performed by the job. This constant
* is typically used for operations that modify the running profile but don't
* handle dynamic changes without restarting the workbench.
*
* @since 2.0
*/
public static final int RESTART_ONLY = 3;
private ProvisioningSession session;
private IProgressMonitor additionalMonitor;
/**
* Create a provisioning job with the given name that uses the
* provided provisioning session for retrieving any services
* needed.
*
* @param name the name of the job
* @param session the session providing the services
*/
public ProvisioningJob(String name, ProvisioningSession session) {
super(name);
this.session = session;
}
/**
* Return the provisioning session that is used by the receiver
* when retrieving necessary provisioning services.
*
* @return the session
* @see ProvisioningSession
*/
protected ProvisioningSession getSession() {
return session;
}
private IProgressMonitor getCombinedProgressMonitor(IProgressMonitor mon1, IProgressMonitor mon2) {
if (mon1 == null)
return mon2;
if (mon2 == null)
return mon1;
return new DoubleProgressMonitor(mon1, mon2);
}
public void setAdditionalProgressMonitor(IProgressMonitor monitor) {
additionalMonitor = monitor;
}
/**
* Executes this job. Returns the result of the execution.
* This method is overridden to look for a wrapped progress monitor for
* reporting progress.
*
* @noreference This method is not intended to be referenced by clients.
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*
*/
@Override
public final IStatus run(IProgressMonitor monitor) {
IProgressMonitor wrappedMonitor = getCombinedProgressMonitor(monitor, additionalMonitor);
IStatus status = Status.OK_STATUS;
try {
status = runModal(wrappedMonitor);
} catch (OperationCanceledException e) {
status = Status.CANCEL_STATUS;
}
return status;
}
/**
* Perform the specific work involved in running this job in
* the current thread. This method can be called directly by
* clients, or in the course of running the job in the
* background.
*
* @param monitor
* the progress monitor to use for the operation
*
* @return a status indicating the result of the operation.
*
*/
public abstract IStatus runModal(IProgressMonitor monitor);
/**
* Return the restart policy that is appropriate for this job.
*
* @return a constant indicating the restart policy
*
* @see #RESTART_NONE
* @see #RESTART_ONLY
* @see #RESTART_OR_APPLY
*/
public int getRestartPolicy() {
return RESTART_NONE;
}
/**
* Return an error status that can be used to report the specified exception.
*
* @param message the message that should be used in the status
* @param e the exception to be reported
* @return a status that can be used to describe the exception
*/
protected IStatus getErrorStatus(String message, ProvisionException e) {
if (message == null)
if (e == null)
message = NLS.bind(Messages.ProvisioningJob_GenericErrorStatusMessage, getName());
else
message = e.getLocalizedMessage();
return new Status(IStatus.ERROR, Constants.BUNDLE_ID, message, e);
}
}