Package org.apache.fulcrum.yaafi.cli

Source Code of org.apache.fulcrum.yaafi.cli.Main

package org.apache.fulcrum.yaafi.cli;

/*
* 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.
*/

import java.io.File;

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.fulcrum.yaafi.framework.container.ServiceContainer;
import org.apache.fulcrum.yaafi.framework.factory.ServiceContainerConfiguration;
import org.apache.fulcrum.yaafi.framework.factory.ServiceContainerFactory;


/**
* An example of the embedding of a YAAFI kernel inside an
* arbitrary application.
*/

public class Main implements Runnable, Disposable
{
    /** parameter for the application name */
    public static final String APPLICATION_NAME = "yaafi.cli.applicationName";

    /** parameter for the application home directory */
    public static final String APPLICATION_HOME = "yaafi.cli.applicationHome";

    /** parameter for the application temporary directory */
    public static final String APPLICATION_TEMP = "yaafi.cli.tempHome";

    /** parameter for the application container configuration file */
    public static final String APPLICATION_CONFIG = "yaafi.cli.config";

    /** parameter for setting a shutdown hook */
    public static final String APPLICATION_HASSHUTDOWNHOOK = "yaafi.cli.hasShutdownHook";

    /** parameter for blocking the main thread in Main.run() */
    public static final String APPLICATION_ISBLOCKING = "yaafi.cli.isBlocking";

    /** the interval to check for termination */
    private static final int SLEEP_TIME = 100;

    /** the timeout for joing the shutdown thread */
    private static final int JOIN_TIME = 1000;

    /** The service manager */
    private ServiceContainer container;

    /** The location of the container configuration */
    private String containerConfigValue;

    /** Thread for processing the shutdown notification of the JVM */
    private Thread shutdownThread;

    /** Do we block the invoking thread until the JVM terminates ?! */
    private boolean isBlocking;

    /** Do we install a shutdown hook for the JVM ?! */
    private boolean hasShutdownHook;

    /** The logger being used */
    private Logger logger;

    /** the name of the application */
    private String applicationName;

    /** the working directory */
    private String applicationHome;

    /** the temp directory */
    private String tempHome;

    /** the command line arguments */
    private String[] args;

    /** is the instance properly initialized */
    private volatile boolean isInitialized;


    /**
     * Constructor
     */
    public Main()
    {
        // default initialization

        this.containerConfigValue   = "./conf/containerConfiguration.xml";
        this.logger                 = new ConsoleLogger();
        this.applicationHome        = ".";
        this.tempHome               = System.getProperty("java.io.tmpdir",".");
        this.applicationName        = "main";
        this.args                   = ( args != null ? args : new String[0] );
        this.isBlocking             = false;
        this.hasShutdownHook        = true;
        this.isInitialized          = false;

        // query the system properties

        this.containerConfigValue = System.getProperty(
                APPLICATION_CONFIG,
                this.containerConfigValue
                );

        this.applicationName = System.getProperty(
                APPLICATION_NAME,
                this.applicationName
                );

        this.applicationHome = System.getProperty(
            APPLICATION_HOME,
            this.applicationHome
            );

        this.tempHome = System.getProperty(
            APPLICATION_TEMP,
            this.tempHome
            );
    }

    /**
     * Constructor
     *
     * The following command line parameters are supported
     * <ul>
     *   <li>--yaafi.cli.applicationName name</li>
     *   <li>--yaafi.cli.applicationHome dir</li>
     *   <li>--yaafi.cli.tempHome dir</li>
     *   <li>--yaafi.cli.isBlocking [true|false]</li>
     *   <li>--yaafi.cli.hasShutdownHook [true|false]</li>
     *   <li>--yaafi.cli.config file</li>
     * </ul>
     *
     * @param args the command line arguments
     */
    public Main( String[] args )
    {
        this();

        this.args = args;

        // parse the command line

        Getopt getopt = new Getopt(this.args);

        this.setApplicationName(
            getopt.getStringValue( APPLICATION_NAME, this.getApplicationName() )
            );

        this.setApplicationHome(
            getopt.getStringValue( APPLICATION_HOME, this.getApplicationHome() )
            );

        this.setTempHome(
            getopt.getStringValue( APPLICATION_TEMP, this.getTempHome() )
            );

        this.setContainerConfigValue(
            getopt.getStringValue( APPLICATION_CONFIG, this.getContainerConfigValue() )
            );

        this.setIsBlocking(
            getopt.getBooleanValue( APPLICATION_ISBLOCKING, this.isBlocking )
            );

        this.setHasShutdownHook(
            getopt.getBooleanValue( APPLICATION_HASSHUTDOWNHOOK, this.hasShutdownHook )
            );
    }

    /**
     * The main method.
     *
     * @param args Command line arguments
     * @throws Exception the execution failed
     */
    public static void main( String[] args ) throws Exception
    {
       int exitCode = 0;

       Main impl = new Main(args);

       try
       {
           impl.run();
       }
       catch (Throwable t)
       {
           exitCode = 1;
       }

       System.exit(exitCode);
    }

    /**
     * Determines the file location of the given name. If the name denotes
     * a relative file location it will be rsolved using the application
     * home directory.
     *
     * @param baseDir the base directory
     * @param name the filename
     * @return the file
     */
    public static File makeAbsoluteFile( File baseDir, String name )
    {
        File result = new File(name);

        if( !result.isAbsolute() )
        {
            result = new File( baseDir, name );
        }

        return result;
    }

    /**
     * Dispose the YAAFI container
     */

    public synchronized void dispose()
    {
        this.shutdown();
    }

    /**
     * Runs the instance by initializing it and potentially blocking
     * the invoking thread depending on the configuration.
     *
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
        try
        {
            this.initialize();
            this.onWait();
        }
        catch (Throwable t)
        {
            String msg = "Failed to run " + this.getClass().getName();
            this.getLogger().error(msg,t);
            throw new RuntimeException(t.getMessage());
        }
    }

    /**
     * Depending on the configuration this method might block
     * the calling thread or return immediatly. We currently
     * poll a volatile variable which is not the most elegant
     * solution.
     */
    public void onWait()
    {
        while( this.isBlocking() && this.isInitialized() )
        {
            try
            {
                Thread.sleep(Main.SLEEP_TIME);
            }
            catch (InterruptedException e)
            {
                // ignore
            }
        }
    }

    /**
     * Locates the file for the given file name.
     * @param fileName the filename
     * @return an absolute file
     */
    public File makeAbsoluteFile( String fileName )
    {
        return Main.makeAbsoluteFile(
            new File(this.getApplicationHome()),
            fileName
            );
    }

    /**
     * Locates the file for the given file name.
     * @param fileName the filename
     * @return an absolute path
     */
    public String makeAbsolutePath( String fileName )
    {
        return Main.makeAbsoluteFile(
            new File(this.getApplicationHome()),
            fileName
            ).getAbsolutePath();
    }

    /////////////////////////////////////////////////////////////////////////
    // Generated getters & setters
    /////////////////////////////////////////////////////////////////////////

    /**
     * @return Returns the ServiceContainer interface
     */
    public ServiceContainer getServiceContainer()
    {
        return this.container;
    }

    /**
     * @return Returns the ServiceManager interface
     */
    public ServiceManager getServiceManager()
    {
        return this.container;
    }

    /**
     * @return Returns the applicationHome.
     */
    public String getApplicationHome()
    {
        return this.applicationHome;
    }

    /**
     * @param applicationHome The applicationHome to set.
     */
    public void setApplicationHome(String applicationHome)
    {
        this.applicationHome = applicationHome;
    }

    /**
     * @return Returns the containerConfigValue.
     */
    public String getContainerConfigValue()
    {
        return containerConfigValue;
    }

    /**
     * @param containerConfigValue The containerConfigValue to set.
     */
    public void setContainerConfigValue(String containerConfigValue)
    {
        this.containerConfigValue = containerConfigValue;
    }

    /**
     * @return Returns the isBlocking.
     */
    public boolean isBlocking()
    {
        return isBlocking;
    }

    /**
     * @param isBlocking The isBlocking to set.
     */
    public void setIsBlocking(boolean isBlocking)
    {
        this.isBlocking = isBlocking;
    }

    /**
     * @param isBlocking The isBlocking to set.
     */
    public void setIsBlocking(Boolean isBlocking)
    {
        this.isBlocking = isBlocking.booleanValue();
    }

    /**
     * @param isBlocking The isBlocking to set.
     */
    public void setIsBlocking(String isBlocking)
    {
        this.isBlocking = Boolean.valueOf(isBlocking).booleanValue();
    }

    /**
     * @return Returns the tempHome.
     */
    public String getTempHome()
    {
        return this.tempHome;
    }

    /**
     * @param tempHome The tempHome to set.
     */
    public void setTempHome(String tempHome)
    {
        this.tempHome = tempHome;
    }

    /**
     * @return Returns the logger.
     */
    public Logger getLogger()
    {
        return this.logger;
    }

    /**
     * @param logger The logger to set.
     */
    public void setLogger(Logger logger)
    {
        this.logger = logger;
    }

    /**
     * @return Returns the applicationName.
     */
    public String getApplicationName()
    {
        return applicationName;
    }

    /**
     * @param applicationName The applicationName to set.
     */
    public void setApplicationName(String applicationName)
    {
        this.applicationName = applicationName;
    }

    /**
     * @return Returns the args.
     */
    public String [] getArgs()
    {
        return args;
    }
    /**
     * @param args The args to set.
     */
    public void setArgs(String [] args)
    {
        this.args = args;
    }

    /**
     * @return Returns the hasShutdownHook.
     */
    public boolean hasShutdownHook()
    {
        return hasShutdownHook;
    }

    /**
     * @param hasShutdownHook The hasShutdownHook to set.
     */
    public void setHasShutdownHook(boolean hasShutdownHook)
    {
        this.hasShutdownHook = hasShutdownHook;
    }

    /**
     * @param hasShutdownHook The hasShutdownHook to set.
     */
    public void setHasShutdownHook(Boolean hasShutdownHook)
    {
        this.hasShutdownHook = hasShutdownHook.booleanValue();
    }

    /**
     * @param hasShutdownHook The hasShutdownHook to set.
     */
    public void setHasShutdownHook(String hasShutdownHook)
    {
        this.hasShutdownHook = Boolean.valueOf(hasShutdownHook).booleanValue();
    }

    /**
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        StringBuffer result = new StringBuffer();
        StringBuffer argsLine = new StringBuffer();

        result.append(getClass().getName() + "@" + Integer.toHexString(hashCode()));

        result.append('[');
        result.append("workingDir=" + new File("").getAbsolutePath());
        result.append(',');

        result.append("args=");

        for( int i=0; i<this.getArgs().length; i++ )
        {
            argsLine.append( this.getArgs()[i] );

            if( (i+1) < this.getArgs().length )
            {
                argsLine.append( " " );
            }
        }

        result.append( argsLine.toString() );
        result.append(',');

        result.append("applicationName=" + this.getApplicationName());
        result.append(',');
        result.append("applicationHome=" + this.getApplicationHome());
        result.append(',');
        result.append("tempHome=" + this.getTempHome());
        result.append(',');
        result.append("logger=" + this.getLogger().getClass().getName());
        result.append(',');
        result.append("isBlocking=" + this.isBlocking);
        result.append(',');
        result.append("hasShutdownHook=" + this.hasShutdownHook());
        result.append(',');
        result.append("containerConfigValue=" + this.getContainerConfigValue());
        result.append(']');

        return result.toString();
    }

    /**
     * @return Returns the isInitialized.
     */
    public boolean isInitialized()
    {
        return isInitialized;
    }

    /////////////////////////////////////////////////////////////////////////
    // Implementation
    /////////////////////////////////////////////////////////////////////////

    /**
     * @param isInitialized The isInitialized to set.
     */
    protected void setInitialized(boolean isInitialized)
    {
        this.isInitialized = isInitialized;
    }

    /**
     * Initialize the instance
     *
     * @throws Exception the initialization failed
     */
    public void initialize() throws Exception
    {
        this.getLogger().debug( "Initializing " + this.getClass().getName() );

        ServiceContainerConfiguration config = new ServiceContainerConfiguration();

        // intialize the Avalon container

        config.setLogger( this.getLogger() );
        config.setApplicationRootDir( this.getApplicationHome() );
        config.setTempRootDir( this.getTempHome() );
        config.loadContainerConfiguration( this.getContainerConfigValue(), "auto" );

        this.container = ServiceContainerFactory.create( config );

        // initialize shutdown hook of JVM for a server application

        if( this.hasShutdownHook() )
        {
            this.getLogger().debug( "Registering shutdown hook" );
            Shutdown shutdown = new Shutdown( this );
            this.shutdownThread = new Thread( shutdown, "ShutdownThread" );
            Runtime.getRuntime().addShutdownHook( this.shutdownThread );
        }

        this.setInitialized(true);
    }

    /**
     * Terminates the instance
     */
    protected void shutdown()
    {
        if( !this.isInitialized())
        {
            return;
        }

        this.getLogger().debug( "Terminating " + this.getClass().getName() );

        try
        {
            // wait for the shutdown thread

            if( this.shutdownThread != null )
            {
                try
                {
                    this.getLogger().debug( "Waiting for shutdown handler thread to terminate" );
                    this.shutdownThread.join(JOIN_TIME);
                    this.shutdownThread = null;
                    this.getLogger().debug( "Shutdown handler thread is terminated" );
                }
                catch (InterruptedException e)
                {
                    // nothing to do
                }
            }

            // dispose the service container

            if( this.getServiceContainer() != null )
            {
                this.getServiceContainer().dispose();
                this.container = null;
            }

            this.setInitialized(false);
        }

        catch (Exception e)
        {
            String msg = "Failed to terminate " + this.getClass().getName();
            this.getLogger().error(msg,e);
        }
    }
}
TOP

Related Classes of org.apache.fulcrum.yaafi.cli.Main

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.