0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.launching;
0011:
0012: import java.io.File;
0013: import com.ibm.icu.text.MessageFormat;
0014: import java.util.ArrayList;
0015: import java.util.HashMap;
0016: import java.util.HashSet;
0017: import java.util.List;
0018: import java.util.Map;
0019: import java.util.Set;
0020:
0021: import org.eclipse.core.resources.IContainer;
0022: import org.eclipse.core.resources.IMarker;
0023: import org.eclipse.core.resources.IProject;
0024: import org.eclipse.core.resources.IResource;
0025: import org.eclipse.core.resources.ResourcesPlugin;
0026: import org.eclipse.core.runtime.CoreException;
0027: import org.eclipse.core.runtime.IPath;
0028: import org.eclipse.core.runtime.IProgressMonitor;
0029: import org.eclipse.core.runtime.IStatus;
0030: import org.eclipse.core.runtime.Path;
0031: import org.eclipse.core.runtime.Status;
0032: import org.eclipse.core.variables.VariablesPlugin;
0033: import org.eclipse.debug.core.DebugEvent;
0034: import org.eclipse.debug.core.DebugPlugin;
0035: import org.eclipse.debug.core.IBreakpointManager;
0036: import org.eclipse.debug.core.IDebugEventSetListener;
0037: import org.eclipse.debug.core.ILaunch;
0038: import org.eclipse.debug.core.ILaunchConfiguration;
0039: import org.eclipse.debug.core.ILaunchManager;
0040: import org.eclipse.debug.core.model.IBreakpoint;
0041: import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
0042: import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
0043: import org.eclipse.jdt.core.IJavaModelMarker;
0044: import org.eclipse.jdt.core.IJavaProject;
0045: import org.eclipse.jdt.core.JavaCore;
0046: import org.eclipse.jdt.debug.core.IJavaDebugTarget;
0047: import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
0048: import org.eclipse.jdt.debug.core.JDIDebugModel;
0049: import org.eclipse.jdt.internal.launching.JRERuntimeClasspathEntryResolver;
0050: import org.eclipse.jdt.internal.launching.JavaSourceLookupDirector;
0051: import org.eclipse.jdt.internal.launching.LaunchingMessages;
0052: import org.eclipse.jdt.internal.launching.LaunchingPlugin;
0053:
0054: /**
0055: * Abstract implementation of a Java launch configuration delegate. Provides
0056: * convenience methods for accessing and verifying launch configuration
0057: * attributes.
0058: * <p>
0059: * Clients implementing Java launch configuration delegates should subclass this
0060: * class.
0061: * </p>
0062: *
0063: * @since 2.0
0064: */
0065: public abstract class AbstractJavaLaunchConfigurationDelegate extends
0066: LaunchConfigurationDelegate implements IDebugEventSetListener {
0067: /**
0068: * A list of prerequisite projects ordered by their build order.
0069: */
0070: private IProject[] fOrderedProjects;
0071:
0072: /**
0073: * Convenience method to get the launch manager.
0074: *
0075: * @return the launch manager
0076: */
0077: protected ILaunchManager getLaunchManager() {
0078: return DebugPlugin.getDefault().getLaunchManager();
0079: }
0080:
0081: /**
0082: * Throws a core exception with an error status object built from the given
0083: * message, lower level exception, and error code.
0084: *
0085: * @param message
0086: * the status message
0087: * @param exception
0088: * lower level exception associated with the error, or
0089: * <code>null</code> if none
0090: * @param code
0091: * error code
0092: * @throws CoreException
0093: * the "abort" core exception
0094: */
0095: protected void abort(String message, Throwable exception, int code)
0096: throws CoreException {
0097: throw new CoreException(new Status(IStatus.ERROR,
0098: LaunchingPlugin.getUniqueIdentifier(), code, message,
0099: exception));
0100: }
0101:
0102: /**
0103: * Returns the VM install specified by the given launch configuration, or
0104: * <code>null</code> if none.
0105: *
0106: * @param configuration
0107: * launch configuration
0108: * @return the VM install specified by the given launch configuration, or
0109: * <code>null</code> if none
0110: * @exception CoreException
0111: * if unable to retrieve the attribute
0112: */
0113: public IVMInstall getVMInstall(ILaunchConfiguration configuration)
0114: throws CoreException {
0115: return JavaRuntime.computeVMInstall(configuration);
0116: }
0117:
0118: /**
0119: * Returns the VM install name specified by the given launch configuration,
0120: * or <code>null</code> if none.
0121: *
0122: * @param configuration
0123: * launch configuration
0124: * @return the VM install name specified by the given launch configuration,
0125: * or <code>null</code> if none
0126: * @exception CoreException
0127: * if unable to retrieve the attribute
0128: */
0129: public String getVMInstallName(ILaunchConfiguration configuration)
0130: throws CoreException {
0131: return configuration.getAttribute(
0132: IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME,
0133: (String) null);
0134: }
0135:
0136: /**
0137: * Returns the VM install type specified by the given launch configuration,
0138: * or <code>null</code> if none.
0139: *
0140: * @param configuration
0141: * launch configuration
0142: * @return the VM install type specified by the given launch configuration,
0143: * or <code>null</code> if none
0144: * @exception CoreException
0145: * if unable to retrieve the attribute
0146: */
0147: public IVMInstallType getVMInstallType(
0148: ILaunchConfiguration configuration) throws CoreException {
0149: String id = getVMInstallTypeId(configuration);
0150: if (id != null) {
0151: IVMInstallType type = JavaRuntime.getVMInstallType(id);
0152: if (type != null) {
0153: return type;
0154: }
0155: }
0156: return null;
0157: }
0158:
0159: /**
0160: * Returns the VM install type identifier specified by the given launch
0161: * configuration, or <code>null</code> if none.
0162: *
0163: * @param configuration
0164: * launch configuration
0165: * @return the VM install type identifier specified by the given launch
0166: * configuration, or <code>null</code> if none
0167: * @exception CoreException
0168: * if unable to retrieve the attribute
0169: */
0170: public String getVMInstallTypeId(ILaunchConfiguration configuration)
0171: throws CoreException {
0172: return configuration.getAttribute(
0173: IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE,
0174: (String) null);
0175: }
0176:
0177: /**
0178: * Verifies the VM install specified by the given launch configuration
0179: * exists and returns the VM install.
0180: *
0181: * @param configuration
0182: * launch configuration
0183: * @return the VM install specified by the given launch configuration
0184: * @exception CoreException
0185: * if unable to retrieve the attribute, the attribute is
0186: * unspecified, or if the home location is unspecified or
0187: * does not exist
0188: */
0189: public IVMInstall verifyVMInstall(ILaunchConfiguration configuration)
0190: throws CoreException {
0191: IVMInstall vm = getVMInstall(configuration);
0192: if (vm == null) {
0193: abort(
0194: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_The_specified_JRE_installation_does_not_exist_4,
0195: null,
0196: IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
0197: }
0198: File location = vm.getInstallLocation();
0199: if (location == null) {
0200: abort(
0201: MessageFormat
0202: .format(
0203: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_not_specified_for__0__5,
0204: new String[] { vm.getName() }),
0205: null,
0206: IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
0207: }
0208: if (!location.exists()) {
0209: abort(
0210: MessageFormat
0211: .format(
0212: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_for__0__does_not_exist___1__6,
0213: new String[] { vm.getName(),
0214: location.getAbsolutePath() }),
0215: null,
0216: IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
0217: }
0218: return vm;
0219: }
0220:
0221: /**
0222: * Returns the VM connector identifier specified by the given launch
0223: * configuration, or <code>null</code> if none.
0224: *
0225: * @param configuration
0226: * launch configuration
0227: * @return the VM connector identifier specified by the given launch
0228: * configuration, or <code>null</code> if none
0229: * @exception CoreException
0230: * if unable to retrieve the attribute
0231: */
0232: public String getVMConnectorId(ILaunchConfiguration configuration)
0233: throws CoreException {
0234: return configuration.getAttribute(
0235: IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR,
0236: (String) null);
0237: }
0238:
0239: /**
0240: * Returns entries that should appear on the bootstrap portion of the
0241: * classpath as specified by the given launch configuration, as an array of
0242: * resolved strings. The returned array is <code>null</code> if all
0243: * entries are standard (i.e. appear by default), or empty to represent an
0244: * empty bootpath.
0245: *
0246: * @param configuration
0247: * launch configuration
0248: * @return the bootpath specified by the given launch configuration. An
0249: * empty bootpath is specified by an empty array, and
0250: * <code>null</code> represents a default bootpath.
0251: * @exception CoreException
0252: * if unable to retrieve the attribute
0253: */
0254: public String[] getBootpath(ILaunchConfiguration configuration)
0255: throws CoreException {
0256: String[][] paths = getBootpathExt(configuration);
0257: String[] pre = paths[0];
0258: String[] main = paths[1];
0259: String[] app = paths[2];
0260: if (pre == null && main == null && app == null) {
0261: // default
0262: return null;
0263: }
0264: IRuntimeClasspathEntry[] entries = JavaRuntime
0265: .computeUnresolvedRuntimeClasspath(configuration);
0266: entries = JavaRuntime.resolveRuntimeClasspath(entries,
0267: configuration);
0268: List bootEntries = new ArrayList(entries.length);
0269: boolean empty = true;
0270: boolean allStandard = true;
0271: for (int i = 0; i < entries.length; i++) {
0272: if (entries[i].getClasspathProperty() != IRuntimeClasspathEntry.USER_CLASSES) {
0273: String location = entries[i].getLocation();
0274: if (location != null) {
0275: empty = false;
0276: bootEntries.add(location);
0277: allStandard = allStandard
0278: && entries[i].getClasspathProperty() == IRuntimeClasspathEntry.STANDARD_CLASSES;
0279: }
0280: }
0281: }
0282: if (empty) {
0283: return new String[0];
0284: } else if (allStandard) {
0285: return null;
0286: } else {
0287: return (String[]) bootEntries
0288: .toArray(new String[bootEntries.size()]);
0289: }
0290: }
0291:
0292: /**
0293: * Returns three sets of entries which represent the boot classpath
0294: * specified in the launch configuration, as an array of three arrays of
0295: * resolved strings. The first array represents the classpath that should be
0296: * prepended to the boot classpath. The second array represents the main
0297: * part of the boot classpath -<code>null</code> represents the default
0298: * bootclasspath. The third array represents the classpath that should be
0299: * appended to the boot classpath.
0300: *
0301: * @param configuration
0302: * launch configuration
0303: * @return a description of the boot classpath specified by the given launch
0304: * configuration.
0305: * @exception CoreException
0306: * if unable to retrieve the attribute
0307: * @since 3.0
0308: */
0309: public String[][] getBootpathExt(ILaunchConfiguration configuration)
0310: throws CoreException {
0311: String[][] bootpathInfo = new String[3][];
0312: IRuntimeClasspathEntry[] entries = JavaRuntime
0313: .computeUnresolvedRuntimeClasspath(configuration);
0314: List bootEntriesPrepend = new ArrayList();
0315: int index = 0;
0316: IRuntimeClasspathEntry jreEntry = null;
0317: while (jreEntry == null && index < entries.length) {
0318: IRuntimeClasspathEntry entry = entries[index++];
0319: if (entry.getClasspathProperty() == IRuntimeClasspathEntry.BOOTSTRAP_CLASSES
0320: || entry.getClasspathProperty() == IRuntimeClasspathEntry.STANDARD_CLASSES) {
0321: if (JavaRuntime.isVMInstallReference(entry)) {
0322: jreEntry = entry;
0323: } else {
0324: bootEntriesPrepend.add(entry);
0325: }
0326: }
0327: }
0328: IRuntimeClasspathEntry[] bootEntriesPrep = JavaRuntime
0329: .resolveRuntimeClasspath(
0330: (IRuntimeClasspathEntry[]) bootEntriesPrepend
0331: .toArray(new IRuntimeClasspathEntry[bootEntriesPrepend
0332: .size()]), configuration);
0333: String[] entriesPrep = null;
0334: if (bootEntriesPrep.length > 0) {
0335: entriesPrep = new String[bootEntriesPrep.length];
0336: for (int i = 0; i < bootEntriesPrep.length; i++) {
0337: entriesPrep[i] = bootEntriesPrep[i].getLocation();
0338: }
0339: }
0340: if (jreEntry != null) {
0341: List bootEntriesAppend = new ArrayList();
0342: for (; index < entries.length; index++) {
0343: IRuntimeClasspathEntry entry = entries[index];
0344: if (entry.getClasspathProperty() == IRuntimeClasspathEntry.BOOTSTRAP_CLASSES) {
0345: bootEntriesAppend.add(entry);
0346: }
0347: }
0348: bootpathInfo[0] = entriesPrep;
0349: IRuntimeClasspathEntry[] bootEntriesApp = JavaRuntime
0350: .resolveRuntimeClasspath(
0351: (IRuntimeClasspathEntry[]) bootEntriesAppend
0352: .toArray(new IRuntimeClasspathEntry[bootEntriesAppend
0353: .size()]), configuration);
0354: if (bootEntriesApp.length > 0) {
0355: bootpathInfo[2] = new String[bootEntriesApp.length];
0356: for (int i = 0; i < bootEntriesApp.length; i++) {
0357: bootpathInfo[2][i] = bootEntriesApp[i]
0358: .getLocation();
0359: }
0360: }
0361: IVMInstall install = getVMInstall(configuration);
0362: LibraryLocation[] libraryLocations = install
0363: .getLibraryLocations();
0364: if (libraryLocations != null) {
0365: // determine if explicit bootpath should be used
0366: // TODO: this test does not tell us if the bootpath entries are different (could still be
0367: // the same, as a non-bootpath entry on the JRE may have been removed/added)
0368: // We really need a way to ask a VM type for its default bootpath library locations and
0369: // compare that to the resolved entries for the "jreEntry" to see if they
0370: // are different (requires explicit bootpath)
0371: if (!JRERuntimeClasspathEntryResolver.isSameArchives(
0372: libraryLocations, install.getVMInstallType()
0373: .getDefaultLibraryLocations(
0374: install.getInstallLocation()))) {
0375: // resolve bootpath entries in JRE entry
0376: IRuntimeClasspathEntry[] bootEntries = null;
0377: if (jreEntry.getType() == IRuntimeClasspathEntry.CONTAINER) {
0378: IRuntimeClasspathEntry bootEntry = JavaRuntime
0379: .newRuntimeContainerClasspathEntry(
0380: jreEntry.getPath(),
0381: IRuntimeClasspathEntry.BOOTSTRAP_CLASSES,
0382: getJavaProject(configuration));
0383: bootEntries = JavaRuntime
0384: .resolveRuntimeClasspathEntry(
0385: bootEntry, configuration);
0386: } else {
0387: bootEntries = JavaRuntime
0388: .resolveRuntimeClasspathEntry(jreEntry,
0389: configuration);
0390: }
0391:
0392: // non-default JRE libraries - use explicit bootpath only
0393: String[] bootpath = new String[bootEntriesPrep.length
0394: + bootEntries.length
0395: + bootEntriesApp.length];
0396: if (bootEntriesPrep.length > 0) {
0397: System.arraycopy(bootpathInfo[0], 0, bootpath,
0398: 0, bootEntriesPrep.length);
0399: }
0400: int dest = bootEntriesPrep.length;
0401: for (int i = 0; i < bootEntries.length; i++) {
0402: bootpath[dest] = bootEntries[i].getLocation();
0403: dest++;
0404: }
0405: if (bootEntriesApp.length > 0) {
0406: System.arraycopy(bootpathInfo[2], 0, bootpath,
0407: dest, bootEntriesApp.length);
0408: }
0409: bootpathInfo[0] = null;
0410: bootpathInfo[1] = bootpath;
0411: bootpathInfo[2] = null;
0412: }
0413: }
0414: } else {
0415: if (entriesPrep == null) {
0416: bootpathInfo[1] = new String[0];
0417: } else {
0418: bootpathInfo[1] = entriesPrep;
0419: }
0420: }
0421: return bootpathInfo;
0422: }
0423:
0424: /**
0425: * Returns the entries that should appear on the user portion of the
0426: * classpath as specified by the given launch configuration, as an array of
0427: * resolved strings. The returned array is empty if no classpath is
0428: * specified.
0429: *
0430: * @param configuration
0431: * launch configuration
0432: * @return the classpath specified by the given launch configuration,
0433: * possibly an empty array
0434: * @exception CoreException
0435: * if unable to retrieve the attribute
0436: */
0437: public String[] getClasspath(ILaunchConfiguration configuration)
0438: throws CoreException {
0439: IRuntimeClasspathEntry[] entries = JavaRuntime
0440: .computeUnresolvedRuntimeClasspath(configuration);
0441: entries = JavaRuntime.resolveRuntimeClasspath(entries,
0442: configuration);
0443: List userEntries = new ArrayList(entries.length);
0444: Set set = new HashSet(entries.length);
0445: for (int i = 0; i < entries.length; i++) {
0446: if (entries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
0447: String location = entries[i].getLocation();
0448: if (location != null) {
0449: if (!set.contains(location)) {
0450: userEntries.add(location);
0451: set.add(location);
0452: }
0453: }
0454: }
0455: }
0456: return (String[]) userEntries.toArray(new String[userEntries
0457: .size()]);
0458: }
0459:
0460: /**
0461: * Returns the Java project specified by the given launch configuration, or
0462: * <code>null</code> if none.
0463: *
0464: * @param configuration
0465: * launch configuration
0466: * @return the Java project specified by the given launch configuration, or
0467: * <code>null</code> if none
0468: * @exception CoreException
0469: * if unable to retrieve the attribute
0470: */
0471: public IJavaProject getJavaProject(
0472: ILaunchConfiguration configuration) throws CoreException {
0473: String projectName = getJavaProjectName(configuration);
0474: if (projectName != null) {
0475: projectName = projectName.trim();
0476: if (projectName.length() > 0) {
0477: IProject project = ResourcesPlugin.getWorkspace()
0478: .getRoot().getProject(projectName);
0479: IJavaProject javaProject = JavaCore.create(project);
0480: if (javaProject != null && javaProject.exists()) {
0481: return javaProject;
0482: }
0483: }
0484: }
0485: return null;
0486: }
0487:
0488: /**
0489: * Returns the Java project name specified by the given launch
0490: * configuration, or <code>null</code> if none.
0491: *
0492: * @param configuration
0493: * launch configuration
0494: * @return the Java project name specified by the given launch
0495: * configuration, or <code>null</code> if none
0496: * @exception CoreException
0497: * if unable to retrieve the attribute
0498: */
0499: public String getJavaProjectName(ILaunchConfiguration configuration)
0500: throws CoreException {
0501: return configuration.getAttribute(
0502: IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
0503: (String) null);
0504: }
0505:
0506: /**
0507: * Returns the main type name specified by the given launch configuration,
0508: * or <code>null</code> if none.
0509: *
0510: * @param configuration
0511: * launch configuration
0512: * @return the main type name specified by the given launch configuration,
0513: * or <code>null</code> if none
0514: * @exception CoreException
0515: * if unable to retrieve the attribute
0516: */
0517: public String getMainTypeName(ILaunchConfiguration configuration)
0518: throws CoreException {
0519: String mainType = configuration.getAttribute(
0520: IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
0521: (String) null);
0522: if (mainType == null) {
0523: return null;
0524: }
0525: return VariablesPlugin.getDefault().getStringVariableManager()
0526: .performStringSubstitution(mainType);
0527: }
0528:
0529: /**
0530: * Returns the program arguments specified by the given launch
0531: * configuration, as a string. The returned string is empty if no program
0532: * arguments are specified.
0533: *
0534: * @param configuration
0535: * launch configuration
0536: * @return the program arguments specified by the given launch
0537: * configuration, possibly an empty string
0538: * @exception CoreException
0539: * if unable to retrieve the attribute
0540: */
0541: public String getProgramArguments(ILaunchConfiguration configuration)
0542: throws CoreException {
0543: String arguments = configuration
0544: .getAttribute(
0545: IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
0546: ""); //$NON-NLS-1$
0547: return VariablesPlugin.getDefault().getStringVariableManager()
0548: .performStringSubstitution(arguments);
0549: }
0550:
0551: /**
0552: * Returns the VM arguments specified by the given launch configuration, as
0553: * a string. The returned string is empty if no VM arguments are specified.
0554: *
0555: * @param configuration
0556: * launch configuration
0557: * @return the VM arguments specified by the given launch configuration,
0558: * possibly an empty string
0559: * @exception CoreException
0560: * if unable to retrieve the attribute
0561: */
0562: public String getVMArguments(ILaunchConfiguration configuration)
0563: throws CoreException {
0564: String arguments = configuration
0565: .getAttribute(
0566: IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
0567: ""); //$NON-NLS-1$
0568: String args = VariablesPlugin.getDefault()
0569: .getStringVariableManager().performStringSubstitution(
0570: arguments);
0571: int libraryPath = args.indexOf("-Djava.library.path"); //$NON-NLS-1$
0572: if (libraryPath < 0) {
0573: // if a library path is already specified, do not override
0574: String[] javaLibraryPath = getJavaLibraryPath(configuration);
0575: if (javaLibraryPath != null && javaLibraryPath.length > 0) {
0576: StringBuffer path = new StringBuffer(args);
0577: path.append(" -Djava.library.path="); //$NON-NLS-1$
0578: path.append("\""); //$NON-NLS-1$
0579: for (int i = 0; i < javaLibraryPath.length; i++) {
0580: if (i > 0) {
0581: path.append(File.pathSeparatorChar);
0582: }
0583: path.append(javaLibraryPath[i]);
0584: }
0585: path.append("\""); //$NON-NLS-1$
0586: args = path.toString();
0587: }
0588: }
0589: return args;
0590: }
0591:
0592: /**
0593: * Returns the Map of VM-specific attributes specified by the given launch
0594: * configuration, or <code>null</code> if none.
0595: *
0596: * @param configuration
0597: * launch configuration
0598: * @return the <code>Map</code> of VM-specific attributes
0599: * @exception CoreException
0600: * if unable to retrieve the attribute
0601: */
0602: public Map getVMSpecificAttributesMap(
0603: ILaunchConfiguration configuration) throws CoreException {
0604: Map map = configuration
0605: .getAttribute(
0606: IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP,
0607: (Map) null);
0608: String[][] paths = getBootpathExt(configuration);
0609: String[] pre = paths[0];
0610: String[] boot = paths[1];
0611: String[] app = paths[2];
0612: if (pre != null || app != null || boot != null) {
0613: if (map == null) {
0614: map = new HashMap(3);
0615: }
0616: if (pre != null) {
0617: map
0618: .put(
0619: IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_PREPEND,
0620: pre);
0621: }
0622: if (app != null) {
0623: map
0624: .put(
0625: IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_APPEND,
0626: app);
0627: }
0628: if (boot != null) {
0629: map
0630: .put(
0631: IJavaLaunchConfigurationConstants.ATTR_BOOTPATH,
0632: boot);
0633: }
0634: }
0635: return map;
0636: }
0637:
0638: /**
0639: * Returns the working directory specified by the given launch
0640: * configuration, or <code>null</code> if none.
0641: *
0642: * @param configuration
0643: * launch configuration
0644: * @return the working directory specified by the given launch
0645: * configuration, or <code>null</code> if none
0646: * @exception CoreException
0647: * if unable to retrieve the attribute
0648: */
0649: public File getWorkingDirectory(ILaunchConfiguration configuration)
0650: throws CoreException {
0651: return verifyWorkingDirectory(configuration);
0652: }
0653:
0654: /**
0655: * Returns the working directory path specified by the given launch
0656: * configuration, or <code>null</code> if none.
0657: *
0658: * @param configuration
0659: * launch configuration
0660: * @return the working directory path specified by the given launch
0661: * configuration, or <code>null</code> if none
0662: * @exception CoreException
0663: * if unable to retrieve the attribute
0664: */
0665: public IPath getWorkingDirectoryPath(
0666: ILaunchConfiguration configuration) throws CoreException {
0667: String path = configuration
0668: .getAttribute(
0669: IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
0670: (String) null);
0671: if (path != null) {
0672: path = VariablesPlugin.getDefault()
0673: .getStringVariableManager()
0674: .performStringSubstitution(path);
0675: return new Path(path);
0676: }
0677: return null;
0678: }
0679:
0680: /**
0681: * Verifies a Java project is specified by the given launch configuration,
0682: * and returns the Java project.
0683: *
0684: * @param configuration
0685: * launch configuration
0686: * @return the Java project specified by the given launch configuration
0687: * @exception CoreException
0688: * if unable to retrieve the attribute or the attribute is
0689: * unspecified
0690: */
0691: public IJavaProject verifyJavaProject(
0692: ILaunchConfiguration configuration) throws CoreException {
0693: String name = getJavaProjectName(configuration);
0694: if (name == null) {
0695: abort(
0696: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Java_project_not_specified_9,
0697: null,
0698: IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_PROJECT);
0699: }
0700: IJavaProject project = getJavaProject(configuration);
0701: if (project == null) {
0702: abort(
0703: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Project_does_not_exist_or_is_not_a_Java_project_10,
0704: null,
0705: IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT);
0706: }
0707: return project;
0708: }
0709:
0710: /**
0711: * Verifies a main type name is specified by the given launch configuration,
0712: * and returns the main type name.
0713: *
0714: * @param configuration
0715: * launch configuration
0716: * @return the main type name specified by the given launch configuration
0717: * @exception CoreException
0718: * if unable to retrieve the attribute or the attribute is
0719: * unspecified
0720: */
0721: public String verifyMainTypeName(ILaunchConfiguration configuration)
0722: throws CoreException {
0723: String name = getMainTypeName(configuration);
0724: if (name == null) {
0725: abort(
0726: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Main_type_not_specified_11,
0727: null,
0728: IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
0729: }
0730: return name;
0731: }
0732:
0733: /**
0734: * Verifies the working directory specified by the given launch
0735: * configuration exists, and returns the working directory, or
0736: * <code>null</code> if none is specified.
0737: *
0738: * @param configuration
0739: * launch configuration
0740: * @return the working directory specified by the given launch
0741: * configuration, or <code>null</code> if none
0742: * @exception CoreException
0743: * if unable to retrieve the attribute
0744: */
0745: public File verifyWorkingDirectory(
0746: ILaunchConfiguration configuration) throws CoreException {
0747: IPath path = getWorkingDirectoryPath(configuration);
0748: if (path == null) {
0749: File dir = getDefaultWorkingDirectory(configuration);
0750: if (dir != null) {
0751: if (!dir.isDirectory()) {
0752: abort(
0753: MessageFormat
0754: .format(
0755: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
0756: new String[] { dir
0757: .toString() }),
0758: null,
0759: IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
0760: }
0761: return dir;
0762: }
0763: } else {
0764: if (path.isAbsolute()) {
0765: File dir = new File(path.toOSString());
0766: if (dir.isDirectory()) {
0767: return dir;
0768: }
0769: // This may be a workspace relative path returned by a variable.
0770: // However variable paths start with a slash and thus are thought to
0771: // be absolute
0772: IResource res = ResourcesPlugin.getWorkspace()
0773: .getRoot().findMember(path);
0774: if (res instanceof IContainer && res.exists()) {
0775: return res.getLocation().toFile();
0776: }
0777: abort(
0778: MessageFormat
0779: .format(
0780: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
0781: new String[] { path.toString() }),
0782: null,
0783: IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
0784: } else {
0785: IResource res = ResourcesPlugin.getWorkspace()
0786: .getRoot().findMember(path);
0787: if (res instanceof IContainer && res.exists()) {
0788: return res.getLocation().toFile();
0789: }
0790: abort(
0791: MessageFormat
0792: .format(
0793: LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
0794: new String[] { path.toString() }),
0795: null,
0796: IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
0797: }
0798: }
0799: return null;
0800: }
0801:
0802: /**
0803: * Returns whether the given launch configuration specifies that termination
0804: * is allowed.
0805: *
0806: * @param configuration
0807: * launch configuration
0808: * @return whether termination is allowed
0809: * @exception CoreException
0810: * if unable to retrieve the attribute
0811: */
0812: public boolean isAllowTerminate(ILaunchConfiguration configuration)
0813: throws CoreException {
0814: return configuration.getAttribute(
0815: IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE,
0816: false);
0817: }
0818:
0819: /**
0820: * Returns whether the given launch configuration specifies that execution
0821: * should suspend on entry of the main method.
0822: *
0823: * @param configuration
0824: * launch configuration
0825: * @return whether execution should suspend in main
0826: * @exception CoreException
0827: * if unable to retrieve the attribute
0828: * @since 2.1
0829: */
0830: public boolean isStopInMain(ILaunchConfiguration configuration)
0831: throws CoreException {
0832: return configuration.getAttribute(
0833: IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN,
0834: false);
0835: }
0836:
0837: /**
0838: * Assigns a default source locator to the given launch if a source locator
0839: * has not yet been assigned to it, and the associated launch configuration
0840: * does not specify a source locator.
0841: *
0842: * @param launch
0843: * launch object
0844: * @param configuration
0845: * configuration being launched
0846: * @exception CoreException
0847: * if unable to set the source locator
0848: */
0849: protected void setDefaultSourceLocator(ILaunch launch,
0850: ILaunchConfiguration configuration) throws CoreException {
0851: // set default source locator if none specified
0852: if (launch.getSourceLocator() == null) {
0853: ISourceLookupDirector sourceLocator = new JavaSourceLookupDirector();
0854: sourceLocator
0855: .setSourcePathComputer(getLaunchManager()
0856: .getSourcePathComputer(
0857: "org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer")); //$NON-NLS-1$
0858: sourceLocator.initializeDefaults(configuration);
0859: launch.setSourceLocator(sourceLocator);
0860: }
0861: }
0862:
0863: /**
0864: * Determines if the given launch configuration specifies the "stop-in-main"
0865: * attribute, and sets up an event listener to handle the option if
0866: * required.
0867: *
0868: * @param configuration
0869: * configuration being launched
0870: * @exception CoreException
0871: * if unable to access the attribute
0872: * @since 2.1
0873: */
0874: protected void prepareStopInMain(ILaunchConfiguration configuration)
0875: throws CoreException {
0876: if (isStopInMain(configuration)) {
0877: // This listener does not remove itself from the debug plug-in
0878: // as an event listener (there is no dispose notification for
0879: // launch delegates). However, since there is only one delegate
0880: // instantiated per config type, this is tolerable.
0881: DebugPlugin.getDefault().addDebugEventListener(this );
0882: }
0883: }
0884:
0885: /**
0886: * Handles the "stop-in-main" option.
0887: *
0888: * @param events
0889: * the debug events.
0890: * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[])
0891: */
0892: public void handleDebugEvents(DebugEvent[] events) {
0893: for (int i = 0; i < events.length; i++) {
0894: DebugEvent event = events[i];
0895: if (event.getKind() == DebugEvent.CREATE
0896: && event.getSource() instanceof IJavaDebugTarget) {
0897: IJavaDebugTarget target = (IJavaDebugTarget) event
0898: .getSource();
0899: ILaunch launch = target.getLaunch();
0900: if (launch != null) {
0901: ILaunchConfiguration configuration = launch
0902: .getLaunchConfiguration();
0903: if (configuration != null) {
0904: try {
0905: if (isStopInMain(configuration)) {
0906: String mainType = getMainTypeName(configuration);
0907: if (mainType != null) {
0908: Map map = new HashMap();
0909: map
0910: .put(
0911: IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN,
0912: IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN);
0913: IJavaMethodBreakpoint bp = JDIDebugModel
0914: .createMethodBreakpoint(
0915: ResourcesPlugin
0916: .getWorkspace()
0917: .getRoot(),
0918: mainType,
0919: "main", //$NON-NLS-1$
0920: "([Ljava/lang/String;)V", //$NON-NLS-1$
0921: true, false, false,
0922: -1, -1, -1, 1,
0923: false, map);
0924: bp.setPersisted(false);
0925: target.breakpointAdded(bp);
0926: DebugPlugin.getDefault()
0927: .removeDebugEventListener(
0928: this );
0929: }
0930: }
0931: } catch (CoreException e) {
0932: LaunchingPlugin.log(e);
0933: }
0934: }
0935: }
0936: }
0937: }
0938: }
0939:
0940: /*
0941: * (non-Javadoc)
0942: *
0943: * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getBuildOrder(org.eclipse.debug.core.ILaunchConfiguration,
0944: * java.lang.String)
0945: */
0946: protected IProject[] getBuildOrder(
0947: ILaunchConfiguration configuration, String mode)
0948: throws CoreException {
0949: return fOrderedProjects;
0950: }
0951:
0952: /*
0953: * (non-Javadoc)
0954: *
0955: * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getProjectsForProblemSearch(org.eclipse.debug.core.ILaunchConfiguration,
0956: * java.lang.String)
0957: */
0958: protected IProject[] getProjectsForProblemSearch(
0959: ILaunchConfiguration configuration, String mode)
0960: throws CoreException {
0961: return fOrderedProjects;
0962: }
0963:
0964: /* (non-Javadoc)
0965: * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#isLaunchProblem(org.eclipse.core.resources.IMarker)
0966: */
0967: protected boolean isLaunchProblem(IMarker problemMarker)
0968: throws CoreException {
0969: return super .isLaunchProblem(problemMarker)
0970: && problemMarker.getType().equals(
0971: IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
0972: }
0973:
0974: /*
0975: * (non-Javadoc)
0976: *
0977: * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration,
0978: * java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
0979: */
0980: public boolean preLaunchCheck(ILaunchConfiguration configuration,
0981: String mode, IProgressMonitor monitor) throws CoreException {
0982: // build project list
0983: if (monitor != null) {
0984: monitor
0985: .subTask(LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_20);
0986: }
0987: fOrderedProjects = null;
0988: IJavaProject javaProject = JavaRuntime
0989: .getJavaProject(configuration);
0990: if (javaProject != null) {
0991: fOrderedProjects = computeReferencedBuildOrder(new IProject[] { javaProject
0992: .getProject() });
0993: }
0994: // do generic launch checks
0995: return super .preLaunchCheck(configuration, mode, monitor);
0996: }
0997:
0998: /* (non-Javadoc)
0999: * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getBreakpoints(org.eclipse.debug.core.ILaunchConfiguration)
1000: */
1001: protected IBreakpoint[] getBreakpoints(
1002: ILaunchConfiguration configuration) {
1003: IBreakpointManager breakpointManager = DebugPlugin.getDefault()
1004: .getBreakpointManager();
1005: if (!breakpointManager.isEnabled()) {
1006: // no need to check breakpoints individually.
1007: return null;
1008: }
1009: return breakpointManager.getBreakpoints(JDIDebugModel
1010: .getPluginIdentifier());
1011: }
1012:
1013: /**
1014: * Returns the VM runner for the given launch mode to use when launching the
1015: * given configuration.
1016: *
1017: * @param configuration launch configuration
1018: * @param mode launch node
1019: * @return VM runner to use when launching the given configuration in the given mode
1020: * @throws CoreException if a VM runner cannot be determined
1021: * @since 3.1
1022: */
1023: public IVMRunner getVMRunner(ILaunchConfiguration configuration,
1024: String mode) throws CoreException {
1025: IVMInstall vm = verifyVMInstall(configuration);
1026: IVMRunner runner = vm.getVMRunner(mode);
1027: if (runner == null) {
1028: abort(
1029: MessageFormat
1030: .format(
1031: LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_0,
1032: new String[] { vm.getName(), mode }),
1033: null,
1034: IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST);
1035: }
1036: return runner;
1037: }
1038:
1039: /**
1040: * Returns an array of environment variables to be used when
1041: * launching the given configuration or <code>null</code> if unspecified.
1042: *
1043: * @param configuration launch configuration
1044: * @throws CoreException if unable to access associated attribute or if
1045: * unable to resolve a variable in an environment variable's value
1046: * @since 3.1
1047: */
1048: public String[] getEnvironment(ILaunchConfiguration configuration)
1049: throws CoreException {
1050: return DebugPlugin.getDefault().getLaunchManager()
1051: .getEnvironment(configuration);
1052: }
1053:
1054: /**
1055: * Returns an array of paths to be used for the <code>java.library.path</code>
1056: * system property, or <code>null</code> if unspecified.
1057: *
1058: * @param configuration
1059: * @return an array of paths to be used for the <code>java.library.path</code>
1060: * system property, or <code>null</code>
1061: * @throws CoreException if unable to determine the attribute
1062: * @since 3.1
1063: */
1064: public String[] getJavaLibraryPath(
1065: ILaunchConfiguration configuration) throws CoreException {
1066: IJavaProject project = getJavaProject(configuration);
1067: if (project != null) {
1068: String[] paths = JavaRuntime.computeJavaLibraryPath(
1069: project, true);
1070: if (paths.length > 0) {
1071: return paths;
1072: }
1073: }
1074: return null;
1075: }
1076:
1077: /**
1078: * Returns the default working directory for the given launch configuration,
1079: * or <code>null</code> if none. Subclasses may override as necessary.
1080: *
1081: * @param configuration
1082: * @return default working directory or <code>null</code> if none
1083: * @throws CoreException if an exception occurs computing the default working
1084: * directory
1085: * @since 3.2
1086: */
1087: protected File getDefaultWorkingDirectory(
1088: ILaunchConfiguration configuration) throws CoreException {
1089: // default working directory is the project if this config has a project
1090: IJavaProject jp = getJavaProject(configuration);
1091: if (jp != null) {
1092: IProject p = jp.getProject();
1093: return p.getLocation().toFile();
1094: }
1095: return null;
1096: }
1097: }
|