KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > ObjectActionContributor


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.ui.internal;
12
13 import java.util.List JavaDoc;
14
15 import org.eclipse.core.expressions.EvaluationContext;
16 import org.eclipse.core.expressions.EvaluationResult;
17 import org.eclipse.core.expressions.Expression;
18 import org.eclipse.core.expressions.ExpressionConverter;
19 import org.eclipse.core.expressions.IEvaluationContext;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IAdaptable;
22 import org.eclipse.core.runtime.IConfigurationElement;
23 import org.eclipse.core.runtime.ISafeRunnable;
24 import org.eclipse.core.runtime.SafeRunner;
25 import org.eclipse.jface.action.IMenuManager;
26 import org.eclipse.jface.viewers.ISelection;
27 import org.eclipse.jface.viewers.ISelectionProvider;
28 import org.eclipse.jface.viewers.IStructuredSelection;
29 import org.eclipse.ui.IWorkbenchPart;
30 import org.eclipse.ui.SelectionEnabler;
31 import org.eclipse.ui.internal.misc.Policy;
32 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
33 import org.eclipse.ui.internal.util.Util;
34 import org.eclipse.ui.model.IWorkbenchAdapter;
35
36 /**
37  * This class describes the object contribution element within the popup menu
38  * action registry.
39  */

40 public class ObjectActionContributor extends PluginActionBuilder implements
41         IObjectActionContributor, IAdaptable {
42
43     private static final String JavaDoc P_TRUE = "true"; //$NON-NLS-1$
44

45     private IConfigurationElement config;
46
47     private boolean configRead = false;
48
49     private boolean adaptable = false;
50     
51     private String JavaDoc objectClass;
52
53     /**
54      * The constructor.
55      *
56      * @param config the element
57      */

58     public ObjectActionContributor(IConfigurationElement config) {
59         this.config = config;
60         this.adaptable = P_TRUE.equalsIgnoreCase(config
61                 .getAttribute(IWorkbenchRegistryConstants.ATT_ADAPTABLE));
62         this.objectClass = config.getAttribute(IWorkbenchRegistryConstants.ATT_OBJECTCLASS);
63     }
64
65     /* (non-Javadoc)
66      * Method declared on IObjectContributor.
67      */

68     public boolean canAdapt() {
69         return adaptable;
70     }
71     
72     /**
73      * Return the object class for this contributor.
74      *
75      * @return the object class
76      */

77     public String JavaDoc getObjectClass() {
78         return objectClass;
79     }
80
81     /* (non-Javadoc)
82      * Method declared on IObjectActionContributor.
83      */

84     public void contributeObjectActionIdOverrides(List JavaDoc actionIdOverrides) {
85         if (!configRead) {
86             readConfigElement();
87         }
88
89         // Easy case out if no actions
90
if (currentContribution.actions != null) {
91             for (int i = 0; i < currentContribution.actions.size(); i++) {
92                 ActionDescriptor ad = (ActionDescriptor) currentContribution.actions
93                         .get(i);
94                 String JavaDoc id = ad.getAction().getOverrideActionId();
95                 if (id != null) {
96                     actionIdOverrides.add(id);
97                 }
98             }
99         }
100     }
101
102     /**
103      * Contributes actions applicable for the current selection.
104      */

105     public boolean contributeObjectActions(final IWorkbenchPart part,
106             IMenuManager menu, ISelectionProvider selProv,
107             List JavaDoc actionIdOverrides) {
108         if (!configRead) {
109             readConfigElement();
110         }
111
112         // Easy case out if no actions
113
if (currentContribution.actions == null) {
114             return false;
115         }
116
117         // Get a structured selection.
118
ISelection sel = selProv.getSelection();
119         if ((sel == null) || !(sel instanceof IStructuredSelection)) {
120             return false;
121         }
122         IStructuredSelection ssel = (IStructuredSelection) sel;
123         
124         if(canAdapt()) {
125            IStructuredSelection newSelection = LegacyResourceSupport.adaptSelection(ssel, getObjectClass());
126            if(newSelection.size() != ssel.size()) {
127                if (Policy.DEBUG_CONTRIBUTIONS) {
128                 WorkbenchPlugin.log("Error adapting selection to " + getObjectClass() + //$NON-NLS-1$
129
". Contribution " + getID(config) + " is being ignored"); //$NON-NLS-1$ //$NON-NLS-2$
130
}
131                 return false;
132            }
133            ssel = newSelection;
134         }
135         
136         final IStructuredSelection selection = ssel;
137             
138         // Generate menu.
139
for (int i = 0; i < currentContribution.actions.size(); i++) {
140             ActionDescriptor ad = (ActionDescriptor) currentContribution.actions
141                     .get(i);
142             if (!actionIdOverrides.contains(ad.getId())) {
143                 currentContribution.contributeMenuAction(ad, menu, true);
144                 // Update action for the current selection and part.
145
if (ad.getAction() instanceof ObjectPluginAction) {
146                     final ObjectPluginAction action = (ObjectPluginAction) ad
147                             .getAction();
148                     ISafeRunnable runnable = new ISafeRunnable() {
149                         public void handleException(Throwable JavaDoc exception) {
150                             WorkbenchPlugin.log("Failed to update action " //$NON-NLS-1$
151
+ action.getId(), exception);
152                         }
153
154                         public void run() throws Exception JavaDoc {
155                             action.setActivePart(part);
156                             action.selectionChanged(selection);
157                         }
158                     };
159                     SafeRunner.run(runnable);
160                 }
161             }
162         }
163         return true;
164     }
165
166     /**
167      * Contributes menus applicable for the current selection.
168      */

169     public boolean contributeObjectMenus(IMenuManager menu,
170             ISelectionProvider selProv) {
171         if (!configRead) {
172             readConfigElement();
173         }
174
175         // Easy case out if no menus
176
if (currentContribution.menus == null) {
177             return false;
178         }
179
180         // Get a structured selection.
181
ISelection sel = selProv.getSelection();
182         if ((sel == null) || !(sel instanceof IStructuredSelection)) {
183             return false;
184         }
185
186         // Generate menu.
187
for (int i = 0; i < currentContribution.menus.size(); i++) {
188             IConfigurationElement menuElement = (IConfigurationElement) currentContribution.menus
189                     .get(i);
190             currentContribution.contributeMenu(menuElement, menu, true);
191         }
192         return true;
193     }
194
195     /* (non-Javadoc)
196      * Method declared on PluginActionBuilder.
197      */

198     protected ActionDescriptor createActionDescriptor(
199             IConfigurationElement element) {
200         return new ActionDescriptor(element, ActionDescriptor.T_POPUP);
201     }
202
203     /* (non-Javadoc)
204      * Method declared on PluginActionBuilder.
205      */

206     protected BasicContribution createContribution() {
207         return new ObjectContribution();
208     }
209
210     /**
211      * Returns true if name filter is not specified for the contribution
212      * or the current selection matches the filter.
213      */

214     public boolean isApplicableTo(Object JavaDoc object) {
215         if (!configRead) {
216             readConfigElement();
217         }
218
219         // Perform all tests with an instance of the objectClass and not
220
// the actual selected object.
221
if (canAdapt()) {
222             Object JavaDoc adapted = LegacyResourceSupport.getAdapter(object, getObjectClass());
223             if (adapted == null) {
224                 if (Policy.DEBUG_CONTRIBUTIONS) {
225                     WorkbenchPlugin
226                             .log("Error adapting " + object.getClass().getName() + //$NON-NLS-1$
227
" to " //$NON-NLS-1$
228
+ getObjectClass()
229                                     + ". Contribution " + getID(config) + " is being ignored"); //$NON-NLS-1$ //$NON-NLS-2$
230
}
231             } else {
232                 object = adapted;
233             }
234         }
235             
236         if (!testName(object)) {
237             return false;
238         }
239
240         return ((ObjectContribution) currentContribution)
241                 .isApplicableTo(object);
242     }
243
244     /**
245      * Reads the configuration element and all the children.
246      * This creates an action descriptor for every action in the extension.
247      */

248     private void readConfigElement() {
249         currentContribution = createContribution();
250         readElementChildren(config);
251         configRead = true;
252     }
253
254     /* (non-Javadoc)
255      * Method declared on PluginActionBuilder.
256      */

257     protected boolean readElement(IConfigurationElement element) {
258         String JavaDoc tag = element.getName();
259
260         // Found visibility sub-element
261
if (tag.equals(IWorkbenchRegistryConstants.TAG_VISIBILITY)) {
262             ((ObjectContribution) currentContribution)
263                     .setVisibilityTest(element);
264             return true;
265         }
266
267         // Found filter sub-element
268
if (tag.equals(IWorkbenchRegistryConstants.TAG_FILTER)) {
269             ((ObjectContribution) currentContribution).addFilterTest(element);
270             return true;
271         }
272
273         if (tag.equals(IWorkbenchRegistryConstants.TAG_ENABLEMENT)) {
274             ((ObjectContribution) currentContribution)
275                     .setEnablementTest(element);
276             return true;
277         }
278
279         return super.readElement(element);
280     }
281
282     /**
283      * Returns whether the current selection matches the contribution name filter.
284      */

285     private boolean testName(Object JavaDoc object) {
286         String JavaDoc nameFilter = config.getAttribute(IWorkbenchRegistryConstants.ATT_NAME_FILTER);
287         if (nameFilter == null) {
288             return true;
289         }
290         String JavaDoc objectName = null;
291         IWorkbenchAdapter de = (IWorkbenchAdapter)Util.getAdapter(object, IWorkbenchAdapter.class);
292         if (de != null) {
293             objectName = de.getLabel(object);
294         }
295         if (objectName == null) {
296             objectName = object.toString();
297         }
298         return SelectionEnabler.verifyNameMatch(objectName, nameFilter);
299     }
300
301     /**
302      * Helper class to collect the menus and actions defined within a
303      * contribution element.
304      */

305     private static class ObjectContribution extends BasicContribution {
306         private ObjectFilterTest filterTest;
307
308         private ActionExpression visibilityTest;
309
310         private Expression enablement;
311
312         /**
313          * Add a filter test.
314          *
315          * @param element the element
316          */

317         public void addFilterTest(IConfigurationElement element) {
318             if (filterTest == null) {
319                 filterTest = new ObjectFilterTest();
320             }
321             filterTest.addFilterElement(element);
322         }
323
324         /**
325          * Set the visibility test.
326          *
327          * @param element the element
328          */

329         public void setVisibilityTest(IConfigurationElement element) {
330             visibilityTest = new ActionExpression(element);
331         }
332
333         /**
334          * Set the enablement test.
335          *
336          * @param element the element
337          */

338         public void setEnablementTest(IConfigurationElement element) {
339             try {
340                 enablement = ExpressionConverter.getDefault().perform(element);
341             } catch (CoreException e) {
342                 WorkbenchPlugin.log(e);
343             }
344         }
345
346         /**
347          * Returns true if name filter is not specified for the contribution
348          * or the current selection matches the filter.
349          *
350          * @param object the object to test
351          * @return whether we're applicable
352          */

353         public boolean isApplicableTo(Object JavaDoc object) {
354             boolean result = true;
355             if (visibilityTest != null) {
356                 result = result && visibilityTest.isEnabledFor(object);
357                 if (!result) {
358                     return result;
359                 }
360             } else if (filterTest != null) {
361                 result = result && filterTest.matches(object, true);
362                 if (!result) {
363                     return result;
364                 }
365             }
366             if (enablement != null) {
367                 try {
368                     IEvaluationContext context = new EvaluationContext(null,
369                             object);
370                     context.setAllowPluginActivation(true);
371                     context.addVariable("selection", object); //$NON-NLS-1$
372
EvaluationResult evalResult = enablement.evaluate(context);
373                     if (evalResult == EvaluationResult.FALSE) {
374                         return false;
375                     }
376                 } catch (CoreException e) {
377                     enablement = null;
378                     WorkbenchPlugin.log(e);
379                     result = false;
380                 }
381             }
382             return result;
383         }
384     }
385     
386     /**
387      * Debugging helper that will print out the contribution names for this
388      * contributor.
389      */

390     public String JavaDoc toString() {
391         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
392         IConfigurationElement[] children = config.getChildren();
393         for (int i = 0; i < children.length; i++) {
394             IConfigurationElement element = children[i];
395             String JavaDoc label = element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
396             if(label != null) {
397                 buffer.append(label);
398                 buffer.append('\n');
399             }
400         }
401         return buffer.toString();
402     }
403
404     /* (non-Javadoc)
405      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
406      */

407     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
408         if (adapter.equals(IConfigurationElement.class)) {
409             return config;
410         }
411         return null;
412     }
413 }
414
Popular Tags