Package org.persvr.util

Source Code of org.persvr.util.JettyStart$InheritingFileResource

package org.persvr.util;

import java.io.*;
import java.lang.management.ManagementFactory;
import java.net.*;
import java.util.*;
import org.apache.commons.cli.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.resource.FileResource;
import org.mortbay.resource.Resource;
import org.mortbay.util.URIUtil;
import org.mortbay.xml.XmlConfiguration;

public class JettyStart {

  static private Log log = LogFactory.getLog(JettyStart.class);
  static Timer timer;
  // options
  public static final String VERSION = "v";
  public static final String HELP = "h";
  public static final String INSTANCE_ROOT = "r";
  public static final String DB_PATH = "d";
  public static final String PORT = "p";
  public static final String CORE_TESTS = "core-tests";
  public static final String BASE_URI = "base-uri";
  public static final String INSTANCE_TESTS = "tests";
  public static final String GEN_SERVER = "gen-server";
  public static final String ERASE_DB = "eraseDB";
  public static final String START = "start";
  public static final String STOP = "stop";

  /* ------------------------------------------------------------ */
  /* ------------------------------------------------------------ */
  /**
   * Construct server from command line arguments.
   *
   * @param args
   */
  @SuppressWarnings( { "finally", "static-access" })
  public static void main(String[] args) throws IOException {
    Options options = generateCliOptions();
    boolean runTests = false;

    CommandLineParser parser = new PosixParser();
    CommandLine commandLine;
    try {
      commandLine = parser.parse(options, args);
    } catch (Exception e) {
      log.warn("Unable to parse command line options: " + e.getMessage());
      showHelp(options);
      return;
    }

    if (commandLine.hasOption(HELP)) {
      showHelp(options);
      return;
    }

    if (commandLine.hasOption(VERSION)) {
      Properties props = new Properties();
      try {
        props.load(JettyStart.class.getResourceAsStream("/org/persvr/persevere.properties"));
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      log.info("Persevere, v" + props.getProperty("version"));
      return;
    }

    int listenPort = Integer.parseInt(commandLine.getOptionValue(PORT, "8080"));
    System.setProperty("persevere.port", Integer.toString(listenPort));
    // we expect these to have been defined by the shell script
    String localPath = System.getProperty("persevere.instance", ".");
    String persvrHome = System.getProperty("persevere.home", ".");
    System.setProperty("persevere.home", persvrHome); //make it available to the PersevereFilter
    if (commandLine.hasOption(GEN_SERVER)) {
      InstanceGenerator.createNewInstance(localPath, commandLine.getOptionValue(GEN_SERVER));
      return;
    }

    String instancePath = ".";
    if (commandLine.hasOption(CORE_TESTS)) {
      instancePath = persvrHome + File.separator + "core-tests";
      System.setProperty("persevere.tests", instancePath + "/WEB-INF/tests");
      runTests = true;
    } else {
      if (commandLine.hasOption(INSTANCE_ROOT))
        instancePath = commandLine.getOptionValue(INSTANCE_ROOT);
      else {
        // our instance path should otherwise be the path the persvr script was invoked from
        instancePath = localPath;
        if (!(new File(instancePath + "/WEB-INF").exists()) && new File(instancePath + "/persvr").exists() &&
            new File(instancePath + "/../WEB-INF").exists()){
          // go to the parent directory if we are in the bin directory
          instancePath += "/..";
        }
      }
    }

    if (commandLine.hasOption(INSTANCE_TESTS)) {
      System.setProperty("persevere.tests", instancePath + "/WEB-INF/tests");
      runTests = true;
    }

    if (commandLine.hasOption(ERASE_DB)) {
      InstanceGenerator.eraseDatabase(instancePath);
      return;
    }
    String webInf = instancePath + "/WEB-INF";
    if (commandLine.hasOption(START)) {
      final File processFile = new File(webInf + "/process");
      String processName = ManagementFactory.getRuntimeMXBean().getName();
      processName = processName.replaceAll("@.*", "");
      FileOutputStream fos = new FileOutputStream(processFile);
      fos.write(processName.getBytes());
      fos.close();
      timer = new Timer("Process file removal monitor", true);
      timer.schedule(new TimerTask(){
        @Override
        public void run() {
          if(!processFile.exists()) // shutdown if the process file doesn't exist anymore
            System.exit(0);
        }
       
      }, 100, 100);
    }
    if (commandLine.hasOption(STOP)) {
      File processFile = new File(webInf + "/process");
      if(processFile.exists())
        processFile.delete();
      else
        throw new RuntimeException("No Persevere process was found");
      return;
    }
    String baseURI = commandLine.getOptionValue(BASE_URI, "/");
    System.setProperty("persevere.base-uri", baseURI);
    String database = commandLine.getOptionValue(DB_PATH, instancePath + "/WEB-INF/" + ((runTests) ? "tests/data" : "data"));
    // System.out.println( "Database " + database );
    System.setProperty("persevere.instance.data", database);
    System.setProperty("persevere.instance.WEB-INF", webInf);
    startJetty(persvrHome, instancePath, listenPort, baseURI);
  }

  static public Options generateCliOptions() {
    Options options = new Options();
    options.addOption(VERSION, "version", false, "Print Persevere's version and quit.");
    options.addOption(HELP, "help", false, "Display this message and quit.");
    options.addOption(OptionBuilder.withLongOpt("port").hasArg().withArgName("port_number").withDescription(
        "Listen on this port for connections.").create(PORT));
    options.addOption(OptionBuilder.withLongOpt("database").hasArg().withArgName("/path/to/db").withDescription("Use the database at this path.")
        .create(DB_PATH));
    options.addOption(OptionBuilder.withLongOpt("root").hasArg().withArgName("/path/to/instance").withDescription(
        "Start up the instance at this path.").create(INSTANCE_ROOT));
    options.addOption(OptionBuilder.withLongOpt(GEN_SERVER).hasArg().withArgName("name").withDescription("Generate a new server instance.")
        .create());
    options.addOption(OptionBuilder.withLongOpt(CORE_TESTS).withDescription("Run Persevere's internal test suite.").create());
    options.addOption(OptionBuilder.withLongOpt(INSTANCE_TESTS).withDescription("Run tests for your instance.").create());
    options.addOption(OptionBuilder.withLongOpt(ERASE_DB).withDescription("Clear out your entire database.").create());
    options.addOption(OptionBuilder.withLongOpt(START).withDescription("Start an instance of Persevere that can be stopped").create());
    options.addOption(OptionBuilder.withLongOpt(STOP).withDescription("Stop the instance of Persevere running at this path").create());
    options.addOption(OptionBuilder.withLongOpt(BASE_URI).hasArg().withArgName("/path").withDescription("Specify the base URI for persevere.")
        .create());
    return options;
  }

  /*
   * Try to load a jetty.xml from the instance's WEB-INF/config dir. If it's
   * not there, fall back to the default version in the core installation.
   */
  static public void startJetty(String persvrHome, String instancePath, int port, String baseURI) {
    try {
      Server server = new Server();

      String sep = File.separator;
      File configFile = new File(instancePath + sep + "WEB-INF" + sep + "config" + sep + "jetty.xml");
      if (!configFile.exists()) {
        configFile = new File(persvrHome + sep + "etc" + sep + "jetty.xml");
        if (!configFile.exists())
          throw new RuntimeException("Couldn't find a valid jetty.xml config in your instance, or in the Persevere installation.");
      }

      XmlConfiguration xmlconfig = new XmlConfiguration(new FileInputStream(configFile));
      Map props = xmlconfig.getProperties();
      props.put("port", port);
      xmlconfig.configure(server);

      WebAppContext webapp = new WebAppContext();
      webapp.setResourceBase(instancePath);

      Resource resource = InheritingFileResource.newResource(instancePath, persvrHome);
      webapp.setBaseResource(resource);
      webapp.setAttribute("persevere.resource", resource);
      webapp.setContextPath(baseURI);
      webapp.setDefaultsDescriptor(persvrHome + sep + "etc" + sep + "webdefault.xml");

      ContextHandlerCollection contexts = new ContextHandlerCollection();
      server.setHandler(contexts);
      contexts.addHandler(webapp);

      server.start();
      String testsDirectory = System.getProperty("persevere.tests");
      if (testsDirectory != null) {
        ((Runnable) webapp.getServletContext().getAttribute("testrunner")).run();
      }
    } catch (Exception e) {
      log.warn(e);
    }
  }

  static public void showHelp(Options opts) {
    HelpFormatter formatter = new HelpFormatter();
    formatter.printHelp("persvr [options]", "\nOptions:", opts, "\n");
  }

  static class InheritingFileResource extends FileResource {
    FileResource baseFileResource;

    private static URL pathToUrl(String path) throws IOException {
      File file = new File(path).getCanonicalFile();
      URL url = file.toURI().toURL();
      return url;
    }

    public static Resource newResource(String instance, String base) throws IOException, URISyntaxException {
      URL instanceURL = pathToUrl(instance);
      URL baseURL = pathToUrl(base);
      Resource instanceFileResource = new FileResource(instanceURL);
      if (baseURL.equals(instanceURL))
        return new FileResource(instanceURL);
      Resource baseFileResource = new FileResource(pathToUrl(base));
      return new InheritingFileResource(instanceFileResource, baseFileResource);
    }

    public InheritingFileResource(Resource instance, Resource base) throws IOException, URISyntaxException {
      super(instance.getURL());
      baseFileResource = (FileResource) base;
    }

    @Override
    public Resource addPath(String path) throws IOException, MalformedURLException {
      Resource resource = super.addPath(path);
      if (resource == null || !resource.exists())
        resource = baseFileResource.addPath(path);
      else if (resource.isDirectory()) {
        Resource baseResource = baseFileResource.addPath(path);
        if (baseResource.isDirectory()) {
          try {
            return new InheritingFileResource(resource, baseResource);
          } catch (URISyntaxException e) {
            throw new RuntimeException(e);
          }
        }

      }
      return resource;
    }

    @Override
    public String[] list() {
      String[] instanceList = super.list();
      String[] baseList = baseFileResource.list();
      if (instanceList == null)
        return baseList;
      if (baseList == null)
        return instanceList;
      Set<String> set = new HashSet<String>(Arrays.asList(instanceList));
      set.addAll(Arrays.asList(baseList));
      return set.toArray(new String[set.size()]);
    }

    public File getFile() {
      File file = super.getFile();
      if (file.exists())
        return file;
      return baseFileResource.getFile();
    }

    @Override
    public long lastModified() {
      return getFile().lastModified();
    }

    @Override
    public boolean exists() {
      return getFile().exists();
    }

    @Override
    public InputStream getInputStream() throws IOException {
      return new FileInputStream(getFile());
    }

    @Override
    public String getName() {
      return getFile().getAbsolutePath();

    }

    @Override
    public OutputStream getOutputStream() throws IOException, SecurityException {
      return new FileOutputStream(getFile());
    }

    @Override
    public boolean isDirectory() {
      return getFile().isDirectory();
    }

    @Override
    public long length() {
      return getFile().length();
    }

    @Override
    public boolean renameTo(Resource dest) throws SecurityException {
      if (dest instanceof FileResource)
        return getFile().renameTo(((FileResource) dest).getFile());
      else
        return false;
    }

  }
}
TOP

Related Classes of org.persvr.util.JettyStart$InheritingFileResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.