KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > contextlaunching > LaunchingResourceManager


1 /*******************************************************************************
2  * Copyright (c) 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.debug.internal.ui.contextlaunching;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.ListenerList;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.core.runtime.jobs.Job;
25 import org.eclipse.debug.core.DebugPlugin;
26 import org.eclipse.debug.core.ILaunch;
27 import org.eclipse.debug.core.ILaunchConfiguration;
28 import org.eclipse.debug.core.ILaunchesListener2;
29 import org.eclipse.debug.internal.ui.DebugUIPlugin;
30 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
31 import org.eclipse.debug.internal.ui.ILaunchHistoryChangedListener;
32 import org.eclipse.debug.internal.ui.ILaunchLabelChangedListener;
33 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
34 import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
35 import org.eclipse.debug.ui.ILaunchGroup;
36 import org.eclipse.jface.action.CoolBarManager;
37 import org.eclipse.jface.action.IContributionItem;
38 import org.eclipse.jface.action.ToolBarContributionItem;
39 import org.eclipse.jface.action.ToolBarManager;
40 import org.eclipse.jface.util.IPropertyChangeListener;
41 import org.eclipse.jface.util.PropertyChangeEvent;
42 import org.eclipse.jface.viewers.ISelection;
43 import org.eclipse.swt.events.MouseEvent;
44 import org.eclipse.swt.events.MouseTrackAdapter;
45 import org.eclipse.swt.widgets.ToolBar;
46 import org.eclipse.ui.ISelectionListener;
47 import org.eclipse.ui.IWindowListener;
48 import org.eclipse.ui.IWorkbench;
49 import org.eclipse.ui.IWorkbenchPart;
50 import org.eclipse.ui.IWorkbenchWindow;
51 import org.eclipse.ui.PlatformUI;
52 import org.eclipse.ui.internal.WorkbenchWindow;
53
54 import com.ibm.icu.text.MessageFormat;
55
56 /**
57  * This manager is used to calculate the labels for the current resource or for the current
58  * state of the launch history, depending on the enabled status of contextual launching. More specifically
59  * if contextual launching is enabled the calculated labels are for the current resource, otherwise
60  * the calculated labels are for the current state of the launch history.
61  *
62  * Any actions interested in being notified of launch label updates need to register with this manager, and implement
63  * the <code>ILaunchLabelChangedListener</code> interface.
64  *
65  * @see ILaunchLabelChangedListener
66  * @see org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction
67  *
68  * @since 3.3
69  */

70 public class LaunchingResourceManager implements IPropertyChangeListener, IWindowListener, ISelectionListener, ILaunchHistoryChangedListener, ILaunchesListener2 {
71     
72     /**
73      *The set of label update listeners
74      */

75     private ListenerList fLabelListeners = new ListenerList();
76     
77     /**
78      * The map of ToolBars that have mouse tracker listeners associated with them:
79      * stored as Map<IWorkbenchWindow, ToolBar>
80      */

81     private HashMap JavaDoc fToolbars = new HashMap JavaDoc();
82     
83     /**
84      * the map of current labels
85      */

86     private HashMap JavaDoc fCurrentLabels = new HashMap JavaDoc();
87     
88     /**
89      * The selection has changed and we need to update the labels
90      */

91     private boolean fUpdateLabel = true;
92     
93     /**
94      * Set of windows that have been opened and that we have registered selection listeners with
95      */

96     private HashSet JavaDoc fWindows = new HashSet JavaDoc();
97     
98     /**
99      * Cache of IResource -> ILaunchConfiguration[] used during a tooltip update job.
100      * The cache is cleared after each tooltip update job is complete.
101      */

102     private HashMap JavaDoc fConfigCache = new HashMap JavaDoc();
103     
104     /**
105      * Cache of IResource -> LaunchShortcutExtension used during a tooltip update job.
106      * The cache is cleared after each tooltip update job is complete.
107      */

108     private HashMap JavaDoc fExtCache = new HashMap JavaDoc();
109     
110     /**
111      * Constant denoting the empty string;
112      */

113     private static final String JavaDoc EMPTY_STRING = ""; //$NON-NLS-1$
114

115     /**
116      * Provides a mouse tracker listener for the launching main toolbar
117      */

118     private MouseTrackAdapter fMouseListener = new MouseTrackAdapter() {
119         public void mouseEnter(MouseEvent e) {
120             if(fUpdateLabel) {
121                 fUpdateLabel = false;
122                 fCurrentLabels.clear();
123                 Job job = new Job("Compute launch button tooltip") { //$NON-NLS-1$
124
protected IStatus run(IProgressMonitor monitor) {
125                         computeLabels();
126                         fConfigCache.clear();
127                         fExtCache.clear();
128                         return Status.OK_STATUS;
129                     }
130                 };
131                 job.setSystem(true);
132                 job.schedule();
133             }
134         }
135     };
136     
137     /**
138      * Returns if context launching is enabled
139      * @return if context launching is enabled
140      */

141     public static boolean isContextLaunchEnabled() {
142         return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH);
143     }
144     
145     /**
146      * Allows an <code>AbstractLaunchHistoryAction</code> to register with this manager to be notified
147      * of a context (<code>IResource</code>) change and have its updateToolTip(..) method called back to.
148      * @param action the action to add
149      * @param group the launch group
150      * @return true if the <code>AbstractLaunchHistoryAction</code> was added as a listener, false otherwise
151      */

152     public void addLaunchLabelUpdateListener(ILaunchLabelChangedListener listener) {
153         fLabelListeners.add(listener);
154     }
155     
156     /**
157      * Removes the specified <code>AbstractLaunchHistoryAction</code> from the listing of registered
158      * listeners
159      * @param action the action to remove
160      * @param group the launch group
161      * @return true if the action was removed from the listing of <code>AbstractLaunchHistoryAction</code> listeners,
162      * false otherwise
163      */

164     public void removeLaunchLabelChangedListener(ILaunchLabelChangedListener listener) {
165         fLabelListeners.remove(listener);
166     }
167     
168     /**
169      * Returns the current resource label to be displayed.
170      *
171      * @param group the launch group to get the label for
172      * @return the current resource label;
173      */

174     public String JavaDoc getLaunchLabel(ILaunchGroup group) {
175         return (String JavaDoc) fCurrentLabels.get(group);
176     }
177     
178     /**
179      * Returns if the parent project should be checked automatically
180      * @return true if the parent project should checked automatically, false otherwise
181      */

182     protected boolean shouldCheckParent() {
183         return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_PARENT_PROJECT);
184     }
185     
186     /**
187      * Returns if the the last launch configuration should be launched if the selected resource is not launchable and context launching is enabled
188      * @return true if the last launched should be launched, false otherwise
189      */

190     protected boolean shouldLaunchLast() {
191         return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE);
192     }
193     
194     /**
195      * Computes the current listing of labels for the given <code>IResource</code> context change or the
196      * current launch history changed event
197      */

198     protected void computeLabels() {
199         ILaunchGroup group = null;
200         ILaunchConfiguration config = null;
201         String JavaDoc label = null;
202         Object JavaDoc[] listeners = fLabelListeners.getListeners();
203         for(int i = 0; i < listeners.length; i++) {
204             group = ((ILaunchLabelChangedListener)listeners[i]).getLaunchGroup();
205             if(group != null) {
206                 if(isContextLaunchEnabled() && !group.getIdentifier().equals("org.eclipse.ui.externaltools.launchGroup")) { //$NON-NLS-1$
207
label = getResourceLabel(SelectedResourceManager.getDefault().getSelectedResource(), group);
208                 }
209                 else {
210                     config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
211                     if(config != null) {
212                         label = appendLaunched(config);
213                     }
214                 }
215                 fCurrentLabels.put(group, label);
216                 label = null;
217             }
218         }
219         notifyLabelChanged();
220     }
221     
222     /**
223      * Notifies all registered listeners that the known labels have changed
224      */

225     protected void notifyLabelChanged() {
226         Object JavaDoc[] listeners = fLabelListeners.getListeners();
227         for(int i = 0; i < listeners.length; i++) {
228             ((ILaunchLabelChangedListener)listeners[i]).labelChanged();
229         }
230     }
231     
232     /**
233      * Appends the text '(already running)' to the tooltip label if there is a launch currently
234      * running (not terminated) with the same backing launch configuration as the one specified
235      * @param config
236      * @return the appended string for the tooltip label or the configuration name (default)
237      */

238     private String JavaDoc appendLaunched(ILaunchConfiguration config) {
239         ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
240         boolean launched = false;
241         ILaunchConfiguration tmp = null;
242         for(int i = 0; i < launches.length; i++) {
243             tmp = launches[i].getLaunchConfiguration();
244             if(tmp != null) {
245                 if(!launches[i].isTerminated() && tmp.equals(config)) {
246                     launched = true;
247                     break;
248                 }
249             }
250         }
251         if(launched) {
252             return MessageFormat.format(ContextMessages.LaunchingResourceManager_0, new String JavaDoc[] {config.getName()});
253         }
254         return config.getName();
255     }
256     
257     /**
258      * Returns the label for the last launched configuration or and empty string if there was no last launch.
259      * @param group
260      * @return the name of the last launched configuration, altered with '(running)' if needed, or the empty
261      * string if there is no last launch.
262      */

263     protected String JavaDoc getlastLaunchedLabel(ILaunchGroup group) {
264         ILaunchConfiguration config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
265         if(config != null) {
266             return appendLaunched(config);
267         }
268         return EMPTY_STRING;
269     }
270     
271     /**
272      * Returns the label for the specified resource or the empty string, never <code>null</code>
273      * @param resource
274      * @param group
275      * @return the label for the resource or the empty string, never <code>null</code>
276      */

277     protected String JavaDoc getResourceLabel(IResource resource, ILaunchGroup group) {
278         if(resource == null) {
279             //no resource try last launch like the runner does
280
if(group != null) {
281                 String JavaDoc label = getlastLaunchedLabel(group);
282                 if(!EMPTY_STRING.equals(label)) {
283                     return label;
284                 }
285             }
286             //otherwise try to determine if there is a way to launch it
287
List JavaDoc shortcuts = ContextRunner.getDefault().getLaunchShortcutsForEmptySelection();
288             if(!shortcuts.isEmpty()) {
289                 return ContextMessages.ContextRunner_14;
290             }
291             else {
292                 return EMPTY_STRING;
293             }
294         }
295         LaunchConfigurationManager lcm = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
296         //see if the context is a shared configuration
297
ILaunchConfiguration config = lcm.isSharedConfig(resource);
298         if(config != null) {
299             return appendLaunched(config);
300         }
301         List JavaDoc configs = (List JavaDoc) fConfigCache.get(resource);
302         if(configs == null) {
303             configs = lcm.getApplicableLaunchConfigurations(resource);
304             fConfigCache.put(resource, configs);
305         }
306         int csize = configs.size();
307         if(csize == 1) {
308             return appendLaunched((ILaunchConfiguration)configs.get(0));
309         }
310         else if(csize > 1) {
311             config = lcm.getMRUConfiguration(configs, group, resource);
312             if(config != null) {
313                 return appendLaunched(config);
314             }
315             else {
316                 return ContextMessages.ContextRunner_14;
317             }
318         }
319         else {
320             List JavaDoc exts = (List JavaDoc) fExtCache.get(resource);
321             if(exts == null) {
322                 exts = lcm.getLaunchShortcuts(resource);
323                 fExtCache.put(resource, exts);
324             }
325             int esize = exts.size();
326             if(esize == 0) {
327                 if(shouldCheckParent()) {
328                     IProject project = resource.getProject();
329                     if(project != null && !project.equals(resource)) {
330                         return getResourceLabel(project, group);
331                     }
332                 }
333                 else if(shouldLaunchLast()) {
334                     return getlastLaunchedLabel(group);
335                 }
336                 else {
337                     return ContextMessages.ContextRunner_15;
338                 }
339             }
340             if(esize == 1) {
341                 return resource.getName();
342             }
343             else {
344                 return ContextMessages.ContextRunner_14;
345             }
346         }
347     }
348     
349     /**
350      * Starts up the manager
351      */

352     public void startup() {
353         IWorkbench workbench = PlatformUI.getWorkbench();
354         if(workbench != null) {
355             workbench.addWindowListener(this);
356         }
357         DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
358         DebugUIPlugin.getDefault().getLaunchConfigurationManager().addLaunchHistoryListener(this);
359         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
360     }
361
362     /**
363      * Shutdown and clean up the manager
364      */

365     public void shutdown() {
366         IWorkbench workbench = PlatformUI.getWorkbench();
367         if(workbench != null) {
368             workbench.removeWindowListener(this);
369         }
370         DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
371         DebugUIPlugin.getDefault().getLaunchConfigurationManager().removeLaunchHistoryListener(this);
372         DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
373         IWorkbenchWindow window = null;
374         ToolBar bar = null;
375         for(Iterator JavaDoc iter = fToolbars.keySet().iterator(); iter.hasNext();) {
376             window = (IWorkbenchWindow) iter.next();
377             bar = (ToolBar) fToolbars.get(window);
378             if(bar != null && !bar.isDisposed()) {
379                 bar.removeMouseTrackListener(fMouseListener);
380             }
381         }
382         for(Iterator JavaDoc iter = fWindows.iterator(); iter.hasNext();) {
383             ((IWorkbenchWindow)iter.next()).getSelectionService().removeSelectionListener(this);
384         }
385         fWindows.clear();
386         fToolbars.clear();
387         fLabelListeners.clear();
388         fCurrentLabels.clear();
389     }
390
391     /**
392      * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
393      */

394     public void windowActivated(IWorkbenchWindow window) {
395         if(!fToolbars.containsKey(window)) {
396             addMouseListener(window);
397         }
398     }
399
400     /**
401      * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
402      */

403     public void windowClosed(IWorkbenchWindow window) {
404         ToolBar bar = (ToolBar) fToolbars.remove(window);
405         if(bar != null && !bar.isDisposed()) {
406             bar.removeMouseTrackListener(fMouseListener);
407         }
408         if(fWindows.remove(window)) {
409             window.getSelectionService().removeSelectionListener(this);
410         }
411     }
412
413     /**
414      * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
415      */

416     public void windowDeactivated(IWorkbenchWindow window) {}
417
418     /**
419      * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
420      */

421     public void windowOpened(IWorkbenchWindow window) {
422         if(fWindows.add(window)) {
423             window.getSelectionService().addSelectionListener(this);
424         }
425     }
426     
427     /**
428      * Adds a mouse listener to the launch toolbar
429      *
430      * @param window
431      */

432     private void addMouseListener(IWorkbenchWindow window) {
433         CoolBarManager cmgr = ((WorkbenchWindow)window).getCoolBarManager();
434         if(cmgr != null) {
435             IContributionItem item = cmgr.find("org.eclipse.debug.ui.launchActionSet"); //$NON-NLS-1$
436
if(item instanceof ToolBarContributionItem) {
437                 ToolBarManager tmgr = (ToolBarManager) ((ToolBarContributionItem)item).getToolBarManager();
438                 ToolBar bar = tmgr.getControl();
439                 if(bar != null && !bar.isDisposed()) {
440                     bar.addMouseTrackListener(fMouseListener);
441                     fToolbars.put(window, bar);
442                 }
443             }
444         }
445     }
446     
447     /**
448      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
449      */

450     public void propertyChange(PropertyChangeEvent event) {
451         if(event.getProperty().equals(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH) ||
452                 event.getProperty().equals(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE)) {
453             if(isContextLaunchEnabled()) {
454                 windowActivated(DebugUIPlugin.getActiveWorkbenchWindow());
455             }
456             fUpdateLabel = true;
457         }
458     }
459
460     /* (non-Javadoc)
461      * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
462      */

463     public void selectionChanged(IWorkbenchPart part, ISelection selection) {
464         fUpdateLabel = isContextLaunchEnabled();
465     }
466
467     /* (non-Javadoc)
468      * @see org.eclipse.debug.internal.ui.ILaunchHistoryChangedListener#launchHistoryChanged()
469      */

470     public void launchHistoryChanged() {
471         //this always must be set to true, because as the history is loaded these events are fired, and we need to
472
//update on workspace load.
473
fUpdateLabel = true;
474     }
475
476     /* (non-Javadoc)
477      * @see org.eclipse.debug.core.ILaunchesListener2#launchesTerminated(org.eclipse.debug.core.ILaunch[])
478      */

479     public void launchesTerminated(ILaunch[] launches) {
480         fUpdateLabel = true;
481     }
482
483     /* (non-Javadoc)
484      * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch[])
485      */

486     public void launchesAdded(ILaunch[] launches) {
487         fUpdateLabel = true;
488     }
489
490     /* (non-Javadoc)
491      * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch[])
492      */

493     public void launchesChanged(ILaunch[] launches) {}
494
495     /* (non-Javadoc)
496      * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch[])
497      */

498     public void launchesRemoved(ILaunch[] launches) {}
499 }
500
Popular Tags