001: /*******************************************************************************
002: * Copyright (c) 2006 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:
014: import org.eclipse.core.runtime.CoreException;
015: import org.eclipse.debug.core.DebugPlugin;
016: import org.eclipse.debug.core.ILaunchConfiguration;
017: import org.eclipse.debug.core.ILaunchConfigurationType;
018: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
019: import org.eclipse.debug.core.ILaunchManager;
020: import org.eclipse.debug.ui.DebugUITools;
021: import org.eclipse.debug.ui.IDebugModelPresentation;
022: import org.eclipse.debug.ui.ILaunchShortcut;
023: import org.eclipse.jface.window.Window;
024: import org.eclipse.pde.internal.ui.IPDEUIConstants;
025: import org.eclipse.pde.internal.ui.PDEPlugin;
026: import org.eclipse.pde.internal.ui.PDEUIMessages;
027: import org.eclipse.ui.dialogs.ElementListSelectionDialog;
028:
029: /**
030: * An abstract class subclassed by the Eclipse Application and OSGi Framework launch shortcuts.
031: * <p>
032: * This class may be subclassed by clients.
033: * </p>
034: * @since 3.3
035: */
036: public abstract class AbstractLaunchShortcut implements ILaunchShortcut {
037:
038: /**
039: * Launches the application in the specified mode, or does nothing if the user canceled
040: * the launch when offered to select one of several available launch configurations.
041: *
042: * @param mode
043: * mode of launch (run, debug or profile)
044: *
045: * @see org.eclipse.debug.core.ILaunchManager
046: */
047: protected void launch(String mode) {
048: ILaunchConfiguration configuration = findLaunchConfiguration(mode);
049: if (configuration != null)
050: DebugUITools.launch(configuration, mode);
051: }
052:
053: /**
054: * This method first tries to locate existing launch configurations that are suitable
055: * for the application or framework being launched.
056: * <p>
057: * <ul>
058: * <li>If none are found, a new launch configuration is created and initialized</li>
059: * <li>If one is found, it is launched automatically</li>
060: * <li>If more than one is found, a selection dialog is presented to the user and the chosen
061: * one will be launched</li>
062: * </ul>
063: * </p>
064: * @param mode
065: * mode of launch (run, debug or profile)
066: *
067: * @return a launch configuration to run or <code>null</code> if launch is canceled
068: */
069: protected ILaunchConfiguration findLaunchConfiguration(String mode) {
070: ILaunchConfiguration[] configs = getLaunchConfigurations();
071: ILaunchConfiguration configuration = null;
072: if (configs.length == 0) {
073: configuration = createNewConfiguration();
074: } else if (configs.length == 1) {
075: configuration = configs[0];
076: } else {
077: configuration = chooseConfiguration(configs, mode);
078: }
079: return configuration;
080: }
081:
082: /**
083: * Returns a list of existing launch configurations that are suitable to launch to selected
084: * application or framework.
085: *
086: * @return an array of launch configurations
087: */
088: private ILaunchConfiguration[] getLaunchConfigurations() {
089: ArrayList result = new ArrayList();
090: try {
091: ILaunchManager manager = DebugPlugin.getDefault()
092: .getLaunchManager();
093: ILaunchConfigurationType type = manager
094: .getLaunchConfigurationType(getLaunchConfigurationTypeName());
095: ILaunchConfiguration[] configurations = manager
096: .getLaunchConfigurations(type);
097: for (int i = 0; i < configurations.length; i++) {
098: if (!DebugUITools.isPrivate(configurations[i])
099: && isGoodMatch(configurations[i])) {
100: result.add(configurations[i]);
101: }
102: }
103: } catch (CoreException e) {
104: }
105: return (ILaunchConfiguration[]) result
106: .toArray(new ILaunchConfiguration[result.size()]);
107: }
108:
109: /**
110: * Display to the user a list of matching existing launch configurations and return the user's selection.
111: *
112: * @param configs
113: * an array of matching existing launch configurations
114: * @param mode
115: * mode of launch
116: * @return
117: * the launch configuration selected by the user or <code>null</code> if Cancel was pressed
118: */
119: protected ILaunchConfiguration chooseConfiguration(
120: ILaunchConfiguration[] configs, String mode) {
121: IDebugModelPresentation labelProvider = DebugUITools
122: .newDebugModelPresentation();
123: ElementListSelectionDialog dialog = new ElementListSelectionDialog(
124: PDEPlugin.getActiveWorkbenchShell(), labelProvider);
125: dialog.setElements(configs);
126: dialog.setTitle(PDEUIMessages.RuntimeWorkbenchShortcut_title);
127: if (mode.equals(ILaunchManager.DEBUG_MODE)) {
128: dialog
129: .setMessage(PDEUIMessages.RuntimeWorkbenchShortcut_select_debug);
130: } else {
131: dialog
132: .setMessage(PDEUIMessages.RuntimeWorkbenchShortcut_select_run);
133: }
134: dialog.setMultipleSelection(false);
135: int result = dialog.open();
136: labelProvider.dispose();
137: return (result == Window.OK) ? (ILaunchConfiguration) dialog
138: .getFirstResult() : null;
139: }
140:
141: /**
142: * Create, initialize and return a new launch configuration of the given type
143: *
144: * @return a new, properly-initialized launch configuration
145: */
146: private ILaunchConfiguration createNewConfiguration() {
147: try {
148: ILaunchManager lm = DebugPlugin.getDefault()
149: .getLaunchManager();
150: ILaunchConfigurationType type = lm
151: .getLaunchConfigurationType(getLaunchConfigurationTypeName());
152: String name = lm
153: .generateUniqueLaunchConfigurationNameFrom(getName(type));
154: ILaunchConfigurationWorkingCopy wc = type.newInstance(null,
155: name);
156: initializeConfiguration(wc);
157: // set a flag to know the information in the new config was generated by PDE
158: wc.setAttribute(IPDEUIConstants.GENERATED_CONFIG, true);
159: return wc.doSave();
160: } catch (CoreException ce) {
161: PDEPlugin.logException(ce);
162: }
163: return null;
164: }
165:
166: /**
167: * Returns the name assigned to the new launch configuration
168: *
169: * @return a name for the new launch configuration
170: */
171: protected String getName(ILaunchConfigurationType type) {
172: return type.getName();
173: }
174:
175: /**
176: * Initialize launch attributes on the new launch configuration.
177: * Must be overridden by subclasses.
178: *
179: * @param wc
180: * the launch configuration working copy to be initialize
181: *
182: * @see IPDELauncherConstants
183: */
184: protected abstract void initializeConfiguration(
185: ILaunchConfigurationWorkingCopy wc);
186:
187: /**
188: * Returns the launch configuration type name.
189: * Must be overridden by subclasses
190: *
191: * @return the launch configuration type name
192: */
193: protected abstract String getLaunchConfigurationTypeName();
194:
195: /**
196: * Determines whether a given launch configuration is a good match given the current application or framework
197: * being launched. This method must be overridden by subclasses. Its purpose is to add criteria on
198: * what makes a good match or not.
199: *
200: * @param configuration
201: * the launch configuration being evaluated
202: * @return
203: * <code>true</code> if the launch configuration is a good match for the application or
204: * framework being launched, <code>false</code> otherwise.
205: */
206: protected abstract boolean isGoodMatch(
207: ILaunchConfiguration configuration);
208:
209: }
|