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
015package org.apache.tapestry5.test;
016
017import java.io.File;
018
019import org.eclipse.jetty.server.Server;
020import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
021import org.eclipse.jetty.webapp.WebAppContext;
022
023/**
024 * Launches an instance of Jetty7.
025 */
026public 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}