1 11 package org.eclipse.pde.internal.ui.views.dependencies; 12 13 import java.util.ArrayList ; 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 HIDE_RESOLVED = "hideResolved"; private static final String SHOW_NONLEAF = "hideNonLeaf"; 88 private ViewerFilter fHideResolvedFilter = new ViewerFilter() { 89 public boolean select(Viewer viewer, Object parentElement, Object 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 parentElement, Object 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 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 [] dependencies; 119 120 public DependencyGroup(Object [] constraints) { 121 dependencies = constraints; 122 } 123 124 public Object [] getChildren() { 125 return dependencies; 126 } 127 128 public String 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 [] getChildren(Object parentElement) { 137 if (parentElement instanceof BundleDescription) { 138 BundleDescription desc = (BundleDescription)parentElement; 139 if (desc.isResolved()) { 140 Object [] required = getResolvedDependencies(desc.getRequiredBundles()); 141 Object [] imported = getResolvedDependencies(desc.getImportPackages()); 142 ArrayList list = new ArrayList (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 [0]; 154 } 155 156 public Object getParent(Object element) { 157 return null; 158 } 159 160 public boolean hasChildren(Object element) { 161 return getChildren(element).length > 0; 162 } 163 164 public Object [] getElements(Object inputElement) { 165 if (inputElement instanceof State) 166 return ((State)inputElement).getBundles(); 167 return new Object [0]; 168 } 169 170 private Object [] getResolvedDependencies(VersionConstraint[] constraints) { 171 ArrayList list = new ArrayList (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 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 getText(Object element) { 215 StringBuffer buffer = new StringBuffer (); 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 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 return (((Integer ) supplier.getDirective("x-equinox-ee")).intValue() > 0); } 243 244 public StateViewPage(DependenciesView view) { 245 fView = view; 246 fPropertyListener = new IPropertyChangeListener() { 247 public void propertyChange(PropertyChangeEvent event) { 248 String 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 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 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"); 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 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 return; 422 fTreeViewer.getTree().getDisplay().asyncExec(new Runnable () { 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 return; 445 fTreeViewer.getTree().getDisplay().asyncExec(new Runnable () { 446 public void run() { 447 fTreeViewer.setInput(newState); 448 } 449 }); 450 } 451 452 private void setFocusOnSelection() { 454 IContributionItem item = getSite().getActionBars().getToolBarManager().find(DependenciesView.SHOW_STATE_ACTION_ID); 456 if (item != null && item instanceof ActionContributionItem) { 457 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 action.setChecked(false); 466 action.run(); 468 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"); if (section == null) { 478 section = master.addNewSection("dependenciesView"); } 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 () { 488 public void run() { 489 fTreeViewer.refresh(); 490 } 491 }); 492 } 493 494 } 495 | Popular Tags |