KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > launchConfigurations > PerspectiveManager


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.debug.internal.ui.launchConfigurations;
12
13
14 import java.io.IOException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import javax.xml.parsers.ParserConfigurationException JavaDoc;
24 import javax.xml.transform.TransformerException JavaDoc;
25
26 import org.eclipse.core.commands.contexts.Context;
27 import org.eclipse.core.resources.ISaveContext;
28 import org.eclipse.core.resources.ISaveParticipant;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.jobs.Job;
31 import org.eclipse.debug.core.DebugPlugin;
32 import org.eclipse.debug.core.ILaunch;
33 import org.eclipse.debug.core.ILaunchConfiguration;
34 import org.eclipse.debug.core.ILaunchConfigurationType;
35 import org.eclipse.debug.core.ILaunchDelegate;
36 import org.eclipse.debug.core.ILaunchListener;
37 import org.eclipse.debug.core.ILaunchManager;
38 import org.eclipse.debug.internal.core.IConfigurationElementConstants;
39 import org.eclipse.debug.internal.core.LaunchManager;
40 import org.eclipse.debug.internal.ui.DebugUIPlugin;
41 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
42 import org.eclipse.debug.internal.ui.views.ViewContextManager;
43 import org.eclipse.debug.internal.ui.views.ViewContextService;
44 import org.eclipse.debug.ui.IDebugUIConstants;
45 import org.eclipse.debug.ui.contexts.ISuspendTrigger;
46 import org.eclipse.debug.ui.contexts.ISuspendTriggerListener;
47 import org.eclipse.jface.dialogs.IDialogConstants;
48 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
49 import org.eclipse.swt.widgets.Display;
50 import org.eclipse.swt.widgets.Shell;
51 import org.eclipse.ui.IPerspectiveDescriptor;
52 import org.eclipse.ui.IWorkbenchPage;
53 import org.eclipse.ui.IWorkbenchWindow;
54 import org.eclipse.ui.PlatformUI;
55 import org.eclipse.ui.WorkbenchException;
56 import org.eclipse.ui.contexts.IContextActivation;
57 import org.eclipse.ui.contexts.IContextService;
58 import org.w3c.dom.Document JavaDoc;
59 import org.w3c.dom.Element JavaDoc;
60 import org.w3c.dom.Node JavaDoc;
61 import org.w3c.dom.NodeList JavaDoc;
62
63 import com.ibm.icu.text.MessageFormat;
64
65 /**
66  * The perspective manager manages the 'perspective' settings
67  * defined by launch configurations. Specifically it:
68  * <ul>
69  * <li>changes perspectives as launches are registered</li>
70  * <li>change perspective when a thread suspends</li>
71  * </ul>
72  *
73  * Since 3.3 the Perspectives Manager is an <code>ISaveParticipant</code>, allowing it to participate in
74  * workspace persistence life-cycles.
75  *
76  * @see IDebugUIContants.ATTR_RUN_PERSPECTIVE
77  * @see IDebugUIContants.ATTR_DEBUG_PERSPECTIVE
78  * @see ISaveParticipant
79  * @see ISuspendTriggerListener
80  * @see ILaunchListener
81  * @see org.eclipse.debug.internal.ui.preferences.LaunchPerspectivePreferencePage
82  * @see DebugUIPlugin
83  */

84 public class PerspectiveManager implements ILaunchListener, ISuspendTriggerListener, ISaveParticipant {
85         
86     /**
87      * Lock used to synchronize perspective switching with view activation.
88      * Clients wanting to perform an action after a perspective switch should
89      * schedule jobs with the perspective manager via #schedulePostSwitch(..)
90      */

91     public class PerspectiveSwitchLock {
92
93         private int fSwitch = 0;
94         private List JavaDoc fJobs = new ArrayList JavaDoc();
95         
96         public synchronized void startSwitch() {
97             fSwitch++;
98         }
99         
100         public synchronized void endSwitch() {
101             fSwitch--;
102             if (fSwitch == 0) {
103                 Iterator JavaDoc jobs = fJobs.iterator();
104                 while (jobs.hasNext()) {
105                     ((Job)jobs.next()).schedule();
106                 }
107                 fJobs.clear();
108             }
109         }
110                 
111         public synchronized void schedulePostSwitch(Job job) {
112             if (fSwitch > 0) {
113                 fJobs.add(job);
114             }
115             else {
116                 job.schedule();
117             }
118         }
119     }
120     
121     /**
122      * Describes exactly one perspective context, which is composed of an <code>ILaunchCOnfigurationType</code>, and set of modes
123      * and an <code>ILaunchDelegate</code>. Perspective ids are then cached for a context based on mode set.
124      *
125      * @since 3.3
126      */

127     class PerspectiveContext {
128         
129         private ILaunchConfigurationType fType = null;
130         private ILaunchDelegate fDelegate = null;
131         private Map JavaDoc fPerspectives = null;
132         
133         /**
134          * Constructor
135          * @param type
136          * @param delegate
137          * @param modes
138          */

139         public PerspectiveContext(ILaunchConfigurationType type, ILaunchDelegate delegate, Set JavaDoc modes) {
140             fType = type;
141             fDelegate = delegate;
142             fPerspectives = new HashMap JavaDoc();
143             fPerspectives.put(modes, null);
144         }
145         
146         /**
147          * We can specially compare two cases:
148          * <ol>
149          * <li>a launch object</li>
150          * <li>an object array of the form [IlaunchConfigurationType, ILaunchDelegate, Set]</li>
151          * </ol>
152          * @see java.lang.Object#equals(java.lang.Object)
153          */

154         public boolean equals(Object JavaDoc object) {
155             ILaunchDelegate delegate = null;
156             ILaunchConfigurationType type = null;
157             if(object instanceof ILaunch) {
158                 try {
159                     ILaunch launch = (ILaunch) object;
160                     type = launch.getLaunchConfiguration().getType();
161                     delegate = resolveLaunchDelegate(launch);
162                 }
163                 catch (CoreException e) {return false;}
164             }
165             else if(object instanceof PerspectiveContext) {
166                 PerspectiveContext context = (PerspectiveContext) object;
167                 type = context.getLaunchConfigurationType();
168                 delegate = context.getLaunchDelegate();
169             }
170             if(fType != null && type != null && fType.getIdentifier().equals(type.getIdentifier())) {
171                 if(fDelegate == null) {
172                     return delegate == null;
173                 }
174                 else {
175                     return fDelegate.equals(delegate);
176                 }
177             }
178             return super.equals(object);
179         }
180         
181         public ILaunchConfigurationType getLaunchConfigurationType() {return fType;}
182         public ILaunchDelegate getLaunchDelegate() {return fDelegate;}
183         public Map JavaDoc getPersepctiveMap() {return fPerspectives;}
184         
185         /**
186          * Creates a new mapping of the specified perspective id to the specified mode set.
187          * If a mapping for the modeset already exists it is over-written.
188          * @param modes the set of modes
189          * @param pid the id of the perspective
190          */

191         public void setPerspective(Set JavaDoc modes, String JavaDoc pid) {
192             if(fPerspectives == null) {
193                 fPerspectives = new HashMap JavaDoc();
194             }
195             fPerspectives.put(modes, pid);
196         }
197         
198         /**
199          * Returns the perspective id associated with the given mode set
200          * @param modes the set of mode
201          * @return the perspective id associated with the given mode set, or
202          * <code>null</code>, if there isn't one
203          */

204         public String JavaDoc getPerspective(Set JavaDoc modes) {
205             if(fPerspectives != null) {
206                 return (String JavaDoc) fPerspectives.get(modes);
207             }
208             return null;
209         }
210     }
211     
212     /**
213      * A listing of <code>PerspectiveContext</code>s
214      *
215      * @since 3.3
216      */

217     private Set JavaDoc fPerspectiveContexts = null;
218     
219     /**
220      * id for the 'delegate' attribute
221      *
222      * @since 3.3
223      */

224     public static final String JavaDoc ATTR_DELEGATE_ID = "delegate"; //$NON-NLS-1$
225

226     /**
227      * Flag used to indicate that the user is already being prompted to
228      * switch perspectives. This flag allows us to not open multiple
229      * prompts at the same time.
230      */

231     private boolean fPrompting;
232     
233     /**
234      * Lock to sync other jobs on the perspective switch
235      */

236     private PerspectiveSwitchLock fPerspectiveSwitchLock = new PerspectiveSwitchLock();
237     
238     /**
239      * Maps each launch to its perspective context activation. These
240      * are disabled when a launch terminates.
241      */

242     private Map JavaDoc fLaunchToContextActivations = new HashMap JavaDoc();
243
244     /**
245      * Called by the debug ui plug-in on startup.
246      * The perspective manager starts listening for
247      * launches to be registered.
248      */

249     public void startup() {
250         DebugUIPlugin.getDefault().addSaveParticipant(this);
251         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
252         initPerspectives();
253     }
254
255     /**
256      * Called by the debug ui plug-in on shutdown.
257      * The perspective manager de-registers as a
258      * launch listener.
259      */

260     public void shutdown() {
261         DebugUIPlugin.getDefault().removeSaveParticipant(this);
262         DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
263     }
264     
265     /**
266      * If there are no launches, remove the Suspend Trigger Listener
267      *
268      * @see ILaunchListener#launchRemoved(ILaunch)
269      */

270     public synchronized void launchRemoved(final ILaunch launch) {
271         ISuspendTrigger trigger = (ISuspendTrigger) launch.getAdapter(ISuspendTrigger.class);
272         if (trigger != null) {
273             trigger.removeSuspendTriggerListener(this);
274         }
275         Runnable JavaDoc r= new Runnable JavaDoc() {
276             public void run() {
277                 IContextActivation[] activations = (IContextActivation[]) fLaunchToContextActivations.remove(launch);
278                 if (activations != null) {
279                     for (int i = 0; i < activations.length; i++) {
280                         IContextActivation activation = activations[i];
281                         activation.getContextService().deactivateContext(activation);
282                     }
283                 }
284             }
285         };
286         async(r);
287     }
288     
289     /**
290      * Do nothing.
291      *
292      * @see ILaunchListener#launchChanged(ILaunch)
293      */

294     public void launchChanged(ILaunch launch) {}
295
296     /**
297      * Switch to the perspective specified by the
298      * launch configuration.
299      *
300      * @see ILaunchListener#launchAdded(ILaunch)
301      */

302     public synchronized void launchAdded(ILaunch launch) {
303         ISuspendTrigger trigger = (ISuspendTrigger) launch.getAdapter(ISuspendTrigger.class);
304         if (trigger != null) {
305             trigger.addSuspendTriggerListener(this);
306         }
307         fPerspectiveSwitchLock.startSwitch();
308         String JavaDoc perspectiveId = null;
309         // check event filters
310
try {
311             perspectiveId = getPerspectiveId(launch);
312         }
313         catch (CoreException e) {
314             String JavaDoc name = DebugUIPlugin.getModelPresentation().getText(launch);
315             switchFailed(e, name);
316         }
317         // don't switch if a private config
318
ILaunchConfiguration configuration = launch.getLaunchConfiguration();
319         if (configuration != null) {
320             if (!LaunchConfigurationManager.isVisible(configuration)) {
321                 perspectiveId = null;
322             }
323         }
324         final String JavaDoc id = perspectiveId;
325         // switch
326
async(new Runnable JavaDoc() {
327             public void run() {
328                 try {
329                     IWorkbenchWindow window = getWindowForPerspective(id);
330                     if (id != null && window != null && shouldSwitchPerspective(window, id, IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE)) {
331                         switchToPerspective(window, id);
332                     }
333                 }
334                 finally {
335                     fPerspectiveSwitchLock.endSwitch();
336                 }
337             }
338         });
339     }
340
341
342     /**
343      * Switches to the specified perspective
344      *
345      * @param id perspective identifier
346      */

347     protected void switchToPerspective(IWorkbenchWindow window, String JavaDoc id) {
348         try {
349             window.getWorkbench().showPerspective(id, window);
350         } catch (WorkbenchException e) {
351             DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(),
352             LaunchConfigurationsMessages.PerspectiveManager_Error_1,
353             MessageFormat.format(LaunchConfigurationsMessages.PerspectiveManager_Unable_to_switch_to_perspective___0__2, new String JavaDoc[]{id}),
354             e);
355         }
356     }
357     
358     /**
359      * Utility method to submit an asynchronous runnable to the UI
360      */

361     protected void async(Runnable JavaDoc r) {
362         Display d = DebugUIPlugin.getStandardDisplay();
363         if (d != null && !d.isDisposed()) {
364             d.asyncExec(r);
365         }
366     }
367     
368     /**
369      * Utility method to submit a synchronous runnable to the UI
370      */

371     protected void sync(Runnable JavaDoc r) {
372         Display d = DebugUIPlugin.getStandardDisplay();
373         if (d != null && !d.isDisposed()) {
374             d.syncExec(r);
375         }
376     }
377
378     /**
379      * Reports failure to switch perspectives to the user
380      *
381      * @param status exception status describing failure
382      * @param launchName the name of the launch that the
383      * failure is associated with
384      */

385     protected void switchFailed(final Throwable JavaDoc t, final String JavaDoc launchName) {
386         sync(new Runnable JavaDoc() {
387             public void run() {
388                 DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), LaunchConfigurationsMessages.PerspectiveManager_Error_1,
389                  MessageFormat.format(LaunchConfigurationsMessages.PerspectiveManager_Unable_to_switch_perpsectives_as_specified_by_launch___0__4, new String JavaDoc[] {launchName}),
390                  t);
391             }});
392     }
393     
394     /**
395      * A breakpoint has been hit. Carry out perspective switching
396      * as appropriate for the given debug event.
397      *
398      * @param event the suspend event
399      */

400     private void handleBreakpointHit(final ILaunch launch) {
401         
402         // Must be called here to indicate that the perspective
403
// may be switching.
404
// Putting this in the async UI call will cause the Perspective
405
// Manager to turn on the lock too late. Consequently, LaunchViewContextListener
406
// may not know that the perspective will switch and will open view before
407
// the perspective switch.
408
fPerspectiveSwitchLock.startSwitch();
409         
410         String JavaDoc perspectiveId = null;
411         try {
412             perspectiveId = getPerspectiveId(launch);
413         }
414         catch (CoreException e) {DebugUIPlugin.log(e);}
415         // if no perspective specified, always switch to debug
416
// perspective
417

418         // this has to be done in an async, such that the workbench
419
// window can be accessed
420
final String JavaDoc targetId = perspectiveId;
421         Runnable JavaDoc r = new Runnable JavaDoc() {
422             public void run() {
423                 IWorkbenchWindow window = null;
424                 try{
425                     if (targetId != null) {
426                         // get the window to open the perspective in
427
window = getWindowForPerspective(targetId);
428                         if (window == null) {
429                             return;
430                         }
431                         
432                         // switch the perspective if user preference is set
433
if (shouldSwitchPerspective(window, targetId, IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND)) {
434                             switchToPerspective(window, targetId);
435                             window = getWindowForPerspective(targetId);
436                             if (window == null) {
437                                 return;
438                             }
439                         }
440                         
441                         // make sure the shell is active
442
Shell shell= window.getShell();
443                         if (shell != null) {
444                             if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH)) {
445                                 if (shell.getMinimized()) {
446                                     shell.setMinimized(false);
447                                 }
448                                 shell.forceActive();
449                             }
450                         }
451     
452                         // Activate a context for the launch
453
Object JavaDoc ca = fLaunchToContextActivations.get(launch);
454                         if (ca == null) {
455                             ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
456                             if (launchConfiguration != null) {
457                                 try {
458                                     String JavaDoc type = launchConfiguration.getType().getIdentifier();
459                                     ViewContextService service = ViewContextManager.getDefault().getService(window);
460                                     if (service != null) {
461                                         IContextService contextServce = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
462                                         String JavaDoc[] ids = service.getEnabledPerspectives();
463                                         IContextActivation[] activations = new IContextActivation[ids.length];
464                                         for (int i = 0; i < ids.length; i++) {
465                                             // Include the word '.internal.' so the context is filtered from the key binding pref page (Bug 144019) also see ViewContextService.contextActivated()
466
Context context = contextServce.getContext(type + ".internal." + ids[i]); //$NON-NLS-1$
467
if (!context.isDefined()) {
468                                                 context.define(context.getId(), null, null);
469                                             }
470                                             IContextActivation activation = contextServce.activateContext(context.getId());
471                                             activations[i] = activation;
472                                         }
473                                         fLaunchToContextActivations.put(launch, activations);
474                                     }
475                                 } catch (CoreException e) {
476                                     DebugUIPlugin.log(e);
477                                 }
478                             }
479                         }
480
481                     }
482                     if (window != null && DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW)) {
483                         ViewContextService service = ViewContextManager.getDefault().getService(window);
484                         service.showViewQuiet(IDebugUIConstants.ID_DEBUG_VIEW);
485                     }
486                 }
487                 finally
488                 {
489                     fPerspectiveSwitchLock.endSwitch();
490                 }
491             }
492         };
493         async(r);
494     }
495     
496     /**
497      * Returns the workbench window in which the given perspective
498      * should be shown. First, check the current window to see if it
499      * is already showing the perspective. Then check any other windows.
500      *
501      * @param perspectiveId the perspective identifier
502      * @return which window the given perspective should be shown in
503      * or <code>null</code> if there are no windows available
504      */

505     private IWorkbenchWindow getWindowForPerspective(String JavaDoc perspectiveId) {
506         IWorkbenchWindow window = DebugUIPlugin.getActiveWorkbenchWindow();
507         if (isWindowShowingPerspective(window, perspectiveId)) {
508             return window;
509         }
510         IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
511         for (int i = 0; i < windows.length; i++) {
512             window = windows[i];
513             if (isWindowShowingPerspective(window, perspectiveId)) {
514                 return window;
515             }
516         }
517         window = DebugUIPlugin.getActiveWorkbenchWindow();
518         if (window != null) {
519             return window;
520         }
521         if (windows.length > 0) {
522             return windows[0];
523         }
524         return null;
525     }
526     
527     /**
528      * Returns if the specified window is showing the perspective denoted by the specified id
529      * @param window the window to query
530      * @param perspectiveId the perspective to ask about
531      * @return true if the specified window is showing the perspective, false otherwise
532      */

533     private boolean isWindowShowingPerspective(IWorkbenchWindow window, String JavaDoc perspectiveId) {
534         if (window != null) {
535             IWorkbenchPage page = window.getActivePage();
536             if (page != null) {
537                 IPerspectiveDescriptor perspectiveDescriptor = page.getPerspective();
538                 if (perspectiveDescriptor != null && perspectiveDescriptor.getId().equals(perspectiveId)) {
539                     return true;
540                 }
541             }
542         }
543         return false;
544     }
545     
546     /**
547      * Returns whether or not the user wishes to switch to the specified
548      * perspective when a launch occurs.
549      *
550      * @param perspectiveName the name of the perspective that will be presented
551      * to the user for confirmation if they've asked to be prompted about
552      * perspective switching
553      * @param message a message to be presented to the user. This message is expected to
554      * contain a slot for the perspective name to be inserted ("{0}").
555      * @param preferenceKey the preference key of the perspective switching preference
556      * @return whether or not the user wishes to switch to the specified perspective
557      * automatically
558      */

559     private boolean shouldSwitchPerspective(IWorkbenchWindow window, String JavaDoc perspectiveId, String JavaDoc preferenceKey) {
560         if (isCurrentPerspective(window, perspectiveId)) {
561             return false;
562         }
563         String JavaDoc perspectiveName = getPerspectiveLabel(perspectiveId);
564         if (perspectiveName == null) {
565             return false;
566         }
567         String JavaDoc perspectiveDesc = getPerspectiveDescription(perspectiveId);
568         String JavaDoc[] args;
569         if (perspectiveDesc != null) {
570             args = new String JavaDoc[] { perspectiveName , perspectiveDesc };
571         }
572         else {
573             args = new String JavaDoc[] { perspectiveName };
574         }
575         String JavaDoc switchPerspective = DebugUIPlugin.getDefault().getPreferenceStore().getString(preferenceKey);
576         if (MessageDialogWithToggle.ALWAYS.equals(switchPerspective)) {
577             return true;
578         } else if (MessageDialogWithToggle.NEVER.equals(switchPerspective)) {
579             return false;
580         }
581         
582         Shell shell= window.getShell();
583         if (shell == null || fPrompting) {
584             return false;
585         }
586         fPrompting= true;
587         // Activate the shell if necessary so the prompt is visible
588
if (shell.getMinimized()) {
589             shell.setMinimized(false);
590         }
591         if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH)) {
592             shell.forceActive();
593         }
594         String JavaDoc message = ""; //$NON-NLS-1$
595
if(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND.equals(preferenceKey)) {
596             if (getPerspectiveDescription(perspectiveId) != null) {
597                 message = LaunchConfigurationsMessages.PerspectiveManager_suspend_description;
598             }
599             else {
600                 message = LaunchConfigurationsMessages.PerspectiveManager_13;
601             }
602         }
603         else if(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE.equals(preferenceKey)) {
604             if (getPerspectiveDescription(perspectiveId) != null) {
605                 message = LaunchConfigurationsMessages.PerspectiveManager_launch_description;
606             }
607             else {
608                 message = LaunchConfigurationsMessages.PerspectiveManager_15;
609             }
610         }
611         MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(shell, LaunchConfigurationsMessages.PerspectiveManager_12, MessageFormat.format(message, args), null, false, DebugUIPlugin.getDefault().getPreferenceStore(), preferenceKey);
612         boolean answer = (dialog.getReturnCode() == IDialogConstants.YES_ID);
613         synchronized (this) {
614             fPrompting= false;
615             notifyAll();
616         }
617         if (isCurrentPerspective(window, perspectiveId)) {
618             answer = false;
619         }
620         return answer;
621     }
622     
623     /**
624      * Returns whether the given perspective identifier matches the
625      * identifier of the current perspective.
626      *
627      * @param perspectiveId the identifier
628      * @return whether the given perspective identifier matches the
629      * identifier of the current perspective
630      */

631     protected boolean isCurrentPerspective(IWorkbenchWindow window, String JavaDoc perspectiveId) {
632         boolean isCurrent= false;
633         if (window != null) {
634             IWorkbenchPage page = window.getActivePage();
635             if (page != null) {
636                 IPerspectiveDescriptor perspectiveDescriptor = page.getPerspective();
637                 if (perspectiveDescriptor != null) {
638                     isCurrent= perspectiveId.equals(perspectiveDescriptor.getId());
639                 }
640             }
641         }
642         return isCurrent;
643     }
644     
645     /**
646      * Returns the label of the perspective with the given identifier or
647      * <code>null</code> if no such perspective exists.
648      *
649      * @param perspectiveId the identifier
650      * @return the label of the perspective with the given identifier or
651      * <code>null</code> if no such perspective exists
652      */

653     protected String JavaDoc getPerspectiveLabel(String JavaDoc perspectiveId) {
654         IPerspectiveDescriptor newPerspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);
655         if (newPerspective == null) {
656             return null;
657         }
658         return newPerspective.getLabel();
659     }
660
661     
662     /**
663      * Returns the label of the perspective with the given identifier or
664      * <code>null</code> if no such perspective exists.
665      *
666      * @param perspectiveId the identifier
667      * @return the label of the perspective with the given identifier or
668      * <code>null</code> if no such perspective exists
669      */

670     protected String JavaDoc getPerspectiveDescription(String JavaDoc perspectiveId) {
671         IPerspectiveDescriptor newPerspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);
672         if (newPerspective == null) {
673             return null;
674         }
675         return newPerspective.getDescription();
676     }
677     
678     /**
679      * Returns the perspective associated with the
680      * given launch, or <code>null</code> if none.
681      *
682      * @param launch a launch
683      * @return the perspective associated with the launch,
684      * or <code>null</code>
685      * @exception CoreException if unable to retrieve a required
686      * launch configuration attribute
687      */

688     protected String JavaDoc getPerspectiveId(ILaunch launch) throws CoreException {
689         if (launch == null) {
690             return null;
691         }
692         ILaunchConfiguration config = launch.getLaunchConfiguration();
693         if (config == null) {
694             return null;
695         }
696         Set JavaDoc modes = launch.getLaunchConfiguration().getModes();
697         modes.add(launch.getLaunchMode());
698         String JavaDoc perspectiveId = getLaunchPerspective(config.getType(), modes, resolveLaunchDelegate(launch));
699         if (perspectiveId != null && perspectiveId.equals(IDebugUIConstants.PERSPECTIVE_NONE)) {
700             perspectiveId = null;
701         }
702         return perspectiveId;
703     }
704     
705     /**
706      * Returns the id of the perspective associated with the given type and set of modes. Passing <code>null</code> for
707      * the launch delegate results in the default perspective id being returned (if there is one).
708      * @param type the type we are launching
709      * @param modes the set of modes the type was launched with
710      * @param delegate the delegate performing the launch for this type and modeset
711      * @return the id of the perspective for the given launch configuration type, modeset and launch delegate
712      *
713      * @since 3.3
714      */

715     public String JavaDoc getLaunchPerspective(ILaunchConfigurationType type, Set JavaDoc modes, ILaunchDelegate delegate) {
716         String JavaDoc id = null;
717         PerspectiveContext context = findContext(new PerspectiveContext(type, delegate, modes));
718         if(context == null || (context != null && !context.getPersepctiveMap().containsKey(modes))) {
719             //try with a null delegate, denoting the perspective for the type
720
context = findContext(new PerspectiveContext(type, null, modes));
721             if(context == null || (context != null && !context.getPersepctiveMap().containsKey(modes))) {
722                 //last resort, try the default perspective
723
return getDefaultLaunchPerspective(type, delegate, modes);
724             }
725         }
726         if(context != null) {
727             id = context.getPerspective(modes);
728         }
729         return id;
730     }
731     
732     /**
733      * Returns the perspective to switch to when a configuration of the given type
734      * is launched in the given mode, or <code>null</code> if no switch should take
735      * place.
736      * <p>
737      * This method is equivalent to calling <code>getLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate)</code>,
738      * with the 'mode' parameter comprising a single element set and passing <code>null</code> as the launch delegate.
739      * </p>
740      * @param type launch configuration type
741      * @param mode launch mode identifier
742      * @return perspective identifier or <code>null</code>
743      * @since 3.0
744      */

745     public String JavaDoc getLaunchPerspective(ILaunchConfigurationType type, String JavaDoc mode) {
746         HashSet JavaDoc modes = new HashSet JavaDoc();
747         modes.add(mode);
748         return getLaunchPerspective(type, modes, null);
749     }
750     
751     /**
752      * Sets the perspective to switch to when a configuration of the given type
753      * is launched in the given mode. <code>PERSPECTIVE_NONE</code> indicates no
754      * perspective switch should take place. <code>PERSPECTIVE_DEFAULT</code> indicates
755      * a default perspective switch should take place, as defined by the associated
756      * launch tab group extension.
757      * <p>
758      * Calling this method is equivalent to calling <code>setLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate, String perspectiveid)</code>,
759      * with the parameter 'mode' used in the set modes, and null passed as the delegate
760      * </p>
761      * @param type launch configuration type
762      * @param mode launch mode identifier
763      * @param perspective identifier, <code>PERSPECTIVE_NONE</code>, or
764      * <code>PERSPECTIVE_DEFAULT</code>
765      * @since 3.0
766      */

767     public void setLaunchPerspective(ILaunchConfigurationType type, String JavaDoc mode, String JavaDoc perspective) {
768         HashSet JavaDoc modes = new HashSet JavaDoc();
769         modes.add(mode);
770         setLaunchPerspective(type, modes, null, perspective);
771     }
772     
773     /**
774      * Sets the perspective that should be switched to when a configuration of the given type is launched with the
775      * specified modes set by the given launch delegate.
776      * <p>
777      * Passing <code>null</code> as a launch delegate will set the default perspective switch for that type and modeset, where
778      * <code>PERSPECTIVE_NONE</code> indicates no perspective switch should take place.
779      * </p>
780      * @param type the type to set a perspective context for
781      * @param modes the set of modes
782      * @param delegate the delegate, or <code>null</code> if the default perspective should be used
783      *
784      * @since 3.3
785      */

786     public void setLaunchPerspective(ILaunchConfigurationType type, Set JavaDoc modes, ILaunchDelegate delegate, String JavaDoc perspectiveid) {
787         PerspectiveContext context = new PerspectiveContext(type, delegate, modes);
788         String JavaDoc id = null;
789         if(!IDebugUIConstants.PERSPECTIVE_NONE.equals(perspectiveid)) {
790             if(IDebugUIConstants.PERSPECTIVE_DEFAULT.equals(perspectiveid)) {
791                 id = getDefaultLaunchPerspective(type, delegate, modes);
792             }
793             else {
794                 id = perspectiveid;
795             }
796         }
797         PerspectiveContext item = findContext(context);
798         if(item != null) {
799             item.setPerspective(modes, id);
800         }
801         else {
802             context.setPerspective(modes, id);
803             item = context;
804         }
805         fPerspectiveContexts.add(item);
806     }
807     
808     /**
809      * Searches the listing of perspective contexts to see if the specified one already exists
810      * @param context the context to compare
811      * @return the matching <code>PerspectiveContext</code> or <code>null</code> if none
812      *
813      * @since 3.3
814      */

815     private PerspectiveContext findContext(PerspectiveContext context) {
816         PerspectiveContext item = null;
817         Object JavaDoc o = null;
818         for(Iterator JavaDoc iter = fPerspectiveContexts.iterator(); iter.hasNext();) {
819             o = iter.next();
820             if(context.equals(o)) {
821                 item = (PerspectiveContext) o;
822                 return item;
823             }
824         }
825         return item;
826     }
827     
828     /**
829      * Generates XML for the user specified perspective settings.
830      *
831      * @return XML
832      * @exception IOException if unable to generate the XML
833      * @exception TransformerException if unable to generate the XML
834      * @exception ParserConfigurationException if unable to generate the XML
835      */

836     private String JavaDoc generatePerspectiveXML() throws ParserConfigurationException JavaDoc, TransformerException JavaDoc, IOException JavaDoc {
837         Document JavaDoc doc = DebugUIPlugin.getDocument();
838         Element JavaDoc root = doc.createElement(IConfigurationElementConstants.LAUNCH_PERSPECTIVES);
839         doc.appendChild(root);
840         PerspectiveContext context = null;
841         Map JavaDoc modesets = null;
842         Element JavaDoc element = null;
843         Set JavaDoc modes = null;
844         String JavaDoc id = null;
845         ILaunchDelegate delegate = null;
846         for(Iterator JavaDoc iter = fPerspectiveContexts.iterator(); iter.hasNext();) {
847             context = (PerspectiveContext) iter.next();
848             modesets = context.getPersepctiveMap();
849             for(Iterator JavaDoc iter2 = modesets.keySet().iterator(); iter2.hasNext();) {
850                 modes = (Set JavaDoc) iter2.next();
851                 id = context.getPerspective(modes);
852                 if(id != null) {
853                     element = doc.createElement(IConfigurationElementConstants.LAUNCH_PERSPECTIVE);
854                     element.setAttribute(IConfigurationElementConstants.MODE, createModesetString(modes));
855                     delegate = context.getLaunchDelegate();
856                     if(delegate != null) {
857                         element.setAttribute(ATTR_DELEGATE_ID, delegate.getId());
858                     }
859                     element.setAttribute(IConfigurationElementConstants.CONFIGURATION_TYPES, context.getLaunchConfigurationType().getIdentifier());
860                     element.setAttribute(IConfigurationElementConstants.PERSPECTIVE, id);
861                     root.appendChild(element);
862                 }
863             }
864             
865         }
866         return DebugUIPlugin.serializeDocument(doc);
867     }
868
869     /**
870      * Returns the default perspective to switch to when a configuration of the given
871      * type is launched in the given mode, or <code>null</code> if none.
872      *
873      * <p>
874      * Calling this method is equivalent to using the new method <code>getDefaultLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set modes)</code>
875      * with a null delegate and the specified mode comprising a set of one mode
876      * </p>
877      *
878      * @param type launch configuration type
879      * @param mode launch mode
880      * @return perspective identifier, or <code>null</code>
881      */

882     public String JavaDoc getDefaultLaunchPerspective(ILaunchConfigurationType type, String JavaDoc mode) {
883         HashSet JavaDoc modes = new HashSet JavaDoc();
884         modes.add(mode);
885         return getDefaultLaunchPerspective(type, null, modes);
886     }
887
888     /**
889      * Returns the default perspective to switch to when a configuration of the given type is launched by the specified
890      * launch delegate in the given mode set, or <code>null</code> if none
891      * @param type the type
892      * @param delegate the associated delegate, or <code>null</code> to specify that the default perspective id for that given type and mode set should be returned
893      * @param modes the set of modes this applies to
894      * @return the default perspective id for the given type, delegate and mode set combination, or <code>null</code> if none
895      *
896      * @since 3.3
897      */

898     public String JavaDoc getDefaultLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set JavaDoc modes) {
899         String JavaDoc id = null;
900         if(delegate != null) {
901             id = delegate.getPerspectiveId(modes);
902         }
903         if(id == null) {
904             LaunchConfigurationTabGroupExtension extension = LaunchConfigurationPresentationManager.getDefault().getExtension(type.getIdentifier(), modes);
905             if (extension != null) {
906                 id = extension.getPerspective(modes);
907                 if (id == null) {
908                     if (modes.contains(ILaunchManager.DEBUG_MODE)) {
909                         id = IDebugUIConstants.ID_DEBUG_PERSPECTIVE;
910                     }
911                 }
912             }
913         }
914         return id;
915     }
916     
917     /**
918      * Resolves the <code>ILaunchDelegate</code> from the given <code>ILaunch</code>
919      * @param launch the launch
920      * @return
921      * @throws CoreException
922      */

923     private ILaunchDelegate resolveLaunchDelegate(ILaunch launch) throws CoreException {
924         Set JavaDoc modes = launch.getLaunchConfiguration().getModes();
925         modes.add(launch.getLaunchMode());
926         ILaunchConfigurationType type = launch.getLaunchConfiguration().getType();
927         ILaunchDelegate[] delegates = LaunchConfigurationManager.filterLaunchDelegates(type, modes);
928         ILaunchDelegate delegate = null;
929         if(delegates.length == 1) {
930             delegate = delegates[0];
931         }
932         else if(delegates.length > 1) {
933             delegate = launch.getLaunchConfiguration().getPreferredDelegate(modes);
934             if(delegate == null) {
935                 delegate = type.getPreferredDelegate(modes);
936             }
937         }
938         return delegate;
939     }
940     
941     /**
942      * Initialize the preference set with settings from user preferences
943      */

944     private void initPerspectives() {
945         if(fPerspectiveContexts == null) {
946             fPerspectiveContexts = new HashSet JavaDoc();
947             String JavaDoc xml = DebugUIPlugin.getDefault().getPreferenceStore().getString(IInternalDebugUIConstants.PREF_LAUNCH_PERSPECTIVES);
948             if (xml != null && xml.length() > 0) {
949                 try {
950                     Element JavaDoc root = DebugPlugin.parseDocument(xml);
951                     NodeList JavaDoc list = root.getChildNodes();
952                     LaunchManager lm = (LaunchManager) DebugPlugin.getDefault().getLaunchManager();
953                     ILaunchConfigurationType lctype = null;
954                     ILaunchDelegate ldelegate = null;
955                     Set JavaDoc modes = null;
956                     Node JavaDoc node = null;
957                     Element JavaDoc element = null;
958                     for (int i = 0; i < list.getLength(); ++i) {
959                         node = list.item(i);
960                         if (node.getNodeType() == Node.ELEMENT_NODE) {
961                             element = (Element JavaDoc) node;
962                             String JavaDoc nodeName = element.getNodeName();
963                             if (nodeName.equalsIgnoreCase(IConfigurationElementConstants.LAUNCH_PERSPECTIVE)) {
964                                 String JavaDoc type = element.getAttribute(IConfigurationElementConstants.CONFIGURATION_TYPES);
965                                 String JavaDoc mode = element.getAttribute(IConfigurationElementConstants.MODE);
966                                 String JavaDoc perspective = element.getAttribute(IConfigurationElementConstants.PERSPECTIVE);
967                                 String JavaDoc delegate = element.getAttribute(ATTR_DELEGATE_ID);
968                                 lctype = lm.getLaunchConfigurationType(type);
969                                 ldelegate = lm.getLaunchDelegate(delegate);
970                                 modes = parseModes(mode);
971                                 if(lctype != null && !modes.isEmpty() && !"".equals(perspective)) { //$NON-NLS-1$
972
setLaunchPerspective(lctype, modes, ldelegate, perspective);
973                                 }
974                             }
975                         }
976                     }
977                 }
978                 catch (CoreException e) {DebugUIPlugin.log(e);}
979             }
980         }
981     }
982     
983     /**
984      * Parses a string argument into a set of modes
985      * @param modes the string to parse
986      * @return a set of modes parsed from the specified string of the empty set, never null
987      *
988      * @since 3.3
989      */

990     private Set JavaDoc parseModes(String JavaDoc modes) {
991         HashSet JavaDoc modeset = new HashSet JavaDoc();
992         String JavaDoc[] ms = modes.split(","); //$NON-NLS-1$
993
for(int i = 0; i < ms.length; i++) {
994             modeset.add(ms[i].trim());
995         }
996         return modeset;
997     }
998     
999     /**
1000     * Creates a standard comma separated list of the modes from the specified set
1001     * @param modes the set to write to string
1002     * @return the
1003     */

1004    private String JavaDoc createModesetString(Set JavaDoc modes) {
1005        String JavaDoc str = ""; //$NON-NLS-1$
1006
if(modes != null) {
1007            for(Iterator JavaDoc iter = modes.iterator(); iter.hasNext();) {
1008                str += iter.next();
1009                if(iter.hasNext()) {
1010                    str += ","; //$NON-NLS-1$
1011
}
1012            }
1013        }
1014        return str;
1015    }
1016    
1017    /**
1018     * Schedules the given job after perspective switching is complete, or
1019     * immediately if a perspective switch is not in progress.
1020     *
1021     * @param job job to run after perspective switching
1022     */

1023    public void schedulePostSwitch(Job job) {
1024        fPerspectiveSwitchLock.schedulePostSwitch(job);
1025    }
1026
1027    /* (non-Javadoc)
1028     * @see org.eclipse.debug.ui.contexts.ISuspendTriggerListener#suspended(org.eclipse.debug.core.ILaunch, java.lang.Object)
1029     */

1030    public void suspended(ILaunch launch, Object JavaDoc context) {
1031        handleBreakpointHit(launch);
1032    }
1033
1034    /**
1035     * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
1036     */

1037    public void doneSaving(ISaveContext context) {}
1038
1039    /**
1040     * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
1041     */

1042    public void prepareToSave(ISaveContext context) throws CoreException {}
1043
1044    /**
1045     * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
1046     */

1047    public void rollback(ISaveContext context) {}
1048
1049    /**
1050     * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
1051     */

1052    public void saving(ISaveContext context) throws CoreException {
1053        try {
1054            DebugUIPlugin.getDefault().getPreferenceStore().putValue(IInternalDebugUIConstants.PREF_LAUNCH_PERSPECTIVES, generatePerspectiveXML());
1055        }
1056        catch (IOException JavaDoc e) {DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception occurred while generating launch perspectives preference XML", e));} //$NON-NLS-1$
1057
catch (ParserConfigurationException JavaDoc e) {DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception occurred while generating launch perspectives preference XML", e));} //$NON-NLS-1$
1058
catch (TransformerException JavaDoc e) {DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception occurred while generating launch perspectives preference XML", e));} //$NON-NLS-1$
1059
}
1060}
1061
Popular Tags