org.apache.cocoon.Main.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.cocoon.Main.java

Source

/*
 * Copyright 1999-2004 The Apache Software Foundation.
 * 
 * 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.apache.cocoon;

import java.io.File;
import java.util.Arrays;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.cocoon.bean.CocoonBean;
import org.apache.cocoon.bean.helpers.OutputStreamListener;
import org.apache.cocoon.bean.helpers.BeanConfigurator;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.lang.BooleanUtils;

import org.w3c.dom.Document;

/**
 * Command line entry point. Parses command line, create Cocoon bean and invokes it
 * with file destination.
 *
 * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
 * @author <a href="mailto:nicolaken@apache.org">Nicola Ken Barozzi</a>
 * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
 * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
 * @version CVS $Id: Main.java 367030 2006-01-08 14:12:32Z antonio $
 */
public class Main {

    protected static final String HELP_OPT = "h";
    protected static final String VERSION_OPT = "v";
    protected static final String VERBOSE_OPT = "V";
    protected static final String LOG_KIT_OPT = "k";
    protected static final String LOGGER_OPT = "l";
    protected static final String LOG_LEVEL_OPT = "u";
    protected static final String CONTEXT_DIR_OPT = "c";
    protected static final String DEST_DIR_OPT = "d";
    protected static final String WORK_DIR_OPT = "w";
    protected static final String CONFIG_FILE_OPT = "C";
    protected static final String BROKEN_LINK_FILE_OPT = "b";
    protected static final String URI_FILE_OPT = "f";
    protected static final String XCONF_OPT = "x";
    protected static final String AGENT_OPT = "a";
    protected static final String ACCEPT_OPT = "p";
    protected static final String FOLLOW_LINKS_OPT = "r";
    protected static final String PRECOMPILE_ONLY_OPT = "P";
    protected static final String CONFIRM_EXTENSIONS_OPT = "e";
    protected static final String LOAD_CLASS_OPT = "L";
    protected static final String DEFAULT_FILENAME_OPT = "D";
    protected static final String URI_GROUP_NAME_OPT = "n";

    protected static final String HELP_LONG = "help";
    protected static final String VERSION_LONG = "version";
    protected static final String VERBOSE_LONG = "verbose";
    protected static final String LOG_KIT_LONG = "logKitconfig";
    protected static final String LOGGER_LONG = "Logger";
    protected static final String LOG_LEVEL_LONG = "logLevel";
    protected static final String CONTEXT_DIR_LONG = "contextDir";
    protected static final String DEST_DIR_LONG = "destDir";
    protected static final String WORK_DIR_LONG = "workDir";
    protected static final String CONFIG_FILE_LONG = "configFile";
    protected static final String BROKEN_LINK_FILE_LONG = "brokenLinkFile";
    protected static final String URI_FILE_LONG = "uriFile";
    protected static final String XCONF_LONG = "xconf";
    protected static final String AGENT_LONG = "userAgent";
    protected static final String ACCEPT_LONG = "accept";
    protected static final String FOLLOW_LINKS_LONG = "followLinks";
    protected static final String PRECOMPILE_ONLY_LONG = "precompileOnly";
    protected static final String CONFIRM_EXTENSIONS_LONG = "confirmExtensions";
    protected static final String LOAD_CLASS_LONG = "loadClass";
    protected static final String DEFAULT_FILENAME_LONG = "defaultFilename";
    protected static final String URI_LONG = "uri";
    protected static final String URI_GROUP_NAME_LONG = "uris";

    private static Options options;
    private static OutputStreamListener listener;

    private static void setOptions() {
        options = new Options();

        options.addOption(new Option(HELP_OPT, HELP_LONG, false, "print this message and exit"));

        options.addOption(new Option(VERSION_OPT, VERSION_LONG, false, "print the version information and exit"));

        options.addOption(new Option(VERBOSE_OPT, VERBOSE_LONG, false, "enable verbose messages to System.out"));

        options.addOption(
                new Option(LOG_KIT_OPT, LOG_KIT_LONG, true, "use given file for LogKit Management configuration"));

        options.addOption(new Option(LOGGER_OPT, LOGGER_LONG, true,
                "use given logger category as default logger for the Cocoon engine"));

        options.addOption(new Option(LOG_LEVEL_OPT, LOG_LEVEL_LONG, true,
                "choose the minimum log level for logging (DEBUG, INFO, WARN, ERROR, FATAL_ERROR) for startup logging"));

        options.addOption(new Option(CONTEXT_DIR_OPT, CONTEXT_DIR_LONG, true, "use given dir as context"));

        options.addOption(new Option(DEST_DIR_OPT, DEST_DIR_LONG, true, "use given dir as destination"));

        options.addOption(new Option(WORK_DIR_OPT, WORK_DIR_LONG, true, "use given dir as working directory"));

        options.addOption(new Option(CONFIG_FILE_OPT, CONFIG_FILE_LONG, true,
                "specify alternate location of the configuration"
                        + " file (default is ${contextDir}/cocoon.xconf)"));

        options.addOption(new Option(BROKEN_LINK_FILE_OPT, BROKEN_LINK_FILE_LONG, true,
                "send a list of broken links to a file (one URI per line)"));

        options.addOption(new Option(URI_FILE_OPT, URI_FILE_LONG, true,
                "use a text file with uris to process (one URI per line)"));

        options.addOption(new Option(XCONF_OPT, XCONF_LONG, true,
                "specify a file containing XML configuration details" + " for the command line interface"));

        options.addOption(new Option(AGENT_OPT, AGENT_LONG, true, "use given string for user-agent header"));

        options.addOption(new Option(ACCEPT_OPT, ACCEPT_LONG, true, "use given string for accept header"));

        options.addOption(new Option(FOLLOW_LINKS_OPT, FOLLOW_LINKS_LONG, true,
                "process pages linked from starting page or not"
                        + " (boolean argument is expected, default is true)"));

        options.addOption(new Option(PRECOMPILE_ONLY_OPT, PRECOMPILE_ONLY_LONG, true,
                "generate java code for xsp and xmap files"));

        options.addOption(new Option(CONFIRM_EXTENSIONS_OPT, CONFIRM_EXTENSIONS_LONG, true,
                "confirm that file extensions match mime-type of" + " pages and amend filename accordingly (default"
                        + " is true)"));

        options.addOption(new Option(LOAD_CLASS_OPT, LOAD_CLASS_LONG, true,
                "specify a class to be loaded at startup (specifically"
                        + " for use with JDBC). Can be used multiple times"));

        options.addOption(new Option(DEFAULT_FILENAME_OPT, DEFAULT_FILENAME_LONG, true,
                "specify a filename to be appended to a URI when the" + " URI refers to a directory"));
        options.addOption(new Option(URI_GROUP_NAME_OPT, URI_GROUP_NAME_LONG, true,
                "specify which <uris> element to process in the configuration"
                        + " file specified with the -x parameter"));
    }

    /**
     * The <code>main</code> method.
     *
     * @param args a <code>String[]</code> of arguments
     * @exception Exception if an error occurs
     */
    public static void main(String[] args) throws Exception {

        Main.setOptions();
        CommandLine line = new PosixParser().parse(options, args);
        listener = new OutputStreamListener(System.out);
        CocoonBean cocoon = new CocoonBean();
        cocoon.addListener(listener);

        if (line.hasOption(HELP_OPT)) {
            printUsage();
        } else if (line.hasOption(VERSION_OPT)) {
            printVersion();
        } else {
            String uriGroup = null;
            if (line.hasOption(URI_GROUP_NAME_OPT)) {
                uriGroup = line.getOptionValue(URI_GROUP_NAME_OPT);
            }

            String destDir = null;
            if (line.hasOption(XCONF_OPT)) {
                // destDir from command line overrides one in xconf file
                destDir = Main.processXConf(cocoon, line.getOptionValue(XCONF_OPT), destDir, uriGroup);
            }
            if (line.hasOption(DEST_DIR_OPT)) {
                destDir = line.getOptionValue(DEST_DIR_OPT);
            }

            if (line.hasOption(VERBOSE_OPT)) {
                cocoon.setVerbose(true);
            }
            if (line.hasOption(PRECOMPILE_ONLY_OPT)) {
                cocoon.setPrecompileOnly(true);
            }

            if (line.hasOption(WORK_DIR_OPT)) {
                String workDir = line.getOptionValue(WORK_DIR_OPT);
                if (workDir.length() == 0) {
                    listener.messageGenerated(
                            "Careful, you must specify a work dir when using the -w/--workDir argument");
                    System.exit(1);
                } else {
                    cocoon.setWorkDir(line.getOptionValue(WORK_DIR_OPT));
                }
            }
            if (line.hasOption(CONTEXT_DIR_OPT)) {
                String contextDir = line.getOptionValue(CONTEXT_DIR_OPT);
                if (contextDir.length() == 0) {
                    listener.messageGenerated(
                            "Careful, you must specify a configuration file when using the -c/--contextDir argument");
                    System.exit(1);
                } else {
                    cocoon.setContextDir(contextDir);
                }
            }
            if (line.hasOption(CONFIG_FILE_OPT)) {
                cocoon.setConfigFile(line.getOptionValue(CONFIG_FILE_OPT));
            }
            if (line.hasOption(LOG_KIT_OPT)) {
                cocoon.setLogKit(line.getOptionValue(LOG_KIT_OPT));
            }
            if (line.hasOption(LOGGER_OPT)) {
                cocoon.setLogger(line.getOptionValue(LOGGER_OPT));
            }
            if (line.hasOption(LOG_LEVEL_OPT)) {
                cocoon.setLogLevel(line.getOptionValue(LOG_LEVEL_OPT));
            }
            if (line.hasOption(AGENT_OPT)) {
                cocoon.setAgentOptions(line.getOptionValue(AGENT_OPT));
            }
            if (line.hasOption(ACCEPT_OPT)) {
                cocoon.setAcceptOptions(line.getOptionValue(ACCEPT_OPT));
            }
            if (line.hasOption(DEFAULT_FILENAME_OPT)) {
                cocoon.setDefaultFilename(line.getOptionValue(DEFAULT_FILENAME_OPT));
            }
            if (line.hasOption(BROKEN_LINK_FILE_OPT)) {
                listener.setReportFile(line.getOptionValue(BROKEN_LINK_FILE_OPT));
            }
            if (line.hasOption(FOLLOW_LINKS_OPT)) {
                cocoon.setFollowLinks(BooleanUtils.toBoolean(line.getOptionValue(FOLLOW_LINKS_OPT)));
            }
            if (line.hasOption(CONFIRM_EXTENSIONS_OPT)) {
                cocoon.setConfirmExtensions(
                        BooleanUtils.toBoolean(line.getOptionValue(CONFIRM_EXTENSIONS_OPT, "yes")));
            }
            if (line.hasOption(LOAD_CLASS_OPT)) {
                cocoon.addLoadedClasses(Arrays.asList(line.getOptionValues(LOAD_CLASS_OPT)));
            }
            if (line.hasOption(URI_FILE_OPT)) {
                cocoon.addTargets(BeanConfigurator.processURIFile(line.getOptionValue(URI_FILE_OPT)), destDir);
            }

            cocoon.addTargets(line.getArgList(), destDir);

            listener.messageGenerated(CocoonBean.getProlog());

            if (cocoon.getTargetCount() == 0 && cocoon.isPrecompileOnly()) {
                listener.messageGenerated("Please, specify at least one starting URI.");
                System.exit(1);
            }

            cocoon.initialize();
            cocoon.process();
            cocoon.dispose();

            listener.complete();

            int exitCode = (listener.isSuccessful() ? 0 : 1);
            System.exit(exitCode);
        }
    }

    private static String processXConf(CocoonBean cocoon, String filename, String destDir, String uriGroup) {

        try {
            final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            final Document xconf = builder.parse(new File(filename).toURL().toExternalForm());
            return BeanConfigurator.configure(xconf, cocoon, destDir, uriGroup, listener);
        } catch (Exception e) {
            System.out.println("ERROR: " + e.getMessage());
            return destDir;
        }
    }

    /**
     * Print the usage message and exit
     */
    private static void printUsage() {
        HelpFormatter formatter = new HelpFormatter();

        formatter.printHelp("cocoon cli [options] [targets]", CocoonBean.getProlog(), options,
                "Note: the context directory defaults to '" + Constants.DEFAULT_CONTEXT_DIR + "'");
    }

    /**
     * Print the version string and exit
     */
    private static void printVersion() {
        System.out.println(Constants.VERSION);
    }
}