001    // Copyright 2006, 2007, 2008 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.test;
016    
017    import org.mortbay.http.NCSARequestLog;
018    import org.mortbay.http.SocketListener;
019    import org.mortbay.http.SunJsseListener;
020    import org.mortbay.jetty.Server;
021    import org.mortbay.jetty.servlet.WebApplicationContext;
022    
023    import java.io.File;
024    import static java.lang.String.format;
025    
026    /**
027     * Used to start up an instance of the Jetty servlet container in-process, as part of an integration
028     * test suite. The
029     * started Jetty is reliant on the file <code>src/test/conf/webdefault.xml</code>.
030     * 
031     * @see AbstractIntegrationTestSuite
032     * @deprecated Use {@link Jetty7Runner} instead
033     */
034    public class JettyRunner
035    {
036        public static final String DEFAULT_CONTEXT_PATH = "/";
037    
038        public static final int DEFAULT_PORT = 8080;
039    
040        public static final int DEFAULT_SECURE_PORT = 8443;
041    
042        private final File workingDir;
043    
044        private final String contextPath;
045    
046        private final int port;
047    
048        private final String warPath;
049    
050        private final Server jetty;
051    
052        private final String[] virtualHosts;
053    
054        /**
055         * Creates and starts a new instance of Jetty. This should be done from a test case setup
056         * method.
057         * 
058         * @param workingDir
059         *            current directory (used for any relative files)
060         * @param contextPath
061         *            the context path for the deployed application
062         * @param port
063         *            the port number used to access the application
064         * @param warPath
065         *            the path to the exploded web application (typically, "src/main/webapp")
066         * @param virtualHosts
067         *            an array with virtual hosts
068         */
069        public JettyRunner(File workingDir, String contextPath, int port, String warPath,
070                String... virtualHosts)
071        {
072            this.workingDir = workingDir;
073            this.contextPath = contextPath;
074            this.port = port;
075            this.warPath = warPath;
076            this.virtualHosts = virtualHosts;
077    
078            jetty = createAndStart();
079        }
080    
081        /**
082         * Stops the Jetty instance. This should be called from a test case tear down method.
083         */
084        public void stop()
085        {
086            System.out.printf("Stopping Jetty instance on port %d\n", port);
087    
088            try
089            {
090                // Stop immediately and not gracefully.
091                jetty.stop(false);
092    
093                while (jetty.isStarted())
094                {
095                    Thread.sleep(100);
096                }
097            }
098            catch (Exception ex)
099            {
100                throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
101            }
102    
103            System.out.println("Jetty instance has stopped.");
104        }
105    
106        @Override
107        public String toString()
108        {
109            return format("<JettyRunner %s:%d (%s)>", contextPath, port, warPath);
110        }
111    
112        private Server createAndStart()
113        {
114            try
115            {
116    
117                File warPathFile = new File(warPath);
118    
119                String webappPath = warPathFile.isAbsolute() ? warPath : new File(workingDir,
120                        this.warPath).getPath();
121                String webDefaults = new File(workingDir, "src/test/conf/webdefault.xml").getPath();
122    
123                File keystoreFile = new File(workingDir, "src/test/conf/keystore");
124                String keystore = keystoreFile.getPath();
125    
126                System.out.printf("Starting Jetty instance on port %d (%s mapped to %s)\n", port,
127                        contextPath, webappPath);
128    
129                Server server = new Server();
130    
131                SocketListener socketListener = new SocketListener();
132                socketListener.setPort(port);
133                server.addListener(socketListener);
134    
135                if (keystoreFile.exists())
136                {
137                    SunJsseListener secureListener = new SunJsseListener();
138                    secureListener.setPort(DEFAULT_SECURE_PORT);
139                    secureListener.setKeystore(keystore);
140                    secureListener.setPassword("tapestry");
141                    secureListener.setKeyPassword("tapestry");
142    
143                    server.addListener(secureListener);
144                }
145    
146                NCSARequestLog log = new NCSARequestLog();
147                server.setRequestLog(log);
148    
149                WebApplicationContext context = server.addWebApplication(contextPath, webappPath);
150    
151                for (String virtualHost : virtualHosts)
152                {
153                    context.addVirtualHost(virtualHost);
154                }
155    
156                context.setDefaultsDescriptor(webDefaults);
157    
158                server.start();
159    
160                return server;
161            }
162            catch (Exception ex)
163            {
164                throw new RuntimeException("Failure starting Jetty instance: " + ex.toString(), ex);
165            }
166        }
167    }