001    
002    /*
003     * Copyright (C) 2010 Archie L. Cobbs. All rights reserved.
004     *
005     * $Id$
006     */
007    
008    package org.dellroad.jvser.client;
009    
010    import org.apache.log4j.ConsoleAppender;
011    import org.apache.log4j.Level;
012    import org.apache.log4j.Logger;
013    import org.apache.log4j.PatternLayout;
014    
015    /**
016     * Support superclass for command line classes.
017     */
018    public abstract class MainClass {
019    
020        protected final Logger log = Logger.getLogger(getClass());
021    
022        protected MainClass() {
023        }
024    
025        /**
026         * Subclass main implementation. This method is free to throw exceptions; these will
027         * be displayed on standard error and converted into non-zero exit values.
028         *
029         * @return exit value
030         */
031        protected abstract int run(String[] args) throws Exception;
032    
033        /**
034         * Display the usage message to standard error.
035         */
036        protected abstract void usageMessage();
037    
038        /**
039         * Print the usage message and exit with exit value 1.
040         */
041        protected void usageError() {
042            usageMessage();
043            System.exit(1);
044        }
045    
046        /**
047         * Setup logging.
048         */
049        protected void setupLogging(Level logLevel) {
050            if (logLevel == null)
051                logLevel = Level.INFO;
052            ConsoleAppender consoleAppender = new ConsoleAppender(new PatternLayout("%p: %m%n"), ConsoleAppender.SYSTEM_ERR);
053            Logger.getRootLogger().removeAllAppenders();
054            Logger.getRootLogger().addAppender(consoleAppender);
055            Logger.getRootLogger().setLevel(logLevel);
056        }
057    
058        /**
059         * Emit an error message an exit with exit value 1.
060         */
061        protected final void errout(String message) {
062            System.err.println(getClass().getSimpleName() + ": " + message);
063            System.exit(1);
064        }
065    
066        /**
067         * Invokes {@link #run}, catching any exceptions thrown and exiting with a non-zero
068         * value if and only if an exception was caught.
069         * <p/>
070         * <p>
071         * The concrete class' {@code main()} method should invoke this method.
072         * </p>
073         */
074        protected void doMain(String[] args) {
075            int exitValue = 1;
076            try {
077                exitValue = run(args);
078            } catch (Throwable t) {
079                t.printStackTrace(System.err);
080            } finally {
081                System.exit(exitValue);
082            }
083        }
084    }
085