/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.eclipse.ui.launcher;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import com.windowtester.codegen.ExecutionProfile;
import com.windowtester.codegen.debug.DebugRecordingInfo;
import com.windowtester.eclipse.ui.UiPlugin;
import com.windowtester.swt.event.recorder.EventRecorderPlugin;
@SuppressWarnings("restriction")
public class RecorderSWTLaunchConfDelegate extends RecorderWorkbenchLaunchConfDelegate {
protected ILaunchConfigurationWorkingCopy wcSwt;
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
*/
protected void launch0(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
// getting SWT launch config working copy
wcSwt = configuration.getWorkingCopy();
// instantiating default RCP launch configuration working copy
ILaunchConfigurationType type = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(UiPlugin.WORKBENCH_LAUNCH_CONFIGURATION_TYPE);
ILaunchConfigurationWorkingCopy wc = type.newInstance(null, ExecutionProfile.TMP_APPLICATION_LAUNCH_CONFIG);
if(wc.exists())
wc.delete();
// map swt launch config to rcp launch config
prepareSwtDummyBundle(wc);
setWorkspaceDataSection(wc);
setApplicationSection(wc);
setJRESection(wc);
setVMArgsSection(wc);
setEnvironment(wc);
setWorkingDir(wc);
mapSources(wc);
super.launch0(wc, mode, launch, monitor);
}
/**
* Maps source locations between SWT application launch configuration and default launch configuration
* @param wc
* @param wcSwt
* @throws CoreException
*/
protected void mapSources(ILaunchConfigurationWorkingCopy wc) throws CoreException {
String locatorMememnto = wcSwt.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String) null);
if(locatorMememnto!=null)
wc.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, locatorMememnto);
String locatorID = wcSwt.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String) null);
if(locatorID!=null)
wc.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, locatorID);
String provider = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, (String) null);
if (provider != null)
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, provider);
}
/**
* @param wc
* @param wcSwt
* @throws CoreException
*/
private void setEnvironment(ILaunchConfigurationWorkingCopy wc) throws CoreException {
wc.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<?, ?>)wcSwt.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<?, ?>)null));
wc.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, wcSwt.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false));
}
/**
* @param wcSwt
* @throws CoreException
*/
private void prepareSwtDummyBundle(ILaunchConfigurationWorkingCopy wc) throws CoreException {
IPath stateDirPath = UiPlugin.getDefault().getStateLocation();
//String projName = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "dummy");
//stateDirPath = stateDirPath.append(new Path(projName));
DummyBundleBuilder db = new DummyBundleBuilder();
IPath bundlePath = db.buildDummyBundle(wcSwt, stateDirPath);
// set required for SWT application type arguments
String vmargs = getVmAttributes(wc);
vmargs += " \"-D"+EventRecorderPlugin.INSTALL_BUNDLES_SYS_PROPERTY+"=reference:file:"+bundlePath.toString()+"\"";
setVmAttributes(wc, vmargs);
String progrargs = wc.getAttribute("progargs", "");
progrargs+=" -noSplash";
wc.setAttribute("progargs", progrargs);
}
/**
* Set VM arguments section
*
* @param wc
* @param wcSwt
* @throws CoreException
*/
protected void setVMArgsSection(ILaunchConfigurationWorkingCopy wc) throws CoreException {
String mainClass = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "");
// get the VM Args specified by the user from the working copy of launch config
String vmargs = getVmAttributes(wcSwt);
// get the VM Args for WindowTester
vmargs += getVmAttributes(wc);
// add the name of class main
vmargs += " -D"+EventRecorderPlugin.LAUNCH_CLASS_NAME_PROP+"="+mainClass;
setVmAttributes(wc, vmargs);
}
/**
* Map JRE settings
*
* @param wc
* @param wcSwt
* @throws CoreException
*/
@SuppressWarnings("deprecation")
private void setJRESection(ILaunchConfigurationWorkingCopy wc) throws CoreException {
// String projectName = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");
// IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
// IJavaProject javaProject = JavaCore.create(project);
// IVMInstall vmInstall = JavaRuntime.getVMInstall(javaProject);
// String vmName = vmInstall.getName();
String vmName = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, (String)null);
wc.setAttribute("vminstall", vmName);
}
/**
* Set an application to SWT bootstrap application
*
* @param wc
*/
private void setApplicationSection(ILaunchConfigurationWorkingCopy wc) {
wc.setAttribute("application", UiPlugin.SWT_BOOTSTRAP_APPLICATION);
wc.setAttribute("useProduct", false);
}
/**
* Set workspace data section to UiPlugin's workspace location. This workspace
* will never be used so it will be always cleared before startup. The only
* reason why we would need it - is to inspect (or ask clients to provide)
* development logs.
*
* @param wc
*/
private void setWorkspaceDataSection(ILaunchConfigurationWorkingCopy wc) {
IPath stateDirPath = UiPlugin.getDefault().getStateLocation();
IPath swtLaunchWorkspace = stateDirPath.append(UiPlugin.SWT_LAUNCH_WORKSPACE);
DebugRecordingInfo.getInfo().setWorkspaceLocation(swtLaunchWorkspace);
wc.setAttribute("location" + String.valueOf(0), swtLaunchWorkspace.toString());
wc.setAttribute("clearws", true);
wc.setAttribute("askclear", false);
}
/**
* Overrides default execution profile to provide SWT execution parameters
*/
protected ExecutionProfile createExecutionProfile(ILaunch launch) throws CoreException {
// create execution profile instance
ExecutionProfile profile = new ExecutionProfile();
profile.setLaunch(launch);
profile.setExecType(ExecutionProfile.SWT_EXEC_TYPE);
profile.setMainSwtClassName(wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, ""));
String args = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, "");
if(!"".equals(args))
profile.setProgramArgs(args.split("[ \t]"));
else
profile.setProgramArgs(new String[] {});
profile.setProjectName(wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""));
return profile;
}
/**
* get the classpath of the launch configuration.
* Override AbstractPDELaunchConfiguration.getClasspath
* @param wc
*/
@SuppressWarnings("unchecked")
public String[] getClasspath(ILaunchConfiguration configuration)
throws CoreException {
String[] classpath = constructClassPath(configuration);
// get the boot path entries
List entries = null;
entries = getBootpath(wcSwt);
// add user classpath entries
entries.addAll(getUserClasspathEntries(wcSwt));
// add the classpath entries from the AbstractPDELaunchConfiguration
for (int i= 0;i < classpath.length;i++)
entries.add(0+i,classpath[i]);
String[] result = (String[]) entries.toArray(new String[entries.size()]);
DebugRecordingInfo.getInfo().setRecorderClasspath(result);
return result;
}
private String[] constructClassPath(ILaunchConfiguration configuration) throws CoreException {
/* $if eclipse.version < 3.6 $ */
return org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper.constructClasspath(configuration);
/* $else$
return org.eclipse.pde.internal.launching.launcher.LaunchArgumentsHelper.constructClasspath(configuration);
$endif$ */
}
/**
* Set the working directory : has to be set to point to project location so that
* the application is launched correctly.
* 5/31/07 : kp
*/
private void setWorkingDir(ILaunchConfigurationWorkingCopy wc){
try {
String projectName = wcSwt.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
// get the absolute path
IPath path = project.getLocation();
String workingDir = path.toOSString();
// set the working dir to absolute path of project
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, workingDir);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Returns the entries that should appear on the user portion of the
* classpath as specified by the given launch configuration, as an array of
* resolved strings. The returned array is empty if no classpath is
* specified.
*
* @param configuration
* launch configuration
* @return the classpath specified by the given launch configuration,
* possibly an empty array
* @exception CoreException
* if unable to retrieve the attribute
* from AbstractJavaLaunchConfigurationDelegate and modified
*/
@SuppressWarnings("unchecked")
public List getUserClasspathEntries(ILaunchConfiguration configuration)
throws CoreException {
IRuntimeClasspathEntry[] entries = JavaRuntime
.computeUnresolvedRuntimeClasspath(configuration);
entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
List userEntries = new ArrayList(entries.length);
Set set = new HashSet(entries.length);
for (int i = 0; i < entries.length; i++) {
if (entries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
String location = entries[i].getLocation();
if (location != null) {
if (!set.contains(location)) {
userEntries.add(location);
set.add(location);
}
}
}
}
return userEntries;
}
/**
* Returns entries that should appear on the bootstrap portion of the
* classpath as specified by the given launch configuration, as an array of
* resolved strings. The returned array is <code>null</code> if all
* entries are standard (i.e. appear by default), or empty to represent an
* empty bootpath.
*
* from AbstractJavaLaunchConfigurationDelegate and modified
*
* @param configuration
* launch configuration
* @return the bootpath specified by the given launch configuration. An
* empty bootpath is specified by an empty array, and
* <code>null</code> represents a default bootpath.
* @exception CoreException
* if unable to retrieve the attribute
*/
@SuppressWarnings("unchecked")
public List getBootpath(ILaunchConfiguration configuration)
throws CoreException {
IRuntimeClasspathEntry[] entries = JavaRuntime
.computeUnresolvedRuntimeClasspath(configuration);
entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
List bootEntries = new ArrayList(entries.length);
for (int i = 0; i < entries.length; i++) {
if (entries[i].getClasspathProperty() != IRuntimeClasspathEntry.USER_CLASSES) {
String location = entries[i].getLocation();
if (!entries[i].getPath().lastSegment().equals("rt.jar"))
if (location != null) {
bootEntries.add(location);
}
}
}
return bootEntries;
}
}