KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > views > dependencies > StateViewPage


1 /*******************************************************************************
2  * Copyright (c) 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.pde.internal.ui.views.dependencies;
12
13 import java.util.ArrayList JavaDoc;
14
15 import org.eclipse.jdt.ui.ISharedImages;
16 import org.eclipse.jdt.ui.JavaUI;
17 import org.eclipse.jface.action.Action;
18 import org.eclipse.jface.action.ActionContributionItem;
19 import org.eclipse.jface.action.IAction;
20 import org.eclipse.jface.action.IContributionItem;
21 import org.eclipse.jface.action.IMenuListener;
22 import org.eclipse.jface.action.IMenuManager;
23 import org.eclipse.jface.action.IStatusLineManager;
24 import org.eclipse.jface.action.IToolBarManager;
25 import org.eclipse.jface.action.MenuManager;
26 import org.eclipse.jface.action.Separator;
27 import org.eclipse.jface.dialogs.IDialogSettings;
28 import org.eclipse.jface.util.IPropertyChangeListener;
29 import org.eclipse.jface.util.PropertyChangeEvent;
30 import org.eclipse.jface.viewers.DoubleClickEvent;
31 import org.eclipse.jface.viewers.IDoubleClickListener;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.jface.viewers.ITreeContentProvider;
34 import org.eclipse.jface.viewers.LabelProvider;
35 import org.eclipse.jface.viewers.StructuredSelection;
36 import org.eclipse.jface.viewers.TreeViewer;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.jface.viewers.ViewerFilter;
39 import org.eclipse.osgi.service.resolver.BundleDelta;
40 import org.eclipse.osgi.service.resolver.BundleDescription;
41 import org.eclipse.osgi.service.resolver.BundleSpecification;
42 import org.eclipse.osgi.service.resolver.ExportPackageDescription;
43 import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
44 import org.eclipse.osgi.service.resolver.ResolverError;
45 import org.eclipse.osgi.service.resolver.State;
46 import org.eclipse.osgi.service.resolver.StateDelta;
47 import org.eclipse.osgi.service.resolver.VersionConstraint;
48 import org.eclipse.osgi.util.NLS;
49 import org.eclipse.pde.core.plugin.PluginRegistry;
50 import org.eclipse.pde.internal.core.IPluginModelListener;
51 import org.eclipse.pde.internal.core.IStateDeltaListener;
52 import org.eclipse.pde.internal.core.PDECore;
53 import org.eclipse.pde.internal.core.PluginModelDelta;
54 import org.eclipse.pde.internal.ui.IPreferenceConstants;
55 import org.eclipse.pde.internal.ui.PDELabelProvider;
56 import org.eclipse.pde.internal.ui.PDEPlugin;
57 import org.eclipse.pde.internal.ui.PDEPluginImages;
58 import org.eclipse.pde.internal.ui.PDEUIMessages;
59 import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
60 import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
61 import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
62 import org.eclipse.swt.SWT;
63 import org.eclipse.swt.graphics.Image;
64 import org.eclipse.swt.layout.GridData;
65 import org.eclipse.swt.layout.GridLayout;
66 import org.eclipse.swt.widgets.Composite;
67 import org.eclipse.swt.widgets.Control;
68 import org.eclipse.swt.widgets.Layout;
69 import org.eclipse.swt.widgets.Menu;
70 import org.eclipse.ui.IWorkbenchActionConstants;
71 import org.eclipse.ui.dialogs.FilteredTree;
72 import org.eclipse.ui.dialogs.PatternFilter;
73 import org.eclipse.ui.part.Page;
74 import org.osgi.framework.Version;
75
76 public class StateViewPage extends Page implements IStateDeltaListener, IPluginModelListener {
77     
78     private IPropertyChangeListener fPropertyListener;
79     private FilteredTree fFilteredTree = null;
80     private TreeViewer fTreeViewer = null;
81     private DependenciesView fView;
82     private Composite fComposite;
83     private Action fOpenAction;
84     
85     private static final String JavaDoc HIDE_RESOLVED = "hideResolved"; //$NON-NLS-1$
86
private static final String JavaDoc SHOW_NONLEAF = "hideNonLeaf"; //$NON-NLS-1$
87

88     private ViewerFilter fHideResolvedFilter = new ViewerFilter() {
89         public boolean select(Viewer viewer, Object JavaDoc parentElement, Object JavaDoc element) {
90             return ((element instanceof BundleDescription && !((BundleDescription)element).isResolved()) ||
91                 parentElement instanceof BundleDescription && !((BundleDescription)parentElement).isResolved());
92         }
93     };
94     
95     private ViewerFilter fShowLeaves = new ViewerFilter() {
96         public boolean select(Viewer viewer, Object JavaDoc parentElement, Object JavaDoc element) {
97             if (element instanceof BundleDescription) {
98                 return ((BundleDescription)element).getDependents().length == 0;
99             }
100             return true;
101         }
102     };
103     
104     class FocusOnAction extends Action {
105         public FocusOnAction(String JavaDoc text) {
106             super(text);
107             setDescription(PDEUIMessages.StateViewPage_focusActionDescription);
108             setToolTipText(PDEUIMessages.StateViewPage_focusActionToolTip);
109         }
110
111         public void run() {
112             setFocusOnSelection();
113         }
114         
115     }
116
117     class DependencyGroup {
118         Object JavaDoc [] dependencies;
119         
120         public DependencyGroup(Object JavaDoc[] constraints) {
121             dependencies = constraints;
122         }
123         
124         public Object JavaDoc[] getChildren() {
125             return dependencies;
126         }
127         
128         public String JavaDoc toString() {
129             return (dependencies[0] instanceof BundleSpecification) ? PDEUIMessages.StateViewPage_requiredBundles
130                     : PDEUIMessages.StateViewPage_importedPackages;
131         }
132     }
133     
134     class StateContentProvider extends DefaultContentProvider implements ITreeContentProvider {
135
136         public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
137             if (parentElement instanceof BundleDescription) {
138                 BundleDescription desc = (BundleDescription)parentElement;
139                 if (desc.isResolved()) {
140                     Object JavaDoc[] required = getResolvedDependencies(desc.getRequiredBundles());
141                     Object JavaDoc[] imported = getResolvedDependencies(desc.getImportPackages());
142                     ArrayList JavaDoc list = new ArrayList JavaDoc(2);
143                     if (required.length > 0)
144                         list.add(new DependencyGroup(required));
145                     if (imported.length > 0)
146                         list.add(new DependencyGroup(imported));
147                     return list.toArray();
148                 }
149                 return desc.getContainingState().getResolverErrors(desc);
150             } else if (parentElement instanceof DependencyGroup) {
151                 return ((DependencyGroup)parentElement).getChildren();
152             }
153             return new Object JavaDoc[0];
154         }
155
156         public Object JavaDoc getParent(Object JavaDoc element) {
157             return null;
158         }
159
160         public boolean hasChildren(Object JavaDoc element) {
161             return getChildren(element).length > 0;
162         }
163
164         public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
165             if (inputElement instanceof State)
166                 return ((State)inputElement).getBundles();
167             return new Object JavaDoc[0];
168         }
169         
170         private Object JavaDoc[] getResolvedDependencies(VersionConstraint[] constraints) {
171             ArrayList JavaDoc list = new ArrayList JavaDoc(constraints.length);
172             for (int i = 0; i < constraints.length; i++)
173                 if (constraints[i].isResolved())
174                     list.add(constraints[i]);
175             return list.toArray();
176         }
177         
178     }
179     
180     class StateLabelProvider extends LabelProvider {
181         private PDELabelProvider fSharedProvider;
182         
183         public StateLabelProvider() {
184             fSharedProvider = PDEPlugin.getDefault().getLabelProvider();
185             fSharedProvider.connect(this);
186         }
187         
188         public void dispose() {
189             fSharedProvider.disconnect(this);
190             super.dispose();
191         }
192         
193         public Image getImage(Object JavaDoc element) {
194             if (element instanceof DependencyGroup)
195                 element = ((DependencyGroup)element).getChildren()[0];
196             if (element instanceof BundleSpecification)
197                 element = ((BundleSpecification)element).getSupplier();
198             if (element instanceof BundleDescription) {
199                 int flags = ((BundleDescription)element).isResolved() ? 0 : SharedLabelProvider.F_ERROR;
200                 return (((BundleDescription)element).getHost() == null) ?
201                         fSharedProvider.get(PDEPluginImages.DESC_PLUGIN_OBJ, flags) :
202                         fSharedProvider.get(PDEPluginImages.DESC_FRAGMENT_OBJ, flags);
203             }
204             if (element instanceof ImportPackageSpecification)
205                 return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_PACKAGE);
206             if (element instanceof ResolverError) {
207                 if (((ResolverError)element).getType() == ResolverError.PLATFORM_FILTER)
208                     return fSharedProvider.get(PDEPluginImages.DESC_OPERATING_SYSTEM_OBJ);
209                 return fSharedProvider.getImage(element);
210             }
211             return null;
212         }
213
214         public String JavaDoc getText(Object JavaDoc element) {
215             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
216             if (element instanceof ImportPackageSpecification) {
217                 ImportPackageSpecification spec = (ImportPackageSpecification) element;
218                 buffer.append(spec.getName());
219                 ExportPackageDescription supplier = (ExportPackageDescription) spec.getSupplier();
220                 if (isJREPackage(supplier))
221                     return buffer.append(PDEUIMessages.StateViewPage_suppliedByJRE).toString();
222                 element = supplier.getSupplier();
223                 buffer.append(PDEUIMessages.StateViewPage_suppliedBy);
224             }
225             if (element instanceof BundleSpecification)
226                 element = ((BundleSpecification)element).getSupplier();
227             if (element instanceof BundleDescription) {
228                 buffer.append(fSharedProvider.getObjectText((BundleDescription)element));
229                 Version version = ((BundleDescription)element).getVersion();
230                 // Bug 183417 - Bidi3.3: Elements' labels in the extensions page in the fragment manifest characters order is incorrect
231
// Use the PDELabelProvider.formatVersion function to properly format the version for all languages including bidi
232
return buffer.append(' ').append(PDELabelProvider.formatVersion(version.toString())).toString();
233             }
234             return element.toString();
235         }
236         
237     }
238     
239     private boolean isJREPackage(ExportPackageDescription supplier) {
240         // check for runtime's non-API directive. This may change in the future
241
return (((Integer JavaDoc) supplier.getDirective("x-equinox-ee")).intValue() > 0); //$NON-NLS-1$
242
}
243     
244     public StateViewPage(DependenciesView view) {
245         fView = view;
246         fPropertyListener = new IPropertyChangeListener() {
247             public void propertyChange(PropertyChangeEvent event) {
248                 String JavaDoc property = event.getProperty();
249                 if (property.equals(IPreferenceConstants.PROP_SHOW_OBJECTS)) {
250                     fTreeViewer.refresh();
251                 }
252             }
253         };
254     }
255
256     public void createControl(Composite parent) {
257         fComposite = new Composite(parent, SWT.NONE);
258         GridLayout layout = new GridLayout();
259         layout.marginHeight = layout.marginWidth = 0;
260         fComposite.setLayout(layout);
261         fComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
262         
263         fFilteredTree = new FilteredTree(fComposite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE, new PatternFilter());
264         fFilteredTree.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
265         
266         // need to give filter Textbox some space from the border
267
Layout filterLayout = fFilteredTree.getFilterControl().getParent().getLayout();
268         if (filterLayout instanceof GridLayout) {
269             ((GridLayout)filterLayout).marginHeight = 4;
270             ((GridLayout)filterLayout).marginWidth = 3;
271         }
272         
273         fTreeViewer = fFilteredTree.getViewer();
274         fTreeViewer.setContentProvider(new StateContentProvider());
275         fTreeViewer.setLabelProvider(new StateLabelProvider());
276         fTreeViewer.setComparator(DependenciesViewComparator.getViewerComparator());
277         fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
278
279             public void doubleClick(DoubleClickEvent event) {
280                 handleDoubleClick();
281             }
282             
283         });
284         
285         if (getSettings().getBoolean(HIDE_RESOLVED))
286             fTreeViewer.addFilter(fHideResolvedFilter);
287         if (getSettings().getBoolean(SHOW_NONLEAF))
288             fTreeViewer.addFilter(fShowLeaves);
289         
290         PDEPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(
291                 fPropertyListener);
292         getSite().setSelectionProvider(fTreeViewer);
293         PDECore.getDefault().getModelManager().addStateDeltaListener(this);
294     }
295
296     public Control getControl() {
297         return fComposite;
298     }
299
300     public void setFocus() {
301         if (fFilteredTree != null) {
302             Control c = fFilteredTree.getFilterControl();
303             if (!c.isFocusControl()) {
304                 c.setFocus();
305             }
306         }
307     }
308     
309     protected void handleDoubleClick() {
310         StructuredSelection selection = (StructuredSelection)fTreeViewer.getSelection();
311         if (selection.size() == 1) {
312             BundleDescription desc = getBundleDescription(selection.getFirstElement());
313             if (desc != null)
314                 ManifestEditor.openPluginEditor(desc.getSymbolicName());
315         }
316     }
317     
318     private BundleDescription getBundleDescription(Object JavaDoc obj) {
319         if (obj instanceof BundleSpecification)
320             obj = ((BundleSpecification)obj).getSupplier();
321         else if (obj instanceof ImportPackageSpecification)
322             obj = ((ExportPackageDescription)((ImportPackageSpecification)obj).getSupplier()).getSupplier();
323         if (obj instanceof BundleDescription)
324             return (BundleDescription)obj;
325         return null;
326     }
327     
328     protected void setActive(boolean active) {
329         if (active) {
330             fView.updateTitle(PDEUIMessages.StateViewPage_title);
331             State state = PDECore.getDefault().getModelManager().getState().getState();
332             state.resolve(true);
333             fTreeViewer.setInput(state);
334             PDECore.getDefault().getModelManager().addPluginModelListener(this);
335         } else {
336             PDECore.getDefault().getModelManager().removePluginModelListener(this);
337         }
338     }
339     
340     public void makeContributions(IMenuManager menuManager,
341             IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
342         super.makeContributions(menuManager, toolBarManager, statusLineManager);
343         Action filterResolved = new Action(PDEUIMessages.StateViewPage_showOnlyUnresolved_label, IAction.AS_CHECK_BOX) {
344             public void run() {
345                 getSettings().put(HIDE_RESOLVED, isChecked());
346                 if (isChecked())
347                     fTreeViewer.addFilter(fHideResolvedFilter);
348                 else
349                     fTreeViewer.removeFilter(fHideResolvedFilter);
350             }
351         };
352         Action filterLeaves = new Action(PDEUIMessages.StateViewPage_showLeaves, IAction.AS_CHECK_BOX) {
353             public void run() {
354                 getSettings().put(SHOW_NONLEAF, isChecked());
355                 if (isChecked())
356                     fTreeViewer.addFilter(fShowLeaves);
357                 else
358                     fTreeViewer.removeFilter(fShowLeaves);
359             }
360         };
361         
362         filterResolved.setChecked(getSettings().getBoolean(HIDE_RESOLVED));
363         filterLeaves.setChecked(getSettings().getBoolean(SHOW_NONLEAF));
364         menuManager.add(filterResolved);
365         menuManager.add(filterLeaves);
366         
367         Action action = new FocusOnAction(PDEUIMessages.StateViewPage_focusOnTitle);
368         action.setImageDescriptor(PDEPluginImages.DESC_FOCUS_ON);
369         if (toolBarManager.find(DependenciesView.TREE_ACTION_GROUP) != null)
370             toolBarManager.prependToGroup(DependenciesView.TREE_ACTION_GROUP,
371                     action);
372         else
373             toolBarManager.add(action);
374                 
375         hookContextMenu();
376     }
377     
378     private void hookContextMenu() {
379         MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
380
menuMgr.setRemoveAllWhenShown(true);
381         menuMgr.addMenuListener(new IMenuListener() {
382             public void menuAboutToShow(IMenuManager manager) {
383                 fillContextMenu(manager);
384             }
385         });
386         Menu menu = menuMgr.createContextMenu(fTreeViewer.getControl());
387         fTreeViewer.getControl().setMenu(menu);
388
389         getSite().registerContextMenu(fView.getSite().getId(), menuMgr, fTreeViewer);
390     }
391     
392     private void fillContextMenu(IMenuManager menu) {
393         IStructuredSelection selection = (IStructuredSelection)fTreeViewer.getSelection();
394         BundleDescription desc = getBundleDescription(selection.getFirstElement());
395         if (desc != null) {
396             if (fOpenAction == null) {
397                 fOpenAction = new Action(PDEUIMessages.StateViewPage_openItem) {
398                     public void run() {
399                         handleDoubleClick();
400                     }
401                 };
402             }
403             menu.add(fOpenAction);
404             menu.add(new Separator());
405             String JavaDoc name = ((LabelProvider)fTreeViewer.getLabelProvider()).getText(desc);
406             menu.add(new FocusOnAction(NLS.bind(PDEUIMessages.StateViewPage_focusOnSelection, name)));
407             
408             menu.add(new Separator());
409             menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
410         }
411     }
412     
413     public void dispose() {
414         PDECore.getDefault().getModelManager().removeStateDeltaListener(this);
415         super.dispose();
416     }
417
418     public void stateResolved(final StateDelta delta) {
419         if (!fView.getCurrentPage().equals(this) || fTreeViewer == null || fTreeViewer.getTree().isDisposed())
420             // if this page is not active, then wait until we call refresh on next activation
421
return;
422         fTreeViewer.getTree().getDisplay().asyncExec(new Runnable JavaDoc() {
423             public void run() {
424                 if (delta == null) {
425                     fTreeViewer.refresh();
426                 } else {
427                     BundleDelta[] deltas = delta.getChanges();
428                     for (int i = 0; i < deltas.length; i++) {
429                         int type = deltas[i].getType();
430                         if (type == BundleDelta.REMOVED || type == BundleDelta.RESOLVED
431                                 || type == BundleDelta.ADDED || type == BundleDelta.UNRESOLVED) {
432                             fTreeViewer.refresh();
433                             break;
434                         }
435                     }
436                 }
437             }
438         });
439     }
440     
441     public void stateChanged(final State newState) {
442         if (!fView.getCurrentPage().equals(this) || fTreeViewer == null || fTreeViewer.getTree().isDisposed())
443             // if this page is not active, then wait until we call refresh on next activation
444
return;
445         fTreeViewer.getTree().getDisplay().asyncExec(new Runnable JavaDoc() {
446             public void run() {
447                 fTreeViewer.setInput(newState);
448             }
449         });
450     }
451     
452     // Changes State view to dependencies view and sets the input as the corresponding selected item in the tree viewer.
453
private void setFocusOnSelection() {
454         // first, find the Show State Action from the toolbar
455
IContributionItem item = getSite().getActionBars().getToolBarManager().find(DependenciesView.SHOW_STATE_ACTION_ID);
456         if (item != null && item instanceof ActionContributionItem) {
457             // then get selection item
458
IStructuredSelection selection = (IStructuredSelection)fTreeViewer.getSelection();
459             if (selection.isEmpty())
460                 return;
461             BundleDescription desc = getBundleDescription(selection.getFirstElement());
462             if (desc != null) {
463                 IAction action = ((ActionContributionItem)item).getAction();
464                 // deselect the action to show the state
465
action.setChecked(false);
466                 // run the action to change the view back to traditional dependencies view
467
action.run();
468                 // set the traditional view to focus on selected object from state view
469
fView.openTo(PluginRegistry.findModel(desc));
470             }
471         }
472     }
473     
474     private IDialogSettings getSettings() {
475         IDialogSettings master = PDEPlugin.getDefault().getDialogSettings();
476         IDialogSettings section = master.getSection("dependenciesView"); //$NON-NLS-1$
477
if (section == null) {
478             section = master.addNewSection("dependenciesView"); //$NON-NLS-1$
479
}
480         return section;
481     }
482     
483     public void modelsChanged(PluginModelDelta delta) {
484         if (fTreeViewer == null || fTreeViewer.getTree().isDisposed())
485             return;
486         if (delta.getAddedEntries().length > 0 || delta.getChangedEntries().length > 0 || delta.getRemovedEntries().length > 0)
487             fTreeViewer.getTree().getDisplay().asyncExec(new Runnable JavaDoc() {
488                 public void run() {
489                     fTreeViewer.refresh();
490                 }
491             });
492     }
493
494 }
495
Popular Tags