Skip to main content
summaryrefslogtreecommitdiffstats
blob: bc0cb6bd681ffa62d33b625fadb62c8ba80713f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.ui;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.actions.*;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;

/**
 * An operation that can be configured to run in the foreground using
 * the {@link org.eclipse.ui.progress.IProgressService} or the background
 * as a {@link org.eclipse.core.runtime.Job}. The executione context is determined
 * by what is returned by the {@link #canRunAsJob()} hint which may be overriden by subclasses. 
 * Subsclass must override the <code>run(IProgressMonitor)</code> method to perform 
 * the behavior of the operation in the desired execution context.
 * <p>
 * If this operation is run as a job, it is registered with the job as a 
 * {@link org.eclipse.core.runtime.jobs.IJobChangeListener} and is scheduled with
 * the part of this operation if it is not <code>null</code>. 
 * Subsclasses can override the methods of this
 * interface to receive job change notificaton.
 * 
 * @see org.eclipse.ui.progress.IProgressService
 * @see org.eclipse.core.runtime.Job
 * @see org.eclipse.core.runtime.ISchedulingRule
 * @see org.eclipse.core.runtime.jobs.IJobChangeListener
 */
public abstract class TeamOperation extends JobChangeAdapter implements IRunnableWithProgress {
	
	private IWorkbenchPart part;
	
	/**
	 * Create an team operation associated with the given part.
	 * @param part the part the operation is associated with or <code>null</code>
	 */
	protected TeamOperation(IWorkbenchPart part) {
		this.part = part;
	}
	
	/**
	 * Return the part that is associated with this operation.
	 * @return Returns the part or <code>null</code>
	 */
	public IWorkbenchPart getPart() {
		return part;
	}
	
	/**
	 * Run the operation in a context that is determined by the <code>canRunAsJob()</code>
	 * hint. If this operation can run as a job then it will be run in a background thread.
	 * Otherwise it will run in the foreground and block the caller.
	 */
	public final void run() throws InvocationTargetException, InterruptedException {
		getRunnableContext().run(this);
	}
	
	/**
	 * Returns the scheduling rule that is to be obtained before this
	 * operation is executed by it's context or <code>null</code> if
	 * no scheduling rule is to be obtained. If the operation is run 
	 * as a job, the schdulin rule is used as the schduling rule of the
	 * job. Otherwise, it is obtained before execution of the operation
	 * occurs.
	 * <p>
	 * By default, no scheduling
	 * rule is obtained. Sublcasses can override to in order ot obtain a
	 * scheduling rule or can obtain schduling rules withing their operation
	 * if finer grained schduling is desired.
	 * @return the schduling rule to be obtained by this operation
	 * or <code>null</code>
	 */
	protected ISchedulingRule getSchedulingRule() {
		return null;
	}
	
	/**
	 * Return whether the auto-build should be postponed until after
	 * the operation is complete. The default is to postpone the auto-build.
	 * subclas can override.
	 * @return whether to postpone the auto-build while the operation is executing
	 */
	protected boolean isPostponeAutobuild() {
		return true;
	}
	
	/**
	 * If this operation can safely be run in the background, then subclasses can
	 * override this method and return <code>true</code>. This will make their
	 * action run in a {@link  org.eclipse.core.runtime.Job}. 
	 * Subsclass that override this method should 
	 * also override the <code>getJobName()</code> method.
	 * 
	 * @return <code>true</code> if this action can be run in the background and
	 * <code>false</code> otherwise.
	 */
	protected boolean canRunAsJob() {
		return false;
	}
	
	/**
	 * Return the job name to be used if the action can run as a job. (i.e.
	 * if <code>canRunAsJob()</code> returns <code>true</code>).
	 * 
	 * @return the string to be used as the job name
	 */
	protected String getJobName() {
		return ""; //$NON-NLS-1$
	}
	
	/**
	 * Return a shell that can be used by the operation to display dialogs, etc.
	 * @return a shell
	 */
	protected Shell getShell() {
		final Shell[] shell = new Shell[] { null };
		if (canRunAsJob()) {
			Display.getDefault().syncExec(new Runnable() {
				public void run() {
					shell[0] = Utils.getShell(getSite());
				}
			});
		} else {
			shell[0] = Utils.getShell(getSite());
		}
		return shell[0];
	}
	
	/*
	 * Uses the {@link #canRunAsJob()} hint to return a {@link ITeamRunnableContext}
	 * that is used to execute the <code>run(SyncInfoSet, IProgressMonitor)</code>
	 * method of this action. 
	 * 
	 * @param syncSet the sync info set containing the selected elements for which this
	 * action is enabled.
	 * @return the runnable context in which to run this action.
	 */
	private ITeamRunnableContext getRunnableContext() {
		if (canRunAsJob()) {
			JobRunnableContext context = new JobRunnableContext(getJobName(), this, getSite());
			context.setPostponeBuild(isPostponeAutobuild());
			context.setSchedulingRule(getSchedulingRule());
			return context;
		} else {
			ProgressDialogRunnableContext context = new ProgressDialogRunnableContext(getShell());
			context.setPostponeBuild(isPostponeAutobuild());
			context.setSchedulingRule(getSchedulingRule());
			return context;
		}
	}
	
	private IWorkbenchSite getSite() {
		IWorkbenchSite site = null;
		if(part != null) {
			site = part.getSite();
		}
		return site;
	}
}

Back to the top