KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > editor > plugin > ExtensionsSection


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.editor.plugin;
12 import java.util.ArrayList JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.Hashtable JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.Platform;
21 import org.eclipse.jface.action.Action;
22 import org.eclipse.jface.action.IAction;
23 import org.eclipse.jface.action.IMenuManager;
24 import org.eclipse.jface.action.MenuManager;
25 import org.eclipse.jface.action.Separator;
26 import org.eclipse.jface.action.ToolBarManager;
27 import org.eclipse.jface.util.IPropertyChangeListener;
28 import org.eclipse.jface.util.PropertyChangeEvent;
29 import org.eclipse.jface.viewers.ISelection;
30 import org.eclipse.jface.viewers.IStructuredSelection;
31 import org.eclipse.jface.viewers.ITreeContentProvider;
32 import org.eclipse.jface.viewers.LabelProvider;
33 import org.eclipse.jface.viewers.StructuredSelection;
34 import org.eclipse.jface.viewers.StructuredViewer;
35 import org.eclipse.jface.viewers.TreeViewer;
36 import org.eclipse.jface.wizard.WizardDialog;
37 import org.eclipse.pde.core.IModelChangedEvent;
38 import org.eclipse.pde.core.IModelChangedListener;
39 import org.eclipse.pde.core.plugin.IExtensions;
40 import org.eclipse.pde.core.plugin.IPluginAttribute;
41 import org.eclipse.pde.core.plugin.IPluginBase;
42 import org.eclipse.pde.core.plugin.IPluginElement;
43 import org.eclipse.pde.core.plugin.IPluginExtension;
44 import org.eclipse.pde.core.plugin.IPluginModelBase;
45 import org.eclipse.pde.core.plugin.IPluginObject;
46 import org.eclipse.pde.core.plugin.IPluginParent;
47 import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
48 import org.eclipse.pde.internal.core.PDECore;
49 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
50 import org.eclipse.pde.internal.core.ischema.ISchema;
51 import org.eclipse.pde.internal.core.ischema.ISchemaComplexType;
52 import org.eclipse.pde.internal.core.ischema.ISchemaElement;
53 import org.eclipse.pde.internal.core.schema.SchemaRegistry;
54 import org.eclipse.pde.internal.core.text.IDocumentNode;
55 import org.eclipse.pde.internal.core.text.plugin.IDocumentElement;
56 import org.eclipse.pde.internal.core.text.plugin.IDocumentExtension;
57 import org.eclipse.pde.internal.ui.PDELabelProvider;
58 import org.eclipse.pde.internal.ui.PDEPlugin;
59 import org.eclipse.pde.internal.ui.PDEPluginImages;
60 import org.eclipse.pde.internal.ui.PDEUIMessages;
61 import org.eclipse.pde.internal.ui.editor.PDEFormPage;
62 import org.eclipse.pde.internal.ui.editor.TreeSection;
63 import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
64 import org.eclipse.pde.internal.ui.editor.actions.SortAction;
65 import org.eclipse.pde.internal.ui.editor.contentassist.XMLElementProposalComputer;
66 import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
67 import org.eclipse.pde.internal.ui.parts.TreePart;
68 import org.eclipse.pde.internal.ui.search.PluginSearchActionGroup;
69 import org.eclipse.pde.internal.ui.util.SWTUtil;
70 import org.eclipse.pde.internal.ui.util.SharedLabelProvider;
71 import org.eclipse.pde.internal.ui.wizards.extension.ExtensionEditorWizard;
72 import org.eclipse.pde.internal.ui.wizards.extension.NewExtensionWizard;
73 import org.eclipse.pde.ui.IExtensionEditorWizard;
74 import org.eclipse.swt.SWT;
75 import org.eclipse.swt.custom.BusyIndicator;
76 import org.eclipse.swt.events.DisposeEvent;
77 import org.eclipse.swt.events.DisposeListener;
78 import org.eclipse.swt.graphics.Cursor;
79 import org.eclipse.swt.graphics.Image;
80 import org.eclipse.swt.internal.BidiUtil;
81 import org.eclipse.swt.widgets.Composite;
82 import org.eclipse.swt.widgets.Display;
83 import org.eclipse.swt.widgets.ToolBar;
84 import org.eclipse.swt.widgets.Tree;
85 import org.eclipse.swt.widgets.TreeItem;
86 import org.eclipse.ui.actions.ActionContext;
87 import org.eclipse.ui.actions.ActionFactory;
88 import org.eclipse.ui.dialogs.PatternFilter;
89 import org.eclipse.ui.forms.widgets.FormToolkit;
90 import org.eclipse.ui.forms.widgets.Section;
91
92 public class ExtensionsSection extends TreeSection implements IModelChangedListener, IPropertyChangeListener {
93     private TreeViewer fExtensionTree;
94     private Image fExtensionImage;
95     private Image fGenericElementImage;
96     private FormFilteredTree fFilteredTree;
97     private SchemaRegistry fSchemaRegistry;
98     private Action fNewExtensionAction;
99     private Hashtable JavaDoc fEditorWizards;
100     private SortAction fSortAction;
101     private CollapseAction fCollapseAction;
102
103     private static final String JavaDoc[] COMMON_LABEL_PROPERTIES = {
104         "label", //$NON-NLS-1$
105
"name", //$NON-NLS-1$
106
"id"}; //$NON-NLS-1$
107

108     class ExtensionContentProvider extends DefaultContentProvider
109     implements
110     ITreeContentProvider {
111         public Object JavaDoc[] getChildren(Object JavaDoc parent) {
112             Object JavaDoc[] children = null;
113             if (parent instanceof IPluginBase)
114                 children = ((IPluginBase) parent).getExtensions();
115             else if (parent instanceof IPluginExtension) {
116                 children = ((IPluginExtension) parent).getChildren();
117             } else if (parent instanceof IPluginElement) {
118                 children = ((IPluginElement) parent).getChildren();
119             }
120             if (children == null)
121                 children = new Object JavaDoc[0];
122             return children;
123         }
124         public boolean hasChildren(Object JavaDoc parent) {
125             return getChildren(parent).length > 0;
126         }
127         public Object JavaDoc getParent(Object JavaDoc child) {
128             if (child instanceof IPluginExtension) {
129                 return ((IPluginModelBase)getPage().getModel()).getPluginBase();
130             }
131             if (child instanceof IPluginObject)
132                 return ((IPluginObject) child).getParent();
133             return null;
134         }
135         public Object JavaDoc[] getElements(Object JavaDoc parent) {
136             return getChildren(parent);
137         }
138     }
139     class ExtensionLabelProvider extends LabelProvider {
140         public String JavaDoc getText(Object JavaDoc obj) {
141             return resolveObjectName(obj);
142         }
143         public Image getImage(Object JavaDoc obj) {
144             return resolveObjectImage(obj);
145         }
146     }
147     public ExtensionsSection(PDEFormPage page, Composite parent) {
148         super(page, parent, Section.DESCRIPTION, new String JavaDoc[]{
149                 PDEUIMessages.ManifestEditor_DetailExtension_new,
150                 PDEUIMessages.ManifestEditor_DetailExtension_edit,
151                 null,
152                 PDEUIMessages.ManifestEditor_DetailExtension_up,
153                 PDEUIMessages.ManifestEditor_DetailExtension_down});
154         fHandleDefaultButton = false;
155     }
156     private static void addItemsForExtensionWithSchema(MenuManager menu,
157             IPluginExtension extension, IPluginParent parent) {
158         ISchema schema = getSchema(extension);
159         String JavaDoc tagName = (parent == extension ? "extension" : parent.getName()); //$NON-NLS-1$
160
ISchemaElement elementInfo = schema.findElement(tagName);
161         
162         if ((elementInfo != null) &&
163                 (elementInfo.getType() instanceof ISchemaComplexType) &&
164                 (parent instanceof IDocumentNode)) {
165             // We have a schema complex type. Either the element has attributes
166
// or the element has children.
167
// Generate the list of element proposals
168
HashSet JavaDoc elementSet = XMLElementProposalComputer
169                     .computeElementProposal(elementInfo, (IDocumentNode)parent);
170             // Create a corresponding menu entry for each element proposal
171
Iterator JavaDoc iterator = elementSet.iterator();
172             while (iterator.hasNext()) {
173                 Action action = new NewElementAction((ISchemaElement) iterator
174                         .next(), parent);
175                 menu.add(action);
176             }
177         }
178     }
179
180     /**
181      * @param parent
182      * @return
183      */

184     private static ISchema getSchema(IPluginParent parent) {
185         if (parent instanceof IPluginExtension) {
186             return getSchema((IPluginExtension)parent);
187         } else if (parent instanceof IPluginElement) {
188             return getSchema((IPluginElement)parent);
189         } else {
190             return null;
191         }
192     }
193     
194     private static ISchema getSchema(IPluginExtension extension) {
195         String JavaDoc point = extension.getPoint();
196         SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
197         return registry.getSchema(point);
198     }
199     
200     /**
201      * @param element
202      * @return
203      */

204     static ISchemaElement getSchemaElement(IPluginElement element) {
205         ISchema schema = getSchema(element);
206         if (schema != null) {
207             return schema.findElement(element.getName());
208         }
209         return null;
210     }
211     
212     /**
213      * @param element
214      * @return
215      */

216     private static ISchema getSchema(IPluginElement element) {
217         IPluginObject parent = element.getParent();
218         while (parent != null && !(parent instanceof IPluginExtension)) {
219             parent = parent.getParent();
220         }
221         if (parent != null) {
222             return getSchema((IPluginExtension) parent);
223         }
224         return null;
225     }
226     
227     public void createClient(Section section, FormToolkit toolkit) {
228         initializeImages();
229         Composite container = createClientContainer(section, 2, toolkit);
230         TreePart treePart = getTreePart();
231         createViewerPartControl(container, SWT.MULTI, 2, toolkit);
232         fExtensionTree = treePart.getTreeViewer();
233         fExtensionTree.setContentProvider(new ExtensionContentProvider());
234         fExtensionTree.setLabelProvider(new ExtensionLabelProvider());
235         toolkit.paintBordersFor(container);
236         section.setClient(container);
237         section.setDescription(PDEUIMessages.ExtensionsSection_sectionDescExtensionsMaster);
238         // See Bug # 160554: Set text before text client
239
section.setText(PDEUIMessages.ManifestEditor_DetailExtension_title);
240         initialize((IPluginModelBase) getPage().getModel());
241         createSectionToolbar(section, toolkit);
242         // Create the adapted listener for the filter entry field
243
fFilteredTree.createUIListenerEntryFilter(this);
244     }
245     
246     /**
247      * @param section
248      * @param toolkit
249      */

250     private void createSectionToolbar(Section section, FormToolkit toolkit) {
251         ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
252         ToolBar toolbar = toolBarManager.createControl(section);
253         final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
254         toolbar.setCursor(handCursor);
255         // Cursor needs to be explicitly disposed
256
toolbar.addDisposeListener(new DisposeListener() {
257             public void widgetDisposed(DisposeEvent e) {
258                 if ((handCursor != null) &&
259                         (handCursor.isDisposed() == false)) {
260                     handCursor.dispose();
261                 }
262             }
263         });
264         // Add sort action to the tool bar
265
fSortAction = new SortAction(fExtensionTree,
266                 PDEUIMessages.ExtensionsPage_sortAlpha, null, null, this);
267         toolBarManager.add(fSortAction);
268         // Add collapse action to the tool bar
269
fCollapseAction = new CollapseAction(fExtensionTree,
270                 PDEUIMessages.ExtensionsPage_collapseAll);
271         toolBarManager.add(fCollapseAction);
272
273         toolBarManager.update(true);
274
275         section.setTextClient(toolbar);
276     }
277     
278     protected void selectionChanged(IStructuredSelection selection) {
279         getPage().getPDEEditor().setSelection(selection);
280         updateUpDownButtons(selection.getFirstElement());
281         getTreePart().setButtonEnabled(1, isSelectionEditable(selection));
282     }
283     protected void handleDoubleClick(IStructuredSelection selection) {
284         /*
285          * PropertiesAction action = new
286          * PropertiesAction(getFormPage().getEditor()); action.run();
287          */

288     }
289     protected void buttonSelected(int index) {
290         switch (index) {
291         case 0 :
292             handleNew();
293             break;
294         case 1 :
295             handleEdit();
296             break;
297         case 2:
298             // blank
299
break;
300         case 3 :
301             handleMove(true);
302             break;
303         case 4 :
304             handleMove(false);
305             break;
306         }
307     }
308     
309     /* (non-Javadoc)
310      * @see org.eclipse.ui.forms.AbstractFormPart#dispose()
311      */

312     public void dispose() {
313         // Explicitly call the dispose method on the extensions tree
314
if (fFilteredTree != null) {
315             fFilteredTree.dispose();
316         }
317         fEditorWizards = null;
318         IPluginModelBase model = (IPluginModelBase) getPage().getPDEEditor()
319         .getAggregateModel();
320         if (model!=null)
321             model.removeModelChangedListener(this);
322         super.dispose();
323     }
324     
325     /* (non-Javadoc)
326      * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
327      */

328     public boolean doGlobalAction(String JavaDoc actionId) {
329         
330         if (!isEditable()) { return false; }
331         
332         if (actionId.equals(ActionFactory.DELETE.getId())) {
333             handleDelete();
334             return true;
335         }
336         if (actionId.equals(ActionFactory.CUT.getId())) {
337             // delete here and let the editor transfer
338
// the selection to the clipboard
339
handleDelete();
340             return false;
341         }
342         if (actionId.equals(ActionFactory.PASTE.getId())) {
343             doPaste();
344             return true;
345         }
346         
347         return false;
348     }
349     
350     public boolean setFormInput(Object JavaDoc object) {
351         if (object instanceof IPluginExtension
352                 || object instanceof IPluginElement) {
353             fExtensionTree.setSelection(new StructuredSelection(object), true);
354             return true;
355         }
356         return false;
357     }
358     protected void fillContextMenu(IMenuManager manager) {
359         ISelection selection = fExtensionTree.getSelection();
360         IStructuredSelection ssel = (IStructuredSelection) selection;
361         IMenuManager newMenu = null;
362         if (ssel.size() == 1) {
363             Object JavaDoc object = ssel.getFirstElement();
364             if (object instanceof IPluginParent) {
365                 IPluginParent parent = (IPluginParent) object;
366                 if (parent.getModel().getUnderlyingResource() != null) {
367                     newMenu = fillContextMenu(getPage(), parent, manager);
368                     manager.add(new Separator());
369                 }
370             }
371         } else if (ssel.size() > 1) {
372             // multiple
373
Action delAction = new Action() {
374                 public void run() {
375                     handleDelete();
376                 }
377             };
378             delAction.setText(PDEUIMessages.Actions_delete_label);
379             manager.add(delAction);
380             manager.add(new Separator());
381             delAction.setEnabled(isEditable());
382         }
383         if (newMenu == null) {
384             newMenu = new MenuManager(PDEUIMessages.Menus_new_label);
385             manager.add(newMenu);
386         }
387         if (ssel.size() == 1) {
388             manager.add(new Separator());
389             Object JavaDoc object = ssel.getFirstElement();
390             if (object instanceof IPluginExtension) {
391                 PluginSearchActionGroup actionGroup = new PluginSearchActionGroup();
392                 actionGroup.setContext(new ActionContext(selection));
393                 actionGroup.fillContextMenu(manager);
394                 manager.add(new Separator());
395             }
396             //manager.add(new PropertiesAction(getFormPage().getEditor()));
397
}
398         if (!newMenu.isEmpty())
399             newMenu.add(new Separator());
400         newMenu.add(fNewExtensionAction);
401         manager.add(new Separator());
402         manager.add(new Separator());
403         getPage().getPDEEditor().getContributor().addClipboardActions(manager);
404         getPage().getPDEEditor().getContributor().contextMenuAboutToShow(
405                 manager, false);
406
407     }
408     static IMenuManager fillContextMenu(PDEFormPage page,
409             final IPluginParent parent, IMenuManager manager) {
410         return fillContextMenu(page, parent, manager, false);
411     }
412     static IMenuManager fillContextMenu(PDEFormPage page,
413             final IPluginParent parent, IMenuManager manager,
414             boolean addSiblingItems) {
415         return fillContextMenu(page, parent, manager, addSiblingItems, true);
416     }
417     static IMenuManager fillContextMenu(PDEFormPage page,
418             final IPluginParent parent, IMenuManager manager,
419             boolean addSiblingItems, boolean fullMenu) {
420         MenuManager menu = new MenuManager(PDEUIMessages.Menus_new_label);
421         IPluginExtension extension = getExtension(parent);
422         ISchema schema = getSchema(extension);
423         if (schema == null) {
424             menu.add(new NewElementAction(null, parent));
425         } else {
426             addItemsForExtensionWithSchema(menu, extension, parent);
427             if (addSiblingItems) {
428                 IPluginObject parentsParent = parent.getParent();
429                 if (!(parentsParent instanceof IPluginExtension)) {
430                     IPluginParent pparent = (IPluginParent) parentsParent;
431                     menu.add(new Separator());
432                     addItemsForExtensionWithSchema(menu, extension, pparent);
433                 }
434             }
435         }
436         manager.add(menu);
437         manager.add(new Separator());
438         if (fullMenu) {
439             Action deleteAction = new Action(PDEUIMessages.Actions_delete_label) {
440                 public void run() {
441                     try {
442                         IPluginObject parentsParent = parent.getParent();
443                         if (parent instanceof IPluginExtension) {
444                             IPluginBase plugin = (IPluginBase) parentsParent;
445                             plugin.remove((IPluginExtension) parent);
446                         } else {
447                             IPluginParent parentElement = (IPluginParent) parent
448                             .getParent();
449                             parentElement.remove(parent);
450                         }
451                     } catch (CoreException e) {
452                     }
453                 }
454             };
455             deleteAction.setEnabled(page.getModel().isEditable());
456             manager.add(deleteAction);
457         }
458         return menu;
459     }
460     static IPluginExtension getExtension(IPluginParent parent) {
461         while (parent != null && !(parent instanceof IPluginExtension)) {
462             parent = (IPluginParent) parent.getParent();
463         }
464         return (IPluginExtension) parent;
465     }
466     private void handleDelete() {
467         IStructuredSelection sel = (IStructuredSelection) fExtensionTree
468         .getSelection();
469         if (sel.isEmpty())
470             return;
471         for (Iterator JavaDoc iter = sel.iterator(); iter.hasNext();) {
472             IPluginObject object = (IPluginObject) iter.next();
473             try {
474                 if (object instanceof IPluginElement) {
475                     IPluginElement ee = (IPluginElement) object;
476                     IPluginParent parent = (IPluginParent) ee.getParent();
477                     parent.remove(ee);
478                 } else if (object instanceof IPluginExtension) {
479                     IPluginExtension extension = (IPluginExtension) object;
480                     IPluginBase plugin = extension.getPluginBase();
481                     plugin.remove(extension);
482                 }
483             } catch (CoreException e) {
484                 PDEPlugin.logException(e);
485             }
486         }
487     }
488     private void handleNew() {
489         final IProject project = getPage().getPDEEditor().getCommonProject();
490         BusyIndicator.showWhile(fExtensionTree.getTree().getDisplay(),
491                 new Runnable JavaDoc() {
492             public void run() {
493                 ((ManifestEditor)getPage().getEditor()).ensurePluginContextPresence();
494                 NewExtensionWizard wizard = new NewExtensionWizard(
495                         project, (IPluginModelBase) getPage()
496                         .getModel(), (ManifestEditor) getPage()
497                         .getPDEEditor()) {
498                     public boolean performFinish() {
499                         return super.performFinish();
500                     }
501                 };
502                 WizardDialog dialog = new WizardDialog(PDEPlugin
503                         .getActiveWorkbenchShell(), wizard);
504                 dialog.create();
505                 SWTUtil.setDialogSize(dialog, 500, 500);
506                 dialog.open();
507             }
508         });
509     }
510     private void handleEdit(IConfigurationElement element, IStructuredSelection selection) {
511         IProject project = getPage().getPDEEditor().getCommonProject();
512         IPluginModelBase model = (IPluginModelBase)getPage().getModel();
513         try {
514             final IExtensionEditorWizard wizard = (IExtensionEditorWizard)element.createExecutableExtension("class"); //$NON-NLS-1$
515
wizard.init(project, model, selection);
516             BusyIndicator.showWhile(fExtensionTree.getTree().getDisplay(),
517                     new Runnable JavaDoc() {
518                 public void run() {
519                     WizardDialog dialog = new WizardDialog(PDEPlugin
520                             .getActiveWorkbenchShell(), wizard);
521                     dialog.create();
522                     SWTUtil.setDialogSize(dialog, 500, 500);
523                     dialog.open();
524                 }
525             });
526         }
527         catch (CoreException e) {
528             PDEPlugin.logException(e);
529         }
530     }
531     private void handleEdit() {
532         final IStructuredSelection selection = (IStructuredSelection)fExtensionTree.getSelection();
533         ArrayList JavaDoc editorWizards = getEditorWizards(selection);
534         if (editorWizards==null) return;
535         if (editorWizards.size()==1) {
536             // open the wizard directly
537
handleEdit((IConfigurationElement)editorWizards.get(0), selection);
538         }
539         else {
540             IProject project = getPage().getPDEEditor().getCommonProject();
541             IPluginModelBase model = (IPluginModelBase)getPage().getModel();
542             final ExtensionEditorWizard wizard = new ExtensionEditorWizard(project, model, selection);
543             BusyIndicator.showWhile(fExtensionTree.getTree().getDisplay(),
544                     new Runnable JavaDoc() {
545                 public void run() {
546                     WizardDialog dialog = new WizardDialog(PDEPlugin
547                             .getActiveWorkbenchShell(), wizard);
548                     dialog.create();
549                     SWTUtil.setDialogSize(dialog, 500, 500);
550                     dialog.open();
551                 }
552             });
553         }
554     }
555     private ArrayList JavaDoc getEditorWizards(IStructuredSelection selection) {
556         if (selection.size()!=1) return null;
557         Object JavaDoc obj = selection.getFirstElement();
558         String JavaDoc pointId = null;
559         if (obj instanceof IPluginExtension) {
560             pointId = ((IPluginExtension)obj).getPoint();
561         }
562         else if (obj instanceof IPluginElement) {
563             IPluginObject parent = ((IPluginElement)obj).getParent();
564             while (parent!=null) {
565                 if (parent instanceof IPluginExtension) {
566                     pointId = ((IPluginExtension)parent).getPoint();
567                     break;
568                 }
569                 parent = parent.getParent();
570             }
571         }
572         if (pointId==null) return null;
573         if (fEditorWizards==null)
574             loadExtensionWizards();
575         return (ArrayList JavaDoc)fEditorWizards.get(pointId);
576     }
577
578     private void loadExtensionWizards() {
579         fEditorWizards = new Hashtable JavaDoc();
580         IConfigurationElement [] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.pde.ui.newExtension"); //$NON-NLS-1$
581
for (int i=0; i<elements.length; i++) {
582             IConfigurationElement element = elements[i];
583             if (element.getName().equals("editorWizard")) { //$NON-NLS-1$
584
String JavaDoc pointId = element.getAttribute("point"); //$NON-NLS-1$
585
if (pointId==null) continue;
586                 ArrayList JavaDoc list = (ArrayList JavaDoc)fEditorWizards.get(pointId);
587                 if (list==null) {
588                     list = new ArrayList JavaDoc();
589                     fEditorWizards.put(pointId, list);
590                 }
591                 list.add(element);
592             }
593         }
594     }
595     private boolean isSelectionEditable(IStructuredSelection selection) {
596         if (!getPage().getModel().isEditable())
597             return false;
598         return getEditorWizards(selection)!=null;
599     }
600
601     public void initialize(IPluginModelBase model) {
602         fExtensionTree.setInput(model.getPluginBase());
603         selectFirstExtension();
604         boolean editable = model.isEditable();
605         TreePart treePart = getTreePart();
606         treePart.setButtonEnabled(0, editable);
607         treePart.setButtonEnabled(1, false);
608         treePart.setButtonEnabled(3, false);
609         treePart.setButtonEnabled(4, false);
610         model.addModelChangedListener(this);
611         fNewExtensionAction = new Action() {
612             public void run() {
613                 handleNew();
614             }
615         };
616         fNewExtensionAction.setText(PDEUIMessages.ManifestEditor_DetailExtension_newExtension);
617         fNewExtensionAction
618         .setImageDescriptor(PDEPluginImages.DESC_EXTENSION_OBJ);
619         fNewExtensionAction.setEnabled(editable);
620     }
621     private void selectFirstExtension() {
622         Tree tree = fExtensionTree.getTree();
623         TreeItem [] items = tree.getItems();
624         if (items.length==0) return;
625         TreeItem firstItem = items[0];
626         Object JavaDoc obj = firstItem.getData();
627         fExtensionTree.setSelection(new StructuredSelection(obj));
628     }
629     void fireSelection() {
630         fExtensionTree.setSelection(fExtensionTree.getSelection());
631     }
632     public void initializeImages() {
633         PDELabelProvider provider = PDEPlugin.getDefault().getLabelProvider();
634         fExtensionImage = provider.get(PDEPluginImages.DESC_EXTENSION_OBJ);
635         fGenericElementImage = provider
636         .get(PDEPluginImages.DESC_GENERIC_XML_OBJ);
637     }
638     public void refresh() {
639         IPluginModelBase model = (IPluginModelBase)getPage().getModel();
640         fExtensionTree.setInput(model.getPluginBase());
641         selectFirstExtension();
642         getManagedForm().fireSelectionChanged(ExtensionsSection.this,
643                 fExtensionTree.getSelection());
644         super.refresh();
645     }
646
647     public void modelChanged(IModelChangedEvent event) {
648         if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
649             markStale();
650             return;
651         }
652         Object JavaDoc changeObject = event.getChangedObjects()[0];
653         if (changeObject instanceof IPluginBase
654                 && event.getChangeType() == IModelChangedEvent.CHANGE
655                 && event.getChangedProperty().equals(
656                         IExtensions.P_EXTENSION_ORDER)) {
657             IStructuredSelection sel = (IStructuredSelection) fExtensionTree
658             .getSelection();
659             IPluginExtension extension = (IPluginExtension) sel
660             .getFirstElement();
661             fExtensionTree.refresh();
662             fExtensionTree.setSelection(new StructuredSelection(extension));
663             return;
664         }
665         if (changeObject instanceof IPluginExtension
666                 || (changeObject instanceof IPluginElement && ((IPluginElement)changeObject).getParent() instanceof IPluginParent)) {
667             IPluginObject pobj = (IPluginObject) changeObject;
668             IPluginObject parent = changeObject instanceof IPluginExtension
669             ? ((IPluginModelBase) getPage().getModel()).getPluginBase()
670                     : pobj.getParent();
671             if (event.getChangeType() == IModelChangedEvent.INSERT) {
672                 fExtensionTree.add(parent, pobj);
673                 fExtensionTree.setSelection(
674                         new StructuredSelection(changeObject), true);
675                 fExtensionTree.getTree().setFocus();
676             } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
677                 fExtensionTree.remove(pobj);
678             } else {
679                 if (event.getChangedProperty().equals(
680                         IPluginParent.P_SIBLING_ORDER)) {
681                     IStructuredSelection sel = (IStructuredSelection) fExtensionTree
682                     .getSelection();
683                     IPluginObject child = (IPluginObject) sel.getFirstElement();
684                     fExtensionTree.refresh(child.getParent());
685                     fExtensionTree.setSelection(new StructuredSelection(child));
686                 } else {
687                     fExtensionTree.update(changeObject, null);
688                 }
689             }
690         }
691     }
692
693     private Image resolveObjectImage(Object JavaDoc obj) {
694         if (obj instanceof IPluginExtension) {
695             return fExtensionImage;
696         }
697         Image elementImage = fGenericElementImage;
698         if (obj instanceof IPluginElement) {
699             IPluginElement element = (IPluginElement) obj;
700             Image customImage = getCustomImage(element);
701             if (customImage != null)
702                 elementImage = customImage;
703             String JavaDoc bodyText = element.getText();
704             boolean hasBodyText = bodyText!=null&&bodyText.length()>0;
705             if (hasBodyText) {
706                 elementImage = PDEPlugin.getDefault().getLabelProvider().get(
707                         elementImage, SharedLabelProvider.F_EDIT);
708             }
709         }
710         return elementImage;
711     }
712
713     private static boolean isStorageModel(IPluginObject object) {
714         IPluginModelBase modelBase = object.getPluginModel();
715         return modelBase.getInstallLocation()==null;
716     }
717
718     static Image getCustomImage(IPluginElement element) {
719         if (isStorageModel(element))return null;
720         ISchemaElement elementInfo = getSchemaElement(element);
721         if (elementInfo != null && elementInfo.getIconProperty() != null) {
722             String JavaDoc iconProperty = elementInfo.getIconProperty();
723             IPluginAttribute att = element.getAttribute(iconProperty);
724             String JavaDoc iconPath = null;
725             if (att != null && att.getValue() != null) {
726                 iconPath = att.getValue();
727             }
728             if (iconPath != null) {
729                 //OK, we have an icon path relative to the plug-in
730
return getImageFromPlugin(element, iconPath);
731             }
732         }
733         return null;
734     }
735
736     private static Image getImageFromPlugin(IPluginElement element,
737             String JavaDoc iconPathName) {
738         // 39283 - ignore icon paths that
739
// point at plugin.properties
740
if (iconPathName.startsWith("%")) //$NON-NLS-1$
741
return null;
742
743         IPluginModelBase model = element.getPluginModel();
744         if (model == null)
745             return null;
746
747         return PDEPlugin.getDefault().getLabelProvider().getImageFromPlugin(model, iconPathName);
748     }
749     private String JavaDoc resolveObjectName(Object JavaDoc obj) {
750         return resolveObjectName(getSchemaRegistry(), obj);
751     }
752
753     private SchemaRegistry getSchemaRegistry() {
754         if (fSchemaRegistry == null)
755             fSchemaRegistry = PDECore.getDefault().getSchemaRegistry();
756         return fSchemaRegistry;
757     }
758
759     public static String JavaDoc resolveObjectName(SchemaRegistry schemaRegistry, Object JavaDoc obj) {
760         boolean fullNames = PDEPlugin.isFullNameModeEnabled();
761         if (obj instanceof IPluginExtension) {
762             IPluginExtension extension = (IPluginExtension) obj;
763             if (!fullNames) {
764                 return extension.getPoint();
765             }
766             if (extension.getName() != null)
767                 return extension.getTranslatedName();
768             ISchema schema = schemaRegistry.getSchema(extension.getPoint());
769             // try extension point schema definition
770
if (schema != null) {
771                 // exists
772
return schema.getName();
773             }
774             return extension.getPoint();
775         } else if (obj instanceof IPluginElement) {
776             IPluginElement element = (IPluginElement) obj;
777             String JavaDoc baseName = element.getName();
778             String JavaDoc fullName = null;
779             ISchemaElement elementInfo = getSchemaElement(element);
780             IPluginAttribute labelAtt = null;
781             if (elementInfo != null && elementInfo.getLabelProperty() != null) {
782                 labelAtt = element.getAttribute(elementInfo.getLabelProperty());
783             }
784             if (labelAtt == null) {
785                 // try some hard-coded attributes that
786
// are used frequently
787
for (int i = 0; i < COMMON_LABEL_PROPERTIES.length; i++) {
788                     labelAtt = element.getAttribute(COMMON_LABEL_PROPERTIES[i]);
789                     if (labelAtt != null)
790                         break;
791                 }
792                 if (labelAtt == null) {
793                     // Last try - if there is only one attribute,
794
// use that
795
if (element.getAttributeCount() == 1)
796                         labelAtt = element.getAttributes()[0];
797                 }
798             }
799             if (labelAtt != null && labelAtt.getValue() != null)
800                 fullName = stripShortcuts(labelAtt.getValue());
801             fullName = element.getResourceString(fullName);
802             if (fullNames)
803                 return fullName != null ? fullName : baseName;
804             if (fullName == null)
805                 return baseName;
806             // Bug 183417 - Bidi3.3: Elements' labels in the extensions page in the fragment manifest characters order is incorrect
807
// add RTL zero length character just before the ( and the LTR character just after to ensure:
808
// 1. The leading parenthesis takes proper orientation when running in bidi configuration
809
// Assumption: baseName (taken from the schema definition), is only latin characters and is therefore always displayed LTR
810
if (BidiUtil.isBidiPlatform())
811                 return fullName + " \u200f(\u200e" + baseName + ')'; //$NON-NLS-1$
812
return fullName + " (" + baseName + ')'; //$NON-NLS-1$
813
}
814         return obj.toString();
815     }
816     public void setFocus() {
817         if (fExtensionTree != null)
818             fExtensionTree.getTree().setFocus();
819     }
820     public static String JavaDoc stripShortcuts(String JavaDoc input) {
821         StringBuffer JavaDoc output = new StringBuffer JavaDoc();
822         for (int i = 0; i < input.length(); i++) {
823             char c = input.charAt(i);
824             if (c == '&')
825                 continue;
826             else if (c == '@')
827                 break;
828             output.append(c);
829         }
830         return output.toString();
831     }
832     
833     /* (non-Javadoc)
834      * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
835      */

836     protected boolean canPaste(Object JavaDoc targetObject, Object JavaDoc[] sourceObjects) {
837         // Note: Multi-select in tree viewer is disabled; but, this function
838
// can support multiple source objects
839
// Rule: Element source objects are always pasted as children of the
840
// target object (if allowable)
841
// Rule: Extension source objects are always pasted and are independent
842
// of the target object
843
// Ensure all the sourceObjects are either extensions or elements
844
boolean allExtensions = true;
845         boolean allElements = true;
846         for (int i = 0; i < sourceObjects.length; i++) {
847             if (sourceObjects[i] instanceof IPluginExtension) {
848                 allElements = false;
849             } else if (sourceObjects[i] instanceof IPluginElement) {
850                 allExtensions = false;
851             } else {
852                 return false;
853             }
854         }
855         // Because of the extension rule, we can paste all extension source
856
// objects
857
if (allExtensions) {
858             return true;
859         }
860         // Pasting a mixture of elements and extensions is not supported
861
// (or wise from the users perspective)
862
if (allElements == false) {
863             return false;
864         }
865         // Ensure the target object can have children
866
if ((targetObject instanceof IPluginParent) == false) {
867             return false;
868         } else if ((targetObject instanceof IDocumentNode) == false) {
869             return false;
870         }
871         // Retrieve the schema corresponding to the target object
872
IPluginParent targetParent = (IPluginParent)targetObject;
873         ISchema schema = getSchema(targetParent);
874         // If there is no schema, then a source object can be pasted as a
875
// child of any target object
876
if (schema == null) {
877             return true;
878         }
879         // Determine the element name of the target object
880
// getName() does not work for extensions for some reason
881
String JavaDoc tagName = null;
882         if (targetParent instanceof IPluginExtension) {
883             tagName = "extension"; //$NON-NLS-1$
884
} else {
885             tagName = targetParent.getName();
886         }
887         // Retrieve the element schema for the target object
888
ISchemaElement schemaElement = schema.findElement(tagName);
889         // Ensure we found a schema element and it is a schema complex type
890
if (schemaElement == null) {
891             // Something is seriously wrong, we have a schema
892
return false;
893         } else if ((schemaElement.getType() instanceof ISchemaComplexType) == false) {
894             // Something is seriously wrong, we are a plugin parent
895
return false;
896         }
897         // We have a schema complex type. Either the target object has
898
// attributes or the element has children.
899
// Generate the list of element proposals
900
HashSet JavaDoc elementSet =
901             XMLElementProposalComputer.computeElementProposal(
902                     schemaElement, (IDocumentNode)targetObject);
903         // Determine whether we can paste the source elements as children of
904
// the target object
905
if (sourceObjects.length > 1) {
906             return canPasteSourceElements((IPluginElement[])sourceObjects, elementSet);
907         }
908         return canPasteSourceElement((IPluginElement)sourceObjects[0], elementSet);
909     }
910
911     /**
912      * @param sourceElements
913      * @param targetElementSet
914      * @return
915      */

916     private boolean canPasteSourceElements(IPluginElement[] sourceElements,
917             HashSet JavaDoc targetElementSet) {
918         // Performance optimization
919
// HashSet of schema elements is not comparable for the source
920
// objects (schema elements are transient)
921
// Create a new HashSet with element names for comparison
922
HashSet JavaDoc targetElementNameSet = new HashSet JavaDoc();
923         Iterator JavaDoc iterator = targetElementSet.iterator();
924         while (iterator.hasNext()) {
925             targetElementNameSet.add(((ISchemaElement)iterator.next()).getName());
926         }
927         // Paste will be enabled only if all source objects can be pasted
928
// as children into the target element
929
// Limitation: Multiplicity checks will be compromised because we
930
// are pasting multiple elements as a single transaction. The
931
// mulitplicity check is computed on the current static state of the
932
// target object with the assumption one new element will be added.
933
// Obviously, adding more than one element can invalidate the check
934
// due to choice, sequence multiplicity constraints. Even if source
935
// elements that are pasted violate multiplicity constraints the
936
// extensions builder will flag them with errors
937
for (int i = 0; i < sourceElements.length; i++) {
938             String JavaDoc sourceTagName = sourceElements[i].getName();
939             if (targetElementNameSet.contains(sourceTagName) == false) {
940                 return false;
941             }
942         }
943         return true;
944     }
945     
946     /**
947      * @param sourceElement
948      * @param targetElementSet
949      * @return
950      */

951     private boolean canPasteSourceElement(IPluginElement sourceElement,
952             HashSet JavaDoc targetElementSet) {
953         boolean canPaste = false;
954         // Get the source element tag name
955
String JavaDoc sourceTagName = sourceElement.getName();
956         // Iterate over set of valid element proposals
957
Iterator JavaDoc iterator = targetElementSet.iterator();
958         while (iterator.hasNext()) {
959             // Get the proposal element tag name
960
String JavaDoc targetTagName = ((ISchemaElement)iterator.next()).getName();
961             // Only a source element that is found ithin the set of element
962
// proposals can be pasted
963
if (sourceTagName.equals(targetTagName)) {
964                 canPaste = true;
965                 break;
966             }
967         }
968         return canPaste;
969     }
970     
971     /**
972      * @return
973      */

974     private IPluginModelBase getPluginModelBase() {
975         // Note: This method will work with fragments as long as a fragment.xml
976
// is defined first. Otherwise, paste will not work out of the box.
977
// Get the model
978
IPluginModelBase model = (IPluginModelBase) getPage().getModel();
979         // Ensure the model is a bundle plugin model
980
if ((model instanceof IBundlePluginModelBase) == false) {
981             return null;
982         }
983         // Get the extension model
984
ISharedExtensionsModel extensionModel =
985             ((IBundlePluginModelBase)model).getExtensionsModel();
986         // Ensure the extension model is defined
987
if ((extensionModel == null) ||
988                 ((extensionModel instanceof IPluginModelBase) == false)) {
989             return null;
990         }
991         return ((IPluginModelBase)extensionModel);
992     }
993     
994     /* (non-Javadoc)
995      * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
996      */

997     protected void doPaste(Object JavaDoc targetObject, Object JavaDoc[] sourceObjects) {
998         // By default, fragment.xml does not exist until the first extension
999
// or extension point is created.
1000
// Ensure the file exists before pasting because the model will be
1001
// null and the paste will fail if it does not exist
1002
((ManifestEditor)getPage().getEditor()).ensurePluginContextPresence();
1003        // Note: Multi-select in tree viewer is disabled; but, this function
1004
// can support multiple source objects
1005
// Get the model
1006
IPluginModelBase model = getPluginModelBase();
1007        // Ensure the model is defined
1008
if (model == null) {
1009            return;
1010        }
1011        IPluginBase pluginBase = model.getPluginBase();
1012        try {
1013            // Paste all source objects into the target object
1014
for (int i = 0; i < sourceObjects.length; i++) {
1015                Object JavaDoc sourceObject = sourceObjects[i];
1016                
1017                if ((sourceObject instanceof IDocumentExtension) &&
1018                        (sourceObject instanceof IPluginExtension) &&
1019                        (pluginBase instanceof IDocumentNode)) {
1020                    // Extension object
1021
IDocumentExtension extension = (IDocumentExtension)sourceObject;
1022                    // Retrieve the associated schema if there is one
1023
ISchema schema = getSchema((IPluginExtension)extension);
1024                    // Adjust all the source object transient field values to
1025
// acceptable values
1026
extension.reconnect(model, schema, (IDocumentNode)pluginBase);
1027                    pluginBase.add((IPluginExtension)extension);
1028
1029                } else if ((sourceObject instanceof IDocumentElement) &&
1030                        (sourceObject instanceof IPluginElement) &&
1031                        (targetObject instanceof IPluginParent) &&
1032                        (targetObject instanceof IDocumentNode)) {
1033                    // Element object
1034
IDocumentElement element = (IDocumentElement)sourceObject;
1035                    // Retrieve the associated schema if there is one
1036
ISchema schema = getSchema((IPluginElement)element);
1037                    // Adjust all the source object transient field values to
1038
// acceptable values
1039
element.reconnect(model, schema, (IDocumentNode)targetObject);
1040                    // Add the element to the plugin parent (extension or
1041
// element)
1042
((IPluginParent)targetObject).add((IPluginElement)element);
1043                }
1044            }
1045        } catch (CoreException e) {
1046            PDEPlugin.logException(e);
1047        }
1048    }
1049    
1050    private void handleMove(boolean up) {
1051        IStructuredSelection sel = (IStructuredSelection) fExtensionTree
1052        .getSelection();
1053        IPluginObject object = (IPluginObject) sel.getFirstElement();
1054        if (object instanceof IPluginElement) {
1055            IPluginParent parent = (IPluginParent) object.getParent();
1056            IPluginObject[] children = parent.getChildren();
1057            int index = parent.getIndexOf(object);
1058            int newIndex = up ? index - 1 : index + 1;
1059            IPluginObject child2 = children[newIndex];
1060            try {
1061                parent.swap(object, child2);
1062            } catch (CoreException e) {
1063                PDEPlugin.logException(e);
1064            }
1065        } else if (object instanceof IPluginExtension) {
1066            IPluginExtension extension = (IPluginExtension) object;
1067            IPluginBase plugin = extension.getPluginBase();
1068            IPluginExtension[] extensions = plugin.getExtensions();
1069            int index = plugin.getIndexOf(extension);
1070            int newIndex = up ? index - 1 : index + 1;
1071            IPluginExtension e2 = extensions[newIndex];
1072            try {
1073                plugin.swap(extension, e2);
1074            } catch (CoreException e) {
1075                PDEPlugin.logException(e);
1076            }
1077        }
1078    }
1079    private void updateUpDownButtons(Object JavaDoc item) {
1080        if (getPage().getModel().isEditable() == false)
1081            return;
1082        boolean sorted = fSortAction != null && fSortAction.isChecked();
1083        if (sorted) {
1084            getTreePart().setButtonEnabled(3, false);
1085            getTreePart().setButtonEnabled(4, false);
1086            return;
1087        }
1088        
1089        boolean upEnabled = false;
1090        boolean downEnabled = false;
1091        if (item instanceof IPluginElement) {
1092            IPluginElement element = (IPluginElement) item;
1093            IPluginParent parent = (IPluginParent) element.getParent();
1094            // check up
1095
int index = parent.getIndexOf(element);
1096            if (index > 0)
1097                upEnabled = true;
1098            if (index < parent.getChildCount() - 1)
1099                downEnabled = true;
1100        } else if (item instanceof IPluginExtension) {
1101            IPluginExtension extension = (IPluginExtension) item;
1102            IExtensions extensions = (IExtensions) extension.getParent();
1103            int index = extensions.getIndexOf(extension);
1104            int size = extensions.getExtensions().length;
1105            if (index > 0)
1106                upEnabled = true;
1107            if (index < size - 1)
1108                downEnabled = true;
1109        }
1110        
1111        getTreePart().setButtonEnabled(3, upEnabled);
1112        getTreePart().setButtonEnabled(4, downEnabled);
1113    }
1114
1115    /* (non-Javadoc)
1116     * @see org.eclipse.pde.internal.ui.editor.TreeSection#createTreeViewer(org.eclipse.swt.widgets.Composite, int)
1117     */

1118    protected TreeViewer createTreeViewer(Composite parent, int style) {
1119        fFilteredTree = new FormFilteredTree(parent, style, new PatternFilter());
1120        parent.setData("filtered", Boolean.TRUE); //$NON-NLS-1$
1121
return fFilteredTree.getViewer();
1122    }
1123    
1124    public void propertyChange(PropertyChangeEvent event) {
1125        if (fSortAction.equals(event.getSource()) && IAction.RESULT.equals(event.getProperty())) {
1126            StructuredViewer viewer = getStructuredViewerPart().getViewer();
1127            IStructuredSelection ssel = (IStructuredSelection)viewer.getSelection();
1128            updateUpDownButtons(ssel.size() != 1 ? null : ssel.getFirstElement());
1129        }
1130    }
1131
1132    protected void selectExtensionElement(ISelection selection) {
1133        fExtensionTree.setSelection(selection, true);
1134    }
1135}
1136
Popular Tags