001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.launcher;
011:
012: import java.util.ArrayList;
013: import java.util.Map;
014: import java.util.Set;
015: import java.util.StringTokenizer;
016: import java.util.TreeMap;
017: import java.util.TreeSet;
018:
019: import org.eclipse.core.resources.IProject;
020: import org.eclipse.core.runtime.CoreException;
021: import org.eclipse.core.runtime.IProgressMonitor;
022: import org.eclipse.core.runtime.Status;
023: import org.eclipse.debug.core.ILaunchConfiguration;
024: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
025: import org.eclipse.jdt.core.IJavaProject;
026: import org.eclipse.jdt.core.JavaCore;
027: import org.eclipse.jface.dialogs.IDialogConstants;
028: import org.eclipse.osgi.service.resolver.BundleDescription;
029: import org.eclipse.pde.core.plugin.IPluginModelBase;
030: import org.eclipse.pde.core.plugin.PluginRegistry;
031: import org.eclipse.pde.internal.core.PDECore;
032: import org.eclipse.pde.internal.core.SearchablePluginsManager;
033: import org.eclipse.pde.internal.core.TargetPlatformHelper;
034: import org.eclipse.pde.internal.ui.IPDEUIConstants;
035: import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
036: import org.eclipse.swt.widgets.Display;
037:
038: public class LaunchPluginValidator {
039:
040: public static void checkBackwardCompatibility(
041: ILaunchConfiguration configuration, boolean save)
042: throws CoreException {
043: ILaunchConfigurationWorkingCopy wc = null;
044: if (configuration.isWorkingCopy()) {
045: wc = (ILaunchConfigurationWorkingCopy) configuration;
046: } else {
047: wc = configuration.getWorkingCopy();
048: }
049:
050: String value = configuration.getAttribute(
051: "wsproject", (String) null); //$NON-NLS-1$
052: if (value != null) {
053: wc.setAttribute("wsproject", (String) null); //$NON-NLS-1$
054: if (value.indexOf(';') != -1) {
055: value = value.replace(';', ',');
056: } else if (value.indexOf(':') != -1) {
057: value = value.replace(':', ',');
058: }
059: value = (value.length() == 0 || value.equals(",")) //$NON-NLS-1$
060: ? null
061: : value.substring(0, value.length() - 1);
062:
063: boolean automatic = configuration.getAttribute(
064: IPDELauncherConstants.AUTOMATIC_ADD, true);
065: String attr = automatic ? IPDELauncherConstants.DESELECTED_WORKSPACE_PLUGINS
066: : IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS;
067: wc.setAttribute(attr, value);
068: }
069:
070: String value2 = configuration.getAttribute(
071: "extplugins", (String) null); //$NON-NLS-1$
072: if (value2 != null) {
073: wc.setAttribute("extplugins", (String) null); //$NON-NLS-1$
074: if (value2.indexOf(';') != -1)
075: value2 = value2.replace(';', ',');
076: else if (value2.indexOf(':') != -1)
077: value2 = value2.replace(':', ',');
078: value2 = (value2.length() == 0 || value2.equals(",")) //$NON-NLS-1$
079: ? null
080: : value2.substring(0, value2.length() - 1);
081: wc.setAttribute(
082: IPDELauncherConstants.SELECTED_TARGET_PLUGINS,
083: value2);
084: }
085:
086: String version = configuration.getAttribute(
087: IPDEUIConstants.LAUNCHER_PDE_VERSION, (String) null); //$NON-NLS-1$
088: boolean newApp = TargetPlatformHelper.usesNewApplicationModel();
089: boolean upgrade = !"3.3".equals(version) && newApp; //$NON-NLS-1$
090: if (!upgrade)
091: upgrade = TargetPlatformHelper.getTargetVersion() >= 3.2
092: && version == null; //$NON-NLS-1$
093: if (upgrade) {
094: wc.setAttribute(IPDEUIConstants.LAUNCHER_PDE_VERSION,
095: newApp ? "3.3" : "3.2a"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
096: boolean usedefault = configuration.getAttribute(
097: IPDELauncherConstants.USE_DEFAULT, true);
098: boolean useFeatures = configuration.getAttribute(
099: IPDELauncherConstants.USEFEATURES, false);
100: boolean automaticAdd = configuration.getAttribute(
101: IPDELauncherConstants.AUTOMATIC_ADD, true);
102: if (!usedefault && !useFeatures) {
103: ArrayList list = new ArrayList();
104: if (version == null) {
105: list.add("org.eclipse.core.contenttype"); //$NON-NLS-1$
106: list.add("org.eclipse.core.jobs"); //$NON-NLS-1$
107: list.add("org.eclipse.equinox.common"); //$NON-NLS-1$
108: list.add("org.eclipse.equinox.preferences"); //$NON-NLS-1$
109: list.add("org.eclipse.equinox.registry"); //$NON-NLS-1$
110: list
111: .add("org.eclipse.core.runtime.compatibility.registry"); //$NON-NLS-1$
112: }
113: if (!"3.3".equals(version) && newApp) //$NON-NLS-1$
114: list.add("org.eclipse.equinox.app"); //$NON-NLS-1$
115: StringBuffer extensions = new StringBuffer(
116: configuration
117: .getAttribute(
118: IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS,
119: "")); //$NON-NLS-1$
120: StringBuffer target = new StringBuffer(
121: configuration
122: .getAttribute(
123: IPDELauncherConstants.SELECTED_TARGET_PLUGINS,
124: "")); //$NON-NLS-1$
125: for (int i = 0; i < list.size(); i++) {
126: String plugin = list.get(i).toString();
127: IPluginModelBase model = PluginRegistry
128: .findModel(plugin);
129: if (model == null)
130: continue;
131: if (model.getUnderlyingResource() != null) {
132: if (automaticAdd)
133: continue;
134: if (extensions.length() > 0)
135: extensions.append(","); //$NON-NLS-1$
136: extensions.append(plugin);
137: } else {
138: if (target.length() > 0)
139: target.append(","); //$NON-NLS-1$
140: target.append(plugin);
141: }
142: }
143: if (extensions.length() > 0)
144: wc
145: .setAttribute(
146: IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS,
147: extensions.toString());
148: if (target.length() > 0)
149: wc
150: .setAttribute(
151: IPDELauncherConstants.SELECTED_TARGET_PLUGINS,
152: target.toString());
153: }
154: }
155:
156: if (save && (value != null || value2 != null || upgrade))
157: wc.doSave();
158: }
159:
160: private static void addToMap(Map map, IPluginModelBase[] models) {
161: for (int i = 0; i < models.length; i++) {
162: addToMap(map, models[i]);
163: }
164: }
165:
166: private static void addToMap(Map map, IPluginModelBase model) {
167: BundleDescription desc = model.getBundleDescription();
168: if (desc != null) {
169: String id = desc.getSymbolicName();
170: // the reason that we are using a map is to easily check
171: // if a plug-in with a certain id is among the plug-ins we are launching with.
172: // Therefore, now that we support multiple plug-ins by the same ID,
173: // once a particular ID is used up as a key, the rest can be entered
174: // with key == id_version, for easy retrieval of values later on,
175: // and without the need to create complicated data structures for values.
176: if (!map.containsKey(id)) {
177: map.put(id, model);
178: } else {
179: map.put(id + "_" + desc.getBundleId(), model); //$NON-NLS-1$
180: }
181: }
182: }
183:
184: private static IPluginModelBase[] getSelectedWorkspacePlugins(
185: ILaunchConfiguration configuration) throws CoreException {
186:
187: boolean usedefault = configuration.getAttribute(
188: IPDELauncherConstants.USE_DEFAULT, true);
189: boolean useFeatures = configuration.getAttribute(
190: IPDELauncherConstants.USEFEATURES, false);
191:
192: IPluginModelBase[] models = PluginRegistry.getWorkspaceModels();
193:
194: if (usedefault || useFeatures || models.length == 0)
195: return models;
196:
197: ArrayList list = new ArrayList();
198: if (configuration.getAttribute(
199: IPDELauncherConstants.AUTOMATIC_ADD, true)) {
200: TreeSet deselected = parsePlugins(configuration,
201: IPDELauncherConstants.DESELECTED_WORKSPACE_PLUGINS);
202: if (deselected.size() == 0)
203: return models;
204: for (int i = 0; i < models.length; i++) {
205: String id = models[i].getPluginBase().getId();
206: if (id != null && !deselected.contains(id))
207: list.add(models[i]);
208: }
209: } else {
210: TreeSet selected = parsePlugins(configuration,
211: IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS);
212: for (int i = 0; i < models.length; i++) {
213: String id = models[i].getPluginBase().getId();
214: if (id != null && selected.contains(id))
215: list.add(models[i]);
216: }
217: }
218: return (IPluginModelBase[]) list
219: .toArray(new IPluginModelBase[list.size()]);
220: }
221:
222: public static TreeSet parsePlugins(
223: ILaunchConfiguration configuration, String attribute)
224: throws CoreException {
225: TreeSet set = new TreeSet();
226: String ids = configuration.getAttribute(attribute,
227: (String) null);
228: if (ids != null) {
229: StringTokenizer tok = new StringTokenizer(ids, ","); //$NON-NLS-1$
230: while (tok.hasMoreTokens())
231: set.add(tok.nextToken());
232: }
233: return set;
234: }
235:
236: public static IPluginModelBase[] getPluginList(
237: ILaunchConfiguration config) throws CoreException {
238: Map map = getPluginsToRun(config);
239: return (IPluginModelBase[]) map.values().toArray(
240: new IPluginModelBase[map.size()]);
241: }
242:
243: public static Map getPluginsToRun(ILaunchConfiguration config)
244: throws CoreException {
245:
246: checkBackwardCompatibility(config, true);
247:
248: TreeMap map = new TreeMap();
249: if (config
250: .getAttribute(IPDELauncherConstants.USE_DEFAULT, true)) {
251: addToMap(map, PluginRegistry.getActiveModels());
252: return map;
253: }
254:
255: if (config.getAttribute(IPDELauncherConstants.USEFEATURES,
256: false)) {
257: addToMap(map, PluginRegistry.getWorkspaceModels());
258: return map;
259: }
260:
261: addToMap(map, getSelectedWorkspacePlugins(config));
262:
263: Set exModels = parsePlugins(config,
264: IPDELauncherConstants.SELECTED_TARGET_PLUGINS);
265: IPluginModelBase[] exmodels = PluginRegistry
266: .getExternalModels();
267: for (int i = 0; i < exmodels.length; i++) {
268: String id = exmodels[i].getPluginBase().getId();
269: if (id != null && exModels.contains(id)) {
270: IPluginModelBase existing = (IPluginModelBase) map
271: .get(id);
272: // only allow dups if plug-in existing in map is not a workspace plug-in
273: if (existing == null
274: || existing.getUnderlyingResource() == null)
275: addToMap(map, exmodels[i]);
276: }
277: }
278: return map;
279: }
280:
281: public static IProject[] getAffectedProjects(
282: ILaunchConfiguration config) throws CoreException {
283: // if restarting, no need to check projects for errors
284: if (config.getAttribute(IPDEUIConstants.RESTART, false))
285: return new IProject[0];
286: ArrayList projects = new ArrayList();
287: IPluginModelBase[] models = getSelectedWorkspacePlugins(config);
288: for (int i = 0; i < models.length; i++) {
289: IProject project = models[i].getUnderlyingResource()
290: .getProject();
291: if (project.hasNature(JavaCore.NATURE_ID))
292: projects.add(project);
293: }
294:
295: // add fake "Java Search" project
296: SearchablePluginsManager manager = PDECore.getDefault()
297: .getSearchablePluginsManager();
298: IJavaProject proxy = manager.getProxyProject();
299: if (proxy != null) {
300: projects.add(proxy.getProject());
301: }
302: return (IProject[]) projects.toArray(new IProject[projects
303: .size()]);
304: }
305:
306: public static void runValidationOperation(
307: final LaunchValidationOperation op, IProgressMonitor monitor)
308: throws CoreException {
309: op.run(monitor);
310: if (op.hasErrors()) {
311: final int[] result = new int[1];
312: final Display display = LauncherUtils.getDisplay();
313: display.syncExec(new Runnable() {
314: public void run() {
315: PluginStatusDialog dialog = new PluginStatusDialog(
316: display.getActiveShell());
317: dialog.showCancelButton(true);
318: dialog.setInput(op.getInput());
319: result[0] = dialog.open();
320: }
321: });
322: if (result[0] == IDialogConstants.CANCEL_ID)
323: throw new CoreException(Status.CANCEL_STATUS);
324: }
325: }
326:
327: }
|