| /******************************************************************************* |
| * Copyright (c) 2014 Ericsson |
| * |
| * 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: |
| * Bernd Hufmann - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.tracecompass.internal.tmf.ui.project.operations; |
| |
| import java.lang.reflect.InvocationTargetException; |
| |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.ui.actions.WorkspaceModifyOperation; |
| |
| /** |
| * Operation to modify the workspace that refreshes workspace at the end of the operation. |
| * |
| * For refreshing periodically use {@link WorkspaceModifyOperation} instead. |
| * |
| * @author Bernd Hufmann |
| * |
| */ |
| public abstract class TmfWorkspaceModifyOperation implements IRunnableWithProgress { |
| |
| private ISchedulingRule rule; |
| |
| /** |
| * Creates a new operation. |
| */ |
| protected TmfWorkspaceModifyOperation() { |
| this(ResourcesPlugin.getWorkspace().getRoot()); |
| } |
| |
| /** |
| * Creates a new operation that will run using the provided scheduling rule. |
| * |
| * @param rule |
| * The ISchedulingRule to use or <code>null</code>. |
| */ |
| protected TmfWorkspaceModifyOperation(ISchedulingRule rule) { |
| this.rule = rule; |
| } |
| |
| @Override |
| public final synchronized void run(IProgressMonitor monitor) |
| throws InvocationTargetException, InterruptedException { |
| final InvocationTargetException[] iteHolder = new InvocationTargetException[1]; |
| try { |
| IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { |
| @Override |
| public void run(IProgressMonitor pm) throws CoreException { |
| try { |
| execute(pm); |
| } catch (InvocationTargetException e) { |
| // Pass it outside the workspace runnable |
| iteHolder[0] = e; |
| } catch (InterruptedException e) { |
| Thread.currentThread().interrupt(); |
| // Re-throw as OperationCanceledException, which will be |
| // caught and re-thrown as InterruptedException below. |
| throw new OperationCanceledException(e.getMessage()); |
| } |
| // CoreException and OperationCanceledException are propagated |
| } |
| }; |
| |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| workspace.run(workspaceRunnable, rule, IWorkspace.AVOID_UPDATE, monitor); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } catch (OperationCanceledException e) { |
| throw new InterruptedException(e.getMessage()); |
| } |
| // Re-throw the InvocationTargetException, if any occurred |
| if (iteHolder[0] != null) { |
| throw iteHolder[0]; |
| } |
| } |
| |
| /** |
| * Performs the steps that are to be treated as a single logical workspace |
| * change. |
| * <p> |
| * Subclasses must implement this method. |
| * </p> |
| * |
| * @param monitor |
| * the progress monitor to use to display progress and field user |
| * requests to cancel |
| * @exception CoreException |
| * if the operation fails due to a CoreException |
| * @exception InvocationTargetException |
| * if the operation fails due to an exception other than |
| * CoreException |
| * @exception InterruptedException |
| * if the operation detects a request to cancel, using |
| * <code>IProgressMonitor.isCanceled()</code>, it should exit |
| * by throwing <code>InterruptedException</code>. It is also |
| * possible to throw <code>OperationCanceledException</code>, |
| * which gets mapped to <code>InterruptedException</code> by |
| * the <code>run</code> method. |
| */ |
| protected abstract void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException; |
| } |