001: /*******************************************************************************
002: * Copyright (c) 2006, 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.ui.launcher;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.Set;
015:
016: import org.eclipse.core.resources.IFile;
017: import org.eclipse.core.resources.IProject;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IAdaptable;
020: import org.eclipse.debug.core.ILaunchConfiguration;
021: import org.eclipse.debug.core.ILaunchConfigurationType;
022: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
023: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
024: import org.eclipse.jface.viewers.ISelection;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.window.Window;
027: import org.eclipse.pde.core.plugin.IPluginAttribute;
028: import org.eclipse.pde.core.plugin.IPluginBase;
029: import org.eclipse.pde.core.plugin.IPluginElement;
030: import org.eclipse.pde.core.plugin.IPluginExtension;
031: import org.eclipse.pde.core.plugin.IPluginModelBase;
032: import org.eclipse.pde.core.plugin.PluginRegistry;
033: import org.eclipse.pde.core.plugin.TargetPlatform;
034: import org.eclipse.pde.internal.core.DependencyManager;
035: import org.eclipse.pde.internal.core.TargetPlatformHelper;
036: import org.eclipse.pde.internal.core.product.WorkspaceProductModel;
037: import org.eclipse.pde.internal.core.util.IdUtil;
038: import org.eclipse.pde.internal.ui.IPDEUIConstants;
039: import org.eclipse.pde.internal.ui.PDEPlugin;
040: import org.eclipse.pde.internal.ui.launcher.ApplicationSelectionDialog;
041: import org.eclipse.pde.internal.ui.launcher.LaunchAction;
042: import org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper;
043: import org.eclipse.ui.IEditorPart;
044:
045: /**
046: * A launch shortcut capable of launching an Eclipse application.
047: * Given the current selection, either a new Eclipse Application launch configuration is created with default settings, or the user is presented
048: * with a list of suitable existing Eclipse Application launch configurations to choose from.
049: * <p>
050: * This class may be substantiated or subclassed by clients.
051: * </p>
052: * @since 3.3
053: */
054: public class EclipseLaunchShortcut extends AbstractLaunchShortcut {
055:
056: public static final String CONFIGURATION_TYPE = "org.eclipse.pde.ui.RuntimeWorkbench"; //$NON-NLS-1$
057:
058: private IPluginModelBase fModel = null;
059:
060: private String fApplicationName = null;
061:
062: /*
063: * (non-Javadoc)
064: * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String)
065: */
066: public void launch(IEditorPart editor, String mode) {
067: fApplicationName = null;
068: fModel = null;
069: launch(mode);
070: }
071:
072: /*
073: * (non-Javadoc)
074: * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String)
075: */
076: public void launch(ISelection selection, String mode) {
077: IPluginModelBase model = null;
078: if (selection instanceof IStructuredSelection) {
079: IStructuredSelection ssel = (IStructuredSelection) selection;
080: if (!ssel.isEmpty()) {
081: Object object = ssel.getFirstElement();
082: IProject project = null;
083: if (object instanceof IFile) {
084: // if instanceof Product model, we are launching from Product Editor. Launch as Product
085: if ("product".equals(((IFile) object).getFileExtension())) { //$NON-NLS-1$
086: WorkspaceProductModel productModel = new WorkspaceProductModel(
087: (IFile) object, false);
088: try {
089: productModel.load();
090: new LaunchAction(productModel.getProduct(),
091: ((IFile) object).getFullPath()
092: .toOSString(), mode).run();
093: } catch (CoreException e) {
094: PDEPlugin.log(e);
095: }
096: return;
097: }
098: // if it isn't a .product file, then find the project of the file inorder to launch using that project's corresponding plug-in
099: // bug 180043
100: project = ((IFile) object).getProject();
101: } else if (object instanceof IAdaptable) {
102: project = (IProject) ((IAdaptable) object)
103: .getAdapter(IProject.class);
104: }
105: if (project != null && project.isOpen())
106: model = PluginRegistry.findModel(project);
107: }
108: }
109: launch(model, mode);
110: }
111:
112: private void launch(IPluginModelBase model, String mode) {
113: fModel = model;
114: fApplicationName = null;
115: if (fModel != null) {
116: String[] applicationNames = getAvailableApplications();
117: if (applicationNames.length == 1) {
118: fApplicationName = applicationNames[0];
119: } else if (applicationNames.length > 1) {
120: ApplicationSelectionDialog dialog = new ApplicationSelectionDialog(
121: PDEPlugin.getActiveWorkbenchShell().getShell(),
122: applicationNames, mode);
123: if (dialog.open() == Window.OK) {
124: fApplicationName = dialog.getSelectedApplication();
125: }
126: }
127: }
128: launch(mode);
129: }
130:
131: protected ILaunchConfiguration findLaunchConfiguration(String mode) {
132: ILaunchConfiguration config = super
133: .findLaunchConfiguration(mode);
134: try {
135: if (!(config.getAttribute(
136: IPDELauncherConstants.USE_DEFAULT, false))
137: && (config.getAttribute(
138: IPDEUIConstants.GENERATED_CONFIG, false))) {
139: ILaunchConfigurationWorkingCopy wc = config
140: .getWorkingCopy();
141: initializePluginsList(wc);
142: return wc.doSave();
143: }
144: } catch (CoreException e) {
145: }
146: return config;
147: }
148:
149: private String[] getAvailableApplications() {
150: IPluginBase plugin = fModel.getPluginBase();
151: String id = plugin.getId();
152: if (id == null || id.trim().length() == 0)
153: return new String[0];
154:
155: IPluginExtension[] extensions = plugin.getExtensions();
156: ArrayList result = new ArrayList();
157: for (int i = 0; i < extensions.length; i++) {
158: IPluginExtension extension = extensions[i];
159: if ("org.eclipse.core.runtime.applications".equals(extension.getPoint())) { //$NON-NLS-1$
160: String extensionID = extension.getId();
161: if (extensionID != null) {
162: result.add(IdUtil.getFullId(extensions[i]));
163: }
164: }
165: }
166: return (String[]) result.toArray(new String[result.size()]);
167: }
168:
169: private String getProduct(String appName) {
170: if (appName == null)
171: return TargetPlatform.getDefaultProduct();
172: if (fModel != null && appName != null) {
173: IPluginExtension[] extensions = fModel.getPluginBase()
174: .getExtensions();
175: for (int i = 0; i < extensions.length; i++) {
176: IPluginExtension ext = extensions[i];
177: String point = ext.getPoint();
178: if ("org.eclipse.core.runtime.products".equals(point)) { //$NON-NLS-1$
179: if (ext.getChildCount() == 1) {
180: IPluginElement prod = (IPluginElement) ext
181: .getChildren()[0];
182: if (prod.getName().equals("product")) { //$NON-NLS-1$
183: IPluginAttribute attr = prod
184: .getAttribute("application"); //$NON-NLS-1$
185: if (attr != null
186: && appName.equals(attr.getValue())) {
187: return IdUtil.getFullId(ext);
188: }
189: }
190: }
191: }
192: }
193: }
194: return null;
195: }
196:
197: /**
198: * Returns a boolean value indicating whether the launch configuration is a good match for
199: * the application or product to launch.
200: *
201: * @param configuration
202: * the launch configuration being evaluated
203: *
204: * @return <code>true</coded> if the launch configuration is suitable for the application
205: * or product to launch with, <code>false</code> otherwise.
206: */
207: protected boolean isGoodMatch(ILaunchConfiguration configuration) {
208: try {
209: if (!configuration.getAttribute(
210: IPDELauncherConstants.USE_PRODUCT, false)) {
211: String configApp = configuration.getAttribute(
212: IPDELauncherConstants.APPLICATION,
213: (String) null);
214: return (configApp == null && fApplicationName == null)
215: || (fApplicationName != null && fApplicationName
216: .equals(configApp));
217: }
218: String this Product = configuration.getAttribute(
219: IPDELauncherConstants.PRODUCT, (String) null);
220: return this Product != null
221: && this Product.equals(getProduct(fApplicationName));
222:
223: } catch (CoreException e) {
224: }
225: return false;
226: }
227:
228: /**
229: * Initializes a new Eclipse Application launch configuration with defaults based
230: * on the current selection:
231: * <ul>
232: * <li>If there is no selection or the selected project is a plug-in that does not declare an application,
233: * the default product is launched.</li>
234: * <li>If the selected project is a plug-in that declares an application, then that application is launched.</li>
235: * <li>If the selected project is a plug-in that declares more than one application, then the user is presented
236: * with a list of choices to choose from.</li>
237: * </ul>
238: * Once an application is chosen, the plug-in is searched to see if there is a product
239: * bound to this application. If a product is found, the product is launched instead, since
240: * a product provides a richer branded experience.
241: *
242: * @since 3.3
243: */
244: protected void initializeConfiguration(
245: ILaunchConfigurationWorkingCopy wc) {
246: if (TargetPlatformHelper.usesNewApplicationModel())
247: wc
248: .setAttribute(IPDEUIConstants.LAUNCHER_PDE_VERSION,
249: "3.3"); //$NON-NLS-1$
250: else if (TargetPlatformHelper.getTargetVersion() >= 3.2)
251: wc.setAttribute(IPDEUIConstants.LAUNCHER_PDE_VERSION,
252: "3.2a"); //$NON-NLS-1$
253: wc.setAttribute(IPDELauncherConstants.LOCATION,
254: LaunchArgumentsHelper.getDefaultWorkspaceLocation(wc
255: .getName())); //$NON-NLS-1$
256: initializeProgramArguments(wc);
257: initializeVMArguments(wc);
258: wc.setAttribute(IPDELauncherConstants.USEFEATURES, false);
259: wc.setAttribute(IPDELauncherConstants.DOCLEAR, false);
260: wc.setAttribute(IPDELauncherConstants.ASKCLEAR, true);
261: wc.setAttribute(IPDEUIConstants.APPEND_ARGS_EXPLICITLY, true);
262: wc.setAttribute(IPDELauncherConstants.TRACING_CHECKED,
263: IPDELauncherConstants.TRACING_NONE);
264: wc.setAttribute(IPDELauncherConstants.USE_DEFAULT,
265: fApplicationName == null);
266: if (fApplicationName != null) {
267: String product = getProduct(fApplicationName);
268: if (product == null) {
269: wc.setAttribute(IPDELauncherConstants.APPLICATION,
270: fApplicationName);
271: } else {
272: wc
273: .setAttribute(
274: IPDELauncherConstants.USE_PRODUCT, true);
275: wc.setAttribute(IPDELauncherConstants.PRODUCT, product);
276: }
277: wc.setAttribute(IPDELauncherConstants.AUTOMATIC_ADD, false);
278: } else {
279: String defaultProduct = TargetPlatform.getDefaultProduct();
280: if (defaultProduct != null) {
281: wc
282: .setAttribute(
283: IPDELauncherConstants.USE_DEFAULT, true);
284: wc
285: .setAttribute(
286: IPDELauncherConstants.USE_PRODUCT, true);
287: wc.setAttribute(IPDELauncherConstants.PRODUCT,
288: defaultProduct);
289: }
290: }
291: wc
292: .setAttribute(
293: IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER,
294: PDESourcePathProvider.ID);
295: }
296:
297: private void initializeProgramArguments(
298: ILaunchConfigurationWorkingCopy wc) {
299: String programArgs = LaunchArgumentsHelper
300: .getInitialProgramArguments();
301: if (programArgs.length() > 0)
302: wc
303: .setAttribute(
304: IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
305: programArgs);
306: }
307:
308: private void initializeVMArguments(
309: ILaunchConfigurationWorkingCopy wc) {
310: String vmArgs = LaunchArgumentsHelper.getInitialVMArguments();
311: if (vmArgs.length() > 0)
312: wc
313: .setAttribute(
314: IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
315: vmArgs);
316: }
317:
318: /**
319: * Returns the Eclipse application configuration type ID as declared in the plugin.xml
320: *
321: * @return the Eclipse application configuration type ID
322: */
323: protected String getLaunchConfigurationTypeName() {
324: return CONFIGURATION_TYPE;
325: }
326:
327: /* (non-Javadoc)
328: * @see org.eclipse.pde.ui.launcher.AbstractLaunchShortcut#getName(org.eclipse.debug.core.ILaunchConfigurationType)
329: */
330: protected String getName(ILaunchConfigurationType type) {
331: // if launching default product, use default naming convention
332: if (fApplicationName == null)
333: return super .getName(type);
334: String product = getProduct(fApplicationName);
335: return (product == null) ? fApplicationName : product;
336: }
337:
338: private void initializePluginsList(
339: ILaunchConfigurationWorkingCopy wc) {
340: StringBuffer wsplugins = new StringBuffer();
341: StringBuffer explugins = new StringBuffer();
342: Set plugins = DependencyManager.getSelfAndDependencies(fModel);
343: Iterator iter = plugins.iterator();
344: while (iter.hasNext()) {
345: String id = iter.next().toString();
346: IPluginModelBase model = PluginRegistry.findModel(id);
347: if (model == null || !model.isEnabled())
348: continue;
349: if (model.getUnderlyingResource() == null) {
350: if (explugins.length() > 0)
351: explugins.append(","); //$NON-NLS-1$
352: explugins.append(id);
353: } else {
354: if (wsplugins.length() > 0)
355: wsplugins.append(","); //$NON-NLS-1$
356: wsplugins.append(id);
357: }
358: }
359: wc.setAttribute(
360: IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS,
361: wsplugins.toString());
362: wc.setAttribute(IPDELauncherConstants.SELECTED_TARGET_PLUGINS,
363: explugins.toString());
364: }
365: }
|