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.ui.launcher;
011:
012: import java.io.File;
013: import java.util.ArrayList;
014: import java.util.Map;
015: import java.util.Properties;
016:
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.IPath;
019: import org.eclipse.core.runtime.IProgressMonitor;
020: import org.eclipse.core.runtime.Path;
021: import org.eclipse.core.runtime.Status;
022: import org.eclipse.core.variables.IStringVariableManager;
023: import org.eclipse.core.variables.VariablesPlugin;
024: import org.eclipse.debug.core.ILaunch;
025: import org.eclipse.debug.core.ILaunchConfiguration;
026: import org.eclipse.pde.core.plugin.IPluginModelBase;
027: import org.eclipse.pde.core.plugin.TargetPlatform;
028: import org.eclipse.pde.internal.core.ClasspathHelper;
029: import org.eclipse.pde.internal.core.PDECore;
030: import org.eclipse.pde.internal.core.TargetPlatformHelper;
031: import org.eclipse.pde.internal.core.util.CoreUtility;
032: import org.eclipse.pde.internal.core.util.VersionUtil;
033: import org.eclipse.pde.internal.ui.PDEPlugin;
034: import org.eclipse.pde.internal.ui.PDEUIMessages;
035: import org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper;
036: import org.eclipse.pde.internal.ui.launcher.LaunchConfigurationHelper;
037: import org.eclipse.pde.internal.ui.launcher.LaunchPluginValidator;
038: import org.eclipse.pde.internal.ui.launcher.LauncherUtils;
039: import org.osgi.framework.Version;
040:
041: /**
042: * A launch delegate for launching Eclipse applications
043: * <p>
044: * Clients may subclass and instantiate this class.
045: * </p>
046: * @since 3.2
047: */
048: public class EclipseApplicationLaunchConfiguration extends
049: AbstractPDELaunchConfiguration {
050:
051: /*
052: * (non-Javadoc)
053: * @see org.eclipse.pde.ui.launcher.AbstractPDELaunchConfiguration#getProgramArguments(org.eclipse.debug.core.ILaunchConfiguration)
054: */
055: public String[] getProgramArguments(
056: ILaunchConfiguration configuration) throws CoreException {
057: ArrayList programArgs = new ArrayList();
058:
059: // If a product is specified, then add it to the program args
060: if (configuration.getAttribute(
061: IPDELauncherConstants.USE_PRODUCT, false)) {
062: programArgs.add("-product"); //$NON-NLS-1$
063: programArgs.add(configuration.getAttribute(
064: IPDELauncherConstants.PRODUCT, "")); //$NON-NLS-1$
065: } else {
066: // specify the application to launch
067: programArgs.add("-application"); //$NON-NLS-1$
068: programArgs.add(configuration.getAttribute(
069: IPDELauncherConstants.APPLICATION, TargetPlatform
070: .getDefaultApplication()));
071: }
072:
073: // specify the workspace location for the runtime workbench
074: String targetWorkspace = LaunchArgumentsHelper
075: .getWorkspaceLocation(configuration);
076: if (targetWorkspace.length() > 0) {
077: programArgs.add("-data"); //$NON-NLS-1$
078: programArgs.add(targetWorkspace);
079: }
080:
081: boolean showSplash = true;
082: Map pluginMap = LaunchPluginValidator
083: .getPluginsToRun(configuration);
084: if (configuration.getAttribute(
085: IPDELauncherConstants.USEFEATURES, false)) {
086: validateFeatures();
087: IPath installPath = PDEPlugin.getWorkspace().getRoot()
088: .getLocation();
089: programArgs.add("-install"); //$NON-NLS-1$
090: programArgs
091: .add("file:" + installPath.removeLastSegments(1).addTrailingSeparator().toString()); //$NON-NLS-1$
092: if (!configuration
093: .getAttribute(
094: IPDELauncherConstants.CONFIG_USE_DEFAULT_AREA,
095: true)) {
096: programArgs.add("-configuration"); //$NON-NLS-1$
097: programArgs
098: .add("file:" + new Path(getConfigDir(configuration).getPath()).addTrailingSeparator().toString()); //$NON-NLS-1$
099: }
100: programArgs.add("-update"); //$NON-NLS-1$
101: // add the output folder names
102: programArgs.add("-dev"); //$NON-NLS-1$
103: programArgs.add(ClasspathHelper.getDevEntriesProperties(
104: getConfigDir(configuration).toString()
105: + "/dev.properties", true)); //$NON-NLS-1$
106: } else {
107: String productID = LaunchConfigurationHelper
108: .getProductID(configuration);
109: Properties prop = LaunchConfigurationHelper
110: .createConfigIniFile(configuration, productID,
111: pluginMap, getConfigDir(configuration));
112: showSplash = prop.containsKey("osgi.splashPath") || prop.containsKey("splashLocation"); //$NON-NLS-1$ //$NON-NLS-2$
113: String brandingId = LaunchConfigurationHelper
114: .getContributingPlugin(productID);
115: TargetPlatform.createPlatformConfiguration(
116: getConfigDir(configuration),
117: (IPluginModelBase[]) pluginMap.values().toArray(
118: new IPluginModelBase[pluginMap.size()]),
119: brandingId != null ? (IPluginModelBase) pluginMap
120: .get(brandingId) : null);
121: TargetPlatformHelper.checkPluginPropertiesConsistency(
122: pluginMap, getConfigDir(configuration));
123: programArgs.add("-configuration"); //$NON-NLS-1$
124: programArgs
125: .add("file:" + new Path(getConfigDir(configuration).getPath()).addTrailingSeparator().toString()); //$NON-NLS-1$
126:
127: // add the output folder names
128: programArgs.add("-dev"); //$NON-NLS-1$
129: programArgs.add(ClasspathHelper.getDevEntriesProperties(
130: getConfigDir(configuration).toString()
131: + "/dev.properties", pluginMap)); //$NON-NLS-1$
132: }
133: // necessary for PDE to know how to load plugins when target platform = host platform
134: // see PluginPathFinder.getPluginPaths() and PluginPathFinder.isDevLaunchMode()
135: IPluginModelBase base = (IPluginModelBase) pluginMap
136: .get(PDECore.PLUGIN_ID);
137: if (base != null
138: && VersionUtil.compareMacroMinorMicro(base
139: .getBundleDescription().getVersion(),
140: new Version("3.3.1")) < 0) //$NON-NLS-1$
141: programArgs.add("-pdelaunch"); //$NON-NLS-1$
142:
143: String[] args = super .getProgramArguments(configuration);
144: for (int i = 0; i < args.length; i++) {
145: programArgs.add(args[i]);
146: }
147:
148: if (!programArgs.contains("-nosplash") && showSplash) { //$NON-NLS-1$
149: if (TargetPlatformHelper.getTargetVersion() >= 3.1) {
150: programArgs.add(0, "-launcher"); //$NON-NLS-1$
151:
152: IPath path = null;
153: if (TargetPlatform.getOS().equals("macosx")) { //$NON-NLS-1$
154: path = new Path(TargetPlatform.getLocation())
155: .append("Eclipse.app/Contents/Resources/Splash.app/Contents/MacOS/eclipse"); //$NON-NLS-1$
156: } else {
157: path = new Path(TargetPlatform.getLocation())
158: .append("eclipse"); //$NON-NLS-1$
159: }
160:
161: programArgs.add(1, path.toOSString()); //This could be the branded launcher if we want (also this does not bring much)
162: programArgs.add(2, "-name"); //$NON-NLS-1$
163: programArgs.add(3, "Eclipse"); //This should be the name of the product //$NON-NLS-1$
164: programArgs.add(4, "-showsplash"); //$NON-NLS-1$
165: programArgs.add(5, "600"); //$NON-NLS-1$
166: } else {
167: programArgs.add(0, "-showsplash"); //$NON-NLS-1$
168: programArgs.add(1, computeShowsplashArgument());
169: }
170: }
171: return (String[]) programArgs.toArray(new String[programArgs
172: .size()]);
173: }
174:
175: private void validateFeatures() throws CoreException {
176: IPath installPath = PDEPlugin.getWorkspace().getRoot()
177: .getLocation();
178: String lastSegment = installPath.lastSegment();
179: boolean badStructure = lastSegment == null;
180: if (!badStructure) {
181: IPath featuresPath = installPath.removeLastSegments(1)
182: .append("features"); //$NON-NLS-1$
183: badStructure = !lastSegment.equalsIgnoreCase("plugins") //$NON-NLS-1$
184: || !featuresPath.toFile().exists();
185: }
186: if (badStructure) {
187: throw new CoreException(
188: LauncherUtils
189: .createErrorStatus(PDEUIMessages.WorkbenchLauncherConfigurationDelegate_badFeatureSetup));
190: }
191: // Ensure important files are present
192: ensureProductFilesExist(getProductPath());
193: }
194:
195: private IPath getProductPath() {
196: return PDEPlugin.getWorkspace().getRoot().getLocation()
197: .removeLastSegments(1);
198: }
199:
200: private String computeShowsplashArgument() {
201: IPath eclipseHome = new Path(TargetPlatform.getLocation());
202: IPath fullPath = eclipseHome.append("eclipse"); //$NON-NLS-1$
203: return fullPath.toOSString() + " -showsplash 600"; //$NON-NLS-1$
204: }
205:
206: private void ensureProductFilesExist(IPath productArea) {
207: File productDir = productArea.toFile();
208: File marker = new File(productDir, ".eclipseproduct"); //$NON-NLS-1$
209: IPath eclipsePath = new Path(TargetPlatform.getLocation());
210: if (!marker.exists())
211: CoreUtility
212: .copyFile(eclipsePath, ".eclipseproduct", marker); //$NON-NLS-1$
213:
214: File configDir = new File(productDir, "configuration"); //$NON-NLS-1$
215: if (!configDir.exists())
216: configDir.mkdirs();
217: File ini = new File(configDir, "config.ini"); //$NON-NLS-1$
218: if (!ini.exists())
219: CoreUtility
220: .copyFile(
221: eclipsePath.append("configuration"), "config.ini", ini); //$NON-NLS-1$ //$NON-NLS-2$
222: }
223:
224: /*
225: * (non-Javadoc)
226: * @see org.eclipse.pde.ui.launcher.AbstractPDELaunchConfiguration#getConfigDir(org.eclipse.debug.core.ILaunchConfiguration)
227: */
228: protected File getConfigDir(ILaunchConfiguration config) {
229: if (fConfigDir == null) {
230: try {
231: if (config.getAttribute(
232: IPDELauncherConstants.USEFEATURES, false)
233: && config
234: .getAttribute(
235: IPDELauncherConstants.CONFIG_USE_DEFAULT_AREA,
236: true)) {
237: String root = getProductPath().toString();
238: root += "/configuration"; //$NON-NLS-1$
239: fConfigDir = new File(root);
240: if (!fConfigDir.exists())
241: fConfigDir.mkdirs();
242: } else {
243: fConfigDir = LaunchConfigurationHelper
244: .getConfigurationArea(config);
245: }
246: } catch (CoreException e) {
247: fConfigDir = LaunchConfigurationHelper
248: .getConfigurationArea(config);
249: }
250: }
251: return fConfigDir;
252: }
253:
254: /**
255: * Clears the workspace prior to launching if the workspace exists and the option to
256: * clear it is turned on. Also clears the configuration area if that option is chosen.
257: *
258: * @param configuration
259: * the launch configuration
260: * @param monitor
261: * the progress monitor
262: * @throws CoreException
263: * if unable to retrieve launch attribute values
264: * @since 3.3
265: */
266: protected void clear(ILaunchConfiguration configuration,
267: IProgressMonitor monitor) throws CoreException {
268: String workspace = LaunchArgumentsHelper
269: .getWorkspaceLocation(configuration);
270: // Clear workspace and prompt, if necessary
271: if (!LauncherUtils.clearWorkspace(configuration, workspace,
272: monitor))
273: throw new CoreException(Status.CANCEL_STATUS);
274:
275: // clear config area, if necessary
276: if (configuration.getAttribute(
277: IPDELauncherConstants.CONFIG_CLEAR_AREA, false))
278: CoreUtility.deleteContent(getConfigDir(configuration));
279: }
280:
281: /* (non-Javadoc)
282: * @see org.eclipse.pde.ui.launcher.AbstractPDELaunchConfiguration#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
283: */
284: protected void preLaunchCheck(ILaunchConfiguration configuration,
285: ILaunch launch, IProgressMonitor monitor)
286: throws CoreException {
287: validateConfigIni(configuration);
288: super .preLaunchCheck(configuration, launch, monitor);
289: }
290:
291: private void validateConfigIni(ILaunchConfiguration configuration)
292: throws CoreException {
293: if (!configuration.getAttribute(
294: IPDELauncherConstants.CONFIG_GENERATE_DEFAULT, true)) {
295: String templateLoc = configuration.getAttribute(
296: IPDELauncherConstants.CONFIG_TEMPLATE_LOCATION, ""); //$NON-NLS-1$
297: IStringVariableManager mgr = VariablesPlugin.getDefault()
298: .getStringVariableManager();
299: templateLoc = mgr.performStringSubstitution(templateLoc);
300:
301: File templateFile = new File(templateLoc);
302: if (!templateFile.exists()) {
303: if (!LauncherUtils.generateConfigIni())
304: throw new CoreException(Status.CANCEL_STATUS);
305: // with the way the launcher works, if a config.ini file is not found one will be generated automatically.
306: // This check was to warn the user a config.ini needs to be generated. - bug 161265, comment #7
307: }
308: }
309: }
310:
311: /* (non-Javadoc)
312: * @see org.eclipse.pde.ui.launcher.AbstractPDELaunchConfiguration#getVMArguments(org.eclipse.debug.core.ILaunchConfiguration)
313: */
314: public String[] getVMArguments(ILaunchConfiguration configuration)
315: throws CoreException {
316: String[] vmArgs = super .getVMArguments(configuration);
317: IPluginModelBase base = (IPluginModelBase) LaunchPluginValidator
318: .getPluginsToRun(configuration).get(PDECore.PLUGIN_ID);
319: if (base != null
320: && VersionUtil.compareMacroMinorMicro(base
321: .getBundleDescription().getVersion(),
322: new Version("3.3.1")) >= 0) { //$NON-NLS-1$
323: // necessary for PDE to know how to load plugins when target platform = host platform
324: // see PluginPathFinder.getPluginPaths() and PluginPathFinder.isDevLaunchMode()
325: String[] result = new String[vmArgs.length + 1];
326: System.arraycopy(vmArgs, 0, result, 0, vmArgs.length);
327: result[vmArgs.length] = "-Declipse.pde.launch=true"; //$NON-NLS-1$
328: return result;
329: }
330: return vmArgs;
331: }
332:
333: }
|