From 4a43f5a197e49c9c141850076d3df2d38d92c123 Mon Sep 17 00:00:00 2001 From: Larry Isaacs Date: Sun, 28 Feb 2016 16:29:59 -0500 Subject: [488652] Add Tomcat 9 support to WTP Server Tools. --- .../plugin.properties | 7 +- .../org.eclipse.jst.server.tomcat.core/plugin.xml | 52 ++ .../jst/server/tomcat/core/internal/Messages.java | 4 +- .../tomcat/core/internal/Messages.properties | 4 +- .../core/internal/Tomcat90Configuration.java | 710 +++++++++++++++++++++ .../tomcat/core/internal/Tomcat90Handler.java | 188 ++++++ .../internal/Tomcat90PublishModuleVisitor.java | 270 ++++++++ .../server/tomcat/core/internal/TomcatPlugin.java | 5 +- .../server/tomcat/core/internal/TomcatRuntime.java | 17 +- .../tomcat/core/internal/TomcatRuntimeLocator.java | 5 +- .../server/tomcat/core/internal/TomcatServer.java | 6 +- .../tomcat/core/internal/TomcatVersionHelper.java | 11 +- .../verifyInstall.properties | 3 +- .../org.eclipse.jst.server.tomcat.ui/plugin.xml | 12 + 14 files changed, 1282 insertions(+), 12 deletions(-) create mode 100644 plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Configuration.java create mode 100644 plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Handler.java create mode 100644 plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90PublishModuleVisitor.java diff --git a/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties b/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties index b7443a629..6417b0e7b 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties +++ b/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2013 IBM Corporation and others. +# Copyright (c) 2004, 2016 IBM Corporation and others. # 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 @@ -29,6 +29,8 @@ runtimeTypeTomcat70Label=Apache Tomcat v7.0 runtimeTypeTomcat70Description=Apache Tomcat v7.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules. runtimeTypeTomcat80Label=Apache Tomcat v8.0 runtimeTypeTomcat80Description=Apache Tomcat v8.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5, 6, and 7 Web modules. +runtimeTypeTomcat90Label=Apache Tomcat v9.0 +runtimeTypeTomcat90Description=Apache Tomcat v9.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5, 6, 7, and 8 Web modules. # --------------- Servers --------------- tomcat32ServerType=Tomcat v3.2 Server @@ -55,6 +57,9 @@ tomcat70ServerDescription=Publishes and runs J2EE and Java EE Web projects and s tomcat80ServerType=Tomcat v8.0 Server tomcat80ServerDescription=Publishes and runs J2EE and Java EE Web projects and server configurations to a local Tomcat server. +tomcat90ServerType=Tomcat v9.0 Server +tomcat90ServerDescription=Publishes and runs J2EE and Java EE Web projects and server configurations to a local Tomcat server. + tomcatLaunchConfigurationType=Apache Tomcat # --------------- General --------------- diff --git a/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml b/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml index c0179893e..466ba167b 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml +++ b/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml @@ -121,6 +121,20 @@ types="jst.utility" versions="1.0"/> + + + + @@ -258,6 +272,21 @@ class="org.eclipse.jst.server.tomcat.core.internal.TomcatServer" behaviourClass="org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour"> + + @@ -333,6 +362,10 @@ type="org.eclipse.jst.server.tomcat" version="8.0"/> + + @@ -443,6 +476,21 @@ id="jst.utility" version="1.0"/> + + + + + + + @@ -485,6 +533,10 @@ runtimeTypeId="org.eclipse.jst.server.tomcat.runtime.80" runtime-component="org.eclipse.jst.server.tomcat" version="8.0"/> + diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java index 724f5bab5..52c0eae07 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2013 IBM Corporation and others. + * Copyright (c) 2005, 2016 IBM Corporation and others. * 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 @@ -32,6 +32,7 @@ public class Messages extends NLS { public static String errorJRETomcat60; public static String errorJRETomcat70; public static String errorJRETomcat80; + public static String errorJRETomcat90; public static String warningJRE; public static String warningCantReadConfig; public static String target32runtime; @@ -55,6 +56,7 @@ public class Messages extends NLS { public static String errorSpec60; public static String errorSpec70; public static String errorSpec80; + public static String errorSpec90; public static String portServer; public static String runtimeDirPrepared; public static String publishConfigurationTask; diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties index b155a50a2..14ef566d2 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2013 IBM Corporation and others. +# Copyright (c) 2004, 2016 IBM Corporation and others. # 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 @@ -70,6 +70,7 @@ errorJRE=The JRE could not be found. Edit the server and change the JRE location errorJRETomcat60=Tomcat version 6.0 requires J2SE 5.0 or later. Change the JRE to one that meets this requirement. errorJRETomcat70=Tomcat version 7.0 requires Java SE 6 or later. Change the JRE to one that meets this requirement. errorJRETomcat80=Tomcat version 8.0 requires Java SE 7 or later. Change the JRE to one that meets this requirement. +errorJRETomcat90=Tomcat version 9.0 requires Java SE 8 or later. Change the JRE to one that meets this requirement. errorPortInvalid=The server cannot be started because one or more of the ports are invalid. Open the server editor and correct the invalid ports. errorPortInUse=Port {0} required by {1} is already in use. The server may already be running in another process, or a system process may be using the port. \ To start this server you will need to stop the other process or change the port number(s). @@ -94,6 +95,7 @@ errorSpec55=Tomcat version 5.5 only supports J2EE 1.2, 1.3, and 1.4 Web modules errorSpec60=Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules errorSpec70=Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules errorSpec80=Tomcat version 8.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5, 6, and 7 Web modules +errorSpec90=Tomcat version 9.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5, 6, 7, and 8 Web modules errorDuplicateContextRoot=Two or more Web modules defined in the configuration have the same context root ({0}). \ To start this server you will need to remove the duplicate(s). errorCouldNotLoadContextXml=Could not load the context configuration for the {0} context due to a syntax error or other exception. diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Configuration.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Configuration.java new file mode 100644 index 000000000..d3eecce8e --- /dev/null +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Configuration.java @@ -0,0 +1,710 @@ +/********************************************************************** + * Copyright (c) 2016 IBM Corporation and others. + * 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: + * IBM Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.jst.server.tomcat.core.internal; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jst.server.tomcat.core.internal.xml.Factory; +import org.eclipse.jst.server.tomcat.core.internal.xml.XMLUtil; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Connector; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Listener; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Server; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Service; +import org.eclipse.osgi.util.NLS; +import org.eclipse.wst.server.core.ServerPort; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +/** + * Tomcat v9.0 server configuration. + */ +public class Tomcat90Configuration extends TomcatConfiguration { + protected static final String DEFAULT_SERVICE = "Catalina"; + protected static final String EOL = System.getProperty("line.separator"); + protected Server server; + protected ServerInstance serverInstance; + protected Factory serverFactory; + protected boolean isServerDirty; + + protected WebAppDocument webAppDocument; + + protected Document contextDocument; + + protected Document tomcatUsersDocument; + + protected String policyFile; + + protected String propertiesFile; + + protected static final Map protocolHandlerMap = new HashMap(); + static { + protocolHandlerMap.put("org.apache.coyote.http11.Http11Protocol", "HTTP/1.1"); + protocolHandlerMap.put("org.apache.coyote.http11.Http11NioProtocol", "HTTP/1.1"); + protocolHandlerMap.put("org.apache.coyote.http11.Http11AprProtocol", "HTTP/1.1"); + protocolHandlerMap.put("org.apache.coyote.ajp.AjpAprProtocol", "AJP/1.3"); + protocolHandlerMap.put("org.apache.jk.server.JkCoyoteHandler", "AJP/1.3"); + } + + /** + * Tomcat90Configuration constructor. + * + * @param path a path + */ + public Tomcat90Configuration(IFolder path) { + super(path); + } + + /** + * Return the port number. + * @return int + */ + public ServerPort getMainPort() { + Iterator iterator = getServerPorts().iterator(); + while (iterator.hasNext()) { + ServerPort port = (ServerPort) iterator.next(); + // Return only an HTTP port from the selected Service + if (port.getProtocol().toLowerCase().equals("http") && port.getId().indexOf('/') < 0) + return port; + } + return null; + } + + /** + * Returns the mime mappings. + * @return java.util.List + */ + public List getMimeMappings() { + return webAppDocument.getMimeMappings(); + } + + /** + * Returns a list of ServerPorts that this configuration uses. + * + * @return java.util.List + */ + public List getServerPorts() { + List ports = new ArrayList(); + + // first add server port + try { + int port = Integer.parseInt(server.getPort()); + ports.add(new ServerPort("server", Messages.portServer, port, "TCPIP")); + } catch (Exception e) { + // ignore + } + + // add connectors + try { + String instanceServiceName = serverInstance.getService().getName(); + int size = server.getServiceCount(); + for (int i = 0; i < size; i++) { + Service service = server.getService(i); + int size2 = service.getConnectorCount(); + for (int j = 0; j < size2; j++) { + Connector connector = service.getConnector(j); + String name = "HTTP/1.1"; + String protocol2 = "HTTP"; + boolean advanced = true; + String[] contentTypes = null; + int port = -1; + try { + port = Integer.parseInt(connector.getPort()); + } catch (Exception e) { + // ignore + } + String protocol = connector.getProtocol(); + if (protocol != null && protocol.length() > 0) { + if (protocol.startsWith("HTTP")) { + name = protocol; + } + else if (protocol.startsWith("AJP")) { + name = protocol; + protocol2 = "AJP"; + } + else { + // Get Tomcat equivalent name if protocol handler class specified + name = protocolHandlerMap.get(protocol); + if (name != null) { + // Prepare simple protocol string for ServerPort protocol + int index = name.indexOf('/'); + if (index > 0) + protocol2 = name.substring(0, index); + else + protocol2 = name; + } + // Specified protocol is unknown, just use as is + else { + name = protocol; + protocol2 = protocol; + } + } + } + if (protocol2.toLowerCase().equals("http")) + contentTypes = new String[] { "web", "webservices" }; + String secure = connector.getSecure(); + if (secure != null && secure.length() > 0) { + name = "SSL"; + protocol2 = "SSL"; + } else + advanced = false; + String portId; + if (instanceServiceName != null && instanceServiceName.equals(service.getName())) + portId = Integer.toString(j); + else + portId = i +"/" + j; + ports.add(new ServerPort(portId, name, port, protocol2, contentTypes, advanced)); + } + } + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error getting server ports", e); + } + return ports; + } + + /** + * Return a list of the web modules in this server. + * @return java.util.List + */ + public List getWebModules() { + List list = new ArrayList(); + + try { + Context [] contexts = serverInstance.getContexts(); + if (contexts != null) { + for (int i = 0; i < contexts.length; i++) { + Context context = contexts[i]; + String reload = context.getReloadable(); + if (reload == null) + reload = "false"; + WebModule module = new WebModule(context.getPath(), + context.getDocBase(), context.getSource(), + reload.equalsIgnoreCase("true") ? true : false); + list.add(module); + } + } + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error getting project refs", e); + } + return list; + } + + /** + * @see TomcatConfiguration#getServerWorkDirectory(IPath) + */ + public IPath getServerWorkDirectory(IPath basePath) { + return serverInstance.getHostWorkDirectory(basePath); + } + + /** + * @see TomcatConfiguration#getContextWorkDirectory(IPath, ITomcatWebModule) + */ + public IPath getContextWorkDirectory(IPath basePath, ITomcatWebModule module) { + Context context = serverInstance.getContext(module.getPath()); + if (context != null) + return serverInstance.getContextWorkDirectory(basePath, context); + + return null; + } + + /** + * @see TomcatConfiguration#load(IPath, IProgressMonitor) + */ + public void load(IPath path, IProgressMonitor monitor) throws CoreException { + try { + monitor = ProgressUtil.getMonitorFor(monitor); + monitor.beginTask(Messages.loadingTask, 7); + + // check for catalina.policy to verify that this is a v5.5 config + InputStream in = new FileInputStream(path.append("catalina.policy").toFile()); + in.read(); + in.close(); + monitor.worked(1); + + serverFactory = new Factory(); + serverFactory.setPackageName("org.eclipse.jst.server.tomcat.core.internal.xml.server40"); + server = (Server) serverFactory.loadDocument(new FileInputStream(path.append("server.xml").toFile())); + serverInstance = new ServerInstance(server, null, null); + monitor.worked(1); + + webAppDocument = new WebAppDocument(path.append("web.xml")); + monitor.worked(1); + + File file = path.append("context.xml").toFile(); + if (file.exists()) + contextDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(new FileInputStream(file))); + monitor.worked(1); + + tomcatUsersDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(new FileInputStream(path.append("tomcat-users.xml").toFile()))); + monitor.worked(1); + + // load policy file + policyFile = TomcatVersionHelper.getFileContents(new FileInputStream(path.append("catalina.policy").toFile())); + monitor.worked(1); + + // load properties file + file = path.append("catalina.properties").toFile(); + if (file.exists()) + propertiesFile = TomcatVersionHelper.getFileContents(new FileInputStream(file)); + else + propertiesFile = null; + monitor.worked(1); + + if (monitor.isCanceled()) + return; + monitor.done(); + } catch (Exception e) { + Trace.trace(Trace.WARNING, "Could not load Tomcat v5.5 configuration from " + path.toOSString() + ": " + e.getMessage()); + throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, path.toOSString()), e)); + } + } + + /** + * @see TomcatConfiguration#importFromPath(IPath, boolean, IProgressMonitor) + */ + public void importFromPath(IPath path, boolean isTestEnv, IProgressMonitor monitor) throws CoreException { + load(path, monitor); + + // for test environment, remove existing contexts since a separate + // catalina.base will be used + if (isTestEnv) { + while (serverInstance.removeContext(0)) { + // no-op + } + } + } + + /** + * @see TomcatConfiguration#load(IFolder, IProgressMonitor) + */ + public void load(IFolder folder, IProgressMonitor monitor) throws CoreException { + try { + monitor = ProgressUtil.getMonitorFor(monitor); + monitor.beginTask(Messages.loadingTask, 1200); + + // check for catalina.policy to verify that this is a v4.0 config + IFile file = folder.getFile("catalina.policy"); + if (!file.exists()) + throw new CoreException(new Status(IStatus.WARNING, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, folder.getFullPath().toOSString()), null)); + + // load server.xml + file = folder.getFile("server.xml"); + InputStream in = file.getContents(); + serverFactory = new Factory(); + serverFactory.setPackageName("org.eclipse.jst.server.tomcat.core.internal.xml.server40"); + server = (Server) serverFactory.loadDocument(in); + serverInstance = new ServerInstance(server, null, null); + monitor.worked(200); + + // load web.xml + file = folder.getFile("web.xml"); + webAppDocument = new WebAppDocument(file); + monitor.worked(200); + + // load context.xml + file = folder.getFile("context.xml"); + if (file.exists()) { + in = file.getContents(); + contextDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(in)); + } + else + contextDocument = null; + monitor.worked(200); + + // load tomcat-users.xml + file = folder.getFile("tomcat-users.xml"); + in = file.getContents(); + + tomcatUsersDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(in)); + monitor.worked(200); + + // load catalina.policy + file = folder.getFile("catalina.policy"); + in = file.getContents(); + policyFile = TomcatVersionHelper.getFileContents(in); + monitor.worked(200); + + // load catalina.properties + file = folder.getFile("catalina.properties"); + if (file.exists()) { + in = file.getContents(); + propertiesFile = TomcatVersionHelper.getFileContents(in); + } + else + propertiesFile = null; + monitor.worked(200); + + if (monitor.isCanceled()) + throw new Exception("Cancelled"); + monitor.done(); + } catch (Exception e) { + Trace.trace(Trace.WARNING, "Could not reload Tomcat v5.5 configuration from: " + folder.getFullPath() + ": " + e.getMessage()); + throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, folder.getFullPath().toOSString()), e)); + } + } + + /** + * Save to the given directory. + * @param path a path + * @param forceDirty boolean + * @param monitor a progress monitor + * @exception CoreException + */ + protected void save(IPath path, boolean forceDirty, IProgressMonitor monitor) throws CoreException { + try { + monitor = ProgressUtil.getMonitorFor(monitor); + monitor.beginTask(Messages.savingTask, 5); + + // make sure directory exists + if (!path.toFile().exists()) { + forceDirty = true; + path.toFile().mkdir(); + } + monitor.worked(1); + + // save files + if (forceDirty || isServerDirty) { + serverFactory.save(path.append("server.xml").toOSString()); + isServerDirty = false; + } + monitor.worked(1); + + webAppDocument.save(path.append("web.xml").toOSString(), forceDirty); + monitor.worked(1); + + if (forceDirty && contextDocument != null) + XMLUtil.save(path.append("context.xml").toOSString(), contextDocument); + monitor.worked(1); + + if (forceDirty) + XMLUtil.save(path.append("tomcat-users.xml").toOSString(), tomcatUsersDocument); + monitor.worked(1); + + if (forceDirty) { + BufferedWriter bw = new BufferedWriter(new FileWriter(path.append("catalina.policy").toFile())); + bw.write(policyFile); + bw.close(); + } + monitor.worked(1); + if (propertiesFile != null && forceDirty) { + BufferedWriter bw = new BufferedWriter(new FileWriter(path.append("catalina.properties").toFile())); + bw.write(propertiesFile); + bw.close(); + } + monitor.worked(1); + + if (monitor.isCanceled()) + return; + monitor.done(); + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Could not save Tomcat v5.5 configuration to " + path, e); + throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotSaveConfiguration, new String[] {e.getLocalizedMessage()}), e)); + } + } + + /** + * Save to the given directory. All configuration files + * are forced to be saved. + * + * @param path Desination path for the configuration files. + * @param monitor A progress monitor + * @exception CoreException + */ + public void save(IPath path, IProgressMonitor monitor) throws CoreException { + save(path, true, monitor); + } + + /** + * Save the information held by this object to the given directory. + * + * @param folder a folder + * @param monitor a progress monitor + * @throws CoreException + */ + public void save(IFolder folder, IProgressMonitor monitor) throws CoreException { + try { + monitor = ProgressUtil.getMonitorFor(monitor); + monitor.beginTask(Messages.savingTask, 1200); + + // save server.xml + byte[] data = serverFactory.getContents(); + InputStream in = new ByteArrayInputStream(data); + IFile file = folder.getFile("server.xml"); + if (file.exists()) { + if (isServerDirty) + file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + else + monitor.worked(200); + } else + file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + isServerDirty = false; + + // save web.xml + webAppDocument.save(folder.getFile("web.xml"), ProgressUtil.getSubMonitorFor(monitor, 200)); + + // save context.xml + if (contextDocument != null) { + data = XMLUtil.getContents(contextDocument); + in = new ByteArrayInputStream(data); + file = folder.getFile("context.xml"); + if (file.exists()) + monitor.worked(200); + //file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + else + file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + } + + // save tomcat-users.xml + data = XMLUtil.getContents(tomcatUsersDocument); + in = new ByteArrayInputStream(data); + file = folder.getFile("tomcat-users.xml"); + if (file.exists()) + monitor.worked(200); + //file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + else + file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + + // save catalina.policy + in = new ByteArrayInputStream(policyFile.getBytes()); + file = folder.getFile("catalina.policy"); + if (file.exists()) + monitor.worked(200); + //file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + else + file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + + // save catalina.properties + if (propertiesFile != null) { + in = new ByteArrayInputStream(propertiesFile.getBytes()); + file = folder.getFile("catalina.properties"); + if (file.exists()) + monitor.worked(200); + //file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + else + file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200)); + } else + monitor.worked(200); + + if (monitor.isCanceled()) + return; + monitor.done(); + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Could not save Tomcat v5.5 configuration to " + folder.toString(), e); + throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotSaveConfiguration, new String[] {e.getLocalizedMessage()}), e)); + } + } + + protected static boolean hasMDBListener(Server server) { + if (server == null) + return false; + + int count = server.getListenerCount(); + if (count == 0) + return false; + + for (int i = 0; i < count; i++) { + Listener listener = server.getListener(i); + if (listener != null && listener.getClassName() != null && listener.getClassName().indexOf("mbean") >= 0) + return true; + } + return false; + } + + /** + * @see ITomcatConfigurationWorkingCopy#addMimeMapping(int, IMimeMapping) + */ + public void addMimeMapping(int index, IMimeMapping map) { + webAppDocument.addMimeMapping(index, map); + firePropertyChangeEvent(ADD_MAPPING_PROPERTY, new Integer(index), map); + } + + /** + * @see ITomcatConfigurationWorkingCopy#addWebModule(int, ITomcatWebModule) + */ + public void addWebModule(int index, ITomcatWebModule module) { + try { + Context context = serverInstance.createContext(index); + if (context != null) { + context.setDocBase(module.getDocumentBase()); + context.setPath(module.getPath()); + context.setReloadable(module.isReloadable() ? "true" : "false"); + if (module.getMemento() != null && module.getMemento().length() > 0) + context.setSource(module.getMemento()); + isServerDirty = true; + firePropertyChangeEvent(ADD_WEB_MODULE_PROPERTY, null, module); + } + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error adding web module " + module.getPath(), e); + } + } + + /** + * Change the extension of a mime mapping. + * + * @param index + * @param map + */ + public void modifyMimeMapping(int index, IMimeMapping map) { + webAppDocument.modifyMimeMapping(index, map); + firePropertyChangeEvent(MODIFY_MAPPING_PROPERTY, new Integer(index), map); + } + + /** + * Modify the port with the given id. + * + * @param id java.lang.String + * @param port int + */ + public void modifyServerPort(String id, int port) { + try { + if ("server".equals(id)) { + server.setPort(port + ""); + isServerDirty = true; + firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port)); + return; + } + + int i = id.indexOf("/"); + // If a connector in the instance Service + if (i < 0) { + int connNum = Integer.parseInt(id); + Connector connector = serverInstance.getConnector(connNum); + if (connector != null) { + connector.setPort(port + ""); + isServerDirty = true; + firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port)); + } + } + // Else a connector in another Service + else { + int servNum = Integer.parseInt(id.substring(0, i)); + int connNum = Integer.parseInt(id.substring(i + 1)); + + Service service = server.getService(servNum); + Connector connector = service.getConnector(connNum); + connector.setPort(port + ""); + isServerDirty = true; + firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port)); + } + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error modifying server port " + id, e); + } + } + /** + * Change a web module. + * @param index int + * @param docBase java.lang.String + * @param path java.lang.String + * @param reloadable boolean + */ + public void modifyWebModule(int index, String docBase, String path, boolean reloadable) { + try { + Context context = serverInstance.getContext(index); + if (context != null) { + context.setPath(path); + context.setDocBase(docBase); + context.setReloadable(reloadable ? "true" : "false"); + isServerDirty = true; + WebModule module = new WebModule(path, docBase, null, reloadable); + firePropertyChangeEvent(MODIFY_WEB_MODULE_PROPERTY, new Integer(index), module); + } + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error modifying web module " + index, e); + } + } + + /** + * Removes a mime mapping. + * @param index int + */ + public void removeMimeMapping(int index) { + webAppDocument.removeMimeMapping(index); + firePropertyChangeEvent(REMOVE_MAPPING_PROPERTY, null, new Integer(index)); + } + + /** + * Removes a web module. + * @param index int + */ + public void removeWebModule(int index) { + try { + serverInstance.removeContext(index); + isServerDirty = true; + firePropertyChangeEvent(REMOVE_WEB_MODULE_PROPERTY, null, new Integer(index)); + } catch (Exception e) { + Trace.trace(Trace.SEVERE, "Error removing module ref " + index, e); + } + } + + /** + * Add context configuration found in META-INF/context.xml files + * present in projects to published server.xml. + * + * @param baseDir path to catalina instance directory + * @param deployDir path to deployment directory + * @param monitor a progress monitor or null + * @return result of operation + */ + protected IStatus publishContextConfig(IPath baseDir, IPath deployDir, IProgressMonitor monitor) { + return TomcatVersionHelper.publishCatalinaContextConfig(baseDir, deployDir, monitor); + } + + /** + * Update contexts in server.xml to serve projects directly without + * publishing. + * + * @param baseDir path to catalina instance directory + * @param monitor a progress monitor or null + * @return result of operation + */ + protected IStatus updateContextsToServeDirectly(IPath baseDir, String tomcatVersion, String loader, IProgressMonitor monitor) { + return TomcatVersionHelper.updateContextsToServeDirectly(baseDir, tomcatVersion, loader, true, monitor); + } + + /** + * Cleanup the server instance. This consists of deleting the work + * directory associated with Contexts that are going away in the + * up coming publish. + * + * @param baseDir path to server instance directory, i.e. catalina.base + * @param installDir path to server installation directory (not currently used) + * @param monitor a progress monitor or null + * @return MultiStatus containing results of the cleanup operation + */ + protected IStatus cleanupServer(IPath baseDir, IPath installDir, boolean removeKeptContextFiles, IProgressMonitor monitor) { + List modules = getWebModules(); + return TomcatVersionHelper.cleanupCatalinaServer(baseDir, installDir, removeKeptContextFiles, modules, monitor); + } + + /** + * @see TomcatConfiguration#localizeConfiguration(IPath, IPath, TomcatServer, IProgressMonitor) + */ + public IStatus localizeConfiguration(IPath baseDir, IPath deployDir, TomcatServer tomcatServer, IProgressMonitor monitor) { + return TomcatVersionHelper.localizeConfiguration(baseDir, deployDir, tomcatServer, monitor); + } +} diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Handler.java new file mode 100644 index 000000000..01bd3a907 --- /dev/null +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90Handler.java @@ -0,0 +1,188 @@ +/********************************************************************** + * Copyright (c) 2016 IBM Corporation and others. + * 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: + * IBM Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.jst.server.tomcat.core.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.launching.IRuntimeClasspathEntry; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.wst.server.core.IModule; +/** + * Tomcat 80 handler. + */ +public class Tomcat90Handler implements ITomcatVersionHandler { + /** + * @see ITomcatVersionHandler#verifyInstallPath(IPath) + */ + public IStatus verifyInstallPath(IPath installPath) { + IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_90); + // If check was canceled, use folder check + if (result.getSeverity() == IStatus.CANCEL) { + result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_90); + } + return result; + } + + /** + * @see ITomcatVersionHandler#getRuntimeClass() + */ + public String getRuntimeClass() { + return "org.apache.catalina.startup.Bootstrap"; + } + + /** + * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath) + */ + public List getRuntimeClasspath(IPath installPath, IPath configPath) { + List cp = new ArrayList(); + + // 8.0 - add bootstrap.jar and tomcat-juli.jar from the Tomcat bin directory + IPath binPath = installPath.append("bin"); + if (binPath.toFile().exists()) { + IPath path = binPath.append("bootstrap.jar"); + cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path)); + // Add tomcat-juli.jar if it exists + path = binPath.append("tomcat-juli.jar"); + if (path.toFile().exists()) { + cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path)); + } + // If tomcat-juli.jar is not found in the install, check the config directory + else if (configPath != null){ + path = configPath.append("bin/tomcat-juli.jar"); + if (path.toFile().exists()) { + cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path)); + } + } + } + + return cp; + } + + /** + * @see ITomcatVersionHandler#getRuntimeProgramArguments(IPath, boolean, boolean) + */ + public String[] getRuntimeProgramArguments(IPath configPath, boolean debug, boolean starting) { + List list = new ArrayList(); + + if (starting) + list.add("start"); + else + list.add("stop"); + + String[] temp = new String[list.size()]; + list.toArray(temp); + return temp; + } + + /** + * @see ITomcatVersionHandler#getExcludedRuntimeProgramArguments(boolean, boolean) + */ + public String[] getExcludedRuntimeProgramArguments(boolean debug, boolean starting) { + return null; + } + + /** + * @see ITomcatVersionHandler#getRuntimeVMArguments(IPath, IPath, IPath, boolean) + */ + public String[] getRuntimeVMArguments(IPath installPath, IPath configPath, IPath deployPath, boolean isTestEnv) { + return TomcatVersionHelper.getCatalinaVMArguments(installPath, configPath, deployPath, getEndorsedDirectories(installPath), isTestEnv); + } + + /** + * @see ITomcatVersionHandler#getRuntimePolicyFile(IPath) + */ + public String getRuntimePolicyFile(IPath configPath) { + return configPath.append("conf").append("catalina.policy").toOSString(); + } + + /** + * @see ITomcatVersionHandler#canAddModule(IModule) + */ + public IStatus canAddModule(IModule module) { + String version = module.getModuleType().getVersion(); + if ("2.2".equals(version) || "2.3".equals(version) || "2.4".equals(version) || "2.5".equals(version) + || "3.0".equals(version) || "3.1".equals(version)) + return Status.OK_STATUS; + + return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorSpec80, null); + } + + /** + * @see ITomcatVersionHandler#getRuntimeBaseDirectory(TomcatServer) + */ + public IPath getRuntimeBaseDirectory(TomcatServer server) { + return TomcatVersionHelper.getStandardBaseDirectory(server); + } + + /** + * @see ITomcatVersionHandler#prepareRuntimeDirectory(IPath) + */ + public IStatus prepareRuntimeDirectory(IPath baseDir) { + return TomcatVersionHelper.createCatalinaInstanceDirectory(baseDir); + } + + /** + * @see ITomcatVersionHandler#prepareDeployDirectory(IPath) + */ + public IStatus prepareDeployDirectory(IPath deployPath) { + return TomcatVersionHelper.createDeploymentDirectory(deployPath, + TomcatVersionHelper.DEFAULT_WEBXML_SERVLET25); + } + + /** + * @see ITomcatVersionHandler#prepareForServingDirectly(IPath, TomcatServer) + */ + public IStatus prepareForServingDirectly(IPath baseDir, TomcatServer server, String tomcatVersion) { + // Nothing beyond configuration required for Tomcat 8 + return Status.OK_STATUS; + } + + /** + * @see ITomcatVersionHandler#getSharedLoader(IPath) + */ + public String getSharedLoader(IPath baseDir) { + return "common"; + } + + /** + * Returns true since Tomcat 9.x supports this feature. + * + * @return true since feature is supported + */ + public boolean supportsServeModulesWithoutPublish() { + return true; + } + + /** + * @see ITomcatVersionHandler#supportsDebugArgument() + */ + public boolean supportsDebugArgument() { + return false; + } + + /** + * @see ITomcatVersionHandler#supportsSeparateContextFiles() + */ + public boolean supportsSeparateContextFiles() { + return true; + } + + /** + * @see ITomcatVersionHandler#getEndorsedDirectories(IPath) + */ + public String getEndorsedDirectories(IPath installPath) { + return installPath.append("endorsed").toOSString(); + } +} diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90PublishModuleVisitor.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90PublishModuleVisitor.java new file mode 100644 index 000000000..9812c6f69 --- /dev/null +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat90PublishModuleVisitor.java @@ -0,0 +1,270 @@ +/********************************************************************** + * Copyright (c) 2016 SAS Institute and others. + * 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: + * SAS Institute - Initial API and implementation + **********************************************************************/ +package org.eclipse.jst.server.tomcat.core.internal; + +import java.io.File; +import java.io.FileFilter; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.JarResources; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.PostResources; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.PreResources; +import org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance; +import org.eclipse.osgi.util.NLS; +import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; +import org.eclipse.wst.common.componentcore.resources.IVirtualResource; +import org.eclipse.wst.server.core.IModule; +import org.eclipse.wst.server.core.ServerUtil; + +public class Tomcat90PublishModuleVisitor extends TomcatPublishModuleVisitor { + + /** + * Instantiate a new Tomcat80PublishModuleVisitor + * + * @param baseDir catalina base path + * @param tomcatVersion tomcat version + * @param serverInstance ServerInstance containing server.xml contents + * @param sharedLoader string value for shared.loader catalina configuration property + * @param enableMetaInfResources flag to indicate if Servlet 3.0 "META-INF/resources" feature should be supported + */ + Tomcat90PublishModuleVisitor(IPath baseDir, String tomcatVersion, ServerInstance serverInstance, String sharedLoader, boolean enableMetaInfResources) { + super(baseDir, tomcatVersion, serverInstance, sharedLoader, enableMetaInfResources); + } + + /** + * {@inheritDoc} + */ + @Override + public void endVisitWebComponent(IVirtualComponent component) + throws CoreException { + + // track context changes, don't rewrite if not needed + boolean dirty = false; + + IModule module = ServerUtil.getModule(component.getProject()); + + // we need this for the user-specified context path + Context context = findContext(module); + if (context == null) { + String name = module != null ? module.getName() : component.getName(); + Trace.trace(Trace.SEVERE, "Could not find context for module " + name); + throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, + NLS.bind(Messages.errorPublishContextNotFound, name), null)); + } + + dirty = includeProjectContextXml(component, context); + dirty = updateDocBaseAndPath(component, context); + + // Add WEB-INF/classes elements as PreResources + for (Iterator iterator = virtualClassClasspathElements.iterator(); + iterator.hasNext();) { + Object virtualClassClasspathElement = iterator.next(); + PreResources preResources = (PreResources)context.getResources().createElement("PreResources"); + preResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + preResources.setBase(virtualClassClasspathElement.toString()); + preResources.setWebAppMount("/WEB-INF/classes"); + preResources.setInternalPath("/"); + preResources.setClassLoaderOnly("false"); + } + virtualClassClasspathElements.clear(); + + // Add Jars as JarResources if a jar, or as PostResources if a utility project + for (Iterator iterator = virtualJarClasspathElements.iterator(); + iterator.hasNext();) { + Object virtualJarClassClasspathElement = iterator.next(); + String jarPath = virtualJarClassClasspathElement.toString(); + if (jarPath.endsWith(".jar")) { + JarResources jarResources = (JarResources)context.getResources().createElement("JarResources"); + jarResources.setClassName("org.apache.catalina.webresources.JarResourceSet"); + jarResources.setBase(jarPath); + jarResources.setWebAppMount("/WEB-INF/classes"); + jarResources.setInternalPath("/"); + jarResources.setClassLoaderOnly("true"); + } + else { + PostResources postResources = (PostResources)context.getResources().createElement("PostResources"); + postResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + postResources.setBase(jarPath); + postResources.setWebAppMount("/WEB-INF/classes"); + postResources.setInternalPath("/"); + postResources.setClassLoaderOnly("false"); + // Map META-INF tld files to WEB-INF + File metaInfDir = new File(jarPath + "/META-INF"); + if (metaInfDir.isDirectory() && metaInfDir.exists()) { + // Map META-INF directory directly to /META-INF + postResources = (PostResources)context.getResources().createElement("PostResources"); + postResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + postResources.setBase(metaInfDir.getPath()); + postResources.setWebAppMount("/META-INF"); + postResources.setInternalPath("/"); + postResources.setClassLoaderOnly("false"); + + File [] tldFiles = metaInfDir.listFiles(new FileFilter() { + public boolean accept(File file) { + if (file.isFile() && file.getName().endsWith(".tld")) { + return true; + } + return false; + } + }); + for (int i = 0; i < tldFiles.length; i++) { + postResources = (PostResources)context.getResources().createElement("PostResources"); + postResources.setClassName("org.apache.catalina.webresources.FileResourceSet"); + postResources.setBase(tldFiles[0].getPath()); + postResources.setWebAppMount("/WEB-INF/" + tldFiles[0].getName()); + postResources.setInternalPath("/"); + postResources.setClassLoaderOnly("false"); + } + } + } + } + virtualJarClasspathElements.clear(); + + Set rtPathsProcessed = new HashSet(); + Set locationsIncluded = new HashSet(); + String docBase = context.getDocBase(); + locationsIncluded.add(docBase); + Map retryLocations = new HashMap(); + IVirtualResource [] virtualResources = component.getRootFolder().getResources(""); + // Loop over the module's resources + for (int i = 0; i < virtualResources.length; i++) { + String rtPath = virtualResources[i].getRuntimePath().toString(); + // Note: The virtual resources returned only know their runtime path. + // Asking for the project path for this resource performs a lookup + // that will only return the path for the first mapping for the + // runtime path. Thus use of getUnderlyingResources() is necessary. + // However, this returns matching resources from all mappings so + // we have to try to keep only those that are mapped directly + // to the runtime path in the .components file. + + // If this runtime path has not yet been processed + if (!rtPathsProcessed.contains(rtPath)) { + // If not a Java related resource + if (!"/WEB-INF/classes".equals(rtPath)) { + // Get all resources for this runtime path + IResource[] underlyingResources = virtualResources[i].getUnderlyingResources(); + // If resource is mapped to "/", then we know it corresponds directly + // to a mapping in the .components file + if ("/".equals(rtPath)) { + for (int j = 0; j < underlyingResources.length; j++) { + IPath resLoc = underlyingResources[j].getLocation(); + String location = resLoc.toOSString(); + if (!location.equals(docBase)) { + PreResources preResources = (PreResources)context.getResources().createElement("PreResources"); + preResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + preResources.setBase(location); + preResources.setWebAppMount("/"); + preResources.setInternalPath("/"); + preResources.setClassLoaderOnly("false"); + // Add to the set of locations included + locationsIncluded.add(location); + } + } + } + // Else this runtime path is something other than "/" + else { + int idx = rtPath.lastIndexOf('/'); + // If a "normal" runtime path + if (idx >= 0) { + // Get the name of the last segment in the runtime path + String lastSegment = rtPath.substring(idx + 1); + // Check the underlying resources to determine which correspond to mappings + for (int j = 0; j < underlyingResources.length; j++) { + IPath resLoc = underlyingResources[j].getLocation(); + String location = resLoc.toOSString(); + // If the last segment of the runtime path doesn't match the + // the last segment of the location, then we have a direct mapping + // from the .contents file. + if (!lastSegment.equals(resLoc.lastSegment())) { + PreResources preResources = (PreResources)context.getResources().createElement("PreResources"); + preResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + preResources.setBase(location); + preResources.setWebAppMount(rtPath); + preResources.setInternalPath("/"); + preResources.setClassLoaderOnly("false"); + // Add to the set of locations included + locationsIncluded.add(location); + } + // Else last segment of runtime path did match the last segment + // of the location. We likely have a subfolder of a mapping + // that matches a portion of the runtime path. + else { + // Since we can't be sure, save so it can be check again later + retryLocations.put(location, rtPath); + } + } + } + } + } + // Add the runtime path to those already processed + rtPathsProcessed.add(rtPath); + } + } + // If there are locations to retry, add any not yet included in extra paths setting + if (!retryLocations.isEmpty()) { + // Remove retry locations already included in the extra paths + for (Iterator iterator = retryLocations.keySet().iterator(); iterator.hasNext();) { + String location = (String)iterator.next(); + for (Iterator iterator2 = locationsIncluded.iterator(); iterator2.hasNext();) { + String includedLocation = (String)iterator2.next(); + if (location.equals(includedLocation) || location.startsWith(includedLocation + File.separator)) { + iterator.remove(); + break; + } + } + } + // If any entries are left, include them in the extra paths + if (!retryLocations.isEmpty()) { + for (Iterator iterator = retryLocations.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry)iterator.next(); + String location = (String)entry.getKey(); + String rtPath = (String)entry.getValue(); + PreResources preResources = (PreResources)context.getResources().createElement("PreResources"); + preResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + preResources.setBase(location); + preResources.setWebAppMount(rtPath); + preResources.setInternalPath("/"); + preResources.setClassLoaderOnly("false"); + } + } + } + if (!virtualDependentResources.isEmpty()) { + for (Map.Entry> entry : virtualDependentResources.entrySet()) { + String rtPath = entry.getKey(); + List locations = entry.getValue(); + for (String location : locations) { + PostResources postResources = (PostResources)context.getResources().createElement("PostResources"); + postResources.setClassName("org.apache.catalina.webresources.DirResourceSet"); + postResources.setBase(location); + postResources.setWebAppMount(rtPath.length() > 0 ? rtPath : "/"); + postResources.setInternalPath("/"); + postResources.setClassLoaderOnly("false"); + } + } + } + virtualDependentResources.clear(); + + if (dirty) { + //TODO If writing to separate context XML files, save "dirty" status for later use + } + } +} diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java index ab0d4dc30..5779f3221 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 IBM Corporation and others. + * Copyright (c) 2003, 2016 IBM Corporation and others. * 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 @@ -42,6 +42,7 @@ public class TomcatPlugin extends Plugin { public static final String TOMCAT_60 = "org.eclipse.jst.server.tomcat.60"; public static final String TOMCAT_70 = "org.eclipse.jst.server.tomcat.70"; public static final String TOMCAT_80 = "org.eclipse.jst.server.tomcat.80"; + public static final String TOMCAT_90 = "org.eclipse.jst.server.tomcat.90"; protected static final String VERIFY_INSTALL_FILE = "verifyInstall.properties"; protected static VerifyResourceSpec[] verify32; @@ -155,6 +156,8 @@ public class TomcatPlugin extends Plugin { return new Tomcat70Handler(); else if (TOMCAT_80.equals(id)) return new Tomcat80Handler(); + else if (TOMCAT_90.equals(id)) + return new Tomcat90Handler(); else return null; } diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java index 37137a048..36630cba4 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 IBM Corporation and others. + * Copyright (c) 2003, 2016 IBM Corporation and others. * 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 @@ -135,8 +135,10 @@ public class TomcatRuntime extends RuntimeDelegate implements ITomcatRuntime, IT // on Tomcat 5.5 and later, the Eclipse JDT compiler is used for JSP's String id = getRuntime().getRuntimeType().getId(); if (!found) { - if (id != null && (id.indexOf("55") > 0 || id.indexOf("60") > 0 || id.indexOf("70") > 0 || id.indexOf("80") > 0)) + if (id != null && (id.indexOf("55") > 0 || id.indexOf("60") > 0 || id.indexOf("70") > 0 || id.indexOf("80") > 0 + || id.indexOf("90") > 0)) { found = true; + } } // on Mac, tools.jar is merged into classes.zip. if tools.jar wasn't found, @@ -191,6 +193,17 @@ public class TomcatRuntime extends RuntimeDelegate implements ITomcatRuntime, IT } } + // Else for Tomcat 9.0, ensure we have J2SE 8.0 + else if (id != null && id.indexOf("90") > 0) { + IVMInstall vmInstall = getVMInstall(); + if (vmInstall instanceof IVMInstall2) { + String javaVersion = ((IVMInstall2)vmInstall).getJavaVersion(); + if (javaVersion != null && !isVMMinimumVersion(javaVersion, 108)) { + return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorJRETomcat90, null); + } + } + } + return Status.OK_STATUS; } diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeLocator.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeLocator.java index 0ffdcbe9b..c36b7847d 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeLocator.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeLocator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 IBM Corporation and others. + * Copyright (c) 2003, 2016 IBM Corporation and others. * 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 @@ -32,7 +32,8 @@ public class TomcatRuntimeLocator extends RuntimeLocatorDelegate { "org.eclipse.jst.server.tomcat.runtime.55", "org.eclipse.jst.server.tomcat.runtime.60", "org.eclipse.jst.server.tomcat.runtime.70", - "org.eclipse.jst.server.tomcat.runtime.80"}; + "org.eclipse.jst.server.tomcat.runtime.80", + "org.eclipse.jst.server.tomcat.runtime.90"}; /* (non-Javadoc) * @see org.eclipse.wst.server.core.model.IRuntimeFactoryDelegate#getKnownRuntimes() diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java index d63749e5f..d9f15dfe5 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 IBM Corporation and others. + * Copyright (c) 2003, 2016 IBM Corporation and others. * 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 @@ -118,6 +118,8 @@ public class TomcatServer extends ServerDelegate implements ITomcatServer, ITomc tcConfig = new Tomcat70Configuration(folder); else if (id.indexOf("80") > 0) tcConfig = new Tomcat80Configuration(folder); + else if (id.indexOf("90") > 0) + tcConfig = new Tomcat90Configuration(folder); else { throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorUnknownVersion, null)); } @@ -171,6 +173,8 @@ public class TomcatServer extends ServerDelegate implements ITomcatServer, ITomc tcConfig = new Tomcat70Configuration(folder); else if (id.indexOf("80") > 0) tcConfig = new Tomcat80Configuration(folder); + else if (id.indexOf("90") > 0) + tcConfig = new Tomcat90Configuration(folder); else { throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorUnknownVersion, null)); } diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java index a05d9f461..de03528f4 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java +++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2007, 2013 SAS Institute, Inc and others. + * Copyright (c) 2007, 2016 SAS Institute, Inc and others. * 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 @@ -107,6 +107,7 @@ public class TomcatVersionHelper { versionStringMap.put(TomcatPlugin.TOMCAT_60, "6.0."); versionStringMap.put(TomcatPlugin.TOMCAT_70, "7.0."); versionStringMap.put(TomcatPlugin.TOMCAT_80, "8.0."); + versionStringMap.put(TomcatPlugin.TOMCAT_90, "9.0."); } /** @@ -918,12 +919,17 @@ public class TomcatVersionHelper { boolean modified = false; boolean isTomcat8 = tomcatVersion.startsWith("8."); + boolean isTomcat9 = tomcatVersion.startsWith("9."); // care about top-level modules only TomcatPublishModuleVisitor visitor; if (isTomcat8) { visitor = new Tomcat80PublishModuleVisitor( baseDir, tomcatVersion, publishedInstance, loader, enableMetaInfResources); } + else if (isTomcat9) { + visitor = new Tomcat90PublishModuleVisitor( + baseDir, tomcatVersion, publishedInstance, loader, enableMetaInfResources); + } else { visitor = new TomcatPublishModuleVisitor( baseDir, tomcatVersion, publishedInstance, loader, enableMetaInfResources); @@ -1136,7 +1142,8 @@ public class TomcatVersionHelper { IPath catalinaJarPath = null; File jarFile = null; - if (TomcatPlugin.TOMCAT_60.equals(serverType) || TomcatPlugin.TOMCAT_70.equals(serverType) || TomcatPlugin.TOMCAT_80.equals(serverType)) { + if (TomcatPlugin.TOMCAT_60.equals(serverType) || TomcatPlugin.TOMCAT_70.equals(serverType) || TomcatPlugin.TOMCAT_80.equals(serverType) + || TomcatPlugin.TOMCAT_90.equals(serverType)) { catalinaJarPath = installPath.append("lib").append("catalina.jar"); jarFile = catalinaJarPath.toFile(); // If jar is not at expected location, try alternate location diff --git a/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties b/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties index f07fb0971..4522610af 100644 --- a/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties +++ b/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2013 IBM Corporation and others. +# Copyright (c) 2003, 2016 IBM Corporation and others. # 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 @@ -19,3 +19,4 @@ verify55install=common/i18n,bin/bootstrap.jar,conf,webapps verify60install=lib/jasper-el.jar,lib/servlet-api.jar|[servletapi6].jar,bin/bootstrap.jar,conf,webapps verify70install=lib/jasper-el.jar,lib/servlet-api.jar|[servletapi6].jar,bin/bootstrap.jar,conf,webapps verify80install=lib/jasper-el.jar,lib/servlet-api.jar,lib/tomcat-websocket.jar,bin/bootstrap.jar,conf,webapps +verify90install=lib/jasper-el.jar,lib/servlet-api.jar,bin/bootstrap.jar,conf,webapps diff --git a/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml b/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml index b128622ad..5776ea3fc 100644 --- a/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml +++ b/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml @@ -35,6 +35,10 @@ id="org.eclipse.jst.server.tomcat.80" icon="icons/obj16/tomcat.gif" typeIds="org.eclipse.jst.server.tomcat.runtime.80"/> + + @@ -161,6 +169,10 @@ id="org.eclipse.jst.server.tomcat.runtime.80" typeIds="org.eclipse.jst.server.tomcat.runtime.80" class="org.eclipse.jst.server.tomcat.ui.internal.TomcatRuntimeWizardFragment"/> + -- cgit v1.2.3