package com.sysdeo.eclipse.tomcat; /* * (c) Copyright Sysdeo SA 2001, 2002. * All Rights Reserved. */ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; 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.Path; 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.debug.core.Launch; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.sourcelookup.ISourceContainer; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourcePathComputer; import org.eclipse.debug.core.sourcelookup.containers.DefaultSourceContainer; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry; import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages; import org.eclipse.jdt.internal.launching.JavaSourceLookupDirector; import org.eclipse.jdt.internal.launching.RuntimeClasspathEntry; import org.eclipse.jdt.launching.ExecutionArguments; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.IVMInstallType; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.LibraryLocation; import org.eclipse.jdt.launching.VMRunnerConfiguration; import org.eclipse.jdt.launching.sourcelookup.containers.ClasspathContainerSourceContainer; import org.eclipse.jdt.launching.sourcelookup.containers.ClasspathVariableSourceContainer; import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer; import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer; import com.sysdeo.eclipse.tomcat.editors.ProjectListElement; /** * Utility class for launching a JVM in Eclipse and registering it to debugger * * It might exist better way to implements those operations, * or they might already exist in other form JDT */ public class VMLauncherUtility { static public ILaunch ILAUNCH = null; static public IVMInstall getVMInstall() { IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes(); for (int i = 0; i < vmTypes.length; i++) { IVMInstall[] vms = vmTypes[i].getVMInstalls(); for (int j = 0; j < vms.length; j++) { if (vms[j].getId().equals(TomcatLauncherPlugin.getDefault().getTomcatJRE())) { return vms[j]; } } } return JavaRuntime.getDefaultVMInstall(); } static public void runVM(String label, String classToLaunch, String[] classpath, String[] bootClasspath, String vmArgs, String prgArgs, boolean debug, boolean showInDebugger, boolean saveConfig) throws CoreException { // IVMInstall vmInstall = getVMInstall(); String mode = ""; if (debug) mode = ILaunchManager.DEBUG_MODE; else mode = ILaunchManager.RUN_MODE; // IVMRunner vmRunner = vmInstall.getVMRunner(mode); ILaunchConfigurationWorkingCopy config = createConfig(label, classToLaunch, classpath, bootClasspath, vmArgs, prgArgs, debug, showInDebugger, saveConfig); ILAUNCH = config.launch(mode, null); // ISourceLocator sourceLocator = getSourceLocator(config, false); // // // Launch launch = createLaunch(label, classToLaunch, classpath, bootClasspath, vmArgs, prgArgs, sourceLocator, debug, showInDebugger, false); // Launch launch = new Launch(config, mode, sourceLocator); // // // if (vmRunner != null) { // VMRunnerConfiguration vmConfig = new VMRunnerConfiguration(classToLaunch, classpath); // ExecutionArguments executionArguments = new ExecutionArguments(vmArgs, prgArgs); // vmConfig.setVMArguments(executionArguments.getVMArgumentsArray()); // vmConfig.setProgramArguments(executionArguments.getProgramArgumentsArray()); // // if (bootClasspath.length == 0) { // vmConfig.setBootClassPath(null); // use default bootclasspath // } else { // vmConfig.setBootClassPath(bootClasspath); // } // // vmRunner.run(vmConfig, launch, null); // } // // // Show in debugger // if (showInDebugger) { // DebugPlugin.getDefault().getLaunchManager().addLaunch(launch); // } } static public void log(String label, String classToLaunch, String[] classpath, String[] bootClasspath, String vmArgs, String prgArgs, boolean debug, boolean showInDebugger) { StringBuffer trace = new StringBuffer("\n-------- Sysdeo Tomcat Launcher settings --------"); trace.append("\n-> Label : " + label); trace.append("\n-> ClassToLaunch : " + classToLaunch); trace.append("\n-> Classpath : "); for (int i = 0; i < classpath.length; i++) { trace.append(" | " + classpath[i] + " | "); } trace.append("\n-> BootClasspath : "); for (int i = 0; i < bootClasspath.length; i++) { trace.append(" | " + bootClasspath[i] + " | "); } trace.append("\n-> Vmargs : " + vmArgs); trace.append("\n-> PrgArgs : " + prgArgs); trace.append("\n-> Debug : " + debug); trace.append("\n-> Source lookup : \n"); TomcatLauncherPlugin.log(trace.toString()); try { ILaunchConfigurationWorkingCopy config = createConfig(label, classToLaunch, classpath, bootClasspath, vmArgs, prgArgs, debug, showInDebugger, false); getSourceLocator(config, true); } catch (CoreException e) { TomcatLauncherPlugin.log("getSourceLocator failed"); } TomcatLauncherPlugin.log("\n-------- Sysdeo Tomcat Launcher settings--------"); } static public ILaunchConfigurationWorkingCopy createConfig(String label, String classToLaunch, String[] classpath, String[] bootClasspath, String vmArgs, String prgArgs, boolean debug, boolean showInDebugger, boolean saveConfig) throws CoreException { IVMInstall vmInstall = getVMInstall(); ILaunchConfigurationType launchType = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType("org.eclipse.jdt.launching.localJavaApplication"); ILaunchConfigurationWorkingCopy config = launchType.newInstance(null, label); config.setAttribute(IDebugUIConstants.ATTR_PRIVATE, !saveConfig); config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, "org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"); ISourceLookupDirector locator = (ISourceLookupDirector) getSourceLocator(config, false); config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, locator.getMemento()); ArrayList classpathMementos = new ArrayList(); for (int i = 0; i < classpath.length; i++) { IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(classpath[i])); cpEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES); classpathMementos.add(cpEntry.getMemento()); } if (bootClasspath.length == 0) { IPath path = new Path(JavaRuntime.JRE_CONTAINER); // Not needed // if (!fJREBlock.isDefaultJRE()) { // IVMInstall vm = fJREBlock.getJRE(); // if (vm != null) { // path = path.append(vm.getVMInstallType().getId()); // path = path.append(vm.getName()); // } // } try { IClasspathEntry cpEntry = JavaCore.newContainerEntry(path); // from org.eclipse.jdt.internal.debug.ui.actions.AddLibraryAction run() IRuntimeClasspathEntry rcpEntry = JavaRuntime.newRuntimeContainerClasspathEntry(cpEntry.getPath(), IRuntimeClasspathEntry.STANDARD_CLASSES); classpathMementos.add(rcpEntry.getMemento()); } catch (CoreException ex) { TomcatLauncherPlugin.log(ex); } // old // LibraryLocation[] librairies = vmInstall.getVMInstallType().getDefaultLibraryLocations(vmInstall.getInstallLocation()); // for (int i = 0; i < librairies.length; i++) { // IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(librairies[i].getSystemLibraryPath()); // cpEntry.setClasspathProperty(IRuntimeClasspathEntry.BOOTSTRAP_CLASSES); // classpathMementos.add(cpEntry.getMemento()); // } } else { for (int i = 0; i < bootClasspath.length; i++) { IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(bootClasspath[i])); cpEntry.setClasspathProperty(IRuntimeClasspathEntry.BOOTSTRAP_CLASSES); classpathMementos.add(cpEntry.getMemento()); } } config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, vmInstall.getVMInstallType().getId()); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, vmInstall.getName()); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, classpathMementos); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, prgArgs); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, classToLaunch); String catalinaBase = TomcatLauncherPlugin.getDefault().getTomcatBase(); if(catalinaBase.length() == 0) { catalinaBase = TomcatLauncherPlugin.getDefault().getTomcatDir(); } config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, catalinaBase); if(saveConfig) { getSourceLocator(config, false); config.doSave(); } return config; } private static ISourceLocator getSourceLocator(ILaunchConfiguration configuration, boolean trace) throws CoreException { ArrayList tempList = new ArrayList(); StringBuffer traceBuffer = new StringBuffer(); traceBuffer.append("Projects in source path :\n"); List projects = TomcatLauncherPlugin.getDefault().getProjectsInSourcePath(); for (Iterator iter = projects.iterator(); iter.hasNext();) { IProject project = ((ProjectListElement) iter.next()).getProject(); traceBuffer.append("Project " + project.getName()); if ((project.isOpen()) && project.hasNature(JavaCore.NATURE_ID)) { tempList.add(project.getNature(JavaCore.NATURE_ID)); traceBuffer.append(" added to tempList\n"); } } ISourceLookupDirector sourceLocator = null; sourceLocator = new JavaSourceLookupDirector(); ISourcePathComputer computer = DebugPlugin.getDefault().getLaunchManager().getSourcePathComputer("org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer"); sourceLocator.setSourcePathComputer(computer); //$NON-NLS-1$ ArrayList sourceContainers = new ArrayList(); if (!tempList.isEmpty()) { IJavaProject[] javaProjects = (IJavaProject[]) tempList.toArray(new IJavaProject[1]); // sourceLocator = new JavaSourceLocator(javaProjects, true); // Eclipse stops looking for source if it finds a jar containing the source code // despite this jar as no attached source (the user will have to use 'Attach source' button). // So we have to enforce that sources in project are searched before jar files, // To do so we add source containers in this orders : // - First project source containers. // - second packageFragmentRoot container (jar files in projects build path will be added to source path) // - third DefaultSourceContainer (jar files added to classpath will be added to source path) // First add all projects source containers for (int i = 0; i < javaProjects.length; i++) { IJavaProject project = javaProjects[i]; traceBuffer.append(" -> Add JavaProjectSourceContainer for " + project.getProject().getName() + "\n"); sourceContainers.add(new JavaProjectSourceContainer(project)); } // Adding packageFragmentRoot source containers, so classes in jar files associated to a project will be seen HashSet external = new HashSet(); for (int i = 0; i < javaProjects.length; i++) { IJavaProject project = javaProjects[i]; traceBuffer.append(" -> Compute SourceContainers for " + project.getProject().getName() + " :\n"); IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); for (int ri = 0; ri < roots.length; ri++) { IPackageFragmentRoot root = roots[ri]; if (root.isExternal()) { IPath location = root.getPath(); if (external.contains(location)) { continue; } external.add(location); } sourceContainers.add(new PackageFragmentRootSourceContainer(root)); traceBuffer.append(" RootSourceContainer created for : " + root.getPath().toPortableString() + "\n"); } } } // Last add DefaultSourceContainer, classes in jar files added to classpath will be visible sourceContainers.add(new DefaultSourceContainer()); sourceLocator.setSourceContainers((ISourceContainer[])sourceContainers.toArray(new ISourceContainer[sourceContainers.size()])); sourceLocator.initializeParticipants(); if(trace) TomcatLauncherPlugin.log(traceBuffer.toString()); return sourceLocator; } }