/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.jackrabbit.standalone; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.chain.Context; import org.apache.commons.chain.impl.ContextBase; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.io.IOUtils; import org.apache.jackrabbit.commons.JcrUtils; import org.apache.jackrabbit.core.RepositoryCopier; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.servlet.jackrabbit.JackrabbitRepositoryServlet; import org.apache.jackrabbit.standalone.cli.CommandException; import org.apache.jackrabbit.standalone.cli.CommandHelper; import org.apache.jackrabbit.standalone.cli.JcrClient; import org.mortbay.jetty.Connector; import org.mortbay.jetty.NCSARequestLog; import org.mortbay.jetty.Server; import org.mortbay.jetty.bio.SocketConnector; import org.mortbay.jetty.handler.RequestLogHandler; import org.mortbay.jetty.servlet.ServletHolder; import org.mortbay.jetty.webapp.WebAppContext; /** * */ public class Main { /** * @param args */ public static void main(String[] args) throws Exception { new Main(args).run(); } private final Options options = new Options(); private final CommandLine command; private final RequestLogHandler accessLog = new RequestLogHandler(); private final WebAppContext webapp = new WebAppContext(); private final Connector connector = new SocketConnector(); private final Server server = new Server(); private Main(String[] args) throws ParseException { options.addOption("?", "help", false, "print this message"); options.addOption("n", "notice", false, "print copyright notices"); options.addOption("l", "license", false, "print license information"); options.addOption( "b", "backup", false, "create a backup of the repository"); options.addOption( "i", "cli", true, "command line access to a remote repository"); options.addOption("q", "quiet", false, "disable console output"); options.addOption("d", "debug", false, "enable debug logging"); options.addOption("h", "host", true, "IP address of the HTTP server"); options.addOption("p", "port", true, "TCP port of the HTTP server (8080)"); options.addOption("f", "file", true, "location of this jar file"); options.addOption("r", "repo", true, "repository directory (jackrabbit)"); options.addOption("c", "conf", true, "repository configuration file"); options.addOption( "R", "backup-repo", true, "backup repository directory (jackrabbit-backupN)"); options.addOption( "C", "backup-conf", true, "backup repository configuration file"); command = new GnuParser().parse(options, args); } public void run() throws Exception { String defaultFile = "jackrabbit-standalone.jar"; URL location = Main.class.getProtectionDomain().getCodeSource().getLocation(); if (location != null && "file".equals(location.getProtocol())) { File file = new File(location.getPath()); if (file.isFile()) { defaultFile = location.getPath(); } } File file = new File(command.getOptionValue("file", defaultFile)); if (command.hasOption("help")) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("java -jar " + file.getName(), options, true); } else if (command.hasOption("notice")) { copyToOutput("/META-INF/NOTICE.txt"); } else if (command.hasOption("license")) { copyToOutput("/META-INF/LICENSE.txt"); } else if (command.hasOption("cli")) { System.setProperty("logback.configurationFile", "logback-cli.xml"); String uri = command.getOptionValue("cli"); Repository repository = JcrUtils.getRepository(uri); Context context = new ContextBase(); CommandHelper.setRepository(context, repository, uri); try { Session session = repository.login(); CommandHelper.setSession(context, session); CommandHelper.setCurrentNode(context, session.getRootNode()); } catch (RepositoryException ignore) { // anonymous login not possible } new JcrClient(context).runInteractive(); try { CommandHelper.getSession(context).logout(); } catch (CommandException ignore) { // already logged out } } else { message("Welcome to Apache Jackrabbit!"); message("-------------------------------"); File repository = new File(command.getOptionValue("repo", "jackrabbit")); message("Using repository directory " + repository); repository.mkdirs(); File tmp = new File(repository, "tmp"); tmp.mkdir(); File log = new File(repository, "log"); log.mkdir(); message("Writing log messages to " + log); prepareServerLog(log); if (command.hasOption("backup")) { backup(repository); } else { message("Starting the server..."); prepareWebapp(file, repository, tmp); accessLog.setHandler(webapp); prepareAccessLog(log); server.setHandler(accessLog); prepareConnector(); server.addConnector(connector); prepareShutdown(); try { server.start(); String host = connector.getHost(); if (host == null) { host = "localhost"; } message("Apache Jackrabbit is now running at " +"http://" + host + ":" + connector.getPort() + "/"); } catch (Throwable t) { System.err.println( "Unable to start the server: " + t.getMessage()); System.exit(1); } } } } private void backup(File sourceDir) throws Exception { RepositoryConfig source; if (command.hasOption("conf")) { source = RepositoryConfig.create( new File(command.getOptionValue("conf")), sourceDir); } else { source = RepositoryConfig.create(sourceDir); } File targetDir; if (command.hasOption("backup-repo")) { targetDir = new File(command.getOptionValue("backup-repo")); } else { int i = 1; do { targetDir = new File("jackrabbit-backup" + i++); } while (targetDir.exists()); } RepositoryConfig target; if (command.hasOption("backup-conf")) { target = RepositoryConfig.install( new File(command.getOptionValue("backup-conf")), targetDir); } else { target = RepositoryConfig.install(targetDir); } message("Creating a repository copy in " + targetDir); RepositoryCopier.copy(source, target); message("The repository has been successfully copied."); } private void prepareServerLog(File log) throws IOException { System.setProperty( "jackrabbit.log", new File(log, "jackrabbit.log").getPath()); System.setProperty( "jetty.log", new File(log, "jetty.log").getPath()); if (command.hasOption("debug")) { System.setProperty("log.level", "DEBUG"); } else { System.setProperty("log.level", "INFO"); } System.setProperty( "derby.stream.error.file", new File(log, "derby.log").getPath()); } private void prepareAccessLog(File log) { NCSARequestLog ncsa = new NCSARequestLog( new File(log, "access.log.yyyy_mm_dd").getPath()); ncsa.setFilenameDateFormat("yyyy-MM-dd"); accessLog.setRequestLog(ncsa); } private void prepareWebapp(File file, File repository, File tmp) { webapp.setContextPath("/"); webapp.setWar(file.getPath()); webapp.setExtractWAR(false); webapp.setTempDirectory(tmp); ServletHolder servlet = new ServletHolder(JackrabbitRepositoryServlet.class); servlet.setInitOrder(1); servlet.setInitParameter("repository.home", repository.getPath()); String conf = command.getOptionValue("conf"); if (conf != null) { servlet.setInitParameter("repository.config", conf); } webapp.addServlet(servlet, "/repository.properties"); } private void prepareConnector() { String port = command.getOptionValue("port", "8080"); connector.setPort(Integer.parseInt(port)); String host = command.getOptionValue("host"); if (host != null) { connector.setHost(host); } } private void prepareShutdown() { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { message("Shutting down the server..."); server.stop(); server.join(); message("-------------------------------"); message("Goodbye from Apache Jackrabbit!"); } catch (Exception e) { e.printStackTrace(); } } }); } private void message(String message) { if (!command.hasOption("quiet")) { System.out.println(message); } } private void copyToOutput(String resource) throws IOException { InputStream stream = Main.class.getResourceAsStream(resource); try { IOUtils.copy(stream, System.out); } finally { stream.close(); } } }