KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > actions > CommonActionDescriptorManager


1 /*******************************************************************************
2  * Copyright (c) 2005, 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  *******************************************************************************/

11 package org.eclipse.ui.internal.navigator.actions;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.LinkedHashMap JavaDoc;
18 import java.util.LinkedHashSet JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21
22 import org.eclipse.core.runtime.Assert;
23 import org.eclipse.core.runtime.IConfigurationElement;
24 import org.eclipse.core.runtime.ISafeRunnable;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.SafeRunner;
27 import org.eclipse.jface.viewers.IStructuredSelection;
28 import org.eclipse.jface.viewers.StructuredSelection;
29 import org.eclipse.ui.actions.ActionContext;
30 import org.eclipse.ui.internal.navigator.NavigatorPlugin;
31 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentRegistryReader;
32 import org.eclipse.ui.navigator.INavigatorContentService;
33 import org.eclipse.ui.navigator.Priority;
34
35 /**
36  * Manages descriptors consumed from the 'actionProvider' elements of the
37  * <b>org.eclipse.ui.navigator.navigatorContent</b> extension point.
38  *
39  * @since 3.2
40  *
41  */

42 public class CommonActionDescriptorManager {
43
44     private static final CommonActionProviderDescriptor[] NO_DESCRIPTORS = new CommonActionProviderDescriptor[0];
45
46     private static final CommonActionDescriptorManager INSTANCE = new CommonActionDescriptorManager();
47
48     private CommonActionDescriptorManager() {
49
50         new ActionProviderRegistry().readRegistry();
51     }
52
53     /**
54      * @return the singleton instance of the registry
55      */

56     public static CommonActionDescriptorManager getInstance() {
57         return INSTANCE;
58     }
59
60     /* Provides a map of (ids, CommonActionProviderDescriptor)-pairs. */
61     private final Map JavaDoc dependentDescriptors = new LinkedHashMap JavaDoc();
62
63     /* Provides a map of (ids, CommonActionProviderDescriptor)-pairs. */
64     private final Set JavaDoc overridingDescriptors = new LinkedHashSet JavaDoc();
65
66     /* Provides a map of (ids, CommonActionProviderDescriptor)-pairs. */
67     private final Map JavaDoc rootDescriptors = new LinkedHashMap JavaDoc();
68
69     /**
70      *
71      * @param aDescriptor
72      * A valid descriptor to begin managing.
73      */

74     protected void addActionDescriptor(
75             CommonActionProviderDescriptor aDescriptor) {
76
77         if (aDescriptor.getDependsOnId() == null) {
78             rootDescriptors.put(aDescriptor.getDefinedId(), aDescriptor);
79         } else {
80             dependentDescriptors.put(aDescriptor.getDefinedId(), aDescriptor);
81         }
82
83         if (aDescriptor.getOverridesId() != null) {
84             overridingDescriptors.add(aDescriptor);
85         }
86     }
87
88     /**
89      * Orders the set of availabe descriptors based on the order defined by the
90      * <i>dependsOn</i> attribute from the <actionProvider /> element in
91      * <b>org.eclipse.ui.navigator.navigatorContent</b>
92      *
93      */

94     protected void computeOrdering() {
95         CommonActionProviderDescriptor dependentDescriptor;
96         CommonActionProviderDescriptor requiredDescriptor;
97
98         CommonActionProviderDescriptor descriptor;
99         CommonActionProviderDescriptor overriddenDescriptor;
100         for (Iterator JavaDoc iter = overridingDescriptors.iterator(); iter.hasNext();) {
101             descriptor = (CommonActionProviderDescriptor) iter.next();
102             if (rootDescriptors.containsKey(descriptor.getOverridesId())) {
103                 overriddenDescriptor = (CommonActionProviderDescriptor) rootDescriptors
104                         .get(descriptor.getOverridesId());
105                 overriddenDescriptor.addOverridingDescriptor(descriptor);
106             } else if (dependentDescriptors.containsKey(descriptor
107                     .getOverridesId())) {
108                 overriddenDescriptor = (CommonActionProviderDescriptor) dependentDescriptors
109                         .get(descriptor.getOverridesId());
110                 overriddenDescriptor.addOverridingDescriptor(descriptor);
111             }
112
113         }
114
115         Collection JavaDoc unresolvedDependentDescriptors = new ArrayList JavaDoc(
116                 dependentDescriptors.values());
117
118         for (Iterator JavaDoc iter = dependentDescriptors.values().iterator(); iter
119                 .hasNext();) {
120             dependentDescriptor = (CommonActionProviderDescriptor) iter.next();
121             requiredDescriptor = (CommonActionProviderDescriptor) rootDescriptors
122                     .get(dependentDescriptor.getDependsOnId());
123             if (requiredDescriptor == null) {
124                 requiredDescriptor = (CommonActionProviderDescriptor) dependentDescriptors
125                         .get(dependentDescriptor.getDependsOnId());
126             }
127             if (requiredDescriptor != null) {
128                 requiredDescriptor.addDependentDescriptor(dependentDescriptor);
129                 unresolvedDependentDescriptors.remove(dependentDescriptor);
130             }
131
132         }
133
134         dependentDescriptors.clear();
135
136         if (!unresolvedDependentDescriptors.isEmpty()) {
137             StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc(
138                     "There were unresolved dependencies for action provider extensions to a Common Navigator.\n" + //$NON-NLS-1$
139
"Verify that the \"dependsOn\" attribute for each <actionProvider /> element is valid."); //$NON-NLS-1$
140

141             CommonActionProviderDescriptor[] unresolvedDescriptors = (CommonActionProviderDescriptor[]) unresolvedDependentDescriptors
142                     .toArray(new CommonActionProviderDescriptor[unresolvedDependentDescriptors
143                             .size()]);
144             for (int i = 0; i < unresolvedDescriptors.length; i++) {
145                 errorMessage
146                         .append(
147                                 "\nUnresolved dependency specified for actionProvider: ").append(unresolvedDescriptors[i].getDefinedId()); //$NON-NLS-1$
148
}
149
150             NavigatorPlugin.log(IStatus.WARNING, 0, errorMessage.toString(),
151                     null);
152
153         }
154         unresolvedDependentDescriptors.clear();
155
156     }
157
158     /**
159      *
160      * @param aContentService
161      * The content service to use when filtering action providers;
162      * only action providers bound directly or indirectly will be
163      * returned.
164      * @param aContext
165      * The action context that contains a valid selection.
166      * @return An array of visible, active, and enabled CommonActionProviders.
167      * See <b>org.eclipse.ui.navigator.navigatorContent</b> for the
168      * details of what each of these adjectives implies.
169      */

170     public CommonActionProviderDescriptor[] findRelevantActionDescriptors(
171             INavigatorContentService aContentService, ActionContext aContext) {
172         Assert.isNotNull(aContext);
173         IStructuredSelection structuredSelection = null;
174         if (aContext.getSelection() instanceof IStructuredSelection) {
175             structuredSelection = (IStructuredSelection) aContext
176                     .getSelection();
177         } else {
178             structuredSelection = StructuredSelection.EMPTY;
179         }
180
181         Set JavaDoc blockedProviders = new HashSet JavaDoc();
182         CommonActionProviderDescriptor actionDescriptor = null;
183         Set JavaDoc providers = new LinkedHashSet JavaDoc();
184         for (Iterator JavaDoc providerItr = rootDescriptors.values().iterator(); providerItr
185                 .hasNext();) {
186             actionDescriptor = (CommonActionProviderDescriptor) providerItr
187                     .next();
188             addProviderIfRelevant(aContentService, structuredSelection,
189                     actionDescriptor, providers, blockedProviders);
190         }
191         if (providers.size() > 0) {
192             providers.removeAll(blockedProviders);
193             return (CommonActionProviderDescriptor[]) providers
194                     .toArray(new CommonActionProviderDescriptor[providers
195                             .size()]);
196         }
197         return NO_DESCRIPTORS;
198     }
199
200     /**
201      * @param aContentService
202      * @param structuredSelection
203      * @param actionDescriptor
204      * @param providers
205      */

206     private boolean addProviderIfRelevant(
207             INavigatorContentService aContentService,
208             IStructuredSelection structuredSelection,
209             CommonActionProviderDescriptor actionDescriptor, Set JavaDoc providers, Set JavaDoc blockedProviders) {
210         if (isVisible(aContentService, actionDescriptor)
211                 && actionDescriptor.isEnabledFor(structuredSelection)) {
212             
213             if(actionDescriptor.hasOverridingDescriptors()) {
214                 for (Iterator JavaDoc iter = actionDescriptor.overridingDescriptors(); iter.hasNext();) {
215                     CommonActionProviderDescriptor descriptor = (CommonActionProviderDescriptor) iter.next();
216                     if(addProviderIfRelevant(aContentService, structuredSelection, descriptor, providers, blockedProviders)) {
217                         while(iter.hasNext())
218                             blockedProviders.add(iter.next());
219                         return true;
220                     }
221                     
222                 }
223             }
224             providers.add(actionDescriptor);
225             if (actionDescriptor.hasDependentDescriptors()) {
226                 for (Iterator JavaDoc iter = actionDescriptor.dependentDescriptors(); iter
227                         .hasNext();) {
228                     addProviderIfRelevant(aContentService, structuredSelection,
229                             (CommonActionProviderDescriptor) iter.next(),
230                             providers, blockedProviders);
231                 }
232             }
233             return true;
234         }
235         return false;
236     }
237
238     private boolean isVisible(INavigatorContentService aContentService,
239             CommonActionProviderDescriptor descriptor) {
240         if (descriptor.isNested()) {
241             return aContentService.isActive(descriptor.getId())
242                     && aContentService.isVisible(descriptor.getId());
243         }
244         return aContentService.getViewerDescriptor().isVisibleActionExtension(
245                 descriptor.getId());
246     }
247
248     private class ActionProviderRegistry extends NavigatorContentRegistryReader {
249
250         public void readRegistry() {
251             super.readRegistry();
252             computeOrdering();
253         }
254
255         protected boolean readElement(IConfigurationElement anElement) {
256             if (TAG_ACTION_PROVIDER.equals(anElement.getName())) {
257                 addActionDescriptor(new CommonActionProviderDescriptor(
258                         anElement));
259                 return true;
260             } else if (TAG_NAVIGATOR_CONTENT.equals(anElement.getName())) {
261                 
262                 IConfigurationElement[] actionProviders = anElement.getChildren(TAG_ACTION_PROVIDER);
263                 
264                 if (actionProviders.length > 0) {
265                     
266                     IConfigurationElement defaultEnablement = null;
267                     IConfigurationElement[] inheritedEnablement = anElement.getChildren(TAG_ENABLEMENT);
268                     if (inheritedEnablement.length == 0) {
269                         inheritedEnablement = anElement.getChildren(TAG_POSSIBLE_CHILDREN);
270                     }
271                     
272                     defaultEnablement = inheritedEnablement.length == 1 ? inheritedEnablement[0] : null;
273   
274                     Priority defaultPriority = Priority.get(anElement.getAttribute(ATT_PRIORITY));
275                     
276                     
277                     if(defaultEnablement == null) {
278                         NavigatorPlugin.logError(0,
279                             "An actionProvider has been defined as the child " + //$NON-NLS-1$
280
"of a navigatorContent extension that does not specify " + //$NON-NLS-1$
281
"an <enablement/> or <possibleChildren /> expression. Please " + //$NON-NLS-1$
282
"review the documenation and correct this error.", null); //$NON-NLS-1$
283
}
284                     for (int i = 0; i < actionProviders.length; i++) {
285                         if(defaultEnablement == null) {
286                             NavigatorPlugin.logError(0,
287                                             "Disabling actionProvider: " + actionProviders[i].getAttribute(ATT_ID), null); //$NON-NLS-1$
288
} else {
289                             SafeRunner.run(new AddProviderSafeRunner(actionProviders[i], defaultEnablement, defaultPriority, anElement));
290                         }
291                     }
292                 }
293                 return true;
294             }
295             return super.readElement(anElement);
296         }
297     
298         private class AddProviderSafeRunner implements ISafeRunnable {
299             
300             private IConfigurationElement parentElement;
301             private IConfigurationElement defaultEnablement;
302             private IConfigurationElement actionProvider;
303             private Priority defaultPriority;
304
305             protected AddProviderSafeRunner(IConfigurationElement actionProvider,
306                                              IConfigurationElement defaultEnablement,
307                                              Priority defaultPriority,
308                                              IConfigurationElement parentElement) {
309                 this.actionProvider = actionProvider;
310                 this.defaultEnablement = defaultEnablement;
311                 this.defaultPriority = defaultPriority;
312                 this.parentElement = parentElement;
313             }
314             
315             /* (non-Javadoc)
316              * @see org.eclipse.core.runtime.ISafeRunnable#run()
317              */

318             public void run() throws Exception JavaDoc {
319                 addActionDescriptor(new CommonActionProviderDescriptor(
320                             actionProvider, defaultEnablement, defaultPriority, parentElement
321                                     .getAttribute(ATT_ID), true));
322             }
323             
324             /* (non-Javadoc)
325              * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
326              */

327             public void handleException(Throwable JavaDoc t) {
328                 NavigatorPlugin.logError(0, "Recovering from error while parsing actionProviders.", t); //$NON-NLS-1$
329
}
330             
331             
332         }
333     }
334
335
336 }
337
Popular Tags