KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > actions > WorkspaceModifyOperation


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.actions;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.resources.IWorkspaceRunnable;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.OperationCanceledException;
20 import org.eclipse.core.runtime.Platform;
21 import org.eclipse.core.runtime.jobs.ISchedulingRule;
22 import org.eclipse.core.runtime.jobs.Job;
23 import org.eclipse.jface.operation.IRunnableWithProgress;
24 import org.eclipse.jface.operation.IThreadListener;
25 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
26
27 /**
28  * An operation which potentially makes changes to the workspace. All resource
29  * modification should be performed using this operation. The primary
30  * consequence of using this operation is that events which typically occur as a
31  * result of workspace changes (such as the firing of resource deltas,
32  * performance of autobuilds, etc.) are deferred until the outermost operation
33  * has successfully completed.
34  * <p>
35  * If a scheduling rule is provided, the operation will obtain that scheduling
36  * rule for the duration of its <code>execute</code> method. If no scheduling
37  * rule is provided, the operation will obtain a scheduling rule that locks
38  * the entire workspace for the duration of the operation.
39  * </p>
40  * <p>
41  * Subclasses must implement <code>execute</code> to do the work of the
42  * operation.
43  * </p>
44  * @see ISchedulingRule
45  * @see org.eclipse.core.resources.IWorkspace#run(IWorkspaceRunnable, IProgressMonitor)
46  * */

47 public abstract class WorkspaceModifyOperation implements IRunnableWithProgress, IThreadListener {
48     private ISchedulingRule rule;
49
50     /**
51      * Creates a new operation.
52      */

53     protected WorkspaceModifyOperation() {
54         this(IDEWorkbenchPlugin.getPluginWorkspace().getRoot());
55     }
56
57     /**
58      * Creates a new operation that will run using the provided
59      * scheduling rule.
60      * @param rule The ISchedulingRule to use or <code>null</code>.
61      * @since 3.0
62      */

63     protected WorkspaceModifyOperation(ISchedulingRule rule) {
64         this.rule = rule;
65     }
66
67     /**
68      * Performs the steps that are to be treated as a single logical workspace
69      * change.
70      * <p>
71      * Subclasses must implement this method.
72      * </p>
73      *
74      * @param monitor the progress monitor to use to display progress and field
75      * user requests to cancel
76      * @exception CoreException if the operation fails due to a CoreException
77      * @exception InvocationTargetException if the operation fails due to an exception other than CoreException
78      * @exception InterruptedException if the operation detects a request to cancel,
79      * using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
80      * <code>InterruptedException</code>. It is also possible to throw
81      * <code>OperationCanceledException</code>, which gets mapped to <code>InterruptedException</code>
82      * by the <code>run</code> method.
83      */

84     protected abstract void execute(IProgressMonitor monitor)
85             throws CoreException, InvocationTargetException JavaDoc,
86             InterruptedException JavaDoc;
87
88     /**
89      * The <code>WorkspaceModifyOperation</code> implementation of this
90      * <code>IRunnableWithProgress</code> method initiates a batch of changes by
91      * invoking the <code>execute</code> method as a workspace runnable
92      * (<code>IWorkspaceRunnable</code>).
93      */

94     public synchronized final void run(IProgressMonitor monitor)
95             throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
96         final InvocationTargetException JavaDoc[] iteHolder = new InvocationTargetException JavaDoc[1];
97         try {
98             IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
99                 public void run(IProgressMonitor pm) throws CoreException {
100                     try {
101                         execute(pm);
102                     } catch (InvocationTargetException JavaDoc e) {
103                         // Pass it outside the workspace runnable
104
iteHolder[0] = e;
105                     } catch (InterruptedException JavaDoc e) {
106                         // Re-throw as OperationCanceledException, which will be
107
// caught and re-thrown as InterruptedException below.
108
throw new OperationCanceledException(e.getMessage());
109                     }
110                     // CoreException and OperationCanceledException are propagated
111
}
112             };
113             IDEWorkbenchPlugin.getPluginWorkspace().run(workspaceRunnable,
114                     rule, IResource.NONE, monitor);
115         } catch (CoreException e) {
116             throw new InvocationTargetException JavaDoc(e);
117         } catch (OperationCanceledException e) {
118             throw new InterruptedException JavaDoc(e.getMessage());
119         }
120         // Re-throw the InvocationTargetException, if any occurred
121
if (iteHolder[0] != null) {
122             throw iteHolder[0];
123         }
124     }
125     /* (non-Javadoc)
126      * @see IThreadListener#threadChange(Thread);
127      * @since 3.2
128      */

129     public void threadChange(Thread JavaDoc thread) {
130         //we must make sure we aren't transferring control away from a thread that
131
//already owns a scheduling rule because this is deadlock prone (bug 105491)
132
if (rule == null) {
133             return;
134         }
135         Job currentJob = Platform.getJobManager().currentJob();
136         if (currentJob == null) {
137             return;
138         }
139         ISchedulingRule currentRule = currentJob.getRule();
140         if (currentRule == null) {
141             return;
142         }
143         throw new IllegalStateException JavaDoc("Cannot fork a thread from a thread owning a rule"); //$NON-NLS-1$
144
}
145
146 }
147
Popular Tags