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: * Brock Janiczak <brockj@tpg.com.au> - bug 189533
0011: *******************************************************************************/package org.eclipse.pde.internal.ui.preferences;
0012:
0013: import java.io.File;
0014: import java.lang.reflect.InvocationTargetException;
0015: import java.net.URL;
0016: import java.util.ArrayList;
0017: import java.util.HashMap;
0018: import java.util.HashSet;
0019: import java.util.Iterator;
0020: import java.util.Map;
0021: import java.util.Set;
0022: import java.util.Stack;
0023: import java.util.StringTokenizer;
0024: import java.util.Vector;
0025:
0026: import org.eclipse.core.resources.IProject;
0027: import org.eclipse.core.runtime.IAdaptable;
0028: import org.eclipse.core.runtime.IPath;
0029: import org.eclipse.core.runtime.IProgressMonitor;
0030: import org.eclipse.core.runtime.Path;
0031: import org.eclipse.core.runtime.Preferences;
0032: import org.eclipse.core.runtime.SubProgressMonitor;
0033: import org.eclipse.core.runtime.jobs.Job;
0034: import org.eclipse.jdt.core.IJavaProject;
0035: import org.eclipse.jface.operation.IRunnableWithProgress;
0036: import org.eclipse.jface.viewers.CheckStateChangedEvent;
0037: import org.eclipse.jface.viewers.CheckboxTableViewer;
0038: import org.eclipse.jface.viewers.CheckboxTreeViewer;
0039: import org.eclipse.jface.viewers.ICheckStateListener;
0040: import org.eclipse.jface.viewers.IStructuredContentProvider;
0041: import org.eclipse.jface.viewers.ITreeContentProvider;
0042: import org.eclipse.jface.window.Window;
0043: import org.eclipse.jface.wizard.WizardDialog;
0044: import org.eclipse.osgi.service.resolver.BundleDescription;
0045: import org.eclipse.osgi.service.resolver.State;
0046: import org.eclipse.osgi.util.NLS;
0047: import org.eclipse.pde.core.IModel;
0048: import org.eclipse.pde.core.IModelProviderEvent;
0049: import org.eclipse.pde.core.plugin.IPluginModelBase;
0050: import org.eclipse.pde.core.plugin.PluginRegistry;
0051: import org.eclipse.pde.internal.core.DependencyManager;
0052: import org.eclipse.pde.internal.core.ExternalFeatureModelManager;
0053: import org.eclipse.pde.internal.core.ExternalModelManager;
0054: import org.eclipse.pde.internal.core.FeatureModelManager;
0055: import org.eclipse.pde.internal.core.ICoreConstants;
0056: import org.eclipse.pde.internal.core.ModelProviderEvent;
0057: import org.eclipse.pde.internal.core.PDECore;
0058: import org.eclipse.pde.internal.core.PDEExtensionRegistry;
0059: import org.eclipse.pde.internal.core.PDEState;
0060: import org.eclipse.pde.internal.core.PluginPathFinder;
0061: import org.eclipse.pde.internal.core.TargetPlatformHelper;
0062: import org.eclipse.pde.internal.core.TargetPlatformResetJob;
0063: import org.eclipse.pde.internal.core.ifeature.IFeature;
0064: import org.eclipse.pde.internal.core.ifeature.IFeatureChild;
0065: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
0066: import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
0067: import org.eclipse.pde.internal.core.itarget.ITarget;
0068: import org.eclipse.pde.internal.core.itarget.ITargetFeature;
0069: import org.eclipse.pde.internal.core.itarget.ITargetPlugin;
0070: import org.eclipse.pde.internal.ui.IHelpContextIds;
0071: import org.eclipse.pde.internal.ui.PDELabelProvider;
0072: import org.eclipse.pde.internal.ui.PDEPlugin;
0073: import org.eclipse.pde.internal.ui.PDEPluginImages;
0074: import org.eclipse.pde.internal.ui.PDEUIMessages;
0075: import org.eclipse.pde.internal.ui.editor.target.TargetErrorDialog;
0076: import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
0077: import org.eclipse.pde.internal.ui.parts.SharedPartWithButtons;
0078: import org.eclipse.pde.internal.ui.util.PersistablePluginObject;
0079: import org.eclipse.pde.internal.ui.util.SWTUtil;
0080: import org.eclipse.pde.internal.ui.wizards.ListUtil;
0081: import org.eclipse.pde.internal.ui.wizards.provisioner.AddTargetPluginsWizard;
0082: import org.eclipse.swt.SWT;
0083: import org.eclipse.swt.events.SelectionAdapter;
0084: import org.eclipse.swt.events.SelectionEvent;
0085: import org.eclipse.swt.graphics.Image;
0086: import org.eclipse.swt.layout.GridData;
0087: import org.eclipse.swt.layout.GridLayout;
0088: import org.eclipse.swt.widgets.Button;
0089: import org.eclipse.swt.widgets.Composite;
0090: import org.eclipse.swt.widgets.Control;
0091: import org.eclipse.swt.widgets.Label;
0092: import org.eclipse.swt.widgets.TableItem;
0093: import org.eclipse.ui.IWorkingSet;
0094: import org.eclipse.ui.IWorkingSetManager;
0095: import org.eclipse.ui.PlatformUI;
0096: import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
0097: import org.eclipse.ui.forms.widgets.FormToolkit;
0098: import org.eclipse.ui.part.PageBook;
0099: import org.eclipse.ui.progress.IProgressConstants;
0100:
0101: public class TargetPluginsTab extends SharedPartWithButtons {
0102: private CheckboxTableViewer fPluginListViewer;
0103: private TargetPlatformPreferencePage fPage;
0104: private boolean fReloaded;
0105: private CheckboxTreeViewer fPluginTreeViewer;
0106: private HashSet fChangedModels = new HashSet();
0107: private PDEState fCurrentState;
0108: private PDEExtensionRegistry fCurrentRegistry;
0109: private PageBook fBook;
0110: private Button fGroupPlugins;
0111: private HashMap fTreeViewerContents;
0112: private Label fCounterLabel;
0113: private int fCounter;
0114: private Map fCurrentFeatures;
0115: private ArrayList fAdditionalLocations = new ArrayList();
0116:
0117: class ReloadOperation implements IRunnableWithProgress {
0118: private String location;
0119:
0120: public ReloadOperation(String platformPath) {
0121: this .location = platformPath;
0122: }
0123:
0124: private URL[] computePluginURLs() {
0125: URL[] base = PluginPathFinder.getPluginPaths(location);
0126: if (fAdditionalLocations.size() == 0)
0127: return base;
0128:
0129: File[] extraLocations = new File[fAdditionalLocations
0130: .size() * 2];
0131: for (int i = 0; i < extraLocations.length; i++) {
0132: String location = fAdditionalLocations.get(i / 2)
0133: .toString();
0134: File dir = new File(location);
0135: extraLocations[i] = dir;
0136: dir = new File(dir, "plugins"); //$NON-NLS-1$
0137: extraLocations[++i] = dir;
0138: }
0139:
0140: URL[] additional = PluginPathFinder
0141: .scanLocations(extraLocations);
0142: if (additional.length == 0)
0143: return base;
0144:
0145: URL[] result = new URL[base.length + additional.length];
0146: System.arraycopy(base, 0, result, 0, base.length);
0147: System.arraycopy(additional, 0, result, base.length,
0148: additional.length);
0149: return result;
0150: }
0151:
0152: public void run(IProgressMonitor monitor)
0153: throws InvocationTargetException, InterruptedException {
0154: monitor.beginTask(
0155: PDEUIMessages.TargetPluginsTab_readingPlatform, 10);
0156: SubProgressMonitor parsePluginMonitor = new SubProgressMonitor(
0157: monitor, 9);
0158: fCurrentState = new PDEState(computePluginURLs(), true,
0159: parsePluginMonitor);
0160: loadFeatures(new SubProgressMonitor(monitor, 1));
0161: monitor.done();
0162: fTreeViewerContents.clear();
0163: initializeTreeContents(getCurrentModels());
0164: if (fCurrentRegistry != null)
0165: fCurrentRegistry.dispose();
0166: fCurrentRegistry = null;
0167: }
0168:
0169: private void loadFeatures(IProgressMonitor monitor) {
0170: IFeatureModel[] externalModels = ExternalFeatureModelManager
0171: .createModels(location, fAdditionalLocations,
0172: monitor);
0173: IFeatureModel[] workspaceModels = PDECore.getDefault()
0174: .getFeatureModelManager().getWorkspaceModels();
0175: int numFeatures = externalModels.length
0176: + workspaceModels.length;
0177: fCurrentFeatures = new HashMap((4 / 3) * (numFeatures) + 1);
0178: for (int i = 0; i < externalModels.length; i++) {
0179: String id = externalModels[i].getFeature().getId();
0180: if (id != null)
0181: fCurrentFeatures.put(id, externalModels[i]);
0182: }
0183: for (int i = 0; i < workspaceModels.length; i++) {
0184: String id = workspaceModels[i].getFeature().getId();
0185: if (id != null)
0186: fCurrentFeatures.put(id, workspaceModels[i]);
0187: }
0188: monitor.done();
0189: }
0190:
0191: }
0192:
0193: public class PluginContentProvider extends DefaultContentProvider
0194: implements IStructuredContentProvider {
0195: public Object[] getElements(Object parent) {
0196: return getCurrentModels();
0197: }
0198: }
0199:
0200: public class TreePluginContentProvider extends
0201: DefaultContentProvider implements ITreeContentProvider {
0202:
0203: public Object[] getChildren(Object parentElement) {
0204: if (parentElement instanceof File) {
0205: Set files = (Set) fTreeViewerContents
0206: .get(parentElement);
0207: if (files != null) {
0208: Object[] result = files.toArray();
0209: return result;
0210: }
0211: }
0212: return new Object[0];
0213: }
0214:
0215: public Object getParent(Object element) {
0216: if (element instanceof IPluginModelBase) {
0217: IPluginModelBase model = (IPluginModelBase) element;
0218: String installPath = model.getInstallLocation();
0219: if (installPath != null)
0220: return new File(installPath).getParentFile();
0221: }
0222: return null;
0223: }
0224:
0225: public boolean hasChildren(Object element) {
0226: if (element instanceof File)
0227: return fTreeViewerContents.containsKey(element);
0228: return false;
0229: }
0230:
0231: public Object[] getElements(Object inputElement) {
0232: if (fTreeViewerContents == null)
0233: return initializeTreeContents(getCurrentModels())
0234: .toArray();
0235: return fTreeViewerContents.keySet().toArray();
0236: }
0237:
0238: }
0239:
0240: public TargetPluginsTab(TargetPlatformPreferencePage page) {
0241: super (new String[] { PDEUIMessages.ExternalPluginsBlock_reload,
0242: PDEUIMessages.TargetPluginsTab_add, null, null,
0243: PDEUIMessages.WizardCheckboxTablePart_selectAll,
0244: PDEUIMessages.WizardCheckboxTablePart_deselectAll,
0245: PDEUIMessages.ExternalPluginsBlock_workingSet,
0246: PDEUIMessages.ExternalPluginsBlock_addRequired });
0247: this .fPage = page;
0248: Preferences preferences = PDECore.getDefault()
0249: .getPluginPreferences();
0250: String additional = preferences
0251: .getString(ICoreConstants.ADDITIONAL_LOCATIONS);
0252: StringTokenizer tokenizer = new StringTokenizer(additional, ","); //$NON-NLS-1$
0253: while (tokenizer.hasMoreTokens()) {
0254: fAdditionalLocations.add(tokenizer.nextToken().trim());
0255: }
0256: PDEPlugin.getDefault().getLabelProvider().connect(this );
0257: }
0258:
0259: void computeDelta() {
0260: int type = 0;
0261: IModel[] changedArray = null;
0262: if (fChangedModels.size() > 0) {
0263: type |= IModelProviderEvent.MODELS_CHANGED;
0264: changedArray = (IModel[]) fChangedModels
0265: .toArray(new IModel[fChangedModels.size()]);
0266: }
0267: fChangedModels.clear();
0268: if (type != 0) {
0269: ExternalModelManager registry = PDECore.getDefault()
0270: .getModelManager().getExternalModelManager();
0271: ModelProviderEvent event = new ModelProviderEvent(registry,
0272: type, null, null, changedArray);
0273: registry.fireModelProviderEvent(event);
0274: }
0275: }
0276:
0277: public Control createContents(Composite parent) {
0278: Composite container = new Composite(parent, SWT.NONE);
0279: GridLayout layout = new GridLayout();
0280: layout.numColumns = 2;
0281: layout.marginHeight = 0;
0282: layout.marginWidth = 0;
0283: layout.verticalSpacing = 5;
0284: container.setLayout(layout);
0285:
0286: super .createControl(container, SWT.NONE, 2, null);
0287:
0288: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
0289:
0290: fGroupPlugins = new Button(container, SWT.CHECK);
0291: gd = new GridData();
0292: gd.horizontalSpan = 2;
0293: fGroupPlugins.setLayoutData(gd);
0294: fGroupPlugins
0295: .setText(PDEUIMessages.TargetPluginsTab_groupPlugins);
0296: fGroupPlugins.addSelectionListener(new SelectionAdapter() {
0297: public void widgetSelected(SelectionEvent e) {
0298: handleSwitchView();
0299: }
0300: });
0301:
0302: initializeView();
0303: PlatformUI.getWorkbench().getHelpSystem().setHelp(container,
0304: IHelpContextIds.TARGET_PLUGINS_PREFERENCE_PAGE);
0305: return container;
0306: }
0307:
0308: /* (non-Javadoc)
0309: * @see org.eclipse.pde.internal.ui.parts.SharedPartWithButtons#createButtons(org.eclipse.swt.widgets.Composite, org.eclipse.ui.forms.widgets.FormToolkit)
0310: */
0311: protected void createButtons(Composite parent, FormToolkit toolkit) {
0312: super .createButtons(parent, toolkit);
0313:
0314: fCounterLabel = new Label(fButtonContainer, SWT.NONE);
0315: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
0316: gd.grabExcessVerticalSpace = true;
0317: gd.verticalAlignment = SWT.BOTTOM;
0318: fCounterLabel.setLayoutData(gd);
0319: }
0320:
0321: protected void initializeView() {
0322: Preferences preferences = PDECore.getDefault()
0323: .getPluginPreferences();
0324: boolean groupPlugins = preferences
0325: .getBoolean(ICoreConstants.GROUP_PLUGINS_VIEW);
0326: fGroupPlugins.setSelection(groupPlugins);
0327: if (groupPlugins) {
0328: fBook.showPage(fPluginTreeViewer.getControl());
0329: } else {
0330: fBook.showPage(fPluginListViewer.getControl());
0331: }
0332: }
0333:
0334: protected void createMainControl(Composite parent, int style,
0335: int span, FormToolkit toolkit) {
0336: fBook = new PageBook(parent, SWT.NONE);
0337: GridData gd = new GridData(GridData.FILL_BOTH);
0338: gd.heightHint = 100;
0339: gd.widthHint = 250;
0340: fBook.setLayoutData(gd);
0341: createTableViewer(fBook);
0342: createTreeViewer(fBook);
0343: }
0344:
0345: private void createTableViewer(Composite container) {
0346: fPluginListViewer = CheckboxTableViewer.newCheckList(container,
0347: SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
0348: GridData gd = new GridData(GridData.FILL_BOTH);
0349: gd.heightHint = 100;
0350: gd.widthHint = 250;
0351: fPluginListViewer.getControl().setLayoutData(gd);
0352: fPluginListViewer
0353: .setContentProvider(new PluginContentProvider());
0354: fPluginListViewer.setLabelProvider(PDEPlugin.getDefault()
0355: .getLabelProvider());
0356: fPluginListViewer.setComparator(ListUtil.PLUGIN_COMPARATOR);
0357: fPluginListViewer
0358: .addCheckStateListener(new ICheckStateListener() {
0359:
0360: public void checkStateChanged(
0361: CheckStateChangedEvent event) {
0362: IPluginModelBase model = (IPluginModelBase) event
0363: .getElement();
0364: boolean checked = event.getChecked();
0365: if (fChangedModels.contains(model)
0366: && model.isEnabled() == checked) {
0367: fChangedModels.remove(model);
0368: } else if (model.isEnabled() != checked) {
0369: fChangedModels.add(model);
0370: }
0371:
0372: // handle checking the TreeViewer
0373: fPluginTreeViewer.setChecked(model, checked);
0374: String path = model.getInstallLocation();
0375: if (path != null) {
0376: File parent = new File(path)
0377: .getParentFile();
0378: if (checked) {
0379: fPluginTreeViewer.setChecked(parent,
0380: true);
0381: handleGrayChecked(parent, false);
0382: } else
0383: handleGrayChecked(parent, true);
0384: }
0385:
0386: // update the counter
0387: if (checked)
0388: setCounter(fCounter + 1);
0389: else
0390: setCounter(fCounter - 1);
0391: }
0392:
0393: });
0394: }
0395:
0396: private void createTreeViewer(Composite container) {
0397: fPluginTreeViewer = new CheckboxTreeViewer(container,
0398: SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
0399: GridData gd = new GridData(GridData.FILL_BOTH);
0400: gd.heightHint = 100;
0401: gd.widthHint = 250;
0402: fPluginTreeViewer.getControl().setLayoutData(gd);
0403: fPluginTreeViewer
0404: .setContentProvider(new TreePluginContentProvider());
0405: fPluginTreeViewer.setComparator(ListUtil.PLUGIN_COMPARATOR);
0406: fPluginTreeViewer.setLabelProvider(new PDELabelProvider() {
0407:
0408: public Image getImage(Object obj) {
0409: if (obj instanceof File) {
0410: return get(PDEPluginImages.DESC_SITE_OBJ);
0411: }
0412: return super .getImage(obj);
0413: }
0414: });
0415: fPluginTreeViewer
0416: .addCheckStateListener(new ICheckStateListener() {
0417:
0418: public void checkStateChanged(
0419: CheckStateChangedEvent event) {
0420: Object element = event.getElement();
0421: boolean checked = event.getChecked();
0422:
0423: // if user selected a plugin in the TreeViewer
0424: if (element instanceof IPluginModelBase) {
0425: IPluginModelBase model = (IPluginModelBase) event
0426: .getElement();
0427: if (fChangedModels.contains(model)
0428: && model.isEnabled() == checked) {
0429: fChangedModels.remove(model);
0430: } else if (model.isEnabled() != checked) {
0431: fChangedModels.add(model);
0432: }
0433: // update Table Viewer
0434: fPluginListViewer
0435: .setChecked(model, checked);
0436:
0437: // update parent in tree
0438: String path = model.getInstallLocation();
0439: if (path != null) {
0440: File parent = new File(path)
0441: .getParentFile();
0442: if (checked) {
0443: fPluginTreeViewer.setChecked(
0444: parent, true);
0445: handleGrayChecked(parent, false);
0446: } else
0447: handleGrayChecked(parent, true);
0448: }
0449:
0450: // update table
0451: if (checked)
0452: setCounter(fCounter + 1);
0453: else
0454: setCounter(fCounter - 1);
0455:
0456: // else if the user selected and eclipse directory in the TreeViewer
0457: } else if (element instanceof File) {
0458: int changedCount = 0;
0459: Set plugins = (Set) fTreeViewerContents
0460: .get(element);
0461: // iterator through plugins from selected eclipse directory
0462: IPluginModelBase[] models = (IPluginModelBase[]) plugins
0463: .toArray(new IPluginModelBase[plugins
0464: .size()]);
0465: for (int i = 0; i < models.length; i++) {
0466: if (fChangedModels.contains(models[i])
0467: && models[i].isEnabled() == checked) {
0468: fChangedModels.remove(models[i]);
0469: } else if (models[i].isEnabled() != checked) {
0470: fChangedModels.add(models[i]);
0471: }
0472: if (checked
0473: && !fPluginTreeViewer
0474: .getChecked(models[i]))
0475: ++changedCount;
0476: else if (!checked
0477: && fPluginTreeViewer
0478: .getChecked(models[i]))
0479: --changedCount;
0480: fPluginListViewer.setChecked(models[i],
0481: checked);
0482: }
0483: // update the element in the TreeViewer
0484: fPluginTreeViewer.setSubtreeChecked(
0485: element, checked);
0486: fPluginTreeViewer.setGrayed(element, false);
0487: fPluginTreeViewer.setChecked(element,
0488: checked);
0489: setCounter(fCounter + changedCount);
0490: }
0491: }
0492:
0493: });
0494: fPluginTreeViewer.setAutoExpandLevel(2);
0495: }
0496:
0497: public void dispose() {
0498: PDEPlugin.getDefault().getLabelProvider().disconnect(this );
0499: }
0500:
0501: protected void loadTargetProfile(ITarget target) {
0502: if (target.useAllPlugins()) {
0503: handleSelectAll(true);
0504: return;
0505: }
0506: Map required = new HashMap(), missingFeatures = new HashMap();
0507: Set optional = new HashSet();
0508: ITargetFeature[] targetFeatures = target.getFeatures();
0509: Stack features = new Stack();
0510:
0511: FeatureModelManager featureManager = null;
0512: if (fCurrentFeatures == null)
0513: featureManager = PDECore.getDefault()
0514: .getFeatureModelManager();
0515: for (int i = 0; i < targetFeatures.length; i++) {
0516: IFeatureModel model = (featureManager != null) ? featureManager
0517: .findFeatureModel(targetFeatures[i].getId())
0518: : (IFeatureModel) fCurrentFeatures
0519: .get(targetFeatures[i].getId());
0520: if (model != null)
0521: features.push(model.getFeature());
0522: else if (!targetFeatures[i].isOptional()) {
0523: missingFeatures.put(targetFeatures[i].getId(),
0524: targetFeatures[i]);
0525: break;
0526: }
0527: while (!features.isEmpty()) {
0528: IFeature feature = (IFeature) features.pop();
0529: IFeaturePlugin[] plugins = feature.getPlugins();
0530: for (int j = 0; j < plugins.length; j++) {
0531: if (target.isValidFeatureObject(plugins[j])) {
0532: if (targetFeatures[i].isOptional()
0533: || plugins[j].isFragment())
0534: optional.add(plugins[j].getId());
0535: else
0536: required
0537: .put(plugins[j].getId(), plugins[j]);
0538: }
0539: }
0540: IFeatureChild[] children = feature
0541: .getIncludedFeatures();
0542: for (int j = 0; j < children.length; j++) {
0543: if (!target.isValidFeatureObject(children[j]))
0544: continue;
0545: model = (featureManager != null) ? featureManager
0546: .findFeatureModel(children[j].getId())
0547: : (IFeatureModel) fCurrentFeatures
0548: .get(children[j].getId());
0549: if (model != null)
0550: features.push(model.getFeature());
0551: else if (!targetFeatures[i].isOptional()
0552: && !missingFeatures.containsKey(children[j]
0553: .getId())) {
0554: // create dummy feature to display feature is missing
0555: ITargetFeature missingFeature = target
0556: .getModel().getFactory()
0557: .createFeature();
0558: missingFeature.setId(children[j].getId());
0559: missingFeatures.put(children[j].getId(),
0560: missingFeature);
0561: }
0562: }
0563: }
0564: }
0565:
0566: ITargetPlugin[] plugins = target.getPlugins();
0567: for (int i = 0; i < plugins.length; i++) {
0568: if (plugins[i].isOptional())
0569: optional.add(plugins[i].getId());
0570: else
0571: required.put(plugins[i].getId(), plugins[i]);
0572: }
0573:
0574: IPluginModelBase workspacePlugins[] = PDECore.getDefault()
0575: .getModelManager().getWorkspaceModels();
0576: for (int i = 0; i < workspacePlugins.length; i++) {
0577: if (workspacePlugins[i].isEnabled())
0578: required.remove(workspacePlugins[i].getPluginBase()
0579: .getId());
0580: }
0581:
0582: IPluginModelBase[] models = getCurrentModels();
0583: int counter = 0;
0584: for (int i = 0; i < models.length; i++) {
0585: String id = models[i].getPluginBase().getId();
0586: if (id == null)
0587: continue;
0588: if (required.containsKey(id) || optional.contains(id)) {
0589: ++counter;
0590: if (!fPluginListViewer.getChecked(models[i])) {
0591: fPluginTreeViewer.setChecked(models[i], true);
0592: fPluginListViewer.setChecked(models[i], true);
0593: if (!models[i].isEnabled())
0594: fChangedModels.add(models[i]);
0595: // handle checking the parent
0596: String path = models[i].getInstallLocation();
0597: if (path != null) {
0598: File parent = new File(path).getParentFile();
0599: fPluginTreeViewer.setChecked(parent, true);
0600: handleGrayChecked(parent, false);
0601: }
0602:
0603: }
0604: required.remove(id);
0605: } else {
0606: if (fPluginListViewer.getChecked(models[i])) {
0607: fPluginTreeViewer.setChecked(models[i], false);
0608: fPluginListViewer.setChecked(models[i], false);
0609: if (models[i].isEnabled())
0610: fChangedModels.add(models[i]);
0611: // handle updating parent
0612: String path = models[i].getInstallLocation();
0613: if (path != null) {
0614: File parent = new File(path).getParentFile();
0615: handleGrayChecked(parent, true);
0616: }
0617: }
0618: }
0619: }
0620: setCounter(counter);
0621: if (!required.isEmpty() || !missingFeatures.isEmpty())
0622: TargetErrorDialog.showDialog(fPage.getShell(),
0623: missingFeatures.values().toArray(), required
0624: .values().toArray());
0625: }
0626:
0627: protected void handleReload() {
0628: String platformPath = fPage.getPlatformPath();
0629: if (platformPath != null && platformPath.length() > 0) {
0630: ReloadOperation op = new ReloadOperation(platformPath);
0631: try {
0632: PlatformUI.getWorkbench().getProgressService().run(
0633: true, false, op);
0634: } catch (InvocationTargetException e) {
0635: } catch (InterruptedException e) {
0636: }
0637: fPluginListViewer.setInput(PDECore.getDefault()
0638: .getModelManager().getExternalModelManager());
0639: fPluginTreeViewer.setInput(PDECore.getDefault()
0640: .getModelManager().getExternalModelManager());
0641: fChangedModels.clear();
0642: handleSelectAll(true);
0643: if (fTreeViewerContents.size() > 1)
0644: fPluginTreeViewer.collapseAll();
0645: fReloaded = true;
0646: fPage.getSourceBlock().resetExtensionLocations(
0647: getCurrentModels());
0648: }
0649: fPage.resetNeedsReload();
0650: }
0651:
0652: protected void handleReload(ArrayList additionalLocations) {
0653: fAdditionalLocations = additionalLocations;
0654: handleReload();
0655: }
0656:
0657: public void initialize() {
0658: String platformPath = fPage.getPlatformPath();
0659: if (platformPath != null && platformPath.length() == 0)
0660: return;
0661:
0662: fPluginTreeViewer.setUseHashlookup(true);
0663: ExternalModelManager manager = PDECore.getDefault()
0664: .getModelManager().getExternalModelManager();
0665: fPluginListViewer.setInput(manager);
0666: fPluginTreeViewer.setInput(manager);
0667: IPluginModelBase[] allModels = getCurrentModels();
0668:
0669: Vector selection = new Vector();
0670: Set parentsToCheck = new HashSet();
0671: for (int i = 0; i < allModels.length; i++) {
0672: IPluginModelBase model = allModels[i];
0673: if (model.isEnabled()) {
0674: selection.add(model);
0675: }
0676: // if model is to be selected, add parent to list of parents to be updated
0677: String path = model.getInstallLocation();
0678: if (path != null) {
0679: File installFile = new File(path);
0680: File parentFile = installFile.getParentFile();
0681: if (model.isEnabled())
0682: parentsToCheck.add(parentFile);
0683: }
0684: }
0685: Object[] elements = selection.toArray();
0686: fPluginListViewer.setCheckedElements(elements);
0687:
0688: // handle checking for the TreeViewer
0689: Object[] parents = parentsToCheck.toArray();
0690: Object[] checkedValues = new Object[parents.length
0691: + elements.length];
0692: System.arraycopy(parents, 0, checkedValues, 0, parents.length);
0693: System.arraycopy(elements, 0, checkedValues, parents.length,
0694: elements.length);
0695: fPluginTreeViewer.setCheckedElements(checkedValues);
0696: for (int i = 0; i < parents.length; i++) {
0697: handleGrayChecked((File) parents[i], false);
0698: }
0699: setCounter(elements.length);
0700: }
0701:
0702: // returns a Set which contains all the new File objects representing a new location
0703: public Set initializeTreeContents(IPluginModelBase[] allModels) {
0704: HashSet parents = new HashSet();
0705: if (fTreeViewerContents == null)
0706: fTreeViewerContents = new HashMap();
0707: for (int i = 0; i < allModels.length; i++) {
0708: IPluginModelBase model = allModels[i];
0709: String path = model.getInstallLocation();
0710: if (path != null) {
0711: File installFile = new File(path);
0712: File parentFile = installFile.getParentFile();
0713: Set models = (Set) fTreeViewerContents.get(parentFile);
0714: if (models == null) {
0715: models = new HashSet();
0716: models.add(model);
0717: fTreeViewerContents.put(parentFile, models);
0718: parents.add(parentFile);
0719: } else {
0720: models.add(model);
0721: }
0722: }
0723: }
0724: return parents;
0725: }
0726:
0727: public void performOk() {
0728: savePreferences();
0729: if (fReloaded) {
0730: updateModels();
0731: Job job = new TargetPlatformResetJob(fCurrentState);
0732: job.setProperty(IProgressConstants.ICON_PROPERTY,
0733: PDEPluginImages.DESC_PLUGIN_OBJ);
0734: job.schedule();
0735: fReloaded = false;
0736: fChangedModels.clear();
0737: } else {
0738: updateModels();
0739: computeDelta();
0740: }
0741: }
0742:
0743: private void savePreferences() {
0744: Preferences preferences = PDECore.getDefault()
0745: .getPluginPreferences();
0746: IPath newPath = new Path(fPage.getPlatformPath());
0747: IPath defaultPath = new Path(
0748: org.eclipse.pde.core.plugin.TargetPlatform
0749: .getDefaultLocation());
0750: String mode = newPath.equals(defaultPath) ? ICoreConstants.VALUE_USE_THIS
0751: : ICoreConstants.VALUE_USE_OTHER;
0752: preferences.setValue(ICoreConstants.TARGET_MODE, mode);
0753: preferences.setValue(ICoreConstants.PLATFORM_PATH, fPage
0754: .getPlatformPath());
0755:
0756: if (fCounter == 0) {
0757: preferences.setValue(ICoreConstants.CHECKED_PLUGINS,
0758: ICoreConstants.VALUE_SAVED_NONE);
0759: } else if (fCounter == fPluginListViewer.getTable()
0760: .getItemCount()) {
0761: preferences.setValue(ICoreConstants.CHECKED_PLUGINS,
0762: ICoreConstants.VALUE_SAVED_ALL);
0763: } else {
0764: StringBuffer saved = new StringBuffer();
0765: TableItem[] models = fPluginListViewer.getTable()
0766: .getItems();
0767: for (int i = 0; i < models.length; i++) {
0768: if (models[i].getChecked())
0769: continue;
0770: IPluginModelBase model = (IPluginModelBase) models[i]
0771: .getData();
0772: if (saved.length() > 0)
0773: saved.append(" "); //$NON-NLS-1$
0774: saved.append(model.getPluginBase().getId());
0775: }
0776: preferences.setValue(ICoreConstants.CHECKED_PLUGINS, saved
0777: .toString());
0778: }
0779:
0780: String[] locations = fPage.getPlatformLocations();
0781: for (int i = 0; i < locations.length && i < 5; i++) {
0782: preferences.setValue(ICoreConstants.SAVED_PLATFORM + i,
0783: locations[i]);
0784: }
0785: preferences.setValue(ICoreConstants.GROUP_PLUGINS_VIEW,
0786: fGroupPlugins.getSelection());
0787:
0788: StringBuffer buffer = new StringBuffer();
0789: for (int i = 0; i < fAdditionalLocations.size(); i++) {
0790: if (buffer.length() > 0)
0791: buffer.append(","); //$NON-NLS-1$
0792: buffer.append(fAdditionalLocations.get(i).toString());
0793: }
0794: preferences.setValue(ICoreConstants.ADDITIONAL_LOCATIONS,
0795: buffer.toString());
0796: PDECore.getDefault().savePluginPreferences();
0797: }
0798:
0799: private void updateModels() {
0800: Iterator iter = fChangedModels.iterator();
0801: while (iter.hasNext()) {
0802: IPluginModelBase model = (IPluginModelBase) iter.next();
0803: model.setEnabled(fPluginListViewer.getChecked(model));
0804: }
0805: }
0806:
0807: public void handleSelectAll(boolean selected) {
0808: fPluginListViewer.setAllChecked(selected);
0809: fPluginTreeViewer.setAllChecked(selected);
0810:
0811: IPluginModelBase[] allModels = getCurrentModels();
0812: for (int i = 0; i < allModels.length; i++) {
0813: IPluginModelBase model = allModels[i];
0814: if (model.isEnabled() != selected) {
0815: fChangedModels.add(model);
0816: } else if (fChangedModels.contains(model)
0817: && model.isEnabled() == selected) {
0818: fChangedModels.remove(model);
0819: }
0820: }
0821: if (selected) {
0822: setCounter(fPluginListViewer.getTable().getItemCount());
0823: } else
0824: setCounter(0);
0825: }
0826:
0827: private void handleWorkingSets() {
0828: IWorkingSetManager manager = PlatformUI.getWorkbench()
0829: .getWorkingSetManager();
0830: IWorkingSetSelectionDialog dialog = manager
0831: .createWorkingSetSelectionDialog(fPluginListViewer
0832: .getControl().getShell(), true);
0833: if (dialog.open() == Window.OK) {
0834: HashSet set = getPluginIDs(dialog.getSelection());
0835: IPluginModelBase[] models = getCurrentModels();
0836: int counter = 0;
0837: for (int i = 0; i < models.length; i++) {
0838: String id = models[i].getPluginBase().getId();
0839: if (id == null)
0840: continue;
0841: if (set.contains(id)) {
0842: if (!fPluginListViewer.getChecked(models[i])) {
0843: fPluginListViewer.setChecked(models[i], true);
0844: counter += 1;
0845: if (!models[i].isEnabled())
0846: fChangedModels.add(models[i]);
0847: }
0848: if (!fPluginTreeViewer.getChecked(models[i])) {
0849: fPluginTreeViewer.setChecked(models[i], true);
0850: String path = models[i].getInstallLocation();
0851: if (path != null) {
0852: File parent = new File(path)
0853: .getParentFile();
0854: fPluginTreeViewer.setChecked(parent, true);
0855: handleGrayChecked(parent, false);
0856: }
0857: }
0858: set.remove(id);
0859: }
0860: if (set.isEmpty())
0861: break;
0862: }
0863: setCounter(fCounter + counter);
0864: }
0865: }
0866:
0867: /*
0868: * Sets the parent object to the right state. This includes the checked state
0869: * and/or the gray state.
0870: *
0871: * @param parent The parent object to check the current state of.
0872: * @param handleCheck True if you wish the set the checked value of the object, False otherwise.
0873: */
0874: // added the second boolean because many time I know the parent will be checked.
0875: // Therefore I didn't want to waste time calling .setChecked() again.
0876: protected void handleGrayChecked(File parent, boolean handleCheck) {
0877: boolean gray = false, check = false, allChecked = true;
0878: Set models = (Set) fTreeViewerContents.get(parent);
0879: Iterator it = models.iterator();
0880: while (it.hasNext()) {
0881: Object model = it.next();
0882: boolean checked = fPluginTreeViewer.getChecked(model);
0883: check = check || checked;
0884: allChecked = allChecked && checked;
0885: if (!gray && checked) {
0886: gray = true;
0887: } else if (gray && !checked) {
0888: allChecked = false;
0889: break;
0890: }
0891: }
0892: if (!allChecked && gray)
0893: fPluginTreeViewer.setGrayed(parent, true);
0894: else
0895: fPluginTreeViewer.setGrayed(parent, false);
0896: if (handleCheck) {
0897: if (check)
0898: fPluginTreeViewer.setChecked(parent, true);
0899: else
0900: fPluginTreeViewer.setChecked(parent, false);
0901: }
0902: }
0903:
0904: private HashSet getPluginIDs(IWorkingSet[] workingSets) {
0905: HashSet set = new HashSet();
0906: for (int i = 0; i < workingSets.length; i++) {
0907: IAdaptable[] elements = workingSets[i].getElements();
0908: for (int j = 0; j < elements.length; j++) {
0909: Object element = elements[j];
0910: if (element instanceof PersistablePluginObject) {
0911: set.add(((PersistablePluginObject) element)
0912: .getPluginID());
0913: } else {
0914: if (element instanceof IJavaProject)
0915: element = ((IJavaProject) element).getProject();
0916: if (element instanceof IProject) {
0917: IPluginModelBase model = PluginRegistry
0918: .findModel((IProject) element);
0919: if (model != null)
0920: set.add(model.getPluginBase().getId());
0921: }
0922: }
0923: }
0924: }
0925: return set;
0926: }
0927:
0928: private void handleAddRequired() {
0929: Object[] checked = fPluginListViewer.getCheckedElements();
0930: if (checked.length == 0)
0931: return;
0932: String[] implicit = fPage.getImplicitPlugins();
0933: State state = getCurrentState().getState();
0934: Set set = DependencyManager.getDependencies(checked, implicit,
0935: state);
0936: Set parents = new HashSet();
0937: IPluginModelBase[] models = getCurrentModels();
0938: int counter = 0;
0939: for (int i = 0; i < models.length; i++) {
0940: if (set.contains(models[i].getPluginBase().getId())) {
0941: fPluginListViewer.setChecked(models[i], true);
0942: fPluginTreeViewer.setChecked(models[i], true);
0943: fChangedModels.add(models[i]);
0944: counter += 1;
0945: String path = models[i].getInstallLocation();
0946: if (path != null) {
0947: parents.add(new File(path).getParentFile());
0948: }
0949: }
0950: }
0951: Iterator it = parents.iterator();
0952: while (it.hasNext())
0953: handleGrayChecked((File) it.next(), true);
0954:
0955: setCounter(fCounter + counter);
0956: }
0957:
0958: protected IPluginModelBase[] getCurrentModels() {
0959: if (fCurrentState != null)
0960: return fCurrentState.getTargetModels();
0961: return PDECore.getDefault().getModelManager()
0962: .getExternalModels();
0963: }
0964:
0965: protected PDEState getCurrentState() {
0966: return (fCurrentState != null) ? fCurrentState
0967: : TargetPlatformHelper.getPDEState();
0968: }
0969:
0970: protected void handleSwitchView() {
0971: if (fGroupPlugins.getSelection())
0972: fBook.showPage(fPluginTreeViewer.getControl());
0973: else
0974: fBook.showPage(fPluginListViewer.getControl());
0975:
0976: }
0977:
0978: private void setCounter(int value) {
0979: fCounter = value;
0980: int total = fPluginListViewer.getTable().getItemCount();
0981: String message = NLS.bind(
0982: PDEUIMessages.WizardCheckboxTablePart_counter,
0983: (new String[] { Integer.toString(fCounter),
0984: Integer.toString(total) }));
0985: fCounterLabel.setText(message);
0986: }
0987:
0988: protected void buttonSelected(Button button, int index) {
0989: switch (index) {
0990: case 0:
0991: // Upon hitting 'Reload', erase the additional directories and load just the main path
0992: handleReload(new ArrayList());
0993: fPage.resetTargetProfile();
0994: break;
0995: case 1:
0996: handleAdd();
0997: break;
0998: case 4:
0999: handleSelectAll(true);
1000: break;
1001: case 5:
1002: handleSelectAll(false);
1003: break;
1004: case 6:
1005: handleWorkingSets();
1006: break;
1007: case 7:
1008: handleAddRequired();
1009: break;
1010: }
1011: }
1012:
1013: private void handleAdd() {
1014: AddTargetPluginsWizard wizard = new AddTargetPluginsWizard();
1015: WizardDialog dialog = new WizardDialog(fPage.getShell(), wizard);
1016: dialog.create();
1017: SWTUtil.setDialogSize(dialog, 400, 450);
1018: dialog.open();
1019:
1020: File[] dirs = wizard.getDirectories();
1021: if (dirs.length == 0) {
1022: // no new URLs found/to add
1023: return;
1024: }
1025: for (int i = 0; i < dirs.length; i++) {
1026: fAdditionalLocations.add(dirs[i].getPath());
1027: File temp = new File(dirs[i], "plugins"); //$NON-NLS-1$
1028: if (temp.exists())
1029: dirs[i] = temp;
1030: }
1031:
1032: URL[] pluginLocs = PluginPathFinder.scanLocations(dirs);
1033: Object[] checkedPlugins = null;
1034: if (fCurrentState == null) {
1035: checkedPlugins = fPluginListViewer.getCheckedElements();
1036: createCopyState();
1037: }
1038: BundleDescription[] descriptions = fCurrentState
1039: .addAdditionalBundles(pluginLocs);
1040: addNewBundles(descriptions, checkedPlugins);
1041: if (fCurrentRegistry != null)
1042: fCurrentRegistry.dispose();
1043: fCurrentRegistry = null;
1044: }
1045:
1046: private void createCopyState() {
1047: fCurrentState = new PDEState(TargetPlatformHelper.getPDEState());
1048: IPluginModelBase[] bases = fCurrentState.getTargetModels();
1049: for (int j = 0; j < bases.length; j++) {
1050: long bundleId = bases[j].getBundleDescription()
1051: .getBundleId();
1052: BundleDescription newDesc = fCurrentState.getState()
1053: .getBundle(bundleId);
1054: bases[j].setBundleDescription(newDesc);
1055: }
1056: }
1057:
1058: private void addNewBundles(BundleDescription[] descriptions,
1059: Object[] checkedPlugins) {
1060: if (descriptions.length > 0) {
1061: IPluginModelBase[] models = fCurrentState
1062: .createTargetModels(descriptions);
1063: // add new models to tree viewer
1064: Set parents = initializeTreeContents(models);
1065:
1066: fPluginListViewer.setInput(PDECore.getDefault()
1067: .getModelManager().getExternalModelManager());
1068: fPluginTreeViewer.setInput(PDECore.getDefault()
1069: .getModelManager().getExternalModelManager());
1070:
1071: if (checkedPlugins == null) {
1072: for (int i = 0; i < models.length; i++) {
1073: fPluginListViewer.setChecked(models[i], true);
1074: fPluginTreeViewer.setChecked(models[i], true);
1075: }
1076: } else {
1077: Object[] newCheckedPlugins = new Object[checkedPlugins.length
1078: + models.length];
1079: System.arraycopy(checkedPlugins, 0, newCheckedPlugins,
1080: 0, checkedPlugins.length);
1081: System.arraycopy(models, 0, newCheckedPlugins,
1082: checkedPlugins.length, models.length);
1083: fPluginListViewer.setCheckedElements(newCheckedPlugins);
1084: fPluginTreeViewer.setCheckedElements(newCheckedPlugins);
1085: }
1086: for (int i = 0; i < models.length; i++) {
1087: fChangedModels.add(models[i]);
1088: }
1089: Iterator it = parents.iterator();
1090: while (it.hasNext())
1091: fPluginTreeViewer.setChecked(it.next(), true);
1092: // have to use getCheckedElements() instead of newCheckedPlugins because a new plug-in might have replaced an plug-in model in the original checked list.
1093: setCounter(fPluginListViewer.getCheckedElements().length);
1094: fPage.getSourceBlock().resetExtensionLocations(
1095: getCurrentModels());
1096: fReloaded = true;
1097: }
1098: }
1099:
1100: // store Extension Registry info in TargetPluginsTab because we need to know when fCurrentState == null. Could store it in TargetSourceTab
1101: // and call .getCurrentState, but would have to compare States. Simply by putting it here will save time otherwise spent comparing States.
1102: protected PDEExtensionRegistry getCurrentExtensionRegistry() {
1103: if (fCurrentState == null)
1104: return PDECore.getDefault().getExtensionsRegistry();
1105: if (fCurrentRegistry == null)
1106: fCurrentRegistry = new PDEExtensionRegistry(
1107: getCurrentModels());
1108: return fCurrentRegistry;
1109: }
1110:
1111: }
|