blob: 12652424dd0bba925c36d0087eafc35ede86574d [file] [log] [blame]
package org.eclipse.jdt.launching;
/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
This file is made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
**********************************************************************/
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.launching.LaunchingMessages;
import org.eclipse.jdt.internal.launching.LaunchingPlugin;
import org.eclipse.jdt.launching.sourcelookup.JavaSourceLocator;
/**
* Abstract implementation of a Java launch configuration delegate.
* Provides convenience methods for accessing and verifying launch
* configuration attributes.
* <p>
* Clients implementing Java launch configuration delegates should
* subclass this class.
* </p>
* @since 2.0
*/
public abstract class AbstractJavaLaunchConfigurationDelegate implements ILaunchConfigurationDelegate, IDebugEventSetListener {
/**
* Convenience method to get the launch manager.
*
* @return the launch manager
*/
protected ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
/**
* Throws a core exception with an error status object built from
* the given message, lower level exception, and error code.
*
* @param message the status message
* @param exception lower level exception associated with the
* error, or <code>null</code> if none
* @param code error code
*/
protected void abort(String message, Throwable exception, int code) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception));
}
/**
* Returns the VM install specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the VM install specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public IVMInstall getVMInstall(ILaunchConfiguration configuration) throws CoreException {
return JavaRuntime.computeVMInstall(configuration);
}
/**
* Returns the VM install name specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the VM install name specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public String getVMInstallName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, (String)null);
}
/**
* Returns the VM install type specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the VM install type specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public IVMInstallType getVMInstallType(ILaunchConfiguration configuration) throws CoreException {
String id = getVMInstallTypeId(configuration);
if (id != null) {
IVMInstallType type = JavaRuntime.getVMInstallType(id);
if (type != null) {
return type;
}
}
return null;
}
/**
* Returns the VM install type identifier specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the VM install type identifier specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public String getVMInstallTypeId(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, (String)null);
}
/**
* Verifies the VM install specified by the given
* launch configuration - i.e. that its home location
* is specified and exists, and returns the VM install.
*
* @param configuration launch configuration
* @return the VM install specified by the given
* launch configuration
* @exception CoreException if unable to retrieve the attribute,
* the attribute is unspecified, or if the home location is
* unspecified or does not exist
*/
public IVMInstall verifyVMInstall(ILaunchConfiguration configuration) throws CoreException {
IVMInstall vm = getVMInstall(configuration);
if (vm == null) {
abort(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.The_specified_JRE_installation_does_not_exist_4"), null, IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST); //$NON-NLS-1$
}
File location = vm.getInstallLocation();
if (location == null) {
abort(MessageFormat.format(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.JRE_home_directory_not_specified_for_{0}_5"), new String[]{vm.getName()}), null, IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST); //$NON-NLS-1$
}
if (!location.exists()) {
abort(MessageFormat.format(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.JRE_home_directory_for_{0}_does_not_exist__{1}_6"), new String[]{vm.getName(), location.getAbsolutePath()}), null, IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST); //$NON-NLS-1$
}
return vm;
}
/**
* Returns the VM connector identifier specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the VM connector identifier specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public String getVMConnectorId(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, (String)null);
}
/**
* 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.
*
* @param configuration launch configuration
* @return the bootpath specified by the given
* launch configuration. An empty bootpath is specfied by
* an empty array, and <code>null</code> represents a default
* boothpath.
* @exception CoreException if unable to retrieve the attribute
*/
public String[] getBootpath(ILaunchConfiguration configuration) throws CoreException {
IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
List bootEntries = new ArrayList(entries.length);
boolean empty = true;
boolean allStandard = true;
for (int i = 0; i < entries.length; i++) {
if (entries[i].getClasspathProperty() != IRuntimeClasspathEntry.USER_CLASSES) {
String location = entries[i].getLocation();
if (location != null) {
empty = false;
bootEntries.add(location);
allStandard = allStandard && entries[i].getClasspathProperty() == IRuntimeClasspathEntry.STANDARD_CLASSES;
}
}
}
if (empty) {
return new String[0];
} else if (allStandard) {
return null;
} else {
return (String[])bootEntries.toArray(new String[bootEntries.size()]);
}
}
/**
* 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
*/
public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException {
IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
List userEntries = 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 (location != null) {
userEntries.add(location);
}
}
}
return (String[])userEntries.toArray(new String[userEntries.size()]);
}
/**
* Returns the Java project specified by the given
* launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the Java project specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public IJavaProject getJavaProject(ILaunchConfiguration configuration) throws CoreException {
String projectName = getJavaProjectName(configuration);
if (projectName != null) {
projectName = projectName.trim();
if (projectName.length() > 0) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
IJavaProject javaProject = JavaCore.create(project);
if (javaProject != null && javaProject.exists()) {
return javaProject;
}
}
}
return null;
}
/**
* Returns the Java project name specified by the given
* launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the Java project name specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public String getJavaProjectName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
}
/**
* Returns the main type name specified by the given
* launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the main type name specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)null);
}
/**
* Returns the program arguments specified by the given launch
* configuration, as a string. The returned string is empty if
* no program arguments are specified.
*
* @param configuration launch configuration
* @return the program arguments specified by the given
* launch configuration, possibly an empty string
* @exception CoreException if unable to retrieve the attribute
*/
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, ""); //$NON-NLS-1$
}
/**
* Returns the VM arguments specified by the given launch
* configuration, as a string. The returned string is empty if
* no VM arguments are specified.
*
* @param configuration launch configuration
* @return the VM arguments specified by the given
* launch configuration, possibly an empty string
* @exception CoreException if unable to retrieve the attribute
*/
public String getVMArguments(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, ""); //$NON-NLS-1$
}
/**
* Returns the Map of VM-specific attributes specified by the given launch configuration,
* or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the <code>Map</code> of VM-specific attributes
* @exception CoreException if unable to retrieve the attribute
*/
public Map getVMSpecificAttributesMap(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, (Map)null);
}
/**
* Returns the working directory specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the working directory specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public File getWorkingDirectory(ILaunchConfiguration configuration) throws CoreException {
return verifyWorkingDirectory(configuration);
}
/**
* Returns the working directory path specified by
* the given launch configuration, or <code>null</code> if none.
*
* @param configuration launch configuration
* @return the working directory path specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration) throws CoreException {
String path = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, (String)null);
if (path != null) {
return new Path(path);
}
return null;
}
/**
* Verifies a Java project is specified by the given
* launch configuration, and returns the Java project.
*
* @param configuration launch configuration
* @return the Java project specified by the given
* launch configuration
* @exception CoreException if unable to retrieve the attribute
* or the attribute is unspecified
*/
public IJavaProject verifyJavaProject(ILaunchConfiguration configuration) throws CoreException {
String name = getJavaProjectName(configuration);
if (name == null) {
abort(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.Java_project_not_specified_9"), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_PROJECT); //$NON-NLS-1$
}
IJavaProject project = getJavaProject(configuration);
if (project == null) {
abort(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.Project_does_not_exist_or_is_not_a_Java_project_10"), null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT); //$NON-NLS-1$
}
return project;
}
/**
* Verifies a main type name is specified by the given
* launch configuration, and returns the main type name.
*
* @param configuration launch configuration
* @return the main type name specified by the given
* launch configuration
* @exception CoreException if unable to retrieve the attribute
* or the attribute is unspecified
*/
public String verifyMainTypeName(ILaunchConfiguration configuration) throws CoreException {
String name = getMainTypeName(configuration);
if (name == null) {
abort(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.Main_type_not_specified_11"), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); //$NON-NLS-1$
}
return name;
}
/**
* Verifies the working directory specified by the given
* launch configuration exists, and returns the working
* directory, or <code>null</code> if none is specified.
*
* @param configuration launch configuration
* @return the working directory specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException if unable to retrieve the attribute
*/
public File verifyWorkingDirectory(ILaunchConfiguration configuration) throws CoreException {
IPath path = getWorkingDirectoryPath(configuration);
if (path == null) {
// default working dir is the project if this config has a project
IJavaProject jp = getJavaProject(configuration);
if (jp != null) {
IProject p = jp.getProject();
return p.getLocation().toFile();
}
} else {
if (path.isAbsolute()) {
File dir = new File(path.toOSString());
if (dir.isDirectory()) {
return dir;
} else {
abort(MessageFormat.format(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.Working_directory_does_not_exist__{0}_12"), new String[] {path.toString()}), null, IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST); //$NON-NLS-1$
}
} else {
IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
if (res instanceof IContainer && res.exists()) {
return res.getLocation().toFile();
} else {
abort(MessageFormat.format(LaunchingMessages.getString("AbstractJavaLaunchConfigurationDelegate.Working_directory_does_not_exist__{0}_12"), new String[] {path.toString()}), null, IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST); //$NON-NLS-1$
}
}
}
return null;
}
/**
* Returns whether the given launch configuration
* specifies that termination is allowed.
*
* @param configuration launch configuration
* @return whether termination is allowed
* @exception CoreException if unable to retrieve the attribute
*/
public boolean isAllowTerminate(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, false);
}
/**
* Returns whether the given launch configuration
* specifies that execution should suspend on entry of the
* main method.
*
* @param configuration launch configuration
* @return whether execution should suspend in main
* @exception CoreException if unable to retrieve the attribute
* @since 2.1
*/
public boolean isStopInMain(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, false);
}
/**
* Assigns a default source locator to the given launch if a source
* locator has not yet been assigned to it, and the associated launch
* configuration does not specify a source locator.
*
* @param launch launch object
* @param configuration configuration being launched
* @exception CoreException if unable to set the source locator
*/
protected void setDefaultSourceLocator(ILaunch launch, ILaunchConfiguration configuration) throws CoreException {
// set default source locator if none specified
if (launch.getSourceLocator() == null) {
String id = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
if (id == null) {
IJavaProject javaProject = JavaRuntime.getJavaProject(configuration);
if (javaProject != null) {
ISourceLocator sourceLocator = new JavaSourceLocator(javaProject);
launch.setSourceLocator(sourceLocator);
}
}
}
}
/**
* Determines if the given launch configuration specifies the
* "stop-in-main" attribute, and sets up an event listener to
* handle the option if required.
*
* @param configuration configuration being launched
* @exception CoreException if unable to access the attribute
* @since 2.1
*/
protected void prepareStopInMain(ILaunchConfiguration configuration) throws CoreException {
if (isStopInMain(configuration)) {
// This listener does not remove itself from the debug plug-in
// as an event listener (there is no dispose notification for
// launch delegates). However, since there is only one delegate
// instantiated per config type, this is tolerable.
DebugPlugin.getDefault().addDebugEventListener(this);
}
}
/**
* Handles the "stop-in-main" option.
*
* @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[])
*/
public void handleDebugEvents(DebugEvent[] events) {
for (int i = 0; i < events.length; i++) {
DebugEvent event = events[i];
if (event.getKind() == DebugEvent.CREATE && event.getSource() instanceof IJavaDebugTarget) {
IJavaDebugTarget target = (IJavaDebugTarget)event.getSource();
ILaunch launch = target.getLaunch();
if (launch != null) {
ILaunchConfiguration configuration = launch.getLaunchConfiguration();
if (configuration != null) {
try {
if (isStopInMain(configuration)) {
String mainType = getMainTypeName(configuration);
if (mainType != null) {
Map map = new HashMap();
map.put(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN);
IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), mainType, "main", //$NON-NLS-1$
"([Ljava/lang/String;)V", true, false, false, -1, -1, -1, 1, false, map); //$NON-NLS-1$
bp.setPersisted(false);
target.breakpointAdded(bp);
}
}
} catch (CoreException e) {
LaunchingPlugin.log(e);
}
}
}
}
}
}
}