001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.plugin;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.Set;
015:
016: import org.eclipse.core.resources.IProject;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.jdt.core.IJavaElement;
020: import org.eclipse.jdt.core.IJavaProject;
021: import org.eclipse.jdt.core.IPackageFragment;
022: import org.eclipse.jdt.core.IPackageFragmentRoot;
023: import org.eclipse.jdt.core.JavaCore;
024: import org.eclipse.jdt.core.JavaModelException;
025: import org.eclipse.jdt.ui.ISharedImages;
026: import org.eclipse.jdt.ui.JavaUI;
027: import org.eclipse.jdt.ui.actions.FindReferencesInWorkingSetAction;
028: import org.eclipse.jdt.ui.actions.ShowInPackageViewAction;
029: import org.eclipse.jface.action.Action;
030: import org.eclipse.jface.action.IMenuManager;
031: import org.eclipse.jface.action.Separator;
032: import org.eclipse.jface.viewers.ISelection;
033: import org.eclipse.jface.viewers.IStructuredSelection;
034: import org.eclipse.jface.viewers.LabelProvider;
035: import org.eclipse.jface.viewers.StructuredSelection;
036: import org.eclipse.jface.viewers.TableViewer;
037: import org.eclipse.jface.viewers.Viewer;
038: import org.eclipse.jface.viewers.ViewerComparator;
039: import org.eclipse.jface.window.Window;
040: import org.eclipse.osgi.service.resolver.BundleDescription;
041: import org.eclipse.osgi.service.resolver.BundleSpecification;
042: import org.eclipse.osgi.service.resolver.ExportPackageDescription;
043: import org.eclipse.osgi.service.resolver.State;
044: import org.eclipse.pde.core.IBaseModel;
045: import org.eclipse.pde.core.IModel;
046: import org.eclipse.pde.core.IModelChangedEvent;
047: import org.eclipse.pde.core.IModelChangedListener;
048: import org.eclipse.pde.core.plugin.IPluginImport;
049: import org.eclipse.pde.core.plugin.IPluginModelBase;
050: import org.eclipse.pde.core.plugin.PluginRegistry;
051: import org.eclipse.pde.internal.core.ICoreConstants;
052: import org.eclipse.pde.internal.core.TargetPlatformHelper;
053: import org.eclipse.pde.internal.core.WorkspaceModelManager;
054: import org.eclipse.pde.internal.core.bundle.BundlePluginBase;
055: import org.eclipse.pde.internal.core.ibundle.IBundle;
056: import org.eclipse.pde.internal.core.ibundle.IBundleModel;
057: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
058: import org.eclipse.pde.internal.core.text.bundle.Bundle;
059: import org.eclipse.pde.internal.core.text.bundle.ExportPackageHeader;
060: import org.eclipse.pde.internal.core.text.bundle.ExportPackageObject;
061: import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader;
062: import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject;
063: import org.eclipse.pde.internal.core.text.bundle.PackageObject;
064: import org.eclipse.pde.internal.core.util.PDEJavaHelper;
065: import org.eclipse.pde.internal.ui.PDELabelProvider;
066: import org.eclipse.pde.internal.ui.PDEPlugin;
067: import org.eclipse.pde.internal.ui.PDEUIMessages;
068: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
069: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
070: import org.eclipse.pde.internal.ui.editor.TableSection;
071: import org.eclipse.pde.internal.ui.editor.context.InputContextManager;
072: import org.eclipse.pde.internal.ui.elements.DefaultTableProvider;
073: import org.eclipse.pde.internal.ui.parts.ConditionalListSelectionDialog;
074: import org.eclipse.pde.internal.ui.parts.TablePart;
075: import org.eclipse.pde.internal.ui.search.dependencies.UnusedDependenciesAction;
076: import org.eclipse.pde.internal.ui.util.SWTUtil;
077: import org.eclipse.search.ui.NewSearchUI;
078: import org.eclipse.swt.SWT;
079: import org.eclipse.swt.custom.BusyIndicator;
080: import org.eclipse.swt.graphics.Image;
081: import org.eclipse.swt.layout.GridData;
082: import org.eclipse.swt.widgets.Composite;
083: import org.eclipse.swt.widgets.Display;
084: import org.eclipse.swt.widgets.Table;
085: import org.eclipse.ui.IViewPart;
086: import org.eclipse.ui.IWorkingSet;
087: import org.eclipse.ui.IWorkingSetManager;
088: import org.eclipse.ui.PartInitException;
089: import org.eclipse.ui.PlatformUI;
090: import org.eclipse.ui.actions.ActionFactory;
091: import org.eclipse.ui.forms.widgets.FormToolkit;
092: import org.eclipse.ui.forms.widgets.Section;
093: import org.osgi.framework.Constants;
094: import org.osgi.framework.Version;
095:
096: public class ImportPackageSection extends TableSection implements
097: IModelChangedListener {
098:
099: private static final int ADD_INDEX = 0;
100: private static final int REMOVE_INDEX = 1;
101: private static final int PROPERTIES_INDEX = 2;
102:
103: private ImportPackageHeader fHeader;
104:
105: class ImportItemWrapper {
106: Object fUnderlying;
107:
108: public ImportItemWrapper(Object underlying) {
109: fUnderlying = underlying;
110: }
111:
112: public String toString() {
113: return getName();
114: }
115:
116: public boolean equals(Object obj) {
117: if (obj instanceof ImportItemWrapper) {
118: ImportItemWrapper item = (ImportItemWrapper) obj;
119: return getName().equals(item.getName());
120: }
121: return false;
122: }
123:
124: public String getName() {
125: if (fUnderlying instanceof ExportPackageDescription)
126: return ((ExportPackageDescription) fUnderlying)
127: .getName();
128: if (fUnderlying instanceof IPackageFragment)
129: return ((IPackageFragment) fUnderlying)
130: .getElementName();
131: if (fUnderlying instanceof ExportPackageObject)
132: return ((ExportPackageObject) fUnderlying).getName();
133: return null;
134: }
135:
136: public Version getVersion() {
137: if (fUnderlying instanceof ExportPackageDescription)
138: return ((ExportPackageDescription) fUnderlying)
139: .getVersion();
140: if (fUnderlying instanceof ExportPackageObject) {
141: String version = ((ExportPackageObject) fUnderlying)
142: .getVersion();
143: if (version != null)
144: return new Version(version);
145: }
146: return null;
147: }
148:
149: boolean hasVersion() {
150: return hasEPD()
151: && ((ExportPackageDescription) fUnderlying)
152: .getVersion() != null;
153: }
154:
155: boolean hasEPD() {
156: return fUnderlying instanceof ExportPackageDescription;
157: }
158: }
159:
160: class ImportPackageContentProvider extends DefaultTableProvider {
161: public Object[] getElements(Object parent) {
162: if (fHeader == null) {
163: Bundle bundle = (Bundle) getBundle();
164: fHeader = (ImportPackageHeader) bundle
165: .getManifestHeader(Constants.IMPORT_PACKAGE);
166: }
167: return fHeader == null ? new Object[0] : fHeader
168: .getPackages();
169: }
170: }
171:
172: class ImportPackageDialogLabelProvider extends LabelProvider {
173: public Image getImage(Object element) {
174: return JavaUI.getSharedImages().getImage(
175: ISharedImages.IMG_OBJS_PACKAGE);
176: }
177:
178: public String getText(Object element) {
179: StringBuffer buffer = new StringBuffer();
180: ImportItemWrapper p = (ImportItemWrapper) element;
181: buffer.append(p.getName());
182: Version version = p.getVersion();
183: if (version != null
184: && !Version.emptyVersion.equals(version)) {
185: // Bug 183417 - Bidi3.3: Elements' labels in the extensions page in the fragment manifest characters order is incorrect
186: // add RTL zero length character just before the ( and the LTR character just after to ensure:
187: // 1. The leading parenthesis takes proper orientation when running in bidi configuration
188: // 2. The bundle's version is always displayed as LTR. Otherwise if qualifier contains an alpha,
189: // it would be displayed incorrectly when running RTL.
190: buffer.append(' ');
191: buffer.append(PDELabelProvider.formatVersion(version
192: .toString()));
193: }
194: return buffer.toString();
195: }
196: }
197:
198: private TableViewer fPackageViewer;
199:
200: private Action fAddAction;
201: private Action fGoToAction;
202: private Action fRemoveAction;
203: private Action fPropertiesAction;
204:
205: public ImportPackageSection(PDEFormPage page, Composite parent) {
206: super (page, parent, Section.DESCRIPTION, new String[] {
207: PDEUIMessages.ImportPackageSection_add,
208: PDEUIMessages.ImportPackageSection_remove,
209: PDEUIMessages.ImportPackageSection_properties });
210: }
211:
212: private boolean isFragment() {
213: IPluginModelBase model = (IPluginModelBase) getPage()
214: .getPDEEditor().getAggregateModel();
215: return model.isFragmentModel();
216: }
217:
218: /*
219: * (non-Javadoc)
220: *
221: * @see org.eclipse.pde.internal.ui.editor.PDESection#createClient(org.eclipse.ui.forms.widgets.Section,
222: * org.eclipse.ui.forms.widgets.FormToolkit)
223: */
224: protected void createClient(Section section, FormToolkit toolkit) {
225: section.setText(PDEUIMessages.ImportPackageSection_required);
226: if (isFragment())
227: section
228: .setDescription(PDEUIMessages.ImportPackageSection_descFragment);
229: else
230: section
231: .setDescription(PDEUIMessages.ImportPackageSection_desc);
232:
233: Composite container = createClientContainer(section, 2, toolkit);
234: createViewerPartControl(container, SWT.MULTI, 2, toolkit);
235: TablePart tablePart = getTablePart();
236: fPackageViewer = tablePart.getTableViewer();
237: fPackageViewer
238: .setContentProvider(new ImportPackageContentProvider());
239: fPackageViewer.setLabelProvider(PDEPlugin.getDefault()
240: .getLabelProvider());
241: fPackageViewer.setComparator(new ViewerComparator() {
242: public int compare(Viewer viewer, Object e1, Object e2) {
243: String s1 = e1.toString();
244: String s2 = e2.toString();
245: if (s1.indexOf(" ") != -1) //$NON-NLS-1$
246: s1 = s1.substring(0, s1.indexOf(" ")); //$NON-NLS-1$
247: if (s2.indexOf(" ") != -1) //$NON-NLS-1$
248: s2 = s2.substring(0, s2.indexOf(" ")); //$NON-NLS-1$
249: return super .compare(viewer, s1, s2);
250: }
251: });
252: toolkit.paintBordersFor(container);
253: section.setClient(container);
254: section.setLayout(FormLayoutFactory.createClearGridLayout(
255: false, 1));
256: section.setLayoutData(new GridData(GridData.FILL_BOTH));
257: makeActions();
258:
259: IBundleModel model = getBundleModel();
260: fPackageViewer.setInput(model);
261: model.addModelChangedListener(this );
262: updateButtons();
263: }
264:
265: public boolean doGlobalAction(String actionId) {
266:
267: if (!isEditable()) {
268: return false;
269: }
270:
271: if (actionId.equals(ActionFactory.DELETE.getId())) {
272: handleRemove();
273: return true;
274: }
275: if (actionId.equals(ActionFactory.CUT.getId())) {
276: // delete here and let the editor transfer
277: // the selection to the clipboard
278: handleRemove();
279: return false;
280: }
281: if (actionId.equals(ActionFactory.PASTE.getId())) {
282: doPaste();
283: return true;
284: }
285: return false;
286: }
287:
288: /* (non-Javadoc)
289: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
290: */
291: protected boolean canPaste(Object targetObject,
292: Object[] sourceObjects) {
293: // Only non-duplicate import packages can be pasted
294: for (int i = 0; i < sourceObjects.length; i++) {
295: // Only import package objects are allowed
296: if ((sourceObjects[i] instanceof ImportPackageObject) == false) {
297: return false;
298: }
299: // Note: Should check if the package fragment represented by the
300: // import package object exists
301: // (like in org.eclipse.pde.internal.ui.editor.plugin.ImportPackageSection.setElements(ConditionalListSelectionDialog))
302: // However, the operation is too performance intensive as it
303: // requires searching all workspace and target plug-in
304:
305: // If the import package header is not defined, no import packages
306: // have been defined yet
307: if (fHeader == null) {
308: continue;
309: }
310: // Only import package objects that have not already been
311: // specified are allowed (no duplicates)
312: ImportPackageObject importPackageObject = (ImportPackageObject) sourceObjects[i];
313: if (fHeader.hasPackage(importPackageObject.getName())) {
314: return false;
315: }
316: }
317: return true;
318: }
319:
320: public void dispose() {
321: IBundleModel model = getBundleModel();
322: if (model != null)
323: model.removeModelChangedListener(this );
324: super .dispose();
325: }
326:
327: /* (non-Javadoc)
328: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
329: */
330: protected void doPaste(Object targetObject, Object[] sourceObjects) {
331: // Get the model
332: IBundleModel model = getBundleModel();
333: // Ensure the model is defined
334: if (model == null) {
335: return;
336: }
337: // Get the bundle
338: IBundle bundle = model.getBundle();
339: // Paste all source objects
340: for (int i = 0; i < sourceObjects.length; i++) {
341: Object sourceObject = sourceObjects[i];
342: if (sourceObject instanceof ImportPackageObject) {
343: ImportPackageObject importPackageObject = (ImportPackageObject) sourceObject;
344: // Import package object
345: // Adjust all the source object transient field values to
346: // acceptable values
347: importPackageObject.reconnect(model, fHeader,
348: getVersionAttribute());
349: // Add the object to the header
350: if (fHeader == null) {
351: // Import package header not defined yet
352: // Define one
353: // Value will get inserted into a new import package object
354: // created by a factory
355: // Value needs to be empty string so no import package
356: // object is created as the initial value
357: bundle.setHeader(getImportedPackageHeader(), ""); //$NON-NLS-1$
358: }
359: // Add the import package to the header
360: fHeader.addPackage(importPackageObject);
361: }
362: }
363: }
364:
365: /**
366: * @return
367: */
368: private String getImportedPackageHeader() {
369: return Constants.IMPORT_PACKAGE;
370: }
371:
372: protected void selectionChanged(IStructuredSelection sel) {
373: getPage().getPDEEditor().setSelection(sel);
374: updateButtons();
375: }
376:
377: private void updateButtons() {
378: Object[] selected = ((IStructuredSelection) fPackageViewer
379: .getSelection()).toArray();
380: int size = selected.length;
381: TablePart tablePart = getTablePart();
382: tablePart.setButtonEnabled(ADD_INDEX, isEditable());
383: tablePart.setButtonEnabled(REMOVE_INDEX, isEditable()
384: && size > 0);
385: tablePart.setButtonEnabled(PROPERTIES_INDEX,
386: shouldEnableProperties(selected));
387: }
388:
389: protected void handleDoubleClick(IStructuredSelection selection) {
390: handleGoToPackage(selection);
391: }
392:
393: protected void buttonSelected(int index) {
394: switch (index) {
395: case ADD_INDEX:
396: handleAdd();
397: break;
398: case REMOVE_INDEX:
399: handleRemove();
400: break;
401: case PROPERTIES_INDEX:
402: handleOpenProperties();
403: }
404: }
405:
406: private IPackageFragment getPackageFragment(ISelection sel) {
407: if (sel instanceof IStructuredSelection) {
408: IStructuredSelection selection = (IStructuredSelection) sel;
409: if (selection.size() != 1)
410: return null;
411:
412: IBaseModel model = getPage().getModel();
413: if (!(model instanceof IPluginModelBase))
414: return null;
415:
416: return PDEJavaHelper.getPackageFragment(
417: ((PackageObject) selection.getFirstElement())
418: .getName(), ((IPluginModelBase) model)
419: .getPluginBase().getId(), getPage()
420: .getPDEEditor().getCommonProject());
421: }
422: return null;
423: }
424:
425: private void handleGoToPackage(ISelection selection) {
426: IPackageFragment frag = getPackageFragment(selection);
427: if (frag != null)
428: try {
429: IViewPart part = PDEPlugin.getActivePage().showView(
430: JavaUI.ID_PACKAGES);
431: ShowInPackageViewAction action = new ShowInPackageViewAction(
432: part.getSite());
433: action.run(frag);
434: } catch (PartInitException e) {
435: }
436: }
437:
438: private void handleOpenProperties() {
439: Object[] selected = ((IStructuredSelection) fPackageViewer
440: .getSelection()).toArray();
441: ImportPackageObject first = (ImportPackageObject) selected[0];
442: DependencyPropertiesDialog dialog = new DependencyPropertiesDialog(
443: isEditable(), first);
444: dialog.create();
445: SWTUtil.setDialogSize(dialog, 400, -1);
446: if (selected.length == 1)
447: dialog.setTitle(((ImportPackageObject) selected[0])
448: .getName());
449: else
450: dialog.setTitle(PDEUIMessages.ExportPackageSection_props);
451: if (dialog.open() == Window.OK && isEditable()) {
452: String newVersion = dialog.getVersion();
453: boolean newOptional = dialog.isOptional();
454: for (int i = 0; i < selected.length; i++) {
455: ImportPackageObject object = (ImportPackageObject) selected[i];
456: if (!newVersion.equals(object.getVersion()))
457: object.setVersion(newVersion);
458: if (!newOptional == object.isOptional())
459: object.setOptional(newOptional);
460: }
461: }
462: }
463:
464: private void handleRemove() {
465: Object[] removed = ((IStructuredSelection) fPackageViewer
466: .getSelection()).toArray();
467: for (int i = 0; i < removed.length; i++) {
468: fHeader.removePackage((PackageObject) removed[i]);
469: }
470: }
471:
472: private void handleAdd() {
473: final ConditionalListSelectionDialog dialog = new ConditionalListSelectionDialog(
474: PDEPlugin.getActiveWorkbenchShell(),
475: new ImportPackageDialogLabelProvider(),
476: PDEUIMessages.ImportPackageSection_dialogButtonLabel);
477: Runnable runnable = new Runnable() {
478: public void run() {
479: setElements(dialog);
480: dialog.setMultipleSelection(true);
481: dialog
482: .setMessage(PDEUIMessages.ImportPackageSection_exported);
483: dialog
484: .setTitle(PDEUIMessages.ImportPackageSection_selection);
485: dialog.create();
486: SWTUtil.setDialogSize(dialog, 400, 500);
487: }
488: };
489:
490: BusyIndicator.showWhile(Display.getCurrent(), runnable);
491: if (dialog.open() == Window.OK) {
492: Object[] selected = dialog.getResult();
493: if (fHeader != null) {
494: for (int i = 0; i < selected.length; i++) {
495: ImportPackageObject impObject = null;
496: if (selected[i] instanceof ImportItemWrapper)
497: selected[i] = ((ImportItemWrapper) selected[i]).fUnderlying;
498:
499: if (selected[i] instanceof ExportPackageDescription)
500: impObject = new ImportPackageObject(fHeader,
501: (ExportPackageDescription) selected[i],
502: getVersionAttribute());
503: else if (selected[i] instanceof IPackageFragment) {
504: // non exported package
505: IPackageFragment fragment = ((IPackageFragment) selected[i]);
506: impObject = new ImportPackageObject(fHeader,
507: fragment.getElementName(), null,
508: getVersionAttribute());
509: } else if (selected[i] instanceof ExportPackageObject) {
510: ExportPackageObject epo = (ExportPackageObject) selected[i];
511: impObject = new ImportPackageObject(fHeader,
512: epo.getName(), epo.getVersion(),
513: getVersionAttribute());
514: }
515: if (impObject != null)
516: fHeader.addPackage(impObject);
517: }
518: } else {
519: getBundle().setHeader(Constants.IMPORT_PACKAGE,
520: getValue(selected));
521: }
522: }
523: }
524:
525: private String getValue(Object[] objects) {
526: StringBuffer buffer = new StringBuffer();
527: for (int i = 0; i < objects.length; i++) {
528: if (!(objects[i] instanceof ImportItemWrapper))
529: continue;
530: Version version = ((ImportItemWrapper) objects[i])
531: .getVersion();
532: if (buffer.length() > 0)
533: buffer.append("," + getLineDelimiter() + " "); //$NON-NLS-1$ //$NON-NLS-2$
534: buffer.append(((ImportItemWrapper) objects[i]).getName());
535: if (version != null
536: && !version.equals(Version.emptyVersion)) {
537: buffer.append(";"); //$NON-NLS-1$
538: buffer.append(getVersionAttribute());
539: buffer.append("=\""); //$NON-NLS-1$
540: buffer.append(version.toString());
541: buffer.append("\""); //$NON-NLS-1$
542: }
543: }
544: return buffer.toString();
545: }
546:
547: private void setElements(ConditionalListSelectionDialog dialog) {
548: Set forbidden = getForbiddenIds();
549: boolean allowJava = "true".equals(getBundle().getHeader(ICoreConstants.ECLIPSE_JREBUNDLE)); //$NON-NLS-1$
550:
551: ArrayList elements = new ArrayList();
552: ArrayList conditional = new ArrayList();
553: IPluginModelBase[] models = PluginRegistry.getActiveModels();
554: Set names = new HashSet();
555:
556: for (int i = 0; i < models.length; i++) {
557: BundleDescription desc = models[i].getBundleDescription();
558: String id = desc == null ? null : desc.getSymbolicName();
559: if (id == null || forbidden.contains(id))
560: continue;
561:
562: ExportPackageDescription[] exported = desc
563: .getExportPackages();
564: for (int j = 0; j < exported.length; j++) {
565: String name = exported[j].getName();
566: if (("java".equals(name) || name.startsWith("java.")) && !allowJava) //$NON-NLS-1$ //$NON-NLS-2$
567: continue;
568: if (names.add(name)
569: && (fHeader == null || !fHeader
570: .hasPackage(name)))
571: elements.add(new ImportItemWrapper(exported[j]));
572: }
573: IPluginModelBase model = (IPluginModelBase) getPage()
574: .getPDEEditor().getAggregateModel();
575: if (model instanceof IBundlePluginModelBase) {
576: IBundleModel bmodel = ((IBundlePluginModelBase) model)
577: .getBundleModel();
578: if (bmodel != null) {
579: ExportPackageHeader header = (ExportPackageHeader) bmodel
580: .getBundle().getManifestHeader(
581: Constants.EXPORT_PACKAGE);
582: if (header != null) {
583: ExportPackageObject[] pkgs = header
584: .getPackages();
585: for (int j = 0; j < pkgs.length; j++) {
586: String name = pkgs[j].getName();
587: if (names.add(name)
588: && (fHeader == null || !fHeader
589: .hasPackage(name)))
590: elements.add(new ImportItemWrapper(
591: pkgs[j]));
592: }
593: }
594: }
595:
596: }
597: }
598: for (int i = 0; i < models.length; i++) {
599: try {
600: // add un-exported packages in workspace non-binary plug-ins
601: IResource resource = models[i].getUnderlyingResource();
602: IProject project = resource != null ? resource
603: .getProject() : null;
604: if (project == null
605: || !project.hasNature(JavaCore.NATURE_ID)
606: || WorkspaceModelManager
607: .isBinaryProject(project)
608: || !project
609: .exists(ICoreConstants.MANIFEST_PATH))
610: continue;
611: IJavaProject jp = JavaCore.create(project);
612: IPackageFragmentRoot[] roots = jp
613: .getPackageFragmentRoots();
614: for (int j = 0; j < roots.length; j++) {
615: if (roots[j].getKind() == IPackageFragmentRoot.K_SOURCE
616: || (roots[j].getKind() == IPackageFragmentRoot.K_BINARY && !roots[j]
617: .isExternal())) {
618: IJavaElement[] children = roots[j]
619: .getChildren();
620: for (int k = 0; k < children.length; k++) {
621: IPackageFragment f = (IPackageFragment) children[k];
622: String name = f.getElementName();
623: if (name.equals("")) //$NON-NLS-1$
624: name = "."; //$NON-NLS-1$
625: if ((f.hasChildren() || f
626: .getNonJavaResources().length > 0)
627: && names.add(name))
628: conditional
629: .add(new ImportItemWrapper(f));
630: }
631: }
632: }
633: } catch (CoreException e) {
634: }
635: }
636: dialog.setElements(elements.toArray());
637: dialog.setConditionalElements(conditional.toArray());
638: }
639:
640: public void modelChanged(IModelChangedEvent event) {
641: if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
642: fHeader = null;
643: markStale();
644: return;
645: }
646:
647: if (Constants.IMPORT_PACKAGE.equals(event.getChangedProperty())) {
648: refresh();
649: // Bug 171896
650: // Since the model sends a CHANGE event instead of
651: // an INSERT event on the very first addition to the empty table
652: // Selection should fire here to take this first insertion into account
653: Object lastElement = fPackageViewer
654: .getElementAt(fPackageViewer.getTable()
655: .getItemCount() - 1);
656: if (lastElement != null) {
657: fPackageViewer.setSelection(new StructuredSelection(
658: lastElement));
659: }
660: return;
661: }
662:
663: Object[] objects = event.getChangedObjects();
664: for (int i = 0; i < objects.length; i++) {
665: if (objects[i] instanceof ImportPackageObject) {
666: ImportPackageObject object = (ImportPackageObject) objects[i];
667: switch (event.getChangeType()) {
668: case IModelChangedEvent.INSERT:
669: fPackageViewer.add(object);
670: fPackageViewer
671: .setSelection(new StructuredSelection(
672: object));
673: fPackageViewer.getTable().setFocus();
674: break;
675: case IModelChangedEvent.REMOVE:
676: Table table = fPackageViewer.getTable();
677: int index = table.getSelectionIndex();
678: fPackageViewer.remove(object);
679: table
680: .setSelection(index < table.getItemCount() ? index
681: : table.getItemCount() - 1);
682: break;
683: default:
684: fPackageViewer.refresh(object);
685: }
686: }
687: }
688: }
689:
690: public void refresh() {
691: fPackageViewer.refresh();
692: super .refresh();
693: }
694:
695: private void makeActions() {
696: fAddAction = new Action(PDEUIMessages.RequiresSection_add) {
697: public void run() {
698: handleAdd();
699: }
700: };
701: fAddAction.setEnabled(isEditable());
702: fGoToAction = new Action(
703: PDEUIMessages.ImportPackageSection_goToPackage) {
704: public void run() {
705: handleGoToPackage(fPackageViewer.getSelection());
706: }
707: };
708: fRemoveAction = new Action(PDEUIMessages.RequiresSection_delete) {
709: public void run() {
710: handleRemove();
711: }
712: };
713: fRemoveAction.setEnabled(isEditable());
714:
715: fPropertiesAction = new Action(
716: PDEUIMessages.ImportPackageSection_propertyAction) {
717: public void run() {
718: handleOpenProperties();
719: }
720: };
721: }
722:
723: protected void fillContextMenu(IMenuManager manager) {
724: final ISelection selection = fPackageViewer.getSelection();
725: manager.add(fAddAction);
726: boolean singleSelection = selection instanceof IStructuredSelection
727: && ((IStructuredSelection) selection).size() == 1;
728: if (singleSelection)
729: manager.add(fGoToAction);
730: manager.add(new Separator());
731: if (!selection.isEmpty())
732: manager.add(fRemoveAction);
733: getPage().getPDEEditor().getContributor()
734: .contextMenuAboutToShow(manager);
735:
736: if (((IModel) getPage().getModel()).getUnderlyingResource() != null) {
737: manager.add(new Separator());
738: if (singleSelection) {
739: manager
740: .add(new Action(
741: PDEUIMessages.DependencyExtentSearchResultPage_referencesInPlugin) {
742: public void run() {
743: doReferenceSearch(selection);
744: }
745: });
746: }
747: manager.add(new UnusedDependenciesAction(
748: (IPluginModelBase) getPage().getModel(), false));
749: }
750:
751: if (shouldEnableProperties(((IStructuredSelection) fPackageViewer
752: .getSelection()).toArray())) {
753: manager.add(new Separator());
754: manager.add(fPropertiesAction);
755: }
756: }
757:
758: private void doReferenceSearch(final ISelection sel) {
759: IPackageFragmentRoot[] roots = null;
760: try {
761: roots = getSourceRoots();
762: } catch (JavaModelException e) {
763: }
764: final IPackageFragment fragment = getPackageFragment(sel);
765: if (fragment != null && roots != null) {
766: IWorkingSetManager manager = PlatformUI.getWorkbench()
767: .getWorkingSetManager();
768: IWorkingSet set = manager.createWorkingSet("temp", roots); //$NON-NLS-1$
769: new FindReferencesInWorkingSetAction(getPage()
770: .getEditorSite(), new IWorkingSet[] { set })
771: .run(fragment);
772: manager.removeWorkingSet(set);
773: } else if (sel instanceof IStructuredSelection) {
774: IStructuredSelection selection = (IStructuredSelection) sel;
775: PackageObject importObject = (PackageObject) selection
776: .getFirstElement();
777: NewSearchUI.runQueryInBackground(new BlankQuery(
778: importObject));
779: }
780: }
781:
782: private IPackageFragmentRoot[] getSourceRoots()
783: throws JavaModelException {
784: ArrayList result = new ArrayList();
785: IProject project = getPage().getPDEEditor().getCommonProject();
786: // would normally return array of size 0, but by returning null can optimize the search to run faster.
787: if (project == null) {
788: return null;
789: }
790: IPackageFragmentRoot[] roots = JavaCore.create(project)
791: .getPackageFragmentRoots();
792: for (int i = 0; i < roots.length; i++) {
793: if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE
794: || (roots[i].isArchive() && !roots[i].isExternal()))
795: result.add(roots[i]);
796: }
797: return (IPackageFragmentRoot[]) result
798: .toArray(new IPackageFragmentRoot[result.size()]);
799: }
800:
801: private BundleInputContext getBundleContext() {
802: InputContextManager manager = getPage().getPDEEditor()
803: .getContextManager();
804: return (BundleInputContext) manager
805: .findContext(BundleInputContext.CONTEXT_ID);
806: }
807:
808: private IBundleModel getBundleModel() {
809: BundleInputContext context = getBundleContext();
810: return (context != null) ? (IBundleModel) context.getModel()
811: : null;
812:
813: }
814:
815: private String getLineDelimiter() {
816: BundleInputContext inputContext = getBundleContext();
817: if (inputContext != null) {
818: return inputContext.getLineDelimiter();
819: }
820: return System.getProperty("line.separator"); //$NON-NLS-1$
821: }
822:
823: private IBundle getBundle() {
824: IBundleModel model = getBundleModel();
825: return (model != null) ? model.getBundle() : null;
826: }
827:
828: private String getVersionAttribute() {
829: return getVersionAttribute(getBundle());
830: }
831:
832: private String getVersionAttribute(IBundle bundle) {
833: int manifestVersion = BundlePluginBase
834: .getBundleManifestVersion(bundle);
835: return (manifestVersion < 2) ? ICoreConstants.PACKAGE_SPECIFICATION_VERSION
836: : Constants.VERSION_ATTRIBUTE;
837: }
838:
839: private Set getForbiddenIds() {
840: HashSet set = new HashSet();
841: IPluginModelBase model = (IPluginModelBase) getPage()
842: .getPDEEditor().getAggregateModel();
843: String id = model.getPluginBase().getId();
844: if (id != null)
845: set.add(id);
846: IPluginImport[] imports = model.getPluginBase().getImports();
847: State state = TargetPlatformHelper.getState();
848: for (int i = 0; i < imports.length; i++) {
849: addDependency(state, imports[i].getId(), set);
850: }
851: return set;
852: }
853:
854: private void addDependency(State state, String bundleID, Set set) {
855: if (bundleID == null || !set.add(bundleID))
856: return;
857:
858: BundleDescription desc = state.getBundle(bundleID, null);
859: if (desc == null)
860: return;
861:
862: BundleDescription[] fragments = desc.getFragments();
863: for (int i = 0; i < fragments.length; i++) {
864: addDependency(state, fragments[i].getSymbolicName(), set);
865: }
866:
867: BundleSpecification[] specs = desc.getRequiredBundles();
868: for (int j = 0; j < specs.length; j++) {
869: if (specs[j].isResolved() && specs[j].isExported()) {
870: addDependency(state, specs[j].getName(), set);
871: }
872: }
873: }
874:
875: protected boolean createCount() {
876: return true;
877: }
878:
879: private boolean shouldEnableProperties(Object[] selected) {
880: if (selected.length == 0)
881: return false;
882: if (selected.length == 1)
883: return true;
884:
885: String version = ((ImportPackageObject) selected[0])
886: .getVersion();
887: boolean optional = ((ImportPackageObject) selected[0])
888: .isOptional();
889: for (int i = 1; i < selected.length; i++) {
890: ImportPackageObject object = (ImportPackageObject) selected[i];
891: if (version == null) {
892: if (object.getVersion() != null
893: || !(optional == object.isOptional())) {
894: return false;
895: }
896: } else if (!version.equals(object.getVersion())
897: || !(optional == object.isOptional())) {
898: return false;
899: }
900: }
901: return true;
902: }
903:
904: }
|