Author: ptahchiev Date: Sun Mar 16 12:09:39 2008 New Revision: 637627 URL: http://svn.apache.org/viewvc?rev=637627&view=rev Log: Added Jetty6xTestSetup.java and also renamed the JettyTestSetup.java to Jetty5xTestSetup.java.
Added: jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty5xTestSetup.java - copied, changed from r634932, jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/JettyTestSetup.java jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java (with props) Removed: jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/JettyTestSetup.java Copied: jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty5xTestSetup.java (from r634932, jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/JettyTestSetup.java) URL: http://svn.apache.org/viewvc/jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty5xTestSetup.java?p2=jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty5xTestSetup.java&p1=jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/JettyTestSetup.java&r1=634932&r2=637627&rev=637627&view=diff ============================================================================== --- jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/JettyTestSetup.java (original) +++ jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty5xTestSetup.java Sun Mar 16 12:09:39 2008 @@ -52,7 +52,7 @@ * * @version $Id: JettyTestSetup.java 239036 2004-08-17 10:35:57Z vmassol $ */ -public class JettyTestSetup extends TestSetup +public class Jetty5xTestSetup extends TestSetup { /** * Name of optional system property that points to a Jetty XML @@ -118,7 +118,7 @@ /** * @param theTest the test we are decorating (usually a test suite) */ - public JettyTestSetup(Test theTest) + public Jetty5xTestSetup(Test theTest) { super(theTest); this.baseConfiguration = new BaseConfiguration(); @@ -135,7 +135,7 @@ * @param theFilterConfiguration the filter configuration object used * to configure Jetty */ - public JettyTestSetup(Test theTest, + public Jetty5xTestSetup(Test theTest, Configuration theBaseConfiguration, ServletConfiguration theServletConfiguration, FilterConfiguration theFilterConfiguration) Added: jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java URL: http://svn.apache.org/viewvc/jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java?rev=637627&view=auto ============================================================================== --- jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java (added) +++ jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java Sun Mar 16 12:09:39 2008 @@ -0,0 +1,663 @@ +/* + * ======================================================================== + * + * Copyright 2001-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ======================================================================== + */ +package org.apache.cactus.extension.jetty; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +import junit.extensions.TestSetup; +import junit.framework.Protectable; +import junit.framework.Test; +import junit.framework.TestResult; + +import org.apache.cactus.internal.configuration.BaseConfiguration; +import org.apache.cactus.internal.configuration.Configuration; +import org.apache.cactus.internal.configuration.DefaultFilterConfiguration; +import org.apache.cactus.internal.configuration.DefaultServletConfiguration; +import org.apache.cactus.internal.configuration.FilterConfiguration; +import org.apache.cactus.internal.configuration.ServletConfiguration; +import org.apache.cactus.internal.util.ClassLoaderUtils; +import org.apache.cactus.server.FilterTestRedirector; +import org.apache.cactus.server.ServletTestRedirector; +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Handler; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.handler.ContextHandlerCollection; +import org.mortbay.jetty.handler.DefaultHandler; +import org.mortbay.jetty.handler.HandlerCollection; +import org.mortbay.jetty.handler.RequestLogHandler; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.security.Constraint; +import org.mortbay.jetty.security.ConstraintMapping; +import org.mortbay.jetty.security.HashUserRealm; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.ServletHolder; +import org.mortbay.jetty.webapp.WebAppContext; +import org.mortbay.xml.XmlConfiguration; + +/** + * Custom JUnit test setup to use to automatically start Jetty. Example:<br/> + * <code><pre> + * public static Test suite() + * { + * TestSuite suite = new TestSuite(Myclass.class); + * return new JettyTestSetup(suite); + * } + * </pre></code> + * + * @version $Id: JettyTestSetup.java 239036 2004-08-17 10:35:57Z vmassol $ + */ +public class Jetty6xTestSetup extends TestSetup +{ + /** + * Name of optional system property that points to a Jetty XML + * configuration file. + */ + private static final String CACTUS_JETTY_CONFIG_PROPERTY = + "cactus.jetty.config"; + + /** + * Name of optional system property that gives the directory + * where JSPs and other resources are located. + */ + private static final String CACTUS_JETTY_RESOURCE_DIR_PROPERTY = + "cactus.jetty.resourceDir"; + + /** + * The configuration file to be used for initializing Jetty. + */ + private File configFile; + + /** + * The directory containing the resources of the web-application. + */ + private File resourceDir; + + /** + * The Jetty server object representing the running instance. It is + * used to stop Jetty in [EMAIL PROTECTED] #tearDown()}. + */ + private Object server; + + /** + * Whether the container had already been running before. + */ + private boolean alreadyRunning; + + /** + * Whether the container is running or not. + */ + private boolean isRunning = false; + + /** + * Whether the container should be stopped on tearDown even though + * it was not started by us. + */ + private boolean forceShutdown = false; + + /** + * The Servlet configuration object used to configure Jetty. + */ + private ServletConfiguration servletConfiguration; + + /** + * The Filter configuration object used to configure Jetty. + */ + private FilterConfiguration filterConfiguration; + + /** + * The base configuration object used to configure Jetty. + */ + private Configuration baseConfiguration; + + /** + * @param theTest the test we are decorating (usually a test suite) + */ + public Jetty6xTestSetup(Test theTest) + { + super(theTest); + this.baseConfiguration = new BaseConfiguration(); + this.servletConfiguration = new DefaultServletConfiguration(); + this.filterConfiguration = new DefaultFilterConfiguration(); + } + + /** + * @param theTest the test we are decorating (usually a test suite) + * @param theBaseConfiguration the base configuration object used to + * configure Jetty + * @param theServletConfiguration the servlet configuration object used + * to configure Jetty + * @param theFilterConfiguration the filter configuration object used + * to configure Jetty + */ + public Jetty6xTestSetup(Test theTest, + Configuration theBaseConfiguration, + ServletConfiguration theServletConfiguration, + FilterConfiguration theFilterConfiguration) + { + this(theTest); + this.baseConfiguration = theBaseConfiguration; + this.servletConfiguration = theServletConfiguration; + this.filterConfiguration = theFilterConfiguration; + } + + /** + * Make sure that [EMAIL PROTECTED] #tearDown} is called if [EMAIL PROTECTED] #setUp} fails + * to start the container properly. The default + * [EMAIL PROTECTED] TestSetup#run(TestResult)} method does not provide this feature + * unfortunately. + * + * [EMAIL PROTECTED] + * @see TestSetup#run(TestResult) + */ + public void run(final TestResult theResult) + { + Protectable p = new Protectable() + { + public void protect() throws Exception + { + try + { + setUp(); + basicRun(theResult); + } + finally + { + tearDown(); + } + } + }; + theResult.runProtected(this, p); + } + + /** + * Start an embedded Jetty server. It is allowed to pass a Jetty XML as + * a system property (<code>cactus.jetty.config</code>) to further + * configure Jetty. Example: + * <code>-Dcactus.jetty.config=./jetty.xml</code>. + * + * @exception Exception if an error happens during initialization + */ + protected void setUp() throws Exception + { + // Try connecting in case the server is already running. If so, does + // nothing + URL contextURL = new URL(this.baseConfiguration.getContextURL() + + "/" + this.servletConfiguration.getDefaultRedirectorName() + + "?Cactus_Service=RUN_TEST"); + this.alreadyRunning = isAvailable(testConnectivity(contextURL)); + if (this.alreadyRunning) + { + // Server is already running. Record this information so that we + // don't stop it afterwards. + this.isRunning = true; + return; + } + + // Note: We are currently using reflection in order not to need Jetty + // to compile Cactus. If the code becomes more complex or we need to + // add other initializer, it will be worth considering moving them + // to a separate "extension" subproject which will need additional jars + // in its classpath (using the same mechanism as the Ant project is + // using to conditionally compile tasks). + + // Create a Jetty Server object and configure a listener + this.server = createServer(this.baseConfiguration); + + // Create a Jetty context. + Object context = createContext(this.server, this.baseConfiguration); + + // Add the Cactus Servlet redirector + addServletRedirector(context, this.servletConfiguration); + + // Add the Cactus Jsp redirector + addJspRedirector(context); + + // Add the Cactus Filter redirector + addFilterRedirector(context, this.filterConfiguration); + + // Configure Jetty with an XML file if one has been specified on the + // command line. + if (getConfigFile() != null) + { + XmlConfiguration configuration = new XmlConfiguration(getConfigFile().toURL()); //or use new XmlConfiguration(new FileInputStream("myJetty.xml")); + configuration.configure(server); + + //this.server.getClass().getMethod("configure", + // new Class[] {String.class}).invoke( + // this.server, new Object[] {getConfigFile().toString()}); + } + + // Start the Jetty server + + this.server.getClass().getMethod("start", null).invoke( + this.server, null); + this.isRunning = true; + } + + /** + * Stop the running Jetty server. + * + * @exception Exception if an error happens during the shutdown + */ + protected void tearDown() throws Exception + { + // Don't shut down a container that has not been started by us + if (!this.forceShutdown && this.alreadyRunning) + { + return; + } + + if (this.server != null) + { + // First, verify if the server is running + boolean started = ((Boolean) this.server.getClass().getMethod( + "isStarted", null).invoke(this.server, null)).booleanValue(); + + // Stop and destroy the Jetty server, if started + if (started) + { + // Stop all listener and contexts + this.server.getClass().getMethod("stop", null).invoke( + this.server, null); + + // Destroy a stopped server. Remove all components and send + // notifications to all event listeners. + //this.server.getClass().getMethod("destroy", null).invoke( + // this.server, null); + } + } + + this.isRunning = false; + } + + /** + * Sets the configuration file to use for initializing Jetty. + * + * @param theConfigFile The configuration file to set + */ + public final void setConfigFile(File theConfigFile) + { + this.configFile = theConfigFile; + } + + /** + * Sets the directory in which Jetty will look for the web-application + * resources. + * + * @param theResourceDir The resource directory to set + */ + public final void setResourceDir(File theResourceDir) + { + this.resourceDir = theResourceDir; + } + + /** + * @param isForcedShutdown if true the container will be stopped even + * if it has not been started by us + */ + public final void setForceShutdown(boolean isForcedShutdown) + { + this.forceShutdown = isForcedShutdown; + } + + /** + * @return The resource directory, or <code>null</code> if it has not been + * set + */ + protected final File getConfigFile() + { + if (this.configFile == null) + { + String configFileProperty = System.getProperty( + CACTUS_JETTY_CONFIG_PROPERTY); + if (configFileProperty != null) + { + this.configFile = new File(configFileProperty); + } + } + return this.configFile; + } + + /** + * @return The resource directory, or <code>null</code> if it has not been + * set + */ + protected final File getResourceDir() + { + if (this.resourceDir == null) + { + String resourceDirProperty = System.getProperty( + CACTUS_JETTY_RESOURCE_DIR_PROPERTY); + if (resourceDirProperty != null) + { + this.resourceDir = new File(resourceDirProperty); + } + } + return this.resourceDir; + } + + /** + * Create a Jetty server object and configures a listener on the + * port defined in the Cactus context URL property. + * + * @param theConfiguration the base Cactus configuration + * @return the Jetty <code>Server</code> object + * + * @exception Exception if an error happens during initialization + */ + private Object createServer(Configuration theConfiguration) + throws Exception + { + // Create Jetty Server object + Class serverClass = ClassLoaderUtils.loadClass( + "org.mortbay.jetty.Server", this.getClass()); + Object server = serverClass.newInstance(); + + URL contextURL = new URL(theConfiguration.getContextURL()); + Connector connector = new SelectChannelConnector(); + connector.setPort(contextURL.getPort()); + connector.setHost(contextURL.getHost()); + // Add a listener on the port defined in the Cactus configuration + server.getClass().getMethod("addConnector", + new Class[] {org.mortbay.jetty.Connector.class}) + .invoke(server, new Object[] {connector}); + return server; + } + + /** + * Create a Jetty Context. We use a <code>WebApplicationContext</code> + * because we need to use Servlet Filters. + * + * @param theServer the Jetty Server object + * @param theConfiguration the base Cactus configuration + * @return Object the <code>WebApplicationContext</code> object + * + * @exception Exception if an error happens during initialization + */ + private Object createContext(Object theServer, + Configuration theConfiguration) throws Exception + { + // Add a web application. This creates a WebApplicationContext. + // Note: We do not put any WEB-INF/, lib/ nor classes/ directory + // in the webapp. + URL contextURL = new URL(theConfiguration.getContextURL()); + //System.out.println(theServer); + Server server = (Server) theServer; + + Context context = null; + HandlerCollection rootHandler = (HandlerCollection)server.getHandler(); + if(rootHandler != null) { + ContextHandlerCollection contesti = (ContextHandlerCollection)rootHandler.getChildHandlerByClass(ContextHandlerCollection.class); + context = new Context(contesti, contextURL.getPath()); + } else { + context = new Context(server,contextURL.getPath(),Context.SESSIONS); + } + + org.mortbay.jetty.webapp.WebAppContext c = new WebAppContext(); + + c.getServletHandler(); + + + + + + + // First you have to create a Context for the servlet and add this to the parent. + + + //!!!!!!!!!!!!!!!!!!!!!!!!! + + //ServletHolder[] s = context.getServletHandler().newServletHolder(ServletTestRedirector.class).setForcedPath(forcedPath) + //ServletHolder h = new ServletHolder(); + //h.setClassName(className); + //h.setName(name); + //h.setInitParameter(param, value); + + //!!!!!!!!!!!!!!!!!!!!!!!!! bis hier + + // Needed to allow servlets to find classes, also needed for beanshell + context.setClassLoader(getClass().getClassLoader()); + + + + return context; + } + + /** + * Adds the Cactus Servlet redirector configuration. + * + * @param theContext the Jetty context under which to add the configuration + * @param theConfiguration the Cactus Servlet configuration + * + * @exception Exception if an error happens during initialization + */ + private void addServletRedirector(Object theContext, + ServletConfiguration theConfiguration) throws Exception + { + Context context = (Context) theContext; + context.addServlet(ServletTestRedirector.class.getName(), "/" + theConfiguration.getDefaultRedirectorName()); + + + /* + theContext.getClass().getMethod("addServlet", + new Class[] {String.class, String.class, String.class}) + .invoke(theContext, + new Object[] {theConfiguration.getDefaultRedirectorName(), + "/" + theConfiguration.getDefaultRedirectorName(), + ServletTestRedirector.class.getName()}); + */ + } + + /** + * Adds the Cactus Jsp redirector configuration. We only add it if the + * CACTUS_JETTY_RESOURCE_DIR_PROPERTY has been provided by the user. This + * is because JSPs need to be attached to a WebApplicationHandler in Jetty. + * + * @param theContext the Jetty context under which to add the configuration + * + * @exception Exception if an error happens during initialization + */ + private void addJspRedirector(Object theContext) throws Exception + { + + if (getResourceDir() != null) + { + theContext.getClass().getMethod("addServlet", + new Class[] {String.class, String.class}) + .invoke(theContext, + new Object[] {org.apache.jasper.servlet.JspServlet.class.getName(),"*.jsp"}); + + // Get the WebApplicationHandler object in order to be able to + // call the addServlet() method that accepts a forced path. + + /* + Object handler = theContext.getClass().getMethod( + "getWebApplicationHandler", + new Class[] {}).invoke(theContext, new Object[] {}); + */ + + /* + handler.getClass().getMethod("addServlet", + new Class[] {String.class, String.class, String.class, + String.class}) + .invoke(handler, + new Object[] { + "JspRedirector", + "/JspRedirector", + "org.apache.jasper.servlet.JspServlet", + "/jspRedirector.jsp"}); + + */ + Context context = (Context) theContext; + context.getServletHandler().addServletWithMapping("org.apache.jasper.servlet.JspServlet", "/jspRedirector.jsp"); + } + } + + /** + * Adds the Cactus Filter redirector configuration. We only add it if the + * CACTUS_JETTY_RESOURCE_DIR_PROPERTY has been provided by the user. This + * is because Filters need to be attached to a WebApplicationHandler in + * Jetty. + * + * @param theContext the Jetty context under which to add the configuration + * @param theConfiguration the Cactus Filter configuration + * + * @exception Exception if an error happens during initialization + */ + private void addFilterRedirector(Object theContext, + FilterConfiguration theConfiguration) throws Exception + { + if (getResourceDir() != null) + { + + theContext.getClass().getMethod("addFilter", + new Class[] {String.class, String.class, Integer.TYPE}) + .invoke(theContext, + new Object[] {org.apache.cactus.server.FilterTestRedirector.class.getName(),theConfiguration.getDefaultRedirectorName(), new Integer(0)}); + + // Get the WebApplicationHandler object in order to be able to add + // the Cactus Filter redirector + + /* + Object handler = theContext.getClass().getMethod( + "getWebApplicationHandler", + new Class[] {}).invoke(theContext, new Object[] {}); + + Object filterHolder = handler.getClass().getMethod("defineFilter", + new Class[] {String.class, String.class}) + .invoke(handler, + new Object[] {theConfiguration.getDefaultRedirectorName(), + FilterTestRedirector.class.getName()}); + */ + + // filterHolder.getClass().getMethod("addAppliesTo", + // new Class[] {String.class}) + // .invoke(filterHolder, new Object[] {"REQUEST"}); + + + // Map the Cactus Filter redirector to a path + + /* + handler.getClass().getMethod("addFilterPathMapping", + new Class[] {String.class, String.class, Integer.TYPE}) + .invoke(handler, + new Object[] {"/" + + theConfiguration.getDefaultRedirectorName(), + theConfiguration.getDefaultRedirectorName(), new Integer(0)}); + + */ + } + } + + /** + * Tests whether we are able to connect to the HTTP server identified by the + * specified URL. + * + * @param theUrl The URL to check + * @return the HTTP response code or -1 if no connection could be + * established + */ + protected int testConnectivity(URL theUrl) + { + int code; + try + { + HttpURLConnection connection = + (HttpURLConnection) theUrl.openConnection(); + connection.setRequestProperty("Connection", "close"); + connection.connect(); + readFully(connection); + connection.disconnect(); + code = connection.getResponseCode(); + } + catch (IOException e) + { + code = -1; + } + return code; + } + + /** + * Tests whether an HTTP return code corresponds to a valid connection + * to the test URL or not. Success is 200 up to but excluding 300. + * + * @param theCode the HTTP response code to verify + * @return <code>true</code> if the test URL could be called without error, + * <code>false</code> otherwise + */ + protected boolean isAvailable(int theCode) + { + boolean result; + if ((theCode != -1) && (theCode < 300 || theCode == 404)) + { + result = true; + } + else + { + result = false; + } + return result; + } + + /** + * Fully reads the input stream from the passed HTTP URL connection to + * prevent (harmless) server-side exception. + * + * @param theConnection the HTTP URL connection to read from + * @exception IOException if an error happens during the read + */ + protected void readFully(HttpURLConnection theConnection) + throws IOException + { + // Only read if there is data to read ... The problem is that not + // all servers return a content-length header. If there is no header + // getContentLength() returns -1. It seems to work and it seems + // that all servers that return no content-length header also do + // not block on read() operations! + if (theConnection.getContentLength() != 0) + { + byte[] buf = new byte[256]; + InputStream in = null; + try { + in = theConnection.getInputStream(); + } catch (FileNotFoundException fex) { + //JAVA BUG #4160499 + return; + } + while (in.read(buf) != -1) + { + // Make sure we read all the data in the stream + } + } + } + + /** + * @return true if the server is running or false otherwise + */ + protected boolean isRunning() + { + return this.isRunning; + } +} Propchange: jakarta/cactus/trunk/framework/framework-13-14/src/main/java/org/apache/cactus/extension/jetty/Jetty6xTestSetup.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]