| /******************************************************************************* |
| * Copyright (c) 2007, 2009 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.p2.operations; |
| |
| import org.eclipse.equinox.p2.core.ProvisionException; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.equinox.internal.p2.operations.Activator; |
| import org.eclipse.equinox.internal.p2.operations.Messages; |
| 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; |
| } |
| |
| public void beginTask(String name, int totalWork) { |
| super.beginTask(name, totalWork); |
| additionalMonitor.beginTask(name, totalWork); |
| } |
| |
| public void clearBlocked() { |
| super.clearBlocked(); |
| if (additionalMonitor instanceof IProgressMonitorWithBlocking) |
| ((IProgressMonitorWithBlocking) additionalMonitor).clearBlocked(); |
| } |
| |
| public void done() { |
| super.done(); |
| additionalMonitor.done(); |
| } |
| |
| public void internalWorked(double work) { |
| super.internalWorked(work); |
| additionalMonitor.internalWorked(work); |
| } |
| |
| public boolean isCanceled() { |
| if (super.isCanceled()) |
| return true; |
| return additionalMonitor.isCanceled(); |
| } |
| |
| public void setBlocked(IStatus reason) { |
| super.setBlocked(reason); |
| if (additionalMonitor instanceof IProgressMonitorWithBlocking) |
| ((IProgressMonitorWithBlocking) additionalMonitor).setBlocked(reason); |
| } |
| |
| public void setCanceled(boolean b) { |
| super.setCanceled(b); |
| additionalMonitor.setCanceled(b); |
| } |
| |
| public void setTaskName(String name) { |
| super.setTaskName(name); |
| additionalMonitor.setTaskName(name); |
| } |
| |
| public void subTask(String name) { |
| super.subTask(name); |
| additionalMonitor.subTask(name); |
| } |
| |
| 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) |
| * |
| */ |
| 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, Activator.ID, message, e); |
| } |
| |
| } |