KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > actions > TeamAction


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.team.internal.ui.actions;
12
13 import java.lang.reflect.Array JavaDoc;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.*;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.commands.*;
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.resources.mapping.ResourceMapping;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.jface.action.IAction;
23 import org.eclipse.jface.dialogs.MessageDialog;
24 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
25 import org.eclipse.jface.operation.IRunnableWithProgress;
26 import org.eclipse.jface.viewers.*;
27 import org.eclipse.swt.custom.BusyIndicator;
28 import org.eclipse.swt.widgets.*;
29 import org.eclipse.team.core.RepositoryProvider;
30 import org.eclipse.team.core.TeamException;
31 import org.eclipse.team.internal.core.TeamPlugin;
32 import org.eclipse.team.internal.ui.*;
33 import org.eclipse.ui.*;
34 import org.eclipse.ui.handlers.HandlerUtil;
35 import org.eclipse.ui.ide.ResourceUtil;
36
37 /**
38  * The abstract superclass of all Team actions. This class contains some convenience
39  * methods for getting selected objects and mapping selected objects to their
40  * providers.
41  *
42  * Team providers may subclass this class when creating their actions.
43  * Team providers may also instantiate or subclass any of the
44  * subclasses of TeamAction provided in this package.
45  */

46 public abstract class TeamAction extends AbstractHandler implements IObjectActionDelegate, IViewActionDelegate, IWorkbenchWindowActionDelegate, IActionDelegate2 {
47     // The current selection
48
private IStructuredSelection selection;
49     
50     // The shell, required for the progress dialog
51
private Shell shell;
52
53     // Constants for determining the type of progress. Subclasses may
54
// pass one of these values to the run method.
55
public final static int PROGRESS_DIALOG = 1;
56     public final static int PROGRESS_BUSYCURSOR = 2;
57
58     private IWorkbenchPart targetPart;
59     private IWorkbenchWindow window;
60     
61     private ISelectionListener selectionListener = new ISelectionListener() {
62         public void selectionChanged(IWorkbenchPart part, ISelection selection) {
63             if(selection instanceof IStructuredSelection)
64                 TeamAction.this.selection = (IStructuredSelection)selection;
65         }
66     };
67
68     /**
69      * Creates an array of the given class type containing all the
70      * objects in the selection that adapt to the given class.
71      *
72      * @param selection
73      * @param c
74      * @return the selected adaptables
75      */

76     public static Object JavaDoc[] getSelectedAdaptables(ISelection selection, Class JavaDoc c) {
77         ArrayList result = null;
78         if (selection != null && !selection.isEmpty()) {
79             result = new ArrayList();
80             Iterator elements = ((IStructuredSelection) selection).iterator();
81             while (elements.hasNext()) {
82                 Object JavaDoc adapter = getAdapter(elements.next(), c);
83                 if (c.isInstance(adapter)) {
84                     result.add(adapter);
85                 }
86             }
87         }
88         if (result != null && !result.isEmpty()) {
89             return result.toArray((Object JavaDoc[])Array.newInstance(c, result.size()));
90         }
91         return (Object JavaDoc[])Array.newInstance(c, 0);
92     }
93     
94     /**
95      * Find the object associated with the given object when it is adapted to
96      * the provided class. Null is returned if the given object does not adapt
97      * to the given class
98      *
99      * @param adaptable
100      * @param c
101      * @return Object
102      */

103     public static Object JavaDoc getAdapter(Object JavaDoc adaptable, Class JavaDoc c) {
104         if (c.isInstance(adaptable)) {
105             return adaptable;
106         }
107         if (adaptable instanceof IAdaptable) {
108             IAdaptable a = (IAdaptable) adaptable;
109             Object JavaDoc adapter = a.getAdapter(c);
110             if (c.isInstance(adapter)) {
111                 return adapter;
112             }
113         }
114         return null;
115     }
116     
117     /**
118      * Returns the selected projects.
119      *
120      * @return the selected projects
121      */

122     protected IProject[] getSelectedProjects() {
123         IResource[] selectedResources = getSelectedResources();
124         if (selectedResources.length == 0) return new IProject[0];
125         ArrayList projects = new ArrayList();
126         for (int i = 0; i < selectedResources.length; i++) {
127             IResource resource = selectedResources[i];
128             if (resource.getType() == IResource.PROJECT) {
129                 projects.add(resource);
130             }
131         }
132         return (IProject[]) projects.toArray(new IProject[projects.size()]);
133     }
134     
135     /**
136      * Returns an array of the given class type c that contains all
137      * instances of c that are either contained in the selection or
138      * are adapted from objects contained in the selection.
139      *
140      * @param c
141      * @return the selection adapted to the given class
142      */

143     protected Object JavaDoc[] getAdaptedSelection(Class JavaDoc c) {
144         return getSelectedAdaptables(selection, c);
145     }
146     
147     /**
148      * Returns the selected resources.
149      *
150      * @return the selected resources
151      */

152     protected IResource[] getSelectedResources() {
153         return Utils.getContributedResources(getSelection().toArray());
154     }
155     
156     protected IStructuredSelection getSelection() {
157         if (selection == null)
158             selection = StructuredSelection.EMPTY;
159         return selection;
160     }
161     
162     /**
163      * Return the selected resource mappins that contain resources in
164      * projects that are associated with a repository of the given id.
165      * @param providerId the repository provider id
166      * @return the resource mappings that contain resources associated with the given provider
167      */

168     protected ResourceMapping[] getSelectedResourceMappings(String JavaDoc providerId) {
169         Object JavaDoc[] elements = getSelection().toArray();
170         ArrayList providerMappings = new ArrayList();
171         for (int i = 0; i < elements.length; i++) {
172             Object JavaDoc object = elements[i];
173             Object JavaDoc adapted = getResourceMapping(object);
174             if (adapted instanceof ResourceMapping) {
175                 ResourceMapping mapping = (ResourceMapping) adapted;
176                 if (providerId == null || isMappedToProvider(mapping, providerId)) {
177                     providerMappings.add(mapping);
178                 }
179             }
180         }
181         return (ResourceMapping[]) providerMappings.toArray(new ResourceMapping[providerMappings.size()]);
182     }
183
184     private Object JavaDoc getResourceMapping(Object JavaDoc object) {
185         if (object instanceof ResourceMapping)
186             return (ResourceMapping)object;
187         return Utils.getResourceMapping(object);
188     }
189     
190     private boolean isMappedToProvider(ResourceMapping element, String JavaDoc providerId) {
191         IProject[] projects = element.getProjects();
192         for (int k = 0; k < projects.length; k++) {
193             IProject project = projects[k];
194             RepositoryProvider provider = RepositoryProvider.getProvider(project);
195             if (provider != null && provider.getID().equals(providerId)) {
196                 return true;
197             }
198         }
199         return false;
200     }
201     
202     /**
203      * Convenience method for getting the current shell.
204      *
205      * @return the shell
206      */

207     protected Shell getShell() {
208         if (shell != null) {
209             return shell;
210         } else if (targetPart != null) {
211             return targetPart.getSite().getShell();
212         } else if (window != null) {
213             return window.getShell();
214         } else {
215             IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench();
216             if (workbench == null) return null;
217             IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
218             if (window == null) return null;
219             return window.getShell();
220         }
221     }
222     /**
223      * Convenience method for running an operation with progress and
224      * error feedback.
225      *
226      * @param runnable the runnable which executes the operation
227      * @param problemMessage the message to display in the case of errors
228      * @param progressKind one of PROGRESS_BUSYCURSOR or PROGRESS_DIALOG
229      */

230     final protected void run(final IRunnableWithProgress runnable, final String JavaDoc problemMessage, int progressKind) {
231         final Exception JavaDoc[] exceptions = new Exception JavaDoc[] {null};
232         switch (progressKind) {
233             case PROGRESS_BUSYCURSOR :
234                 BusyIndicator.showWhile(Display.getCurrent(), new Runnable JavaDoc() {
235                     public void run() {
236                         try {
237                             runnable.run(new NullProgressMonitor());
238                         } catch (InvocationTargetException JavaDoc e) {
239                             exceptions[0] = e;
240                         } catch (InterruptedException JavaDoc e) {
241                             exceptions[0] = null;
242                         }
243                     }
244                 });
245                 break;
246             default :
247             case PROGRESS_DIALOG :
248                 try {
249                     new ProgressMonitorDialog(getShell()).run(true, true, runnable);
250                 } catch (InvocationTargetException JavaDoc e) {
251                     exceptions[0] = e;
252                 } catch (InterruptedException JavaDoc e) {
253                     exceptions[0] = null;
254                 }
255                 break;
256         }
257         if (exceptions[0] != null) {
258             handle(exceptions[0], null, problemMessage);
259         }
260     }
261     
262     /*
263      * Method declared on IActionDelegate.
264      */

265     public void selectionChanged(IAction action, ISelection selection) {
266         if (selection instanceof IStructuredSelection) {
267             this.selection = (IStructuredSelection) selection;
268             if (action != null) {
269                 setActionEnablement(action);
270             }
271         }
272     }
273     
274     /**
275      * Method invoked from <code>selectionChanged(IAction, ISelection)</code>
276      * to set the enablement status of the action. The instance variable
277      * <code>selection</code> will contain the latest selection so the methods
278      * <code>getSelectedResources()</code> and <code>getSelectedProjects()</code>
279      * will provide the proper objects.
280      *
281      * This method can be overridden by subclasses but should not be invoked by them.
282      */

283     protected void setActionEnablement(IAction action) {
284         action.setEnabled(isEnabled());
285     }
286     
287     /**
288      * If an exception occurs during enablement testing, this method is invoked
289      * to determine if the action should be enabled or not.
290      * @param exception the exception
291      * @return whether the action should be enabled or not
292      */

293     protected boolean isEnabledForException(TeamException exception) {
294         if (exception.getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) {
295             // Enable the action to allow the user to discover the problem
296
return true;
297         }
298         // We should not open a dialog when determining menu enablement so log it instead
299
TeamPlugin.log(exception);
300         return false;
301     }
302     
303     /*
304      * Method declared on IObjectActionDelegate.
305      */

306     public void setActivePart(IAction action, IWorkbenchPart targetPart) {
307         if(targetPart != null) {
308             this.shell = targetPart.getSite().getShell();
309             this.targetPart = targetPart;
310         }
311     }
312     /**
313      * Shows the given errors to the user.
314      *
315      * @param exception the status containing the error
316      * @param title the title of the error dialog
317      * @param message the message for the error dialog
318      */

319     protected void handle(Exception JavaDoc exception, String JavaDoc title, String JavaDoc message) {
320         Utils.handleError(getShell(), exception, title, message);
321     }
322     
323     /**
324      * Convenience method that maps the given resources to their providers.
325      * The returned Hashtable has keys which are ITeamProviders, and values
326      * which are Lists of IResources that are shared with that provider.
327      *
328      * @return a hashtable mapping providers to their resources
329      */

330     protected Hashtable getProviderMapping(IResource[] resources) {
331         Hashtable result = new Hashtable();
332         for (int i = 0; i < resources.length; i++) {
333             RepositoryProvider provider = RepositoryProvider.getProvider(resources[i].getProject());
334             List JavaDoc list = (List JavaDoc)result.get(provider);
335             if (list == null) {
336                 list = new ArrayList();
337                 result.put(provider, list);
338             }
339             list.add(resources[i]);
340         }
341         return result;
342     }
343     
344     /**
345      * @return IWorkbenchPart
346      */

347     protected IWorkbenchPart getTargetPart() {
348         if(targetPart == null) {
349             IWorkbenchPage page = TeamUIPlugin.getActivePage();
350             if (page != null) {
351                 targetPart = page.getActivePart();
352             }
353         }
354         return targetPart;
355
356     }
357
358     /**
359      * Return the path that was active when the menu item was selected.
360      * @return IWorkbenchPage
361      */

362     protected IWorkbenchPage getTargetPage() {
363         if (getTargetPart() == null) return TeamUIPlugin.getActivePage();
364         return getTargetPart().getSite().getPage();
365     }
366     
367     /**
368      * Show the view with the given ID in the perspective from which the action
369      * was executed. Returns null if the view is not registered.
370      *
371      * @param viewId
372      * @return IViewPart
373      */

374     protected IViewPart showView(String JavaDoc viewId) {
375         try {
376             return getTargetPage().showView(viewId);
377         } catch (PartInitException pe) {
378             return null;
379         }
380     }
381     
382     /* (non-Javadoc)
383      * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
384      */

385     public void init(IViewPart view) {
386         if(view != null) {
387             this.shell = view.getSite().getShell();
388             this.targetPart = view;
389         }
390     }
391     
392     public void init(IWorkbenchWindow window) {
393         this.window = window;
394         this.shell = window.getShell();
395         window.getSelectionService().addPostSelectionListener(selectionListener);
396     }
397     
398     public IWorkbenchWindow getWindow() {
399         return window;
400     }
401     
402     public void dispose() {
403         super.dispose();
404         if(window != null) {
405             window.getSelectionService().removePostSelectionListener(selectionListener);
406         }
407         // Don't hold on to anything when we are disposed to prevent memory leaks (see bug 195521)
408
selection = null;
409         window = null;
410         targetPart = null;
411         shell = null;
412     }
413
414     /**
415      * Actions must override to do their work.
416      */

417     protected abstract void execute(IAction action)
418             throws InvocationTargetException JavaDoc, InterruptedException JavaDoc;
419
420     /**
421      * This method is called by the platform UI framework when a command is run for
422      * which this action is the handler. The handler doesn't have an explicit context, for
423      * example unlike a view, editor, or workbench window actions, they are not initialized
424      * with a part. As a result when the action is run it will use the selection service
425      * to determine to elements on which to perform the action.
426      * <p>
427      * CVS actions should ensure that they can run without a proxy action. Meaning that
428      * <code>selectionChanged</code> and <code>run</code> should support passing
429      * <code>null</code> as the IAction parameter.
430      * </p>
431      * @throws ExecutionException
432      */

433     public Object JavaDoc execute(ExecutionEvent event) throws ExecutionException {
434         IWorkbenchWindow activeWorkbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
435         if (activeWorkbenchWindow != null) {
436             ISelection selection = HandlerUtil.getCurrentSelection(event);
437             if (selection != null) {
438                 IWorkbenchPart part = HandlerUtil.getActivePart(event);
439                 try {
440                     execute(activeWorkbenchWindow, part, selection);
441                 } catch (InvocationTargetException JavaDoc e) {
442                     throw new ExecutionException(TeamUIMessages.TeamAction_errorTitle, e);
443                 } catch (InterruptedException JavaDoc e) {
444                     // Operation was canceled. Ignore
445
}
446             }
447         }
448         return null;
449     }
450
451     private void execute(IWorkbenchWindow activeWorkbenchWindow,
452             IWorkbenchPart part, ISelection selection)
453             throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
454         // If the action is run from within an editor, try and find the
455
// file for the given editor.
456
if (part != null && part instanceof IEditorPart) {
457             IEditorInput input = ((IEditorPart) part).getEditorInput();
458             IFile file = ResourceUtil.getFile(input);
459             if (file != null) {
460                 selectionChanged((IAction) null, new StructuredSelection(file));
461             }
462         } else {
463             // Fallback is to prime the action with the selection
464
selectionChanged((IAction) null, selection);
465         }
466         // Safe guard to ensure that the action is only run when enabled.
467
if (isEnabled()) {
468             execute((IAction) null);
469         } else {
470             MessageDialog.openInformation(activeWorkbenchWindow.getShell(),
471                     TeamUIMessages.TeamAction_handlerNotEnabledTitle,
472                     TeamUIMessages.TeamAction_handlerNotEnabledMessage);
473         }
474     }
475
476     /**
477      * Common run method for all Team actions.
478      */

479     public void run(IAction action) {
480         try {
481             execute(action);
482         } catch (InvocationTargetException JavaDoc e) {
483             // Handle the exception and any accumulated errors
484
handle(e);
485         } catch (InterruptedException JavaDoc e) {
486             // Operation was canceled. Ignore.
487
}
488     }
489
490     /**
491      * This method can be overridden by subclasses but should not be invoked by
492      * them.
493      *
494      * @param e
495      * Exception to handle
496      */

497     protected void handle(Exception JavaDoc e) {
498         handle(e, TeamUIMessages.TeamAction_errorTitle, null);
499     }
500
501     /**
502      * The <code>TeamAction</code> implementation of this
503      * <code>IActionDelegate2</code> method does nothing. Subclasses may
504      * reimplement.
505      */

506     public void init(IAction action) {
507     }
508
509     /**
510      * The <code>TeamAction</code> implementation of this
511      * <code>IActionDelegate2</code> method redirects to the <code>run</code>
512      * method. Subclasses may reimplement.
513      */

514     final public void runWithEvent(IAction action, Event event) {
515         run(action);
516     }
517
518 }
519
Popular Tags