/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.wgadesigner.tomcat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
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.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.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
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.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer;
import org.eclipse.jdt.launching.sourcelookup.containers.JavaSourceLookupParticipant;
import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
public class VMRuntime {
public static ILaunch runVM(String label, IVMInstall vmInstall, String classToLaunch, List<IPath> classpath, String[] bootClasspath, String vmArgs, String prgArgs, boolean debug, boolean showInDebugger, boolean saveConfig)
throws CoreException {
String mode = "";
if (debug) {
mode = ILaunchManager.DEBUG_MODE;
}
else {
mode = ILaunchManager.RUN_MODE;
}
ILaunchConfigurationWorkingCopy config = createConfig(label, vmInstall, classToLaunch, classpath, bootClasspath, vmArgs, prgArgs, debug, showInDebugger, saveConfig);
return config.launch(mode, null);
}
private static ILaunchConfigurationWorkingCopy createConfig(String label, IVMInstall vmInstall, String classToLaunch, List<IPath> classpath, String[] bootClasspath, String vmArgs, String prgArgs, boolean debug, boolean showInDebugger, boolean saveConfig) throws CoreException {
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType launchType = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
ILaunchConfigurationWorkingCopy config = launchType.newInstance(null, label);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(vmInstall).toString());
config.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);
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());
List<String> classpathMementos = new ArrayList<String>();
Iterator<IPath> classPathEntries = classpath.iterator();
while (classPathEntries.hasNext()) {
IPath cpPath = classPathEntries.next();
IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(cpPath);
cpEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
classpathMementos.add(cpEntry.getMemento());
}
if (bootClasspath.length == 0) {
IPath systemLibsPath = new Path(JavaRuntime.JRE_CONTAINER);
IRuntimeClasspathEntry systemLibsEntry = JavaRuntime.newRuntimeContainerClasspathEntry(systemLibsPath,IRuntimeClasspathEntry.STANDARD_CLASSES);
classpathMementos.add(systemLibsEntry.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_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);
/*
if(saveConfig) {
getSourceLocator(config, false);
config.doSave();
} */
return config;
}
private static ISourceLocator getSourceLocator(ILaunchConfiguration configuration, boolean trace) throws CoreException {
ISourceLookupDirector sourceLocator = new AbstractSourceLookupDirector() {
public void initializeParticipants() {
addParticipants(new ISourceLookupParticipant[] {new JavaSourceLookupParticipant()});
}
};
ISourcePathComputer computer = DebugPlugin.getDefault().getLaunchManager().getSourcePathComputer("org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer");
sourceLocator.setSourcePathComputer(computer);
List<IJavaProject> javaProjectList = new ArrayList<IJavaProject>();
StringBuffer traceBuffer = new StringBuffer();
traceBuffer.append("Projects in source path :\n");
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (int i=0; i < projects.length; i++) {
IProject project = projects[i];
if ((project.isOpen()) && project.hasNature(JavaCore.NATURE_ID)) {
javaProjectList.add((IJavaProject)project.getNature(JavaCore.NATURE_ID));
}
}
List<ISourceContainer> sourceContainers = new ArrayList<ISourceContainer>();
if (!javaProjectList.isEmpty()) {
IJavaProject[] javaProjects = javaProjectList.toArray(new IJavaProject[0]);
// 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
Set<IPath> external = new HashSet<IPath>();
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;
}
}