001    // Copyright 2009, 2010, 2011 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 java.io.File;
018    
019    import org.eclipse.jetty.server.Server;
020    import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
021    import org.eclipse.jetty.webapp.WebAppContext;
022    
023    /**
024     * Launches an instance of Jetty7.
025     */
026    public class Jetty7Runner implements ServletContainerRunner
027    {
028        private Server jettyServer;
029    
030        private String description;
031    
032        private int port;
033    
034        private int sslPort;
035    
036        public Jetty7Runner() {
037            // un-configured runner
038        }
039    
040        public Jetty7Runner(String webappFolder, String contextPath, int port, int sslPort) throws Exception {
041            configure(webappFolder, contextPath, port, sslPort).start();
042        }
043    
044        public Jetty7Runner configure(String webappFolder, String contextPath, int port, int sslPort) throws Exception
045        {
046            this.port = port;
047    
048            this.sslPort = sslPort;
049    
050            String expandedPath = expand(webappFolder);
051    
052            description = String.format("<Jetty7Runner: %s:%s/%s (%s)", contextPath, port, sslPort, expandedPath);
053    
054            jettyServer = new Server(port);
055    
056            WebAppContext webapp = new WebAppContext();
057            webapp.setContextPath(contextPath);
058            webapp.setWar(expandedPath);
059    
060            // SSL support
061            File keystoreFile = new File(TapestryTestConstants.MODULE_BASE_DIR, "src/test/conf/keystore");
062    
063            if (keystoreFile.exists())
064            {
065                SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
066    
067                sslConnector.setPort(sslPort);
068    
069                sslConnector.setKeystore(keystoreFile.getPath());
070    
071                sslConnector.setPassword("tapestry");
072    
073                sslConnector.setKeyPassword("tapestry");
074    
075                jettyServer.addConnector(sslConnector);
076            }
077    
078            jettyServer.setHandler(webapp);
079            return this;
080        }
081    
082        public void start() throws Exception {
083            jettyServer.start();
084        }
085    
086        /** Immediately shuts down the server instance. */
087        public void stop()
088        {
089            System.out.printf("Stopping Jetty instance on port %d/%d\n", port, sslPort);
090    
091            try
092            {
093                // Stop immediately and not gracefully.
094                jettyServer.stop();
095            }
096            catch (Exception ex)
097            {
098                throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
099            }
100    
101            System.out.println("Jetty instance has stopped.");
102        }
103    
104        public Server getServer()
105        {
106            return jettyServer;
107        }
108    
109        @Override
110        public String toString()
111        {
112            return description;
113        }
114    
115        /**
116         * Needed inside Maven multi-projects to expand a path relative to the module to a complete
117         * path. If the path already is absolute and points to an existing directory, it will be used
118         * unchanged.
119         *
120         * @param moduleLocalPath
121         * @return expanded path
122         * @see TapestryTestConstants#MODULE_BASE_DIR
123         */
124        protected String expand(String moduleLocalPath)
125        {
126            File path = new File(moduleLocalPath);
127    
128            // Don't expand if the path provided already exists.
129            if (path.isAbsolute() && path.isDirectory())
130                return moduleLocalPath;
131    
132            return new File(TapestryTestConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
133        }
134    }