KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > contexts > DebugModelContextBindingManager


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Pawel Piech - Bug 154598: DebugModelContextBindingManager does not use IAdaptable.getAdapter() to retrieve IDebugModelProvider adapter
11  *******************************************************************************/

12 package org.eclipse.debug.internal.ui.contexts;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21 import java.util.regex.Pattern JavaDoc;
22
23 import org.eclipse.core.commands.common.NotDefinedException;
24 import org.eclipse.core.commands.contexts.Context;
25 import org.eclipse.core.runtime.IAdaptable;
26 import org.eclipse.core.runtime.IConfigurationElement;
27 import org.eclipse.core.runtime.IExtensionPoint;
28 import org.eclipse.core.runtime.Platform;
29 import org.eclipse.debug.core.DebugPlugin;
30 import org.eclipse.debug.core.ILaunch;
31 import org.eclipse.debug.core.ILaunchesListener2;
32 import org.eclipse.debug.core.model.IDebugElement;
33 import org.eclipse.debug.core.model.IDebugModelProvider;
34 import org.eclipse.debug.core.model.IStackFrame;
35 import org.eclipse.debug.internal.ui.DebugUIPlugin;
36 import org.eclipse.debug.ui.DebugUITools;
37 import org.eclipse.debug.ui.contexts.DebugContextEvent;
38 import org.eclipse.debug.ui.contexts.IDebugContextListener;
39 import org.eclipse.jface.viewers.ISelection;
40 import org.eclipse.jface.viewers.IStructuredSelection;
41 import org.eclipse.ui.PlatformUI;
42 import org.eclipse.ui.activities.ActivityManagerEvent;
43 import org.eclipse.ui.activities.IActivity;
44 import org.eclipse.ui.activities.IActivityManager;
45 import org.eclipse.ui.activities.IActivityManagerListener;
46 import org.eclipse.ui.activities.IActivityPatternBinding;
47 import org.eclipse.ui.activities.IWorkbenchActivitySupport;
48 import org.eclipse.ui.contexts.IContextActivation;
49 import org.eclipse.ui.contexts.IContextService;
50
51 /**
52  * Manages <code>debugModelContextBindings</code> extensions.
53  * <p>
54  * As debug contexts are activated, associated <code>org.eclipse.ui.contexts</code>
55  * are activated. When a debug session (launch) terminates, the associated contexts
56  * are disabled. Debug model activation also triggers assocaited activities.
57  * </p>
58  * @since 3.2
59  */

60 public class DebugModelContextBindingManager implements IDebugContextListener, ILaunchesListener2, IActivityManagerListener {
61     
62     /**
63      * Map of debug model identifier to associated contexts as defined
64      * by <code>debugModelContextBindings</code> extensions.
65      */

66     private Map JavaDoc fModelToContextIds = new HashMap JavaDoc();
67     
68     /**
69      * Map of launch objects to enabled model ids
70      */

71     private Map JavaDoc fLaunchToModelIds = new HashMap JavaDoc();
72     
73     /**
74      * Map of launch objects to context activations
75      */

76     private Map JavaDoc fLanuchToContextActivations = new HashMap JavaDoc();
77     
78     /**
79      * A list of activity pattern bindings for debug models.
80      */

81     private List JavaDoc fModelPatternBindings = new ArrayList JavaDoc();
82     
83     /**
84      * Map of debug model ids to assocaited activity ids.
85      */

86     private Map JavaDoc fModelToActivities = new HashMap JavaDoc();
87     
88     /**
89      * A set of debug model ids for which activities have been enabled.
90      * Cleared when enabled activities change.
91      */

92     private Set JavaDoc fModelsEnabledForActivities = new HashSet JavaDoc();
93     
94     // extension point
95
public static final String JavaDoc ID_DEBUG_MODEL_CONTEXT_BINDINGS= "debugModelContextBindings"; //$NON-NLS-1$
96

97     // extension point attributes
98
public static final String JavaDoc ATTR_CONTEXT_ID= "contextId"; //$NON-NLS-1$
99
public static final String JavaDoc ATTR_DEBUG_MODEL_ID= "debugModelId"; //$NON-NLS-1$
100

101     // base debug context
102
public static final String JavaDoc DEBUG_CONTEXT= "org.eclipse.debug.ui.debugging"; //$NON-NLS-1$
103

104     // suffix for debug activities triggered by debug model context binding activation
105
private static final String JavaDoc DEBUG_MODEL_ACTIVITY_SUFFIX = "/debugModel"; //$NON-NLS-1$
106

107     // singleton manager
108
private static DebugModelContextBindingManager fgManager;
109     
110     private static IContextService fgContextService = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
111     
112     public static DebugModelContextBindingManager getDefault() {
113         if (fgManager == null) {
114             fgManager = new DebugModelContextBindingManager();
115         }
116         return fgManager;
117     }
118     
119     private DebugModelContextBindingManager() {
120         loadDebugModelContextBindings();
121         loadDebugModelActivityExtensions();
122         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
123         DebugUITools.getDebugContextManager().addDebugContextListener(this);
124         IWorkbenchActivitySupport activitySupport = PlatformUI.getWorkbench().getActivitySupport();
125         activitySupport.getActivityManager().addActivityManagerListener(this);
126     }
127     
128     /**
129      * Loads the extensions which map debug model identifiers
130      * to context ids.
131      */

132     private void loadDebugModelContextBindings() {
133         IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), ID_DEBUG_MODEL_CONTEXT_BINDINGS);
134         IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
135         for (int i = 0; i < configurationElements.length; i++) {
136             IConfigurationElement element = configurationElements[i];
137             String JavaDoc modelIdentifier = element.getAttribute(ATTR_DEBUG_MODEL_ID);
138             String JavaDoc contextId = element.getAttribute(ATTR_CONTEXT_ID);
139             if (modelIdentifier != null && contextId != null) {
140                 List JavaDoc contextIds = (List JavaDoc) fModelToContextIds.get(modelIdentifier);
141                 if (contextIds == null) {
142                     contextIds = new ArrayList JavaDoc();
143                     fModelToContextIds.put(modelIdentifier, contextIds);
144                 }
145                 contextIds.add(contextId);
146             }
147         }
148     }
149     
150     /**
151      * Loads the extensions which map debug model patterns
152      * to activity ids. This information is used to activate the
153      * appropriate activities when a debug element is selected.
154      */

155     private void loadDebugModelActivityExtensions() {
156         IActivityManager activityManager = PlatformUI.getWorkbench().getActivitySupport().getActivityManager();
157         Set JavaDoc activityIds = activityManager.getDefinedActivityIds();
158         Iterator JavaDoc activityIterator = activityIds.iterator();
159         while (activityIterator.hasNext()) {
160             String JavaDoc activityId= (String JavaDoc) activityIterator.next();
161             IActivity activity = activityManager.getActivity(activityId);
162             if (activity != null) {
163                 Set JavaDoc patternBindings = activity.getActivityPatternBindings();
164                 Iterator JavaDoc patternIterator= patternBindings.iterator();
165                 while (patternIterator.hasNext()) {
166                     IActivityPatternBinding patternBinding= (IActivityPatternBinding) patternIterator.next();
167                     String JavaDoc pattern = patternBinding.getPattern().pattern();
168                     if (pattern.endsWith(DEBUG_MODEL_ACTIVITY_SUFFIX)) {
169                         fModelPatternBindings.add(patternBinding);
170                     }
171                 }
172             }
173         }
174     }
175
176     public void debugContextChanged(DebugContextEvent event) {
177         if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
178             ISelection selection = event.getContext();
179             if (selection instanceof IStructuredSelection) {
180                 IStructuredSelection ss = (IStructuredSelection) selection;
181                 Iterator JavaDoc iterator = ss.iterator();
182                 while (iterator.hasNext()) {
183                     activated(iterator.next());
184                 }
185             }
186         }
187     }
188     
189     /**
190      * The specified object has been activated. Activate contexts and activities as
191      * required for the object.
192      *
193      * @param object object that has been activated
194      */

195     private void activated(Object JavaDoc object) {
196         String JavaDoc[] modelIds = getDebugModelIds(object);
197         if (modelIds == null) {
198             return;
199         }
200         ILaunch launch = getLaunch(object);
201         if (launch == null) {
202             return;
203         }
204         Set JavaDoc alreadyEnabled = (Set JavaDoc) fLaunchToModelIds.get(launch);
205         if (alreadyEnabled == null) {
206             alreadyEnabled = new HashSet JavaDoc();
207             fLaunchToModelIds.put(launch, alreadyEnabled);
208         }
209         for (int i = 0; i < modelIds.length; i++) {
210             String JavaDoc id = modelIds[i];
211             if (!alreadyEnabled.contains(id)) {
212                 alreadyEnabled.add(id);
213                 activateModel(id, launch);
214             }
215         }
216         enableActivitiesFor(modelIds);
217     }
218     
219     /**
220      * Activates the given model identifier for the specified launch. This activates
221      * associated contexts and all parent contexts for the model.
222      *
223      * @param modelId model to be enabled
224      * @param launch the launch the model is being enabled for
225      */

226     private void activateModel(String JavaDoc modelId, ILaunch launch) {
227         List JavaDoc contextIds = (List JavaDoc) fModelToContextIds.get(modelId);
228         if (contextIds == null) {
229             // if there are no contexts for a model, the base debug context should
230
// be activated (i.e. a debug model with no org.eclipse.ui.contexts and
231
// associated org.eclipse.debug.ui.modelContextBindings)
232
contextIds = new ArrayList JavaDoc();
233             contextIds.add(DEBUG_CONTEXT);
234             fModelToContextIds.put(modelId, contextIds);
235         }
236         Iterator JavaDoc iterator = contextIds.iterator();
237         while (iterator.hasNext()) {
238             activateContext((String JavaDoc) iterator.next(), launch);
239         }
240     }
241     
242     /**
243      * Activates the given context and all its parent contexts.
244      *
245      * @param contextId
246      * @param launch
247      */

248     private void activateContext(String JavaDoc contextId, ILaunch launch) {
249         while (contextId != null) {
250             Context context = fgContextService.getContext(contextId);
251             IContextActivation activation = fgContextService.activateContext(contextId);
252             addActivation(launch, activation);
253             try {
254                 if (contextId.equals(DEBUG_CONTEXT)) {
255                     // don't enable windows contexts and higher
256
break;
257                 }
258                 contextId = context.getParentId();
259             } catch (NotDefinedException e) {
260                 contextId = null;
261                 DebugUIPlugin.log(e);
262             }
263         }
264     }
265     
266     /**
267      * Notes the activation for a context and launch so we can de-activate later.
268      *
269      * @param launch
270      * @param activation
271      */

272     private void addActivation(ILaunch launch, IContextActivation activation) {
273         List JavaDoc activations = (List JavaDoc) fLanuchToContextActivations.get(launch);
274         if (activations == null) {
275             activations = new ArrayList JavaDoc();
276             fLanuchToContextActivations.put(launch, activations);
277         }
278         activations.add(activation);
279     }
280
281     /**
282      * Returns the debug model identifiers associated with the given object or <code>null</code>
283      * if none.
284      *
285      * @param object
286      * @return debug model identifiers associated with the given object or <code>null</code>
287      */

288     private String JavaDoc[] getDebugModelIds(Object JavaDoc object) {
289         if (object instanceof IAdaptable) {
290             IDebugModelProvider modelProvider= (IDebugModelProvider)((IAdaptable)object).getAdapter(IDebugModelProvider.class);
291             if (modelProvider != null) {
292                 String JavaDoc[] modelIds= modelProvider.getModelIdentifiers();
293                 if (modelIds != null) {
294                     return modelIds;
295                 }
296             }
297         }
298         if (object instanceof IStackFrame) {
299             return new String JavaDoc[] { ((IStackFrame) object).getModelIdentifier() };
300         }
301         return null;
302     }
303     
304     /**
305      * Returns the ILaunch associated with the given object or
306      * <code>null</code> if none.
307      *
308      * @param object object for which launch is required
309      * @return the ILaunch associated with the given object or <code>null</code>
310      */

311     public static ILaunch getLaunch(Object JavaDoc object) {
312         ILaunch launch = null;
313         if (object instanceof IAdaptable) {
314             launch = (ILaunch) ((IAdaptable)object).getAdapter(ILaunch.class);
315         }
316         if (launch == null && object instanceof IDebugElement) {
317             launch = ((IDebugElement) object).getLaunch();
318         }
319         return launch;
320     }
321
322     /* (non-Javadoc)
323      * @see org.eclipse.debug.core.ILaunchesListener2#launchesTerminated(org.eclipse.debug.core.ILaunch[])
324      */

325     public void launchesTerminated(ILaunch[] launches) {
326         // disable activated contexts
327
for (int i = 0; i < launches.length; i++) {
328             ILaunch launch = launches[i];
329             final List JavaDoc activations = (List JavaDoc) fLanuchToContextActivations.remove(launch);
330             fLaunchToModelIds.remove(launch);
331             if (activations != null) {
332                 Runnable JavaDoc r = new Runnable JavaDoc() {
333                     public void run() {
334                         Iterator JavaDoc iterator = activations.iterator();
335                         while (iterator.hasNext()) {
336                             IContextActivation activation = (IContextActivation) iterator.next();
337                             activation.getContextService().deactivateContext(activation);
338                         }
339                     }
340                 };
341                 DebugUIPlugin.getStandardDisplay().asyncExec(r);
342             }
343             
344         }
345         // TODO: Terminated notification
346
}
347
348     /* (non-Javadoc)
349      * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch[])
350      */

351     public void launchesRemoved(ILaunch[] launches) {}
352
353     /* (non-Javadoc)
354      * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch[])
355      */

356     public void launchesAdded(ILaunch[] launches) {
357     }
358
359     /* (non-Javadoc)
360      * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch[])
361      */

362     public void launchesChanged(ILaunch[] launches) {
363     }
364     
365     /**
366      * Returns the workbench contexts associated with a debug context
367      *
368      * @param target debug context
369      * @return associated workbench contexts
370      */

371     public List JavaDoc getWorkbenchContextsForDebugContext(Object JavaDoc target) {
372         List JavaDoc workbenchContexts = new ArrayList JavaDoc();
373         String JavaDoc[] modelIds = getDebugModelIds(target);
374         if (modelIds != null) {
375             for (int i = 0; i < modelIds.length; i++) {
376                 String JavaDoc modelId = modelIds[i];
377                 List JavaDoc contextIds = (List JavaDoc) fModelToContextIds.get(modelId);
378                 if (contextIds != null) {
379                     Iterator JavaDoc contextIterator = contextIds.iterator();
380                     while (contextIterator.hasNext()) {
381                         String JavaDoc contextId = (String JavaDoc) contextIterator.next();
382                         if (!workbenchContexts.contains(contextId)) {
383                             workbenchContexts.add(contextId);
384                         }
385                     }
386                 }
387             }
388         }
389         return workbenchContexts;
390     }
391     
392     /**
393      * Enables activities in the workbench associated with the given debug
394      * model ids that have been activated.
395      *
396      * @param debug model ids for which to enable activities
397      */

398     private void enableActivitiesFor(String JavaDoc[] modelIds) {
399         Set JavaDoc activities = null;
400         for (int i = 0; i < modelIds.length; i++) {
401             String JavaDoc id = modelIds[i];
402             if (!fModelsEnabledForActivities.contains(id)) {
403                 Set JavaDoc ids= (Set JavaDoc) fModelToActivities.get(id);
404                 if (ids == null) {
405                     // first time the model has been seen, perform pattern matching
406
ids = new HashSet JavaDoc();
407                     fModelToActivities.put(id, ids);
408                     Iterator JavaDoc bindings = fModelPatternBindings.iterator();
409                     while (bindings.hasNext()) {
410                         IActivityPatternBinding binding = (IActivityPatternBinding) bindings.next();
411                         String JavaDoc regex = binding.getPattern().pattern();
412                         regex = regex.substring(0, regex.length() - DEBUG_MODEL_ACTIVITY_SUFFIX.length());
413                         if (Pattern.matches(regex, id)) {
414                             ids.add(binding.getActivityId());
415                         }
416                     }
417                 }
418                 if (!ids.isEmpty()) {
419                     if (activities == null) {
420                         activities = new HashSet JavaDoc();
421                     }
422                     activities.addAll(ids);
423                 }
424                 fModelsEnabledForActivities.add(id);
425             }
426         }
427         if (activities != null) {
428             IWorkbenchActivitySupport activitySupport = PlatformUI.getWorkbench().getActivitySupport();
429             Set JavaDoc enabledActivityIds = activitySupport.getActivityManager().getEnabledActivityIds();
430             if (!enabledActivityIds.containsAll(activities)) {
431                 enabledActivityIds = new HashSet JavaDoc(enabledActivityIds);
432                 enabledActivityIds.addAll(activities);
433                 activitySupport.setEnabledActivityIds(activities);
434             }
435         }
436     }
437
438     /* (non-Javadoc)
439      * @see org.eclipse.ui.activities.IActivityManagerListener#activityManagerChanged(org.eclipse.ui.activities.ActivityManagerEvent)
440      */

441     public void activityManagerChanged(ActivityManagerEvent activityManagerEvent) {
442         if (activityManagerEvent.haveEnabledActivityIdsChanged()) {
443             fModelsEnabledForActivities.clear();
444         }
445     }
446
447 }
448
Popular Tags