KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > navigator > NavigatorActionService


1 /*******************************************************************************
2  * Copyright (c) 2003, 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.navigator;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.core.runtime.ISafeRunnable;
21 import org.eclipse.core.runtime.SafeRunner;
22 import org.eclipse.jface.action.GroupMarker;
23 import org.eclipse.jface.action.IContributionItem;
24 import org.eclipse.jface.action.IMenuManager;
25 import org.eclipse.jface.action.MenuManager;
26 import org.eclipse.jface.action.Separator;
27 import org.eclipse.jface.viewers.ISelectionProvider;
28 import org.eclipse.jface.viewers.StructuredSelection;
29 import org.eclipse.jface.viewers.StructuredViewer;
30 import org.eclipse.ui.IActionBars;
31 import org.eclipse.ui.IMemento;
32 import org.eclipse.ui.actions.ActionContext;
33 import org.eclipse.ui.actions.ActionGroup;
34 import org.eclipse.ui.internal.navigator.NavigatorContentService;
35 import org.eclipse.ui.internal.navigator.NavigatorPlugin;
36 import org.eclipse.ui.internal.navigator.actions.CommonActionDescriptorManager;
37 import org.eclipse.ui.internal.navigator.actions.CommonActionProviderDescriptor;
38 import org.eclipse.ui.internal.navigator.extensions.CommonActionExtensionSite;
39 import org.eclipse.ui.internal.navigator.extensions.SkeletonActionProvider;
40
41 /**
42  * <p>
43  * Provides context menu items and {@link IActionBars} contributions for a particular abstract
44  * viewer. The interface matches that of {@link ActionGroup} and may be used in the same manner.
45  * Clients must call
46  * {@link NavigatorActionService#prepareMenuForPlatformContributions(MenuManager, ISelectionProvider, boolean)}
47  * when using this class to allow object or viewer contributions. The
48  * <b>org.eclipse.ui.navigator.viewer/viewer/popupMenu</b> element may override whether platform
49  * contributions are allowed to the menu with its <i>allowsPlatformContributions</i> attribute.
50  * "Platform Contributions" are menu items that are added through the <b>org.eclipse.ui.popupMenus</b>
51  * extension point.
52  * </p>
53  * <p>
54  * A {@link CommonActionProvider} has opportunities to contribute to the context menu and
55  * {@link org.eclipse.ui.IActionBars} whenever the selection in the viewer changes. Action Providers
56  * are selected based on the enablement expressions of their associated content extension or their
57  * own enablement expression if it is declared as a top-level &lt;actionProvider /&gt; element (of
58  * the <b>org.eclipse.ui.navigator.navigatorContent</b> extension point). See the schema
59  * documentation of <b>org.eclipse.ui.navigator.navigatorContent</b> for more information on how to
60  * specify an Action Provider.
61  * </p>
62  * <p>
63  * Clients that reuse this service outside of an instance of {@link CommonNavigator} must be sure
64  * that {{@link #fillActionBars(IActionBars)} is called whenever the selection changes. The
65  * retargetable actions for each selection could change, based on who contributed the items.
66  *
67  * @since 3.2
68  *
69  */

70 public final class NavigatorActionService extends ActionGroup implements IMementoAware {
71
72     private static final IContributionItem[] DEFAULT_GROUPS = new IContributionItem[]{new Separator(ICommonMenuConstants.GROUP_NEW), new GroupMarker(ICommonMenuConstants.GROUP_GOTO), new GroupMarker(ICommonMenuConstants.GROUP_OPEN), new GroupMarker(ICommonMenuConstants.GROUP_OPEN_WITH), new Separator(ICommonMenuConstants.GROUP_EDIT), new GroupMarker(ICommonMenuConstants.GROUP_SHOW), new GroupMarker(ICommonMenuConstants.GROUP_REORGANIZE), new GroupMarker(ICommonMenuConstants.GROUP_PORT), new Separator(ICommonMenuConstants.GROUP_GENERATE), new Separator(ICommonMenuConstants.GROUP_SEARCH), new Separator(ICommonMenuConstants.GROUP_BUILD), new Separator(ICommonMenuConstants.GROUP_ADDITIONS), new Separator(ICommonMenuConstants.GROUP_PROPERTIES)};
73
74     private final ICommonViewerSite commonViewerSite;
75
76     private final StructuredViewer structuredViewer;
77
78     private final NavigatorContentService contentService;
79
80     private final INavigatorViewerDescriptor viewerDescriptor;
81
82     private final Set JavaDoc actionProviderDescriptors = new HashSet JavaDoc();
83
84     /*
85      * Map of CommonActionProviderDescriptors to CommonActionProviders
86      */

87     private final Map JavaDoc actionProviderInstances = new HashMap JavaDoc();
88
89     private IMemento memento;
90
91     private IContributionItem[] menuGroups;
92
93     private boolean disposed = false;
94
95     /**
96      * @param aCommonViewerSite
97      * A site that provides information about the context for extensions.
98      * @param aStructuredViewer
99      * The associated StructuredViewer. Used to initialize extensions. <b>May NOT be
100      * null.</b>
101      * @param aContentService
102      * The associated INavigatorContentService (for extensions that coordinate behavior
103      * with content extensions -- either nested or top-level action providers). <b>May
104      * NOT be null.</b>
105      */

106     public NavigatorActionService(ICommonViewerSite aCommonViewerSite, StructuredViewer aStructuredViewer, INavigatorContentService aContentService) {
107         super();
108         Assert.isNotNull(aCommonViewerSite);
109         Assert.isNotNull(aStructuredViewer);
110         Assert.isNotNull(aContentService);
111
112         commonViewerSite = aCommonViewerSite;
113         contentService = (NavigatorContentService) aContentService;
114         structuredViewer = aStructuredViewer;
115         viewerDescriptor = contentService.getViewerDescriptor();
116
117     }
118
119     /**
120      * Prepares the menu for object contributions, if the option is set in the extension. The option
121      * is controlled by the &lgt;popupMenu /&gt; element's 'allowPlatformContributions' attribute.
122      * Clients may choose to ignore this setting by supplying a value of <b>true</b> for the
123      * <code>force</code> attribute.
124      *
125      * @param menu
126      * The context menu of the IViewPart
127      * @param aSelectionProvider
128      * The selection provider that will supplement actions with a valid, current
129      * selection.
130      * @param force
131      * A value of 'true' forces the menu to be registered for object/view contributions.
132      * Otherwise, the option from the extension point will be respected. See
133      * <b>org.eclipse.ui.navigator.viewer/viewer</b> for more information.
134      */

135     public void prepareMenuForPlatformContributions(MenuManager menu, ISelectionProvider aSelectionProvider, boolean force) {
136         Assert.isTrue(!disposed);
137
138         if (commonViewerSite instanceof ICommonViewerWorkbenchSite) {
139             /*
140              * Hooks into the Eclipse framework for Object contributions, and View contributions.
141              */

142             if (force || viewerDescriptor.allowsPlatformContributionsToContextMenu()) {
143                 ((ICommonViewerWorkbenchSite) commonViewerSite).registerContextMenu(contentService.getViewerDescriptor().getPopupMenuId(), menu, aSelectionProvider);
144             }
145         }
146     }
147
148     /**
149      * Requests that the service invoke extensions to fill the given menu with Action Providers that
150      * are interested in elements from the given selection.
151      *
152      * <p>
153      * Object contributions (see <b>org.eclipes.ui.popupMenus</b>) may also respected by this
154      * method if <code>toRespectObjectContributions</code> is true.
155      * </p>
156      *
157      * @param aMenu
158      * The menu being presented to the user.
159      * @see ActionGroup#fillContextMenu(IMenuManager)
160      */

161     public void fillContextMenu(IMenuManager aMenu) {
162         Assert.isTrue(!disposed);
163
164         if (menuGroups == null) {
165             createMenuGroups();
166         }
167
168         for (int i = 0; i < menuGroups.length; i++) {
169             aMenu.add(menuGroups[i]);
170         }
171
172         addCommonActionProviderMenu(aMenu);
173
174     }
175
176     private void createMenuGroups() {
177         MenuInsertionPoint[] customPoints = viewerDescriptor.getCustomInsertionPoints();
178
179         if (customPoints == null) {
180             menuGroups = DEFAULT_GROUPS;
181         } else {
182             menuGroups = new IContributionItem[customPoints.length];
183             for (int i = 0; i < customPoints.length; i++) {
184                 if (customPoints[i].isSeparator()) {
185                     menuGroups[i] = new Separator(customPoints[i].getName());
186                 } else {
187                     menuGroups[i] = new GroupMarker(customPoints[i].getName());
188                 }
189             }
190         }
191     }
192
193     /**
194      * @param aMenu
195      */

196     private void addCommonActionProviderMenu(IMenuManager aMenu) {
197
198         CommonActionProviderDescriptor[] providerDescriptors = CommonActionDescriptorManager.getInstance().findRelevantActionDescriptors(contentService, getContext());
199         if (providerDescriptors.length > 0) {
200             CommonActionProvider provider = null;
201             for (int i = 0; i < providerDescriptors.length; i++) {
202                 try {
203                     provider = getActionProviderInstance(providerDescriptors[i]);
204                     provider.setContext(getContext());
205                     provider.fillContextMenu(aMenu);
206                 } catch (Throwable JavaDoc t) {
207                     NavigatorPlugin.logError(0, t.getMessage(), t);
208                 }
209             }
210         }
211     }
212
213     /**
214      * Request that the service invoke extensions to fill the given IActionBars with retargetable
215      * actions or view menu contributions from Action Providers that are interested in the given
216      * selection.
217      *
218      * @param theActionBars
219      * The action bars in use by the current view site.
220      * @see ActionGroup#fillActionBars(IActionBars)
221      */

222     public void fillActionBars(IActionBars theActionBars) {
223         Assert.isTrue(!disposed);
224
225         theActionBars.clearGlobalActionHandlers();
226         ActionContext context = getContext();
227         if (context == null) {
228             context = new ActionContext(StructuredSelection.EMPTY);
229         }
230
231         CommonActionProviderDescriptor[] providerDescriptors = CommonActionDescriptorManager.getInstance().findRelevantActionDescriptors(contentService, context);
232         if (providerDescriptors.length > 0) {
233             CommonActionProvider provider = null;
234             for (int i = 0; i < providerDescriptors.length; i++) {
235                 try {
236                     provider = getActionProviderInstance(providerDescriptors[i]);
237                     if(provider != null) {
238                         provider.setContext(context);
239                         provider.fillActionBars(theActionBars);
240                         provider.updateActionBars();
241                     }
242
243                 } catch (RuntimeException JavaDoc e) {
244                     NavigatorPlugin.logError(0, e.getMessage(), e);
245                 }
246             }
247         }
248         theActionBars.updateActionBars();
249         theActionBars.getMenuManager().update();
250     }
251
252     /**
253      * Dispose of any state or resources held by the service.
254      *
255      * @see ActionGroup#dispose()
256      */

257     public void dispose() {
258         synchronized (actionProviderInstances) {
259             for (Iterator JavaDoc iter = actionProviderInstances.values().iterator(); iter.hasNext();) {
260                 CommonActionProvider element = (CommonActionProvider) iter.next();
261                 element.dispose();
262             }
263             actionProviderInstances.clear();
264         }
265         actionProviderDescriptors.clear();
266         disposed = false;
267     }
268
269     /**
270      * Use the given memento to restore the state of each Action Provider as it is initialized.
271      *
272      * @param aMemento
273      * The memento retrieved from the dialog settings
274      */

275     public void restoreState(IMemento aMemento) {
276         Assert.isTrue(!disposed);
277         memento = aMemento;
278
279         synchronized (actionProviderInstances) {
280             for (Iterator JavaDoc actionProviderIterator = actionProviderInstances.values().iterator(); actionProviderIterator.hasNext();) {
281                 final CommonActionProvider provider = (CommonActionProvider) actionProviderIterator.next();
282                 ISafeRunnable runnable = new ISafeRunnable() {
283                     public void run() throws Exception JavaDoc {
284                         provider.restoreState(memento);
285                     }
286
287                     public void handleException(Throwable JavaDoc exception) {
288                         NavigatorPlugin.logError(0, "Could not restore state for action provider " + provider.getClass(), exception); //$NON-NLS-1$
289

290                     }
291                 };
292                 SafeRunner.run(runnable);
293
294             }
295         }
296     }
297
298     /**
299      * Request that Action Providers save any state that they find interesting.
300      *
301      * @param aMemento
302      * The memento retrieved from the dialog settings
303      */

304     public void saveState(IMemento aMemento) {
305         Assert.isTrue(!disposed);
306
307         memento = aMemento;
308         CommonActionProvider provider = null;
309         synchronized (actionProviderInstances) {
310             for (Iterator JavaDoc actionProviderIterator = actionProviderInstances.values().iterator(); actionProviderIterator.hasNext();) {
311                 provider = (CommonActionProvider) actionProviderIterator.next();
312                 provider.saveState(memento);
313             }
314         }
315     }
316
317     private CommonActionProvider getActionProviderInstance(
318             CommonActionProviderDescriptor aProviderDescriptor) {
319         CommonActionProvider provider = null;
320         try {
321             provider = (CommonActionProvider) actionProviderInstances
322                     .get(aProviderDescriptor);
323             if (provider != null) {
324                 return provider;
325             }
326             synchronized (actionProviderInstances) {
327                 provider = (CommonActionProvider) actionProviderInstances
328                         .get(aProviderDescriptor);
329                 if (provider == null) {
330                     provider = aProviderDescriptor.createActionProvider();
331                     if (provider != null) {
332                         initialize(aProviderDescriptor.getId(), provider);
333                         actionProviderInstances.put(aProviderDescriptor, provider);
334                     } else {
335                         actionProviderInstances.put(aProviderDescriptor,
336                                 (provider = SkeletonActionProvider.INSTANCE));
337                     }
338                 }
339             }
340         } catch(Throwable JavaDoc t) {
341             NavigatorPlugin.logError(0, t.getMessage(), t);
342         }
343         return provider;
344     }
345
346     private void initialize(String JavaDoc id, CommonActionProvider anActionProvider) {
347         if (anActionProvider != null && anActionProvider != SkeletonActionProvider.INSTANCE) {
348             ICommonActionExtensionSite configuration = new CommonActionExtensionSite(id, commonViewerSite, contentService, structuredViewer);
349             anActionProvider.init(configuration);
350             anActionProvider.restoreState(memento);
351             anActionProvider.setContext(new ActionContext(StructuredSelection.EMPTY));
352             if (commonViewerSite instanceof ICommonViewerWorkbenchSite) {
353                 anActionProvider.fillActionBars(((ICommonViewerWorkbenchSite) commonViewerSite).getActionBars());
354             }
355         }
356     }
357 }
358
Popular Tags