0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.plugin;
0011:
0012: import java.util.ArrayList;
0013: import java.util.HashSet;
0014:
0015: import org.eclipse.core.resources.IFile;
0016: import org.eclipse.core.resources.IFolder;
0017: import org.eclipse.core.resources.IProject;
0018: import org.eclipse.core.resources.IResource;
0019: import org.eclipse.core.runtime.CoreException;
0020: import org.eclipse.core.runtime.IPath;
0021: import org.eclipse.core.runtime.Path;
0022: import org.eclipse.jdt.core.IClasspathEntry;
0023: import org.eclipse.jdt.core.IJavaProject;
0024: import org.eclipse.jdt.core.JavaCore;
0025: import org.eclipse.jdt.core.JavaModelException;
0026: import org.eclipse.jface.action.Action;
0027: import org.eclipse.jface.action.IMenuManager;
0028: import org.eclipse.jface.action.Separator;
0029: import org.eclipse.jface.viewers.IStructuredContentProvider;
0030: import org.eclipse.jface.viewers.IStructuredSelection;
0031: import org.eclipse.jface.viewers.StructuredSelection;
0032: import org.eclipse.jface.viewers.TableViewer;
0033: import org.eclipse.jface.viewers.Viewer;
0034: import org.eclipse.jface.viewers.ViewerDropAdapter;
0035: import org.eclipse.jface.window.Window;
0036: import org.eclipse.pde.core.IBaseModel;
0037: import org.eclipse.pde.core.IModel;
0038: import org.eclipse.pde.core.IModelChangedEvent;
0039: import org.eclipse.pde.core.IModelChangedListener;
0040: import org.eclipse.pde.core.build.IBuild;
0041: import org.eclipse.pde.core.build.IBuildEntry;
0042: import org.eclipse.pde.core.build.IBuildModel;
0043: import org.eclipse.pde.core.plugin.IPluginBase;
0044: import org.eclipse.pde.core.plugin.IPluginElement;
0045: import org.eclipse.pde.core.plugin.IPluginLibrary;
0046: import org.eclipse.pde.core.plugin.IPluginModelBase;
0047: import org.eclipse.pde.core.plugin.ISharedPluginModel;
0048: import org.eclipse.pde.internal.build.IBuildPropertiesConstants;
0049: import org.eclipse.pde.internal.core.ClasspathUtilCore;
0050: import org.eclipse.pde.internal.core.bundle.BundlePluginBase;
0051: import org.eclipse.pde.internal.core.plugin.PluginLibrary;
0052: import org.eclipse.pde.internal.ui.PDEPlugin;
0053: import org.eclipse.pde.internal.ui.PDEUIMessages;
0054: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
0055: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
0056: import org.eclipse.pde.internal.ui.editor.TableSection;
0057: import org.eclipse.pde.internal.ui.editor.build.BuildInputContext;
0058: import org.eclipse.pde.internal.ui.editor.build.BuildSourcePage;
0059: import org.eclipse.pde.internal.ui.editor.build.JARFileFilter;
0060: import org.eclipse.pde.internal.ui.editor.context.InputContextManager;
0061: import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
0062: import org.eclipse.pde.internal.ui.parts.EditableTablePart;
0063: import org.eclipse.pde.internal.ui.parts.TablePart;
0064: import org.eclipse.pde.internal.ui.util.SWTUtil;
0065: import org.eclipse.swt.SWT;
0066: import org.eclipse.swt.events.SelectionAdapter;
0067: import org.eclipse.swt.events.SelectionEvent;
0068: import org.eclipse.swt.layout.GridData;
0069: import org.eclipse.swt.widgets.Button;
0070: import org.eclipse.swt.widgets.Composite;
0071: import org.eclipse.swt.widgets.Control;
0072: import org.eclipse.swt.widgets.Display;
0073: import org.eclipse.swt.widgets.Table;
0074: import org.eclipse.ui.actions.ActionFactory;
0075: import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
0076: import org.eclipse.ui.forms.editor.IFormPage;
0077: import org.eclipse.ui.forms.widgets.FormToolkit;
0078: import org.eclipse.ui.forms.widgets.Section;
0079: import org.eclipse.ui.model.WorkbenchContentProvider;
0080: import org.eclipse.ui.model.WorkbenchLabelProvider;
0081: import org.eclipse.ui.views.navigator.ResourceComparator;
0082:
0083: public class LibrarySection extends TableSection implements
0084: IModelChangedListener, IBuildPropertiesConstants {
0085:
0086: private static final int NEW_INDEX = 0;
0087: private static final int ADD_INDEX = 1;
0088: private static final int REMOVE_INDEX = 2;
0089: private static final int UP_INDEX = 3;
0090: private static final int DOWN_INDEX = 4;
0091:
0092: private Action fRenameAction;
0093: private Action fRemoveAction;
0094: private Action fNewAction;
0095:
0096: private TableViewer fLibraryTable;
0097:
0098: class LibraryFilter extends JARFileFilter {
0099: public LibraryFilter(HashSet set) {
0100: super (set);
0101: }
0102:
0103: public boolean select(Viewer viewer, Object parent,
0104: Object element) {
0105: if (element instanceof IFolder)
0106: return isPathValid(((IFolder) element)
0107: .getProjectRelativePath());
0108: if (element instanceof IFile)
0109: return isFileValid(((IFile) element)
0110: .getProjectRelativePath());
0111: return false;
0112: }
0113: }
0114:
0115: class LibrarySelectionValidator extends JarSelectionValidator {
0116:
0117: public LibrarySelectionValidator(Class[] acceptedTypes,
0118: boolean allowMultipleSelection) {
0119: super (acceptedTypes, allowMultipleSelection);
0120: }
0121:
0122: public boolean isValid(Object element) {
0123: return (element instanceof IFolder) ? true : super
0124: .isValid(element);
0125: }
0126: }
0127:
0128: class TableContentProvider extends DefaultContentProvider implements
0129: IStructuredContentProvider {
0130: public Object[] getElements(Object parent) {
0131: return getModel().getPluginBase().getLibraries();
0132: }
0133: }
0134:
0135: public LibrarySection(PDEFormPage page, Composite parent) {
0136: super (page, parent, Section.DESCRIPTION, new String[] {
0137: PDEUIMessages.NewManifestEditor_LibrarySection_new,
0138: PDEUIMessages.NewManifestEditor_LibrarySection_add,
0139: PDEUIMessages.NewManifestEditor_LibrarySection_remove,
0140: PDEUIMessages.ManifestEditor_LibrarySection_up,
0141: PDEUIMessages.ManifestEditor_LibrarySection_down });
0142: }
0143:
0144: private String getSectionDescription() {
0145: IPluginModelBase model = getModel();
0146: if (isBundle()) {
0147: return (model.isFragmentModel()) ? PDEUIMessages.ClasspathSection_fragment
0148: : PDEUIMessages.ClasspathSection_plugin;
0149: }
0150: return (model.isFragmentModel()) ? PDEUIMessages.ManifestEditor_LibrarySection_fdesc
0151: : PDEUIMessages.ManifestEditor_LibrarySection_desc;
0152: }
0153:
0154: protected boolean isBundle() {
0155: return getBundleContext() != null;
0156: }
0157:
0158: private BundleInputContext getBundleContext() {
0159: InputContextManager manager = getPage().getPDEEditor()
0160: .getContextManager();
0161: return (BundleInputContext) manager
0162: .findContext(BundleInputContext.CONTEXT_ID);
0163: }
0164:
0165: public void createClient(Section section, FormToolkit toolkit) {
0166: section
0167: .setText(PDEUIMessages.ManifestEditor_LibrarySection_title);
0168: section.setDescription(getSectionDescription());
0169:
0170: Composite container = createClientContainer(section, 2, toolkit);
0171: EditableTablePart tablePart = getTablePart();
0172: tablePart.setEditable(isEditable());
0173:
0174: createViewerPartControl(container, SWT.MULTI, 2, toolkit);
0175: fLibraryTable = tablePart.getTableViewer();
0176: fLibraryTable.setContentProvider(new TableContentProvider());
0177: fLibraryTable.setLabelProvider(PDEPlugin.getDefault()
0178: .getLabelProvider());
0179: toolkit.paintBordersFor(container);
0180:
0181: makeActions();
0182: updateButtons();
0183: section.setLayout(FormLayoutFactory.createClearGridLayout(
0184: false, 1));
0185: section.setLayoutData(new GridData(GridData.FILL_BOTH));
0186: section.setClient(container);
0187:
0188: IPluginModelBase model = getModel();
0189: fLibraryTable.setInput(model.getPluginBase());
0190: model.addModelChangedListener(this );
0191: }
0192:
0193: private void updateButtons() {
0194: Table table = fLibraryTable.getTable();
0195: boolean hasSelection = table.getSelection().length > 0;
0196: boolean singleSelection = table.getSelection().length == 1;
0197: int count = table.getItemCount();
0198: int index = table.getSelectionIndex();
0199: boolean canMoveUp = singleSelection && index > 0;
0200: boolean canMoveDown = singleSelection && index < count - 1;
0201:
0202: TablePart tablePart = getTablePart();
0203: tablePart.setButtonEnabled(ADD_INDEX, isEditable());
0204: tablePart.setButtonEnabled(NEW_INDEX, isEditable());
0205: tablePart.setButtonEnabled(REMOVE_INDEX, isEditable()
0206: && hasSelection);
0207: tablePart.setButtonEnabled(UP_INDEX, isEditable() && canMoveUp);
0208: tablePart.setButtonEnabled(DOWN_INDEX, isEditable()
0209: && canMoveDown);
0210: }
0211:
0212: private void makeActions() {
0213: fNewAction = new Action(
0214: PDEUIMessages.ManifestEditor_LibrarySection_newLibrary) {
0215: public void run() {
0216: handleNew();
0217: }
0218: };
0219: fNewAction.setEnabled(isEditable());
0220:
0221: fRenameAction = new Action(
0222: PDEUIMessages.EditableTablePart_renameAction) {
0223: public void run() {
0224: getRenameAction().run();
0225: }
0226: };
0227: fRenameAction.setEnabled(isEditable());
0228:
0229: fRemoveAction = new Action(
0230: PDEUIMessages.NewManifestEditor_LibrarySection_remove) {
0231: public void run() {
0232: handleRemove();
0233: }
0234: };
0235: fRemoveAction.setEnabled(isEditable());
0236: }
0237:
0238: protected void selectionChanged(IStructuredSelection selection) {
0239: getPage().getPDEEditor().setSelection(selection);
0240: if (getPage().getModel().isEditable())
0241: updateButtons();
0242: }
0243:
0244: protected void buttonSelected(int index) {
0245: switch (index) {
0246: case NEW_INDEX:
0247: handleNew();
0248: break;
0249: case ADD_INDEX:
0250: handleAdd();
0251: break;
0252: case REMOVE_INDEX:
0253: handleRemove();
0254: break;
0255: case UP_INDEX:
0256: handleUp();
0257: break;
0258: case DOWN_INDEX:
0259: handleDown();
0260: break;
0261: }
0262: }
0263:
0264: public void dispose() {
0265: IPluginModelBase model = getModel();
0266: if (model != null)
0267: model.removeModelChangedListener(this );
0268: super .dispose();
0269: }
0270:
0271: /* (non-Javadoc)
0272: * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
0273: */
0274: public boolean doGlobalAction(String actionId) {
0275:
0276: if (!isEditable()) {
0277: return false;
0278: }
0279:
0280: if (actionId.equals(ActionFactory.DELETE.getId())) {
0281: handleRemove();
0282: return true;
0283: }
0284: if (actionId.equals(ActionFactory.CUT.getId())) {
0285: // delete here and let the editor transfer
0286: // the selection to the clipboard
0287: handleRemove();
0288: return false;
0289: }
0290: if (actionId.equals(ActionFactory.PASTE.getId())) {
0291: doPaste();
0292: return true;
0293: }
0294: return false;
0295: }
0296:
0297: public boolean setFormInput(Object object) {
0298: if (object instanceof IPluginLibrary) {
0299: fLibraryTable.setSelection(new StructuredSelection(object),
0300: true);
0301: return true;
0302: }
0303: return false;
0304: }
0305:
0306: protected void fillContextMenu(IMenuManager manager) {
0307: manager.add(fNewAction);
0308: if (!fLibraryTable.getSelection().isEmpty()) {
0309: manager.add(new Separator());
0310: manager.add(fRenameAction);
0311: manager.add(fRemoveAction);
0312: }
0313: // Copy, cut, and paste operations not supported for plug-ins that do
0314: // not have a MANIFEST.MF (not a Bundle)
0315: getPage().getPDEEditor().getContributor()
0316: .contextMenuAboutToShow(manager, isBundle());
0317: }
0318:
0319: private void handleRemove() {
0320: Object[] selection = ((IStructuredSelection) fLibraryTable
0321: .getSelection()).toArray();
0322: int index = fLibraryTable.getTable().getSelectionIndex();
0323: int[] indices = fLibraryTable.getTable().getSelectionIndices();
0324: for (int i = 0; i < indices.length; i++)
0325: if (indices[i] < index)
0326: index = indices[i];
0327:
0328: String[] remove = new String[selection.length];
0329: for (int i = 0; i < selection.length; i++) {
0330: if (selection[i] != null
0331: && selection[i] instanceof IPluginLibrary) {
0332: IPluginLibrary ep = (IPluginLibrary) selection[i];
0333: IPluginBase plugin = ep.getPluginBase();
0334: try {
0335: plugin.remove(ep);
0336: } catch (CoreException e) {
0337: PDEPlugin.logException(e);
0338: }
0339: remove[i] = ep.getName();
0340: }
0341: }
0342: updateBuildProperties(remove, new String[remove.length], true);
0343: updateJavaClasspathLibs(remove, new String[remove.length]);
0344:
0345: int itemCount = fLibraryTable.getTable().getItemCount();
0346: if (itemCount > 0) {
0347: if (index >= itemCount)
0348: index = itemCount - 1;
0349: fLibraryTable.getTable().setSelection(index);
0350: fLibraryTable.getTable().setFocus();
0351: }
0352: updateButtons();
0353: }
0354:
0355: private void handleDown() {
0356: Table table = getTablePart().getTableViewer().getTable();
0357: int index = table.getSelectionIndex();
0358: if (index != table.getItemCount() - 1)
0359: swap(index, index + 1);
0360: }
0361:
0362: private void handleUp() {
0363: int index = getTablePart().getTableViewer().getTable()
0364: .getSelectionIndex();
0365: if (index >= 1)
0366: swap(index, index - 1);
0367: }
0368:
0369: public void swap(int index1, int index2) {
0370: Table table = getTablePart().getTableViewer().getTable();
0371: IPluginLibrary l1 = (IPluginLibrary) table.getItem(index1)
0372: .getData();
0373: IPluginLibrary l2 = (IPluginLibrary) table.getItem(index2)
0374: .getData();
0375:
0376: try {
0377: IPluginModelBase model = getModel();
0378: IPluginBase pluginBase = model.getPluginBase();
0379: pluginBase.swap(l1, l2);
0380: refresh();
0381: table.setSelection(index2);
0382: table.setFocus();
0383: updateButtons();
0384: } catch (CoreException e) {
0385: PDEPlugin.logException(e);
0386: }
0387: }
0388:
0389: private void handleNew() {
0390: IPluginModelBase model = getModel();
0391: NewRuntimeLibraryDialog dialog = new NewRuntimeLibraryDialog(
0392: getPage().getSite().getShell(), model.getPluginBase()
0393: .getLibraries());
0394: dialog.create();
0395: dialog
0396: .getShell()
0397: .setText(
0398: PDEUIMessages.ManifestEditor_LibrarySection_newLibraryEntry);
0399: SWTUtil.setDialogSize(dialog, 250, 175);
0400:
0401: if (dialog.open() == Window.OK) {
0402: String libName = dialog.getLibraryName();
0403: if (libName == null || libName.length() == 0)
0404: return;
0405: try {
0406: IPluginLibrary library = model.getPluginFactory()
0407: .createLibrary();
0408: library.setName(libName);
0409: library.setExported(true);
0410: model.getPluginBase().add(library);
0411: checkSourceRootEntry();
0412: updateBuildProperties(new String[] { null },
0413: new String[] { library.getName() }, true);
0414: fLibraryTable.setSelection(new StructuredSelection(
0415: library));
0416: fLibraryTable.getTable().setFocus();
0417: } catch (CoreException e) {
0418: PDEPlugin.logException(e);
0419: }
0420: }
0421: }
0422:
0423: private void checkSourceRootEntry() {
0424: IPluginModelBase pluginModel = getModel();
0425: IPluginLibrary[] libraries = pluginModel.getPluginBase()
0426: .getLibraries();
0427: for (int i = 0; i < libraries.length; i++)
0428: if (libraries[i].getName().equals(".")) //$NON-NLS-1$
0429: return;
0430: IBuildModel model = getBuildModel();
0431: if (model == null)
0432: return;
0433:
0434: IBuildEntry[] entires = model.getBuild().getBuildEntries();
0435: for (int i = 0; i < entires.length; i++) {
0436: if (entires[i].getName().equals(
0437: PROPERTY_SOURCE_PREFIX + '.')) {
0438: IPluginLibrary library = pluginModel.getPluginFactory()
0439: .createLibrary();
0440: try {
0441: library.setName("."); //$NON-NLS-1$
0442: pluginModel.getPluginBase().add(library);
0443: } catch (CoreException e) {
0444: }
0445: }
0446: }
0447: }
0448:
0449: private IBuildModel getBuildModel() {
0450: IFormPage page = getPage().getEditor().findPage(
0451: BuildInputContext.CONTEXT_ID);
0452: IBaseModel model = null;
0453: if (page instanceof BuildSourcePage)
0454: model = ((BuildSourcePage) page).getInputContext()
0455: .getModel();
0456:
0457: if (model != null && model instanceof IBuildModel)
0458: return (IBuildModel) model;
0459: return null;
0460: }
0461:
0462: private void configureSourceBuildEntry(IBuildModel bmodel,
0463: String oldPath, String newPath) throws CoreException {
0464: IBuild build = bmodel.getBuild();
0465: IBuildEntry entry = build.getEntry(PROPERTY_SOURCE_PREFIX
0466: + (oldPath != null ? oldPath : newPath));
0467: try {
0468: if (newPath != null) {
0469: if (entry == null) {
0470: IProject project = ((IModel) getPage().getModel())
0471: .getUnderlyingResource().getProject();
0472: IJavaProject jproject = JavaCore.create(project);
0473: ArrayList tokens = new ArrayList();
0474: IClasspathEntry[] entries = jproject
0475: .getRawClasspath();
0476: for (int i = 0; i < entries.length; i++)
0477: if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE)
0478: tokens.add(entries[i].getPath()
0479: .removeFirstSegments(1)
0480: .addTrailingSeparator().toString());
0481: if (tokens.size() == 0)
0482: return;
0483:
0484: entry = bmodel.getFactory().createEntry(
0485: PROPERTY_SOURCE_PREFIX + newPath);
0486: for (int i = 0; i < tokens.size(); i++)
0487: entry.addToken((String) tokens.get(i));
0488: build.add(entry);
0489: } else
0490: entry.setName(PROPERTY_SOURCE_PREFIX + newPath);
0491: } else if (entry != null && newPath == null)
0492: build.remove(entry);
0493: } catch (JavaModelException e) {
0494: }
0495: }
0496:
0497: private void handleAdd() {
0498: final boolean[] updateClasspath = new boolean[] { true };
0499: ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
0500: getPage().getSite().getShell(),
0501: new WorkbenchLabelProvider(),
0502: new WorkbenchContentProvider()) {
0503: protected Control createDialogArea(Composite parent) {
0504: Composite comp = (Composite) super
0505: .createDialogArea(parent);
0506: final Button button = new Button(comp, SWT.CHECK);
0507: button
0508: .setText(PDEUIMessages.LibrarySection_addDialogButton);
0509: button.setSelection(updateClasspath[0]);
0510: button.addSelectionListener(new SelectionAdapter() {
0511: public void widgetSelected(SelectionEvent e) {
0512: updateClasspath[0] = button.getSelection();
0513: }
0514: });
0515: applyDialogFont(button);
0516: return comp;
0517: }
0518: };
0519:
0520: Class[] acceptedClasses = new Class[] { IFile.class };
0521: dialog.setValidator(new LibrarySelectionValidator(
0522: acceptedClasses, true));
0523: dialog
0524: .setTitle(PDEUIMessages.BuildEditor_ClasspathSection_jarsTitle);
0525: dialog.setMessage(PDEUIMessages.ClasspathSection_jarsMessage);
0526: IPluginLibrary[] libraries = getModel().getPluginBase()
0527: .getLibraries();
0528: HashSet set = new HashSet();
0529: for (int i = 0; i < libraries.length; i++)
0530: set.add(new Path(ClasspathUtilCore
0531: .expandLibraryName(libraries[i].getName())));
0532:
0533: dialog.addFilter(new LibraryFilter(set));
0534: IProject project = ((IModel) getPage().getModel())
0535: .getUnderlyingResource().getProject();
0536: dialog.setInput(project);
0537: dialog.setComparator(new ResourceComparator(
0538: ResourceComparator.NAME));
0539:
0540: if (dialog.open() == Window.OK) {
0541: Object[] elements = dialog.getResult();
0542: String[] filePaths = new String[elements.length];
0543: IPluginModelBase model = getModel();
0544: ArrayList list = new ArrayList();
0545: for (int i = 0; i < elements.length; i++) {
0546: IResource elem = (IResource) elements[i];
0547: IPath path = elem.getProjectRelativePath();
0548: if (elem instanceof IFolder)
0549: path = path.addTrailingSeparator();
0550: filePaths[i] = path.toString();
0551: IPluginLibrary library = model.getPluginFactory()
0552: .createLibrary();
0553: try {
0554: library.setName(filePaths[i]);
0555: library.setExported(true);
0556: model.getPluginBase().add(library);
0557: list.add(library);
0558: } catch (CoreException e) {
0559: PDEPlugin.logException(e);
0560: }
0561: }
0562: checkSourceRootEntry();
0563: updateBuildProperties(new String[filePaths.length],
0564: filePaths, false);
0565: if (updateClasspath[0])
0566: updateJavaClasspathLibs(new String[filePaths.length],
0567: filePaths);
0568: fLibraryTable.setSelection(new StructuredSelection(list
0569: .toArray()));
0570: fLibraryTable.getTable().setFocus();
0571: }
0572: }
0573:
0574: private void updateBuildProperties(final String[] oldPaths,
0575: final String[] newPaths, boolean modifySourceEntry) {
0576: IBuildModel bmodel = getBuildModel();
0577: if (bmodel == null)
0578: return;
0579:
0580: IBuild build = bmodel.getBuild();
0581:
0582: IBuildEntry entry = build.getEntry(PROPERTY_BIN_INCLUDES);
0583: if (entry == null)
0584: entry = bmodel.getFactory().createEntry(
0585: PROPERTY_BIN_INCLUDES);
0586:
0587: try {
0588: // adding new entries
0589: if (oldPaths[0] == null) {
0590: for (int i = 0; i < newPaths.length; i++)
0591: if (newPaths[i] != null) {
0592: entry.addToken(newPaths[i]);
0593: if (modifySourceEntry)
0594: configureSourceBuildEntry(bmodel, null,
0595: newPaths[i]);
0596: }
0597: // removing entries
0598: } else if (newPaths[0] == null) {
0599: for (int i = 0; i < oldPaths.length; i++)
0600: if (oldPaths[i] != null) {
0601: entry.removeToken(oldPaths[i]);
0602: if (modifySourceEntry)
0603: configureSourceBuildEntry(bmodel,
0604: oldPaths[i], null);
0605: }
0606: if (entry.getTokens().length == 0)
0607: build.remove(entry);
0608: // rename entries
0609: } else {
0610: for (int i = 0; i < oldPaths.length; i++)
0611: if (newPaths[i] != null && oldPaths[i] != null) {
0612: entry.renameToken(oldPaths[i], newPaths[i]);
0613: if (modifySourceEntry)
0614: configureSourceBuildEntry(bmodel,
0615: oldPaths[i], newPaths[i]);
0616: }
0617: }
0618: } catch (CoreException e) {
0619: }
0620: }
0621:
0622: private void updateJavaClasspathLibs(String[] oldPaths,
0623: String[] newPaths) {
0624: IProject project = ((IModel) getPage().getModel())
0625: .getUnderlyingResource().getProject();
0626: IJavaProject jproject = JavaCore.create(project);
0627: try {
0628: IClasspathEntry[] entries = jproject.getRawClasspath();
0629: ArrayList toBeAdded = new ArrayList();
0630: int index = -1;
0631: entryLoop: for (int i = 0; i < entries.length; i++) {
0632: if (entries[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
0633: if (index == -1)
0634: index = i;
0635: // do not add the old paths (handling deletion/renaming)
0636: IPath path = entries[i].getPath()
0637: .removeFirstSegments(1)
0638: .removeTrailingSeparator();
0639: for (int j = 0; j < oldPaths.length; j++)
0640: if (oldPaths[j] != null
0641: && path.equals(new Path(oldPaths[j])
0642: .removeTrailingSeparator()))
0643: continue entryLoop;
0644: } else if (entries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
0645: if (index == -1)
0646: index = i;
0647: toBeAdded.add(entries[i]);
0648: }
0649: if (index == -1)
0650: index = entries.length;
0651:
0652: // add paths
0653: for (int i = 0; i < newPaths.length; i++) {
0654: if (newPaths[i] == null)
0655: continue;
0656: IClasspathEntry entry = JavaCore.newLibraryEntry(
0657: project.getFullPath().append(newPaths[i]),
0658: null, null, true);
0659: if (!toBeAdded.contains(entry))
0660: toBeAdded.add(index++, entry);
0661: }
0662:
0663: if (toBeAdded.size() == entries.length)
0664: return;
0665:
0666: IClasspathEntry[] updated = (IClasspathEntry[]) toBeAdded
0667: .toArray(new IClasspathEntry[toBeAdded.size()]);
0668: jproject.setRawClasspath(updated, null);
0669: } catch (JavaModelException e) {
0670: }
0671: }
0672:
0673: public void refresh() {
0674: if (fLibraryTable.getControl().isDisposed())
0675: return;
0676: fLibraryTable.setSelection(null);
0677: fLibraryTable.refresh();
0678: super .refresh();
0679: }
0680:
0681: public void modelChanged(IModelChangedEvent event) {
0682: if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
0683: markStale();
0684: return;
0685: }
0686: Object changeObject = event.getChangedObjects()[0];
0687: if (changeObject instanceof IPluginLibrary) {
0688: if (event.getChangeType() == IModelChangedEvent.INSERT) {
0689: fLibraryTable.refresh();
0690: } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
0691: fLibraryTable.remove(changeObject);
0692: } else {
0693: fLibraryTable.update(changeObject, null);
0694: }
0695: } else if (changeObject.equals(fLibraryTable.getInput())) {
0696: markStale();
0697: } else if (changeObject instanceof IPluginElement
0698: && ((IPluginElement) changeObject).getParent() instanceof IPluginLibrary) {
0699: fLibraryTable.update(((IPluginElement) changeObject)
0700: .getParent(), null);
0701: }
0702: }
0703:
0704: public void setFocus() {
0705: fLibraryTable.getTable().setFocus();
0706: }
0707:
0708: /* (non-Javadoc)
0709: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
0710: */
0711: protected void doPaste(Object targetObject, Object[] sourceObjects) {
0712: // Get the model
0713: IPluginModelBase model = getModel();
0714: IPluginBase plugin = model.getPluginBase();
0715: try {
0716: // Paste all source objects
0717: for (int i = 0; i < sourceObjects.length; i++) {
0718: Object sourceObject = sourceObjects[i];
0719: if (sourceObject instanceof PluginLibrary) {
0720: // Plugin library object
0721: PluginLibrary library = (PluginLibrary) sourceObject;
0722: // Adjust all the source object transient field values to
0723: // acceptable values
0724: library.reconnect(model, plugin);
0725: // Add the library to the plug-in
0726: plugin.add(library);
0727: }
0728: }
0729: } catch (CoreException e) {
0730: PDEPlugin.logException(e);
0731: }
0732: }
0733:
0734: /* (non-Javadoc)
0735: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
0736: */
0737: protected boolean canPaste(Object targetObject,
0738: Object[] sourceObjects) {
0739: HashSet librarySet = null;
0740: // Only source objects that are plugin libraries that have not already
0741: // been specified can be pasted
0742: for (int i = 0; i < sourceObjects.length; i++) {
0743: // Only plugin libraries are allowed
0744: if ((sourceObjects[i] instanceof IPluginLibrary) == false) {
0745: return false;
0746: }
0747: // We have a plugin library
0748: // Get the current libraries already specified and store them in
0749: // a set to assist with searching
0750: if (librarySet == null) {
0751: librarySet = createPluginLibrarySet();
0752: }
0753: // No duplicate libraries are allowed
0754: IPluginLibrary library = (IPluginLibrary) sourceObjects[i];
0755: if (librarySet.contains(new Path(ClasspathUtilCore
0756: .expandLibraryName(library.getName())))) {
0757: return false;
0758: }
0759: }
0760: return true;
0761: }
0762:
0763: /**
0764: * @return
0765: */
0766: private HashSet createPluginLibrarySet() {
0767: // Get the current libraries and add them to a set for easy searching
0768: IPluginLibrary[] libraries = getModel().getPluginBase()
0769: .getLibraries();
0770: HashSet librarySet = new HashSet();
0771: for (int i = 0; i < libraries.length; i++) {
0772: librarySet.add(new Path(ClasspathUtilCore
0773: .expandLibraryName(libraries[i].getName())));
0774: }
0775: return librarySet;
0776: }
0777:
0778: protected void entryModified(Object entry, String value) {
0779: try {
0780: IPluginModelBase model = getModel();
0781: IProject project = model.getUnderlyingResource()
0782: .getProject();
0783: IPluginLibrary library = (IPluginLibrary) entry;
0784: model.getPluginBase().remove(library);
0785: String[] oldValue = { library.getName() };
0786: String[] newValue = { value };
0787: library.setName(value);
0788: boolean memberExists = project.findMember(value) != null;
0789: updateBuildProperties(oldValue, newValue, !memberExists);
0790: updateJavaClasspathLibs(oldValue, memberExists ? newValue
0791: : new String[] { null });
0792: model.getPluginBase().add(library);
0793: } catch (CoreException e) {
0794: PDEPlugin.logException(e);
0795: }
0796: }
0797:
0798: /**
0799: * @return
0800: */
0801: private IPluginModelBase getModel() {
0802: return (IPluginModelBase) getPage().getModel();
0803: }
0804:
0805: /* (non-Javadoc)
0806: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#isDragAndDropEnabled()
0807: */
0808: protected boolean isDragAndDropEnabled() {
0809: return true;
0810: }
0811:
0812: /* (non-Javadoc)
0813: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canDragMove(java.lang.Object[])
0814: */
0815: public boolean canDragMove(Object[] sourceObjects) {
0816: if (validateDragMoveSanity(sourceObjects) == false) {
0817: return false;
0818: }
0819: return true;
0820: }
0821:
0822: /**
0823: * @param sourceObjects
0824: * @return
0825: */
0826: private boolean validateDragMoveSanity(Object[] sourceObjects) {
0827: // Validate source
0828: if (sourceObjects == null) {
0829: // No objects
0830: return false;
0831: } else if (sourceObjects.length != 1) {
0832: // Multiple selection not supported
0833: return false;
0834: } else if ((sourceObjects[0] instanceof IPluginLibrary) == false) {
0835: // Must be the right type
0836: return false;
0837: }
0838: return true;
0839: }
0840:
0841: /* (non-Javadoc)
0842: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canDropMove(java.lang.Object, java.lang.Object[], int)
0843: */
0844: public boolean canDropMove(Object targetObject,
0845: Object[] sourceObjects, int targetLocation) {
0846: // Sanity check
0847: if (validateDropMoveSanity(targetObject, sourceObjects) == false) {
0848: return false;
0849: }
0850: // Multiple selection not supported
0851: IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
0852: IPluginLibrary targetPluginLibrary = (IPluginLibrary) targetObject;
0853: // Validate model
0854: if (validateDropMoveModel(sourcePluginLibrary,
0855: targetPluginLibrary) == false) {
0856: return false;
0857: }
0858: // Get the bundle plug-in base
0859: BundlePluginBase bundlePluginBase = (BundlePluginBase) getModel()
0860: .getPluginBase();
0861: // Validate move
0862: if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
0863: // Get the previous element of the target
0864: IPluginLibrary previousLibrary = bundlePluginBase
0865: .getPreviousLibrary(targetPluginLibrary);
0866: // Ensure the previous element is not the source
0867: if (sourcePluginLibrary.equals(previousLibrary)) {
0868: return false;
0869: }
0870: return true;
0871: } else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0872: // Get the next element of the target
0873: IPluginLibrary nextLibrary = bundlePluginBase
0874: .getNextLibrary(targetPluginLibrary);
0875: // Ensure the next element is not the source
0876: if (sourcePluginLibrary.equals(nextLibrary)) {
0877: return false;
0878: }
0879: return true;
0880: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0881: // Not supported
0882: return false;
0883: }
0884: return false;
0885: }
0886:
0887: /**
0888: * @param targetObject
0889: * @param sourceObjects
0890: * @return
0891: */
0892: private boolean validateDropMoveSanity(Object targetObject,
0893: Object[] sourceObjects) {
0894: // Validate target object
0895: if ((targetObject instanceof IPluginLibrary) == false) {
0896: return false;
0897: }
0898: // Validate source objects
0899: if (validateDragMoveSanity(sourceObjects) == false) {
0900: return false;
0901: }
0902: return true;
0903: }
0904:
0905: /**
0906: * @param sourcePluginLibrary
0907: * @param targetPluginLibrary
0908: * @return
0909: */
0910: private boolean validateDropMoveModel(
0911: IPluginLibrary sourcePluginLibrary,
0912: IPluginLibrary targetPluginLibrary) {
0913: // Objects have to be from the same model
0914: ISharedPluginModel sourceModel = sourcePluginLibrary.getModel();
0915: ISharedPluginModel targetModel = targetPluginLibrary.getModel();
0916: if (sourceModel.equals(targetModel) == false) {
0917: return false;
0918: } else if ((getModel().getPluginBase() instanceof BundlePluginBase) == false) {
0919: return false;
0920: }
0921: return true;
0922: }
0923:
0924: /* (non-Javadoc)
0925: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doDropMove(java.lang.Object, java.lang.Object[], int)
0926: */
0927: public void doDropMove(Object targetObject, Object[] sourceObjects,
0928: int targetLocation) {
0929: // Sanity check
0930: if (validateDropMoveSanity(targetObject, sourceObjects) == false) {
0931: Display.getDefault().beep();
0932: return;
0933: }
0934: // Multiple selection not supported
0935: IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
0936: IPluginLibrary targetPluginLibrary = (IPluginLibrary) targetObject;
0937: // Validate move
0938: if ((targetLocation == ViewerDropAdapter.LOCATION_BEFORE)
0939: || (targetLocation == ViewerDropAdapter.LOCATION_AFTER)) {
0940: // Do move
0941: doDropMove(sourcePluginLibrary, targetPluginLibrary,
0942: targetLocation);
0943: } else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
0944: // Not supported
0945: }
0946: }
0947:
0948: /**
0949: * @param sourcePluginLibrary
0950: * @param targetPluginLibrary
0951: * @param targetLocation
0952: */
0953: private void doDropMove(IPluginLibrary sourcePluginLibrary,
0954: IPluginLibrary targetPluginLibrary, int targetLocation) {
0955: // Remove the original source object
0956: // Normally we remove the original source object after inserting the
0957: // serialized source object; however, the libraries are removed via ID
0958: // and having both objects with the same ID co-existing will confound
0959: // the remove operation
0960: doDragRemove();
0961: // Get the bundle plug-in base
0962: IPluginModelBase model = getModel();
0963: BundlePluginBase bundlePluginBase = (BundlePluginBase) model
0964: .getPluginBase();
0965: // Get the index of the target
0966: int index = bundlePluginBase.getIndexOf(targetPluginLibrary);
0967: // Ensure the target index was found
0968: if (index == -1) {
0969: return;
0970: }
0971: // Determine the location index
0972: int targetIndex = index;
0973: if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
0974: targetIndex++;
0975: }
0976: // Ensure the plugin library is concrete
0977: if ((sourcePluginLibrary instanceof PluginLibrary) == false) {
0978: return;
0979: }
0980: // Adjust all the source object transient field values to
0981: // acceptable values
0982: ((PluginLibrary) sourcePluginLibrary).reconnect(model,
0983: bundlePluginBase);
0984: // Add source as sibling of target
0985: bundlePluginBase.add(sourcePluginLibrary, targetIndex);
0986: }
0987:
0988: /**
0989: *
0990: */
0991: private void doDragRemove() {
0992: // Get the bundle plug-in base
0993: BundlePluginBase bundlePluginBase = (BundlePluginBase) getModel()
0994: .getPluginBase();
0995: // Retrieve the original non-serialized source objects dragged initially
0996: Object[] sourceObjects = getDragSourceObjects();
0997: // Validate source objects
0998: if (validateDragMoveSanity(sourceObjects) == false) {
0999: return;
1000: }
1001: // Remove the library
1002: IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
1003: try {
1004: bundlePluginBase.remove(sourcePluginLibrary);
1005: } catch (CoreException e) {
1006: PDEPlugin.logException(e);
1007: }
1008: }
1009:
1010: }
|