org.onebusaway.quickstart.bootstrap.WebappBootstrapMain.java Source code

Java tutorial

Introduction

Here is the source code for org.onebusaway.quickstart.bootstrap.WebappBootstrapMain.java

Source

/**
 * Copyright (C) 2011 Brian Ferris (bdferris@google.com)
 *
 * 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.onebusaway.quickstart.bootstrap;

import java.io.IOException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Parser;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.WebAppContext;
import org.onebusaway.quickstart.BootstrapCommon;
import org.onebusaway.quickstart.WebappCommon;

/**
 * Boostrap a Jetty webapp container for running an instance of OneBusAway.
 * 
 * @author bdferris
 * 
 */
public class WebappBootstrapMain {

    private static final String ARG_PORT = "port";

    public static void run(URL warUrl, boolean consoleMode, String[] args) throws Exception {

        if (args.length == 0 || isHelp(args)) {
            BootstrapCommon.printUsage(WebappBootstrapMain.class, "usage-webapp.txt");
            System.exit(-1);
        }

        Options options = createOptions();
        Parser parser = new GnuParser();

        CommandLine cli = parser.parse(options, args);
        args = cli.getArgs();

        if (args.length != 1) {
            BootstrapCommon.printUsage(WebappBootstrapMain.class, "usage-webapp.txt");
            System.exit(-1);
        }

        String bundlePath = args[0];
        System.setProperty("bundlePath", bundlePath);

        int port = 8080;
        if (cli.hasOption(ARG_PORT))
            port = Integer.parseInt(cli.getOptionValue(ARG_PORT));

        Server server = new Server();
        SocketConnector connector = new SocketConnector();

        // Set some timeout options to make debugging easier.
        connector.setMaxIdleTime(1000 * 60 * 60);
        connector.setSoLingerTime(-1);
        connector.setPort(port);
        server.setConnectors(new Connector[] { connector });

        WebAppContext context = new WebAppContext();
        context.setContextPath("/");
        // context.setWelcomeFiles(new String[] {"index.action"});
        context.setWar(warUrl.toExternalForm());
        // We store the command line object as a webapp context attribute so it can
        // be used by the context loader to inject additional beans as needed
        context.setAttribute(WebappCommon.COMMAND_LINE_CONTEXT_ATTRIBUTE, cli);

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { new WelcomeFileHandler(context), context });

        server.setHandler(handlers);

        /**
         * We specify a Jetty override descriptor to inject additional definitions
         * into our web.xml configuration. Specifically, we specify a
         * <context-param> to specify the "contextClass" that will be used to create
         * our Spring ApplicationContext. We create a custom version that will
         * inject additional beans based on command-line arguments.
         */
        context.addOverrideDescriptor("/WEB-INF/override-web.xml");

        if (cli.hasOption(WebappCommon.ARG_BUILD)) {
            System.setProperty("hibernate.hbm2ddl.auto", "update");
            System.setProperty("bundleCacheDir", bundlePath + "/cache");
            System.setProperty("gtfsPath", cli.getOptionValue(WebappCommon.ARG_GTFS_PATH));
            context.addOverrideDescriptor("/WEB-INF/builder-override-web.xml");
        }

        try {
            server.start();

            System.err.println("=============================================================");
            System.err.println("=");
            System.err.println("= Your OneBusAway instance has started.  Browse to:");
            System.err.println("=");
            System.err.println("= http://localhost:8080/");
            System.err.println("=");
            System.err.println("= to see your instance in action.");
            if (consoleMode) {
                System.err.println("=");
                System.err.println("= When you are finished, press return to exit gracefully...");
            }
            System.err.println("=============================================================");

            if (consoleMode) {
                System.in.read();
                server.stop();
                server.join();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(100);
        }
    }

    private static boolean isHelp(String[] options) {
        for (String option : options) {
            option = option.replaceAll("-", "");
            option = option.toLowerCase();
            if (option.equals("help") || option.equals("h") || option.equals("?"))
                return true;
        }
        return false;
    }

    private static Options createOptions() {
        Options options = new Options();
        options.addOption(ARG_PORT, true, "port (default=8080)");
        options.addOption(WebappCommon.ARG_BUILD, false, "");
        options.addOption(WebappCommon.ARG_GTFS_PATH, true, "");
        options.addOption(WebappCommon.ARG_GTFS_REALTIME_TRIP_UPDATES_URL, true, "");
        options.addOption(WebappCommon.ARG_GTFS_REALTIME_VEHICLE_POSITIONS_URL, true, "");
        options.addOption(WebappCommon.ARG_GTFS_REALTIME_ALERTS_URL, true, "");
        options.addOption(WebappCommon.ARG_GTFS_REALTIME_REFRESH_INTERVAL, true, "");

        Option pOption = new Option("P", "use value for given property");
        pOption.setArgName("beanName.beanProperty=value");
        pOption.setArgs(2);
        pOption.setValueSeparator('=');
        options.addOption(pOption);

        return options;
    }

    private static class WelcomeFileHandler extends AbstractHandler {

        private final WebAppContext _context;

        public WelcomeFileHandler(WebAppContext context) {
            _context = context;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request,
                HttpServletResponse response) throws IOException, ServletException {

            String[] welcomeFiles = _context.getWelcomeFiles();

            if (welcomeFiles != null && target.endsWith("/")) {
                for (String welcomeFile : welcomeFiles) {
                    String path = target;
                    path += welcomeFile;
                    Context context = _context.getServletContext();
                    URL resource = context.getResource(path);
                    if (resource != null) {
                        target = path;
                        baseRequest.setPathInfo(target);
                        _context.handle(target, baseRequest, request, response);
                        return;
                    }
                }
            }
        }
    }
}