001    // Copyright 2006 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.tapestry.integration;
016    
017    import static java.lang.String.format;
018    
019    import java.io.File;
020    
021    import org.mortbay.http.NCSARequestLog;
022    import org.mortbay.http.SocketListener;
023    import org.mortbay.jetty.Server;
024    import org.mortbay.jetty.servlet.WebApplicationContext;
025    
026    /**
027     * 
028     */
029    public class JettyRunner
030    {
031        public static final String DEFAULT_CONTEXT_PATH = "/";
032    
033        public static final int DEFAULT_PORT = 80;
034    
035        private static final String DEFAULTS_DESCRIPTOR = "src/test-data/conf/webdefault.xml";
036        
037        private final String _contextPath;
038    
039        private final int _port;
040    
041        private String _warPath;
042    
043        private final Server _jetty;
044        
045        public static void main(String[] args)
046        {
047            new JettyRunner("src/test-data/app1");
048        }
049    
050        /** Defaults the context path to "/" and the port to 80. */
051        public JettyRunner(String warPath)
052        {
053            this(DEFAULT_CONTEXT_PATH, DEFAULT_PORT, warPath);
054        }
055    
056        /**
057         * Creates and starts a new instance of Jetty. This should be done from a test case setup
058         * method.
059         * 
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         */
067        public JettyRunner(String contextPath, int port, String warPath)
068        {
069            _contextPath = contextPath;
070            _port = port;
071            _warPath = warPath;
072            
073            _jetty = createAndStart();
074        }
075    
076        /** Stops the Jetty instance. This should be called from a test case tear down method. */
077        public void stop()
078        {
079            try
080            {
081                _jetty.stop();
082            }
083            catch (Exception ex)
084            {
085                throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
086            }
087        }
088    
089        @Override
090        public String toString()
091        {
092            return format("<JettyRunner %s:%d (%s)>", _contextPath, _port, _warPath);
093        }
094    
095        private Server createAndStart()
096        {
097            try
098            {
099                Server server = new Server();
100    
101                SocketListener socketListener = new SocketListener();
102                socketListener.setPort(_port);
103                server.addListener(socketListener);
104                
105                NCSARequestLog log = new NCSARequestLog();
106                server.setRequestLog(log);
107                
108                File warPath = new File(_warPath);
109                if (!warPath.exists()) {
110                    _warPath = new File("tapestry-framework", _warPath).getPath();
111                }
112                
113                WebApplicationContext context = server.addWebApplication(_contextPath, _warPath);
114                
115                File descPath = new File(DEFAULTS_DESCRIPTOR);
116                String descriptorPath = descPath.getPath();
117                
118                if (!descPath.exists()) {
119                    descriptorPath = new File("tapestry-framework", DEFAULTS_DESCRIPTOR).getPath();
120                }
121                
122                context.setDefaultsDescriptor(descriptorPath);
123    
124                server.start();
125    
126                return server;
127            }
128            catch (Exception ex)
129            {
130                throw new RuntimeException("Failure starting Jetty instance: " + ex.toString(), ex);
131            }
132        }
133    }