package com.sysdeo.eclipse.tomcat; /* * (c) Copyright Sysdeo SA 2001, 2002. * All Rights Reserved. */ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; 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.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.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.launching.JavaSourceLookupDirector; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer; import com.sysdeo.eclipse.tomcat.editors.ProjectListElement; /** * Start and stop Tomcat * Subclasses contains all information specific to a Tomcat Version */ public abstract class TomcatBootstrap { private static final String WEBAPP_CLASSPATH_FILENAME = ".#webclasspath"; private static final int RUN = 1; private static final int LOG = 2; private static final int ADD_LAUNCH = 3; public abstract String[] getClasspath(); public abstract String[] getVmArgs(); public abstract String[] getPrgArgs(String command); public abstract String getStartCommand(); public abstract String getStopCommand(); public abstract String getMainClass(); abstract public String getLabel(); abstract public String getContextWorkDir(String workFolder); abstract public IPath getServletJarPath(); abstract public IPath getJasperJarPath(); abstract public IPath getJSPJarPath(); public Collection getTomcatJars() { IPath tomcatHomePath = TomcatLauncherPlugin.getDefault().getTomcatIPath(); ArrayList jars = new ArrayList(); if(this.getServletJarPath() != null) { jars.add(JavaCore.newVariableEntry(tomcatHomePath.append(this.getServletJarPath()), null, null)); } if(this.getJasperJarPath() != null) { jars.add(JavaCore.newVariableEntry(tomcatHomePath.append(this.getJasperJarPath()), null, null)); } if(this.getJSPJarPath() != null) { jars.add(JavaCore.newVariableEntry(tomcatHomePath.append(this.getJSPJarPath()), null, null)); } return jars; } /** * Return the tag that will be used to find where context definition should be added in server.xml */ public abstract String getXMLTagAfterContextDefinition(); /** * See %TOMCAT_HOME%/bin/startup.bat */ public void start() throws CoreException { this.runTomcatBootsrap(getStartCommand(), true, RUN, false); } /** * See %TOMCAT_HOME%/bin/shutdown.bat */ public void stop() throws CoreException { this.runTomcatBootsrap(getStopCommand(), false, RUN, false); } /** * Simply stop and start */ public void restart() throws CoreException { this.stop(); // Hack, need more testings try { Thread.sleep(5000); } catch (InterruptedException ex) { } this.start(); } /** * Write tomcat launch configuration to .metadata/.log */ public void logConfig() throws CoreException { this.runTomcatBootsrap(getStartCommand(), true, LOG, false); } /** * Create an Eclipse launch configuration */ public void addLaunch() throws CoreException { this.runTomcatBootsrap(getStartCommand(), true, ADD_LAUNCH, true); } /** * Launch a new JVM running Tomcat Main class * Set classpath, bootclasspath and environment variable */ private void runTomcatBootsrap(String tomcatBootOption, boolean showInDebugger, int action, boolean saveConfig) throws CoreException { String[] prgArgs = this.getPrgArgs(tomcatBootOption); IProject[] projects = TomcatLauncherPlugin.getWorkspace().getRoot().getProjects(); for (int i = 0; i < projects.length; i++) { if (!projects[i].isOpen()) continue; TomcatProject tomcatProject = (TomcatProject) projects[i].getNature(TomcatLauncherPlugin.NATURE_ID); if (tomcatProject != null) { ArrayList al = new ArrayList(); ArrayList visitedProjects = new ArrayList(); /*IMC*/ IJavaProject javaProject = (IJavaProject) projects[i].getNature(JavaCore.NATURE_ID); WebClassPathEntries entries = tomcatProject.getWebClassPathEntries(); if (entries != null) { getClassPathEntries(javaProject, al, entries.getList(), visitedProjects); IFile file = null; if(tomcatProject.getRootDirFolder() == null) { file = projects[i].getFile(new Path(WEBAPP_CLASSPATH_FILENAME)); } else { file = tomcatProject.getRootDirFolder().getFile(new Path(WEBAPP_CLASSPATH_FILENAME)); } File cpFile = file.getLocation().makeAbsolute().toFile(); if (cpFile.exists()) { cpFile.delete(); } try { if (cpFile.createNewFile()) { PrintWriter pw = new PrintWriter(new FileOutputStream(cpFile)); for (int j = 0; j < al.size(); j++) { pw.println(al.get(j)); } pw.close(); } } catch (IOException e) { e.printStackTrace(); } } } } String[] classpath = new String[0]; classpath = addPreferenceJvmToClasspath(classpath); classpath = addPreferenceProjectListToClasspath(classpath); classpath = StringUtil.concatUniq(classpath, this.getClasspath()); String[] vmArgs = this.getVmArgs(); vmArgs = addPreferenceParameters(vmArgs); String[] bootClasspath = addPreferenceJvmToBootClasspath(new String[0]); StringBuffer programArguments = new StringBuffer(); for (int i = 0; i < prgArgs.length; i++) { programArguments.append(" " + prgArgs[i]); } StringBuffer jvmArguments = new StringBuffer(); for (int i = 0; i < vmArgs.length; i++) { jvmArguments.append(" " + vmArgs[i]); } if(action == RUN) { VMLauncherUtility.runVM(getLabel(), getMainClass(), classpath, bootClasspath, jvmArguments.toString(), programArguments.toString(), isDebugMode(), showInDebugger, saveConfig); } if(action == LOG) { VMLauncherUtility.log(getLabel(), getMainClass(), classpath, bootClasspath, jvmArguments.toString(), programArguments.toString(), isDebugMode(), showInDebugger); } if(action == ADD_LAUNCH) { VMLauncherUtility.createConfig(getLabel(), getMainClass(), classpath, bootClasspath, jvmArguments.toString(), programArguments.toString(), isDebugMode(), showInDebugger, true); } } private void add(ArrayList data, IPath entry) { if (entry.isAbsolute() == false) entry = entry.makeAbsolute(); String tmp = entry.toFile().toString(); if (!data.contains(tmp)) { data.add(tmp); } } private void add(ArrayList data, IResource con) { if (con == null) return; add(data, con.getLocation()); } private void getClassPathEntries(IJavaProject prj, ArrayList data, List selectedPaths, ArrayList visitedProjects) { IClasspathEntry[] entries = null; IPath outputPath = null; try { outputPath = prj.getOutputLocation(); if (selectedPaths.contains(outputPath.toFile().toString().replace('\\', '/'))) { add(data, prj.getProject().getWorkspace().getRoot().findMember(outputPath)); } entries = prj.getRawClasspath(); } catch (JavaModelException e) { TomcatLauncherPlugin.log(e); } if (entries != null) { getClassPathEntries(entries, prj, data, selectedPaths, visitedProjects, outputPath); } } private void getClassPathEntries(IClasspathEntry[] entries, IJavaProject prj, ArrayList data, List selectedPaths, ArrayList visitedProjects, IPath outputPath) { for (int i = 0; i < entries.length; i++) { IClasspathEntry entry = entries[i]; IPath path = entry.getPath(); if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { path = entry.getOutputLocation(); if(path == null) continue; } if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { String prjName = entry.getPath().lastSegment(); if(!visitedProjects.contains(prjName)) { visitedProjects.add(prjName); getClassPathEntries(prj.getJavaModel().getJavaProject(prjName), data, selectedPaths, visitedProjects); } continue; } else if (!selectedPaths.contains(path.toFile().toString().replace('\\', '/'))) { if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && !entry.getPath().toString().equals("org.eclipse.jdt.launching.JRE_CONTAINER")) { // entires in container are only processed individually // if container itself is not selected IClasspathContainer container; try { container = JavaCore.getClasspathContainer(path, prj); } catch (JavaModelException e1) { TomcatLauncherPlugin.log(e1); container = null; } if (container != null) { getClassPathEntries( container.getClasspathEntries(), prj, data, selectedPaths, visitedProjects, outputPath); } } continue; } IClasspathEntry[] tmpEntry = null; if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { try { tmpEntry = JavaCore.getClasspathContainer(path, prj).getClasspathEntries(); } catch (JavaModelException e1) { TomcatLauncherPlugin.log(e1); continue; } } else { tmpEntry = new IClasspathEntry[1]; tmpEntry[0] = JavaCore.getResolvedClasspathEntry(entry); } for (int j = 0; j < tmpEntry.length; j++) { if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IResource res = prj.getProject().getWorkspace().getRoot().findMember(tmpEntry[j].getPath()); if (res != null) add(data, res); else add(data, tmpEntry[j].getPath()); } else if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { IPath srcPath = entry.getOutputLocation(); if(srcPath != null && !srcPath.equals(outputPath)) { add(data, prj.getProject().getWorkspace().getRoot().findMember(srcPath)); } } else { TomcatLauncherPlugin.log(">>> " + tmpEntry[j]); if(tmpEntry[j].getPath() != null) add(data, tmpEntry[j].getPath()); } } } } private boolean isDebugMode() { return TomcatLauncherPlugin.getDefault().isDebugMode(); } protected String getTomcatDir() { return TomcatLauncherPlugin.getDefault().getTomcatDir(); } protected String getTomcatBase() { return TomcatLauncherPlugin.getDefault().getTomcatBase(); } private String[] addPreferenceProjectListToClasspath(String[] previouscp) { List projectsList = TomcatLauncherPlugin.getDefault().getProjectsInCP(); String[] result = previouscp; Iterator it = projectsList.iterator(); while (it.hasNext()) { try { ProjectListElement ple = (ProjectListElement) it.next(); IJavaProject jproject = JavaCore.create(ple.getProject()); result = this.addProjectToClasspath(result, jproject); } catch (Exception e) { // nothing will be added to classpath } } return result; } private String[] addProjectToClasspath(String[] previouscp, IJavaProject project) throws CoreException { // IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); // IJavaProject project = JavaCore.getJavaCore().create(root.getProject(projectName)); if ((project != null) && (project.exists() && project.isOpen())) { String[] projectcp = JavaRuntime.computeDefaultRuntimeClassPath(project); return StringUtil.concatUniq(projectcp, previouscp); } else { return previouscp; } } private String[] addPreferenceParameters(String[] previous) { String[] prefParams = StringUtil.cutString(TomcatLauncherPlugin.getDefault().getJvmParamaters(), TomcatPluginResources.PREF_PAGE_LIST_SEPARATOR); return StringUtil.concat(previous, prefParams); } private String[] addPreferenceJvmToClasspath(String[] previous) { String[] prefClasspath = StringUtil.cutString(TomcatLauncherPlugin.getDefault().getJvmClasspath(), TomcatPluginResources.PREF_PAGE_LIST_SEPARATOR); return StringUtil.concatUniq(previous, prefClasspath); } private String[] addPreferenceJvmToBootClasspath(String[] previous) { String[] prefBootClasspath = StringUtil.cutString(TomcatLauncherPlugin.getDefault().getJvmBootClasspath(), TomcatPluginResources.PREF_PAGE_LIST_SEPARATOR); return StringUtil.concatUniq(previous, prefBootClasspath); } }