You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by le...@apache.org on 2001/04/05 21:10:13 UTC

cvs commit: jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/facilities Facility.java

leosimons    01/04/05 12:10:13

  Added:       proposal/4.0/src/java/org/apache/phoenix Restart.java
                        Shutdown.java Start.java
               proposal/4.0/src/java/org/apache/phoenix/applications
                        Application.java ApplicationException.java
                        ServerApplication.java
               proposal/4.0/src/java/org/apache/phoenix/core Block.java
                        BlockContext.java Embeddor.java Kernel.java
                        ServerKernel.java
               proposal/4.0/src/java/org/apache/phoenix/engine
                        PhoenixEmbeddor.java PhoenixKernel.java
               proposal/4.0/src/java/org/apache/phoenix/engine/applications
                        DefaultServerApplication.java
                        ServerApplicationFactory.java
               proposal/4.0/src/java/org/apache/phoenix/engine/deployer
                        DefaultSarDeployer.java
               proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks
                        BlockDAG.java BlockEntry.java BlockVisitor.java
                        DefaultBlockContext.java DefaultBlockDeployer.java
                        RoleEntry.java
               proposal/4.0/src/java/org/apache/phoenix/engine/facilities
                        ApplicationManager.java ClassLoader.java
                        ConfigurationManager.java LogManager.java
                        SecurityManager.java ThreadManager.java
               proposal/4.0/src/java/org/apache/phoenix/engine/jmx
                        Manager.java
               proposal/4.0/src/java/org/apache/phoenix/facilities
                        Facility.java
  Log:
  Creating a proposal structure for version 4 of phoenix. Phoenix 4 is ment
  to work with version 4 of the framework, include jmx support, use an
  embeddor to talk with the environment as detailed in the JSF JSR and
  generally be a lot cleaner than the current setup.
  A detailed changes.txt will be written once the first version of this
  proposal stabilises.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Restart.java
  
  Index: Restart.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix;
  
  /**
   * Class to restart phoenix. Call to restart the server.
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   */
  public class Restart {
      public Restart() {
          (new Start()).restart();
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Shutdown.java
  
  Index: Shutdown.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix;
  
  /**
   * Class to exit phoenix. Call to shut down the server.
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   */
  public class Shutdown {
      public Shutdown() {
          (new Start()).shutdown();
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Start.java
  
  Index: Start.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix;
  
  import java.security.AccessController;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  
  import javax.management.MBeanServer;
  
  import org.apache.framework.context.Context;
  import org.apache.framework.context.DefaultContext;
  import org.apache.framework.container.Entry;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.DefaultConfiguration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.framework.lifecycle.Disposable;
  
  import org.apache.avalon.component.DefaultComponentManager;
  
  import org.apache.phoenix.core.Embeddor;
  import org.apache.phoenix.engine.PhoenixEmbeddor;
  
  /**
   * Entry point to phoenix. Call to start the server.
  // TODO: list available arguments
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class Start implements Disposable
  {
      // embeddor
      private static Embeddor embeddor;
          // embeddor configuration settings
          private static String embeddorClass;
          private static final String DEFAULT_EMBEDDOR_CLASS =
                                                      "org.apache.phoenix.engine.PhoenixEmbeddor";
          private static String deployerClass;
          private static final String DEFAULT_DEPLOYER_CLASS =
                                                      "org.apache.phoenix.engine.DefaultSarDeployer";
          private static String mBeanServerClass;
          private static final String DEFAULT_MBEANSERVER_CLASS =
                                                      "org.apache.jmx.MBeanServerImpl";
          private static String kernelClass;
          private static final String DEFAULT_KERNEL_CLASS =
                                                      "org.apache.phoenix.engine.DefaultKernel";
          private static String configurationSource;
          private static final String DEFAULT_CONFIGURATION_SOURCE = "../conf/server.xml";
  
      // monitor these for status changes
      private static boolean singleton = false;
      private static boolean shutdown = false;
      private static boolean restart = false;
  
      // command line options
      private static final int       DEBUG_LOG_OPT        = 'd';
      private static final int       HELP_OPT             = 'h';
      private static final int       LOG_FILE_OPT         = 'l';
      private static final int       APPS_PATH_OPT        = 'a';
  
  
      /**
       * Entry-point into Phoenix. See the class description for a list of the possible
       * arguments.
       */
      public void main( final String[] args )
      {
          if( singleton )
          {
              System.out.println( "Sorry, an instance of phoenix is already running. Phoenix cannot be run multiple times in the same VM." );
              System.exit( 1 );
          }
          singleton = true;
  
          final Start start = new Start();
  
          try
          {
              start.execute( args );
          }
          catch( final Throwable throwable )
          {
              System.out.println( "There was an uncaught exception:" );
              System.out.println( "---------------------------------------------------------" );
              System.out.println( throwable.toString() );
              System.out.println( "---------------------------------------------------------" );
              System.out.println( "Please check the configuration files and restart phoenix." );
              System.out.println( "If the problem persists, contact the Avalon project.  See" );
              System.out.println( "http://jakarta.apache.org/avalon for more information." );
              System.exit( 1 );
          }
      }
  
      /////////////////////////
      /// LIFECYCLE METHODS ///
      /////////////////////////
      /**
       * Shuts down and immediately restarts the server using the
       * same settings.
       */
      public void restart()
      {
          this.restart = true;
      }
      /**
       * Shuts down the server.
       */
      public void dispose()
      {
          this.shutdown = true;
      }
  
      /////////////////////////
      /// EXECUTION METHODS ///
      /////////////////////////
      private void execute( final String[] args ) throws Exception
      {
          try
          {
              final PrivilegedExceptionAction action = new PrivilegedExceptionAction()
              {
                  public Object run() throws Exception
                  {
                      exec( args );
                      return null;
                  }
              };
  
              AccessController.doPrivileged( action );
          }
          catch( final PrivilegedActionException pae )
          {
              // only "checked" exceptions will be "wrapped" in a PrivilegedActionException.
              throw pae.getException();
          }
      }
      private void exec( final String[] args ) throws Exception
      {
          this.parseCommandLineOptions( args );
          this.createEmbeddor();
  
          final DefaultContext ctx = new DefaultContext();
              ctx.put( "kernel-class", this.kernelClass );
              ctx.put( "deployer-class", this.deployerClass );
              ctx.put( "mBeanServer-class", this.mBeanServerClass );
              ctx.put( "kernel-configuration-source", this.configurationSource );
              ctx.put( "log-destination", "../log/phoenix.log" );
          final Configuration conf = new DefaultConfiguration("phoenix","localhost");
  
          // run Embeddor lifecycle
          this.embeddor.contextualize(ctx);
          this.embeddor.configure(conf);
          this.embeddor.init();
  
          while( !this.shutdown )
          {
              while( !this.restart )
              {
                  this.embeddor.run();
              }
              this.embeddor.restart();
              this.restart = false;
          }
          embeddor.dispose();
          System.exit( 0 );
      }
      //////////////////////
      /// HELPER METHODS ///
      //////////////////////
      private void parseCommandLineOptions( final String[] args )
      {
          // start with the defaults
          this.mBeanServerClass = this.DEFAULT_MBEANSERVER_CLASS;
          this.kernelClass = this.DEFAULT_KERNEL_CLASS;
          this.embeddorClass = this.DEFAULT_EMBEDDOR_CLASS;
          this.deployerClass = this.DEFAULT_DEPLOYER_CLASS;
          this.configurationSource = this.DEFAULT_CONFIGURATION_SOURCE;
  
          // TODO: update code below to set the code above
  
          // setup parser and get arguments
          final CLOptionDescriptor[] clOptionsDescriptor = createCommandLineOptions();
          final CLArgsParser parser = new CLArgsParser( args, clOptionsDescriptor );
          if( null != parser.getErrorString() )
          {
              System.err.println( "Error: " + parser.getErrorString() );
              return;
          }
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          boolean debugLog = false;
  
          // parse options
          for( int i = 0; i < size; i++ )
          {
              final CLOption option = (CLOption)clOptions.get( i );
  
              switch( option.getId() )
              {
              case 0:
                  System.err.println( "Error: Unknown argument" + option.getArgument() );
                  //fall threw
              case HELP_OPT:
                  usage();
                  return;
  
              case DEBUG_LOG_OPT: debugLog = true; break;
              case LOG_FILE_OPT: m_logFile = option.getArgument(); break;
              case APPS_PATH_OPT: m_appsPath = option.getArgument(); break;
              }
          }
  
          if( !debugLog ) LogKit.setGlobalPriority( Priority.DEBUG );
      }
      protected CLOptionDescriptor[] createCommandLineOptions()
      {
          //TODO: localise
          final CLOptionDescriptor options[] = new CLOptionDescriptor[ 4 ];
          options[0] =
              new CLOptionDescriptor( "help",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      HELP_OPT,
                                      "display this help" );
          options[1] =
              new CLOptionDescriptor( "log-file",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      LOG_FILE_OPT,
                                      "the name of log file." );
  
          options[2] =
              new CLOptionDescriptor( "apps-path",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      APPS_PATH_OPT,
                                      "the path to apps/ directory that contains .sars" );
  
          options[3] =
              new CLOptionDescriptor( "debug-init",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      DEBUG_LOG_OPT,
                                      "use this option to specify enable debug " +
                                      "initialisation logs." );
          return options;
      }
      protected void usage(List commandLineOptions)
      {
          System.out.println( "java " + getClass().getName() + " [options]" );
          System.out.println( "\tAvailable options:");
          System.out.println( CLUtil.describeOptions( commandLineOptions ) );
      }
      private void createEmbeddor() throws ConfigurationException
      {
          try
          {
              Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
              this.embeddor = (Embeddor)Class.forName( this.embeddorClass ).newInstance();
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create Embeddor of class " +
                                                this.embeddorClass, e );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/Application.java
  
  Index: Application.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.applications;
  
  import org.apache.framework.lifecycle.Disposable;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.framework.lifecycle.Startable;
  import org.apache.framework.lifecycle.Stoppable;
  
  import org.apache.avalon.camelot.Container;
  
  /**
   * The Application is a self-contained component that performs a specific
   * function.
   *
   * Example ServerApplications may be a Mail Server, File Server, Directory Server etc.
   * Example JesktopApplications may be a Spreadsheet program, browser, mail client
   * Example WebApplications may be a particular website or application within a website
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Application
      extends Initializable, Startable, Stoppable, Disposable, Container
  {
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/ApplicationException.java
  
  Index: ApplicationException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.applications;
  
  import org.apache.framework.CascadingException;
  
  /**
   * The ApplicationException is used to indicate problems with applications.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ApplicationException
      extends CascadingException
  {
      public ApplicationException( final String message )
      {
          this( message, null );
      }
  
      public ApplicationException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/ServerApplication.java
  
  Index: ServerApplication.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.applications;
  
  import org.apache.framework.context.Contextualizable;
  import org.apache.framework.configuration.Configurable;
  
  /**
   * The ServerApplication is a self-contained server component that performs a specific
   * user function.
   *
   * Example ServerApplications may be a Mail Server, File Server, Directory Server etc.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ServerApplication
      extends Application, Contextualizable, Configurable
  {
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Block.java
  
  Index: Block.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.core;
  
  import org.apache.framework.component.Component;
  
  /**
   * The main interface to implement for building servers using Avalon patterns.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public interface Block
      extends Component
  {
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/BlockContext.java
  
  Index: BlockContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.core;
  
  import java.io.File;
  import org.apache.framework.context.Context;
  import org.apache.avalon.thread.ThreadPool;
  import org.apache.log.Logger;
  
  /**
   * Context via which Blocks communicate with container.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface BlockContext
      extends Context
  {
      String    APP_NAME          = "app.name";
      String    APP_HOME_DIR      = "app.home";
      String    NAME              = "block.name";
  
      /**
       * Base directory of .sar application.
       *
       * @return the base directory
       */
      File getBaseDirectory();
  
      /**
       * Retrieve name of block.
       *
       * @return the name of block
       */
      String getName();
  
      /**
       * Retrieve thread pool by category.
       * ThreadPools are given names so that you can manage different thread
       * count to different components.
       *
       * @param category the category
       * @return the ThreadManager
       */
      ThreadPool getThreadPool( String category );
  
      /**
       * Retrieve default thread pool.
       * Equivelent to getThreadPool( "default" );
       *
       * @return the default ThreadPool
       */
      ThreadPool getDefaultThreadPool();
  
      /**
       * Retrieve logger coresponding to root category of application.
       *
       * @return the base logger
       */
      Logger getBaseLogger();
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Embeddor.java
  
  Index: Embeddor.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.core;
  
  import java.lang.Runnable;
  import java.lang.UnsupportedOperationException;
  
  import org.apache.framework.context.Contextualizable;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.framework.lifecycle.Disposable;
  
  
  /**
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   */
  public interface Embeddor
      extends Contextualizable, Configurable, Initializable, Runnable, Disposable
  {
      public void restart() throws UnsupportedOperationException;
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Kernel.java
  
  Index: Kernel.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.core;
  
  import org.apache.avalon.camelot.ContainerException;
  
  import org.apache.phoenix.applications.Application;
  
  /**
   * The Kernel is the core of any system.
   * The kernel is responsible for orchestrating low level services
   * such as loading, configuring and destroying applications. It also
   * gives access to basic facilities specific to that particular kernel.
   * A ServerKernel may offer scheduling, naming, security, classloading etc.
   * A JesktopKernel may offer inter-application drag-n-drop support.
   * A VEKernel may offer inter-VE transport for Avatars.
   *
   * Note that no facilities are available until after the Kernel has been initialized.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Kernel
      extends Application, Runnable
      // and thus extends Initializable, Startable, Stoppable, Disposable, Container, Component
  {
      /**
       * Retrieve Application from container.
       * The Application that is returned must be initialized
       * and prepared for manipulation.
       *
       * @param name the name of application
       * @return the application
       * @exception ContainerException if an error occurs
       */
      Application getApplication( String name )
          throws ContainerException;
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/ServerKernel.java
  
  Index: ServerKernel.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.core;
  
  import org.apache.framework.logger.Loggable;
  import org.apache.framework.context.Contextualizable;
  
  /**
   * The ServerKernel is the core of the Phoenix system.
   * The kernel is responsible for orchestrating low level services
   * such as loading, configuring and destroying blocks. It also
   * gives access to basic facilities such as scheduling sub-systems,
   * protected execution contexts, naming and directory services etc.
   *
   * Note that no facilities are available until after the Kernel has been
   * contextualized, configured and initialized.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ServerKernel
      extends Loggable, Kernel, Contextualizable
      // and thus extends Application, Runnable, Initializable, Startable,
      // Stoppable, Disposable, Container, Component
  {
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/PhoenixEmbeddor.java
  
  Index: PhoenixEmbeddor.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine;
  
  import javax.management.MBeanServer;
  import java.io.File;
  
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.context.Contextualizable;
  import org.apache.framework.container.Container;
  import org.apache.framework.component.Composer;
  import org.apache.framework.logger.Loggable;
  import org.apache.framework.container.Deployer;
  import org.apache.framework.lifecycle.Suspendable;
  import org.apache.framework.lifecycle.Resumable;
  
  import org.apache.framework.context.Context;
  import org.apache.framework.container.Entry;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  
  import org.apache.avalon.camelot.CamelotUtil;
  import org.apache.avalon.atlantis.Kernel;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.avalon.component.DefaultComponentManager;
  import org.apache.avalon.configuration.DefaultConfigurationBuilder;
  
  import org.apache.phoenix.engine.facilities.Manager;
  
  import org.apache.log.format.AvalonLogFormatter;
  import org.apache.log.output.FileOutputLogTarget;
  import org.apache.log.Logger;
  import org.apache.log.LogKit;
  import org.apache.log.Priority;
  import org.apache.log.LogTarget;
  
  /**
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class DefaultEmbeddor
      implements Embeddor
  {
      private Context         context;
  
      private Logger          logger;
      private Deployer        deployer;
          private DefaultContext      deployerContext;
      private Manager         manager;
          private MBeanServer         mBeanServer;
          private DefaultContext      managerContext;
      private Kernel          kernel;
          private Thread              kernelThread;
          private DefaultContext      kernelContext;
          private Configuration       kernelConfiguration;
          private boolean             kernelSupportsSuspend = false;
  
      // monitor these for status changes
      private boolean shutdown = false;
      private boolean restart = false;
      private boolean suspend = false;
      private boolean recontextualized = false;
      private boolean reconfigured = false;
  
      /////////////////////////
      /// LIFECYCLE METHODS ///
      /////////////////////////
      /**
       * Make sure to provide all the neccessary information through
       * this context. All information it needs consists of strings.
       * These are also indexed using strings. Neccessary are:
       * <ul>
       * <li><b>kernel-class</b>, the classname of the
       * org.apache.phoenix.core.Kernel to be used.</li>
       * <li><b>deployer-class</b>, the classname of the
       * org.apache.avalon.camelot.Deployer to be used.</li>
       * <li><b>mBeanServer-class</b>, the classname of the
       * javax.management.MBeanServer to be used.</li>
       * <li><b>kernel-configuration-source</b>, the location
       * of the configuration file to be used for configuring the
       * kernel.</li>
       * <li><b>log-destination</b>, the file to save log
       * messages in. If omitted, no logs are written.</li>
       * <li>TODO: <b>facilities-directory</b>, the directory in
       * which the  facilities you wish to load into the kernel
       * are stored (in .far format).<br />
       * When ommited, the default facilities are used.</li>
       * <li><b>applications-directory</b>, the directory in which
       * the applications to be loaded by the kernel are stored
       * (in .sar format).<br />
       * When ommited, no applications are loaded.</li>
       * </ul>
       */
      public void contextualize( Context context )
      {
          this.context = context;
      }
      /**
       * Currently unused, but Embeddor extends it so call anyway
       * using a dummy configuration.
       */
      void configure( Configuration configuration )
          throws ConfigurationException;
      {
          // TODO
      }
      /**
       * Creates the core handlers - logger, deployer, Manager and
       * Kernel. Note that these are not set up properly until you have
       * called the <code>run()</code> method.
       */
      public void init()
          throws Exception
      {
          this.createLogger();
          try { this.createDeployer(); }
          catch( Exception e ) { logger.fatalError("Unable to create deployer!", e);
                                 throw new Exception(e); }
          try { this.createManager(); }
          catch( Exception e ) { logger.fatalError("Unable to create manager!", e);
                                 throw new Exception(e); }
          try { this.createKernel(); }
          catch( Exception e ) { logger.fatalError("Unable to create kernel!", e);
                                 throw new Exception(e); }
      }
      /**
       * This is the main method of the embeddor. It sets up the core
       * components, and then deploys the <code>Facilities</code>. These
       * are registered with the Kernel and the Manager. The same
       * happens for the <code>Applications</code>.
       * Now, the Kernel is taken through its lifecycle. When it is
       * finished, as well as all the applications running in it, it
       * is shut down, after which the PhoenixEmbeddor is as well.
       */
      public void run()
      {
          this.setupLogger();
          try { this.setupDeployer(); }
          catch( Exception e ) {  logger.fatalError("Unable to setup deployer!", e);
                                  System.exit( 1 ); }
          try { this.setupManager(); }
          catch( Exception e ) {  logger.fatalError("Unable to setup manager!", e);
                                  System.exit( 1 ); }
          try { this.setupKernel(); }
          catch( Exception e ) {  logger.fatalError("Unable to setup kernel!", e);
                                  System.exit( 1 ); }
  
          try
          {
              kernel.start();
  
              while( !this.shutdown )
              {
                  while( !this.restart && !this.suspend )
                  {
                      kernel.run();
                      try { synchronized( this ) { wait(); } }
                      catch (InterruptedException e) {}
                  }
                  if( this.restart )
                  {
                      handleRestart();
                  }
                  else if( this.suspend )
                  {
                      handleSuspend();
                  }
              }
              handleDispose();
          }
          catch ( Exception e )
          {
              // whoops!
              this.logger.fatalError("There was a fatal error while running phoenix.", e );
              System.exit( 1 );
          }
      }
  
      /**
       * This stops and then restarts the Embeddor,
       * re-creating the logger, deployer, Manager
       * and Kernel in the process.
       */
      public void restart()
      {
          this.restart = true;
      }
      /**
       * Shut down the Embeddor together with the
       * Logger, Deployer, Manager and Kernel.
       */
      public void dispose()
      {
          this.shutdown = true;
      }
      /**
       * Suspend both the Embeddor and its Manager.
       * If the Kernel does not support suspend,
       * this shuts down the Kernel and all
       * Applications running in it. This is not
       * recommended!
       */
      public void suspend()
      {
          this.suspend = true;
      }
      /**
       * Resume both the Embeddor and its Manager.
       * If the Kernel does not support suspend, it
       * has to be re-created and re-setup. This
       * happens now.
       */
      public void resume()
      {
          try
          {
              if( this.kernelSupportsSuspend )
              {
                  if( kernel instanceof Resumable )
                  {
                      manager.resume();
                      ((Resumable)kernel).resume();
  
                      this.suspend = false;
                      synchronized( this ) { notifyAll(); }
                  } else
                  {
                      // it's stupid if this happens
                      // but let's handle it anyway...
                      kernel.stop();
                      kernel.dispose();
                      kernel = null;
                      this.createKernel();
                      this.setupKernel();
  
                      manager.resume();
                      kernel.start();
  
                      this.suspend = false;
                      synchronized( this ) { notifyAll(); }
                  }
              } else
              {
                  this.createKernel();
                  this.setupKernel();
  
                  manager.resume();
                  kernel.start();
  
                  this.suspend = false;
                  synchronized( this ) { notifyAll(); }
              }
          }
          catch( Exception e )
          {
              // this is bad...
              logger.fatalError( "A fatal error occured while resuming. Phoenix will exit.", e );
              System.exit( 1 );
          }
      }
  
      //////////////////////
      /// HELPER METHODS ///
      //////////////////////
      private void createLogger() throws ConfigurationException
      {
          try
          {
              final FileOutputLogTarget logTarget = new FileOutputLogTarget( (String)this.context.get( "log-destination" ) );
              final AvalonLogFormatter formatter = new AvalonLogFormatter();
              formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
                                   "(%{context}): %{message}\\n%{throwable}" );
              logTarget.setFormatter( formatter );
  
              LogKit.addLogTarget( (String)this.context.get( "log-destination" ), logTarget );
              this.logger = LogKit.createLogger( LogKit.createCategory( "Phoenix", Priority.DEBUG ),
                                              new LogTarget[] { logTarget } );
              this.logger.info( "Loader started" );
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create Logger", e );
          }
      }
      private void setupLogger() {}
  
      private void createDeployer() throws ConfigurationException
      {
          try
          {
              Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
              this.deployer = (Deployer)Class.forName( (String)this.context.get( "deployer-class" ) ).newInstance();
              this.deployerContext = new DefaultContext();
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create Deployer of class " +
                                                (String)this.context.get( "deployer-class" ), e );
          }
      }
      private void setupDeployer() throws Exception
      {
          if( this.deployer instanceof Loggable )
          {
              ((Loggable)this.deployer).setLogger( this.logger );
          }
          if( this.deployer instanceof Contextualizable )
          {
              ((Contextualizable)this.deployer).contextualize( (Context)this.deployerContext );
          }
          if( this.deployer instanceof Composer )
          {
              final DefaultComponentManager componentManager = new DefaultComponentManager();
              componentManager.put( "org.apache.avalon.camelot.Container", (Container)this.kernel );
              ((Composer)this.deployer).compose( componentManager );
          }
          final File directory = new File( (String)this.context.get( "default-apps-location" ) );
          CamelotUtil.deployFromDirectory( deployer, directory, ".sar" );
  
          // TODO: load facilities from .fars
          // final File directory2 = new File( (String)this.context.get( "default-facilities-location" ) );
          // CamelotUtil.deployFromDirectory( deployer, directory2, ".far" );
      }
      private void createManager() throws ConfigurationException
      {
          try
          {
              Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
              this.mBeanServer = (MBeanServer)Class.forName( (String)this.context.get( "mBeanServer-class" ) ).newInstance();
              this.managerContext = new DefaultContext();
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create MBean Server of class " +
                                                (String)this.context.get( "mBeanServer-class" ), e );
          }
      }
      private void setupManager()
      {
          this.manager = new Manager( this.mBeanServer );
          if( this.manager instanceof Loggable )
          {
              ((Loggable)this.manager).setLogger( this.logger );
          }
          if( this.manager instanceof Contextualizable )
          {
              this.managerContext.put( "org.apache.framework.container.Deployer", this.deployer );
              /* add references to default facilities so they will be loaded.
                 TODO: put the facilities in .sars, make the deployer load
                 those and remove this.  */
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.ComponentBuilder",
                  "org.apache.phoenix.engine.facilities.DefaultComponentBuilder" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.ComponentManager",
                  "org.apache.phoenix.engine.facilities.DefaultComponentManager" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.ConfigurationRepository",
                  "org.apache.phoenix.engine.facilities.DefaultConfigurationRepository" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.ContextBuilder",
                  "org.apache.phoenix.engine.facilities.DefaultContextBuilder" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.LoggerBuilder",
                  "org.apache.phoenix.engine.facilities.DefaultLoggerBuilder" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.LogManager",
                  "org.apache.phoenix.engine.facilities.DefaultLogManager" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.DefaultPolicy",
                  "org.apache.phoenix.engine.facilities.DefaultPolicy" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.ThreadManager",
                  "org.apache.phoenix.engine.facilities.DefaultThreadManager" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.SarBlockFactory",
                  "org.apache.phoenix.engine.facilities.SarBlockFactory" );
              this.managerContext.put( "org.apache.avalon.atlantis.Facility.SarClassLoader",
                  "org.apache.phoenix.engine.facilities.SarClassLoader" );
              ((Contextualizable)this.manager).contextualize( (Context)this.managerContext );
          }
  
          /* TODO
          add DynamicMBeans for the default kernel services here
          */
      }
      private void createKernel() throws ConfigurationException
      {
          try
          {
              Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
              this.kernel = (Kernel)Class.forName( (String)this.context.get( "kernel-class" ) ).newInstance();
              this.kernelContext = new DefaultContext();
          } catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create Kernel of class " +
                                                (String)this.context.get( "kernel-class" ), e );
          }
      }
      private void setupKernel()
      {
          if( this.kernel instanceof Loggable )
          {
              ((Loggable)this.kernel).setLogger( this.logger );
          }
          if( this.kernel instanceof Contextualizable )
          {
              this.kernelContext.put( "org.apache.phoenix.facilities.Manager", this.manager );
              ((Contextualizable)this.kernel).contextualize( (Context)this.kernelContext );
          }
          if( this.kernel instanceof Configurable )
          {
              try {
                  this.kernelConfiguration = (new DefaultConfigurationBuilder()).build(
                     (String)this.context.get( "kernel-configuration-source" ) );
                  ((Configurable)this.kernel).configure( this.kernelConfiguration );
              }
              catch ( Exception se )
              {
                  // it's okay; we don't use this yet anyway...
              }
          }
          if( this.kernel instanceof Suspendable )
          {
              this.kernelSupportsSuspend = true;
          }
  
          try {
              this.kernel.init();
          } catch ( Exception e )
          {
              this.logger.log( Priority.FATAL_ERROR,
                  "There was a fatal error; phoenix could not be started", e );
              System.exit( 1 );
          }
      }
  
      private void handleRestart()
      {
          this.restart = false;
  
          kernel.stop();
          kernel.dispose();
          manager.stop();
          manager.dispose();
  
          logger = null;
          kernel = null;
          manager = null;
          mBeanServer = null;
          deployer = null;
          System.gc(); // make sure resources are released
  
          try
          {
              this.init();
              this.setupLogger();
              this.setupDeployer();
              this.setupManager();
              this.setupKernel();
          }
          catch( Exception e )
          {
              // this is bad...
              logger.fatalError( "A fatal error occured while restarting. Phoenix will exit.", e );
              System.exit( 1 );
          }
          kernel.start();
      }
      private void handleSuspend()
      {
          //this.suspend = false;
  
          if( this.kernelSupportsSuspend )
          {
              ((Suspendable)kernel).suspend();
          } else
          {
              // the kernel does not support suspend,
              // thus, we must destroy and then
              // re-create it.
              kernel.stop();
              kernel.dispose();
              kernel = null;
              System.gc(); // make sure resources are released
          }
  
          // wait for resume
          try { synchronized( this ) { wait(); } }
          catch (InterruptedException e) {}
      }
      private void handleDispose()
      {
          kernel.stop();
          kernel.dispose();
          manager.stop();
          manager.dispose();
  
          kernel = null;
          manager = null;
          mBeanServer = null;
          deployer = null;
          System.gc(); // make sure resources are released
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/PhoenixKernel.java
  
  Index: PhoenixKernel.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine;
  
  import org.apache.phoenix.applications.Application;
  import org.apache.framework.container.Entry;
  
  /**
   * This is the DefaultServerKernel for phoenix.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultServerKernel
  {
      public final static String BANNER = Constants.SOFTWARE + " " + Constants.VERSION;
  
      public DefaultServerKernel()
      {
          m_entryClass = ServerApplicationEntry.class;
          m_applicationClass = ServerApplication.class;
      }
  
      /**
       * Prepare an application before it is initialized.
       * Overide to provide functionality.
       * Usually used to setLogger(), contextualize, compose, configure.
       *
       * @param name the name of application
       * @param entry the application entry
       * @param application the application instance
       * @exception Exception if an error occurs
       */
      protected void prepareApplication( final String name,
                                         final Entry entry,
                                         final Application application )
          throws Exception
      {
          final ServerApplicationEntry saEntry = (ServerApplicationEntry)entry;
          final ServerApplication saApplication = (ServerApplication)application;
  
          setupLogger( saApplication, LogKit.getLoggerFor( name ) );
          saApplication.contextualize( saEntry.getContext() );
  
          if( saApplication instanceof Composer )
          {
              ((Composer)saApplication).compose( saEntry.getComponentManager() );
          }
  
          saApplication.configure( saEntry.getConfiguration() );
      }
  
      protected void postAdd( final String name, final Entry entry )
      {
      }
      public void init()
          throws Exception
      {
          System.out.println();
          System.out.println( BANNER );
  
          super.init();
      }
  
      protected Application newApplication( final String name, final Entry entry )
          throws Exception
      {
          //It is here where you could return new EASServerApplication()
          //if you wanted to host multiple different types of apps
          return new DefaultServerApplication();
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/applications/DefaultServerApplication.java
  
  Index: DefaultServerApplication.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine;
  
  import java.security.Policy;
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.framework.component.Component;
  import org.apache.framework.component.ComponentManager;
  import org.apache.framework.component.ComponentException;
  import org.apache.framework.component.Composer;
  import org.apache.framework.context.Context;
  import org.apache.framework.context.Contextualizable;
  import org.apache.avalon.component.DefaultComponentManager;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.avalon.atlantis.ApplicationException;
  import org.apache.avalon.camelot.AbstractContainer;
  import org.apache.avalon.camelot.pipeline.AvalonState;
  import org.apache.framework.container.ContainerException;
  import org.apache.framework.container.Entry;
  import org.apache.framework.container.Factory;
  import org.apache.avalon.camelot.pipeline.ComponentBuilder;
  import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder;
  import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
  import org.apache.avalon.camelot.pipeline.ContextBuilder;
  import org.apache.avalon.camelot.pipeline.LoggerBuilder;
  import org.apache.avalon.camelot.pipeline.ShutdownPipeline;
  import org.apache.avalon.camelot.pipeline.StartupPipeline;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.framework.thread.ThreadManager;
  import org.apache.phoenix.engine.blocks.BlockDAG;
  import org.apache.phoenix.engine.blocks.BlockEntry;
  import org.apache.phoenix.engine.blocks.RoleEntry;
  import org.apache.phoenix.engine.facilities.DefaultComponentBuilder;
  import org.apache.phoenix.engine.facilities.DefaultComponentManagerBuilder;
  import org.apache.phoenix.engine.facilities.DefaultConfigurationRepository;
  import org.apache.phoenix.engine.facilities.DefaultContextBuilder;
  import org.apache.phoenix.engine.facilities.DefaultLogManager;
  import org.apache.phoenix.engine.facilities.DefaultLoggerBuilder;
  import org.apache.phoenix.engine.facilities.DefaultPolicy;
  import org.apache.phoenix.engine.facilities.DefaultThreadManager;
  import org.apache.phoenix.engine.facilities.SarClassLoader;
  import org.apache.phoenix.engine.phases.DefaultPhase;
  import org.apache.phoenix.engine.phases.Phase;
  import org.apache.phoenix.engine.phases.Traversal;
  import org.apache.phoenix.metainfo.DependencyInfo;
  
  /**
   * This is the basic container of blocks. A server application
   * represents an aggregation of blocks that act together to form
   * an application.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class DefaultServerApplication
      extends AbstractContainer
      implements ServerApplication
  {
      protected HashMap                  m_phases           = new HashMap();
      protected BlockDAG                 m_dag              = new BlockDAG();
  
      //the following are used for setting up facilities
      protected Context                  m_context;
      protected Configuration            m_configuration;
      protected ComponentManager         m_componentManager;
  
      protected DefaultLogManager        m_logManager;
      protected ThreadManager            m_threadManager;
      protected DefaultPolicy            m_policy;
      protected SarClassLoader           m_classLoader;
  
      //these are the facilities (internal components) of ServerApplication
      protected ComponentBuilder         m_componentBuilder;
      protected LoggerBuilder            m_loggerBuilder;
      protected ContextBuilder           m_contextBuilder;
      protected ComponentManagerBuilder  m_componentManagerBuilder;
      protected ConfigurationRepository  m_configurationRepository;
  
      public DefaultServerApplication()
      {
          m_entryClass = BlockEntry.class;
      }
  
      public void contextualize( final Context context )
      {
          //save it to contextualize policy/logManager/etc
          final DefaultContext newContext = new DefaultContext( context );
          newContext.put( "name", context.get( SarContextResources.APP_NAME ) );
          newContext.put( "directory", context.get( SarContextResources.APP_HOME_DIR ) );
          m_context = newContext;
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          m_configuration = configuration;
      }
  
      public void init()
          throws Exception
      {
          createComponents();
  
          //setup the component manager
          m_componentManager = createComponentManager();
  
          setupComponents();
  
          initPhases();
          setupPhases();
      }
  
      protected void initPhases()
          throws ApplicationException
      {
          Phase phase = null;
  
          phase = new DefaultPhase( Phase.FORWARD,
                                    new StartupPipeline(),
                                    AvalonState.BASE,
                                    AvalonState.RUNNING );
          m_phases.put( "startup", phase );
  
          phase = new DefaultPhase( Phase.REVERSE,
                                    new ShutdownPipeline(),
                                    AvalonState.RUNNING,
                                    AvalonState.DISPOSED );
          m_phases.put( "shutdown", phase );
      }
  
      protected void setupPhases()
          throws Exception
      {
          final Iterator phases = m_phases.values().iterator();
          while( phases.hasNext() )
          {
              final Phase phase = (Phase)phases.next();
              setupComponent( phase );
          }
      }
  
      public void start()
          throws Exception
      {
          // load blocks
          try
          {
              getLogger().info( "Number of blocks to load: " + m_entries.size() );
              final Phase phase = (Phase)m_phases.get( "startup" );
              runPhase( phase );
          }
          catch( final ApplicationException ae )
          {
              getLogger().warn( "Error loading blocks: " + ae.getMessage(), ae );
              throw ae;
          }
      }
  
      public void stop()
          throws Exception
      {
      }
  
      public void dispose()
          throws Exception
      {
          getLogger().info( "Number of blocks to unload: " + m_entries.size() );
  
          final Phase phase = (Phase)m_phases.get( "shutdown" );
          runPhase( phase );
  
          m_entries.clear();
      }
  
      /**
       * Create all required components.
       *
       * @exception Exception if an error occurs
       */
      protected void createComponents()
          throws Exception
      {
          //TODO: Refactor logManager so it does more useful managing
          // possibly including setting up rolling etc
          m_logManager = new DefaultLogManager();
  
          m_contextBuilder = new DefaultContextBuilder();
          m_componentManagerBuilder = new DefaultComponentManagerBuilder();
          m_configurationRepository = new DefaultConfigurationRepository();
          m_loggerBuilder = new DefaultLoggerBuilder();
          m_componentBuilder = new DefaultComponentBuilder();
  
          m_classLoader = new SarClassLoader();
          m_threadManager = new DefaultThreadManager();
          m_policy = new DefaultPolicy();
      }
  
      /**
       * Setup all the components. (ir run all required lifecycle methods).
       *
       * @exception Exception if an error occurs
       */
      protected void setupComponents()
          throws Exception
      {
          Configuration configuration = null;
  
          configuration = m_configuration.getChild( "logs" );
          setupComponent( m_logManager, "<core>.logs", configuration );
  
          configuration = m_configuration.getChild( "threads" );
          setupComponent( m_threadManager, "<core>.threads", configuration );
  
          configuration = m_configuration.getChild( "policy" );
          setupComponent( (Component)m_policy, "<policy>", configuration );
  
          setupComponent( m_classLoader );
  
          setupComponent( m_componentBuilder );
          setupComponent( m_loggerBuilder );
          setupComponent( m_contextBuilder );
          setupComponent( m_componentManagerBuilder );
          setupComponent( m_configurationRepository );
  
          setupComponent( m_dag, "<core>.dag", null );
      }
  
      protected void setupComponent( final Component object )
          throws Exception
      {
          setupComponent( object, null, null );
      }
  
      protected void setupComponent( final Component object,
                                     final String logName,
                                     final Configuration configuration )
          throws Exception
      {
          setupLogger( object, logName );
  
          if( object instanceof Contextualizable )
          {
              ((Contextualizable)object).contextualize( m_context );
          }
  
          if( object instanceof Composer )
          {
              ((Composer)object).compose( m_componentManager );
          }
  
          if( object instanceof Configurable )
          {
              ((Configurable)object).configure( configuration );
          }
  
          if( object instanceof Initializable )
          {
              ((Initializable)object).init();
          }
      }
  
      protected void runPhase( final Phase phase )
          throws Exception
      {
  
          if( Phase.FORWARD == phase.getTraversal() )
          {
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  m_dag.walkGraph( name, phase );
              }
          }
          else if( Phase.REVERSE == phase.getTraversal() )
          {
              //TODO:
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  //m_dag.reverseWalkGraph( name, phase );
              }
          }
          else
          {
              //TODO: Does this make sense ????
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  final BlockEntry entry = (BlockEntry)getEntry( name );
                  phase.visitBlock( name, entry );
              }
          }
      }
  
      /**
       * This method is called before entry is added to give chance for
       * sub-class to veto addition.
       *
       * @param name the name of entry
       * @param entry the entry
       * @exception ContainerException to stop removal of entry
       */
      protected void preAdd( final String name, final Entry entry )
          throws ContainerException
      {
          final BlockEntry blockEntry = (BlockEntry)entry;
          verifyDependenciesMap( name, blockEntry );
      }
  
      /**
       * Retrieve a list of RoleEntry objects that were specified
       * in configuration file and verify they were expected based
       * on BlockInfo file. Also verify that all entries specified
       * in BlockInfo file have been provided.
       *
       * @param entry the BlockEntry describing block
       * @return the list of RoleEntry objects
       */
      protected void verifyDependenciesMap( final String name, final BlockEntry entry )
          throws ContainerException
      {
          //Make sure all role entries specified in config file are valid
          final RoleEntry[] roleEntrys = entry.getRoleEntrys();
          for( int i = 0; i < roleEntrys.length; i++ )
          {
              final String role = roleEntrys[ i ].getRole();
              final DependencyInfo info = entry.getBlockInfo().getDependency( role );
  
              if( null == info )
              {
                  final String message = "Unknown dependency " + roleEntrys[ i ].getName() +
                      " with role " + role + " declared for Block " + name;
  
                  getLogger().warn( message );
                  throw new ContainerException( message );
              }
          }
  
          //Make sure all dependencies in BlockInfo file are satisfied
          final DependencyInfo[] dependencies = entry.getBlockInfo().getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              final RoleEntry roleEntry =
                  entry.getRoleEntry( dependencies[ i ].getRole() );
  
              if( null == roleEntry )
              {
                  final String message = "Dependency " + dependencies[ i ].getRole() +
                      " not provided in configuration for Block " + name;
  
                  getLogger().warn( message );
                  throw new ContainerException( message );
              }
          }
      }
  
      /**
       * Create a ComponentManager containing all components in engine.
       *
       * @return the ComponentManager
       */
      protected ComponentManager createComponentManager()
      {
          final DefaultComponentManager componentManager = new DefaultComponentManager();
          componentManager.put( "org.apache.phoenix.engine.ServerApplication", this );
          componentManager.put( "java.security.Policy", m_policy );
          componentManager.put( "java.lang.ClassLoader", m_classLoader );
          componentManager.put( "NOT_DONE_YET", m_logManager );
          componentManager.put( "org.apache.avalon.util.thread.ThreadManager", m_threadManager );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ContextBuilder", m_contextBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.LoggerBuilder", m_loggerBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentBuilder",
                                m_componentBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentManagerBuilder",
                                m_componentManagerBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository",
                                m_configurationRepository );
  
          return componentManager;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/applications/ServerApplicationFactory.java
  
  Index: ServerApplicationFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine;
  
  import java.security.Policy;
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.framework.component.Component;
  import org.apache.framework.component.ComponentManager;
  import org.apache.framework.component.ComponentException;
  import org.apache.framework.component.Composer;
  import org.apache.framework.context.Context;
  import org.apache.framework.context.Contextualizable;
  import org.apache.avalon.component.DefaultComponentManager;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.avalon.atlantis.ApplicationException;
  import org.apache.avalon.camelot.AbstractContainer;
  import org.apache.avalon.camelot.pipeline.AvalonState;
  import org.apache.framework.container.ContainerException;
  import org.apache.framework.container.Entry;
  import org.apache.framework.container.Factory;
  import org.apache.avalon.camelot.pipeline.ComponentBuilder;
  import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder;
  import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
  import org.apache.avalon.camelot.pipeline.ContextBuilder;
  import org.apache.avalon.camelot.pipeline.LoggerBuilder;
  import org.apache.avalon.camelot.pipeline.ShutdownPipeline;
  import org.apache.avalon.camelot.pipeline.StartupPipeline;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.framework.thread.ThreadManager;
  import org.apache.phoenix.engine.blocks.BlockDAG;
  import org.apache.phoenix.engine.blocks.BlockEntry;
  import org.apache.phoenix.engine.blocks.RoleEntry;
  import org.apache.phoenix.engine.facilities.DefaultComponentBuilder;
  import org.apache.phoenix.engine.facilities.DefaultComponentManagerBuilder;
  import org.apache.phoenix.engine.facilities.DefaultConfigurationRepository;
  import org.apache.phoenix.engine.facilities.DefaultContextBuilder;
  import org.apache.phoenix.engine.facilities.DefaultLogManager;
  import org.apache.phoenix.engine.facilities.DefaultLoggerBuilder;
  import org.apache.phoenix.engine.facilities.DefaultPolicy;
  import org.apache.phoenix.engine.facilities.DefaultThreadManager;
  import org.apache.phoenix.engine.facilities.SarClassLoader;
  import org.apache.phoenix.engine.phases.DefaultPhase;
  import org.apache.phoenix.engine.phases.Phase;
  import org.apache.phoenix.engine.phases.Traversal;
  import org.apache.phoenix.metainfo.DependencyInfo;
  
  /**
   * This is the basic container of blocks. A server application
   * represents an aggregation of blocks that act together to form
   * an application.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class DefaultServerApplication
      extends AbstractContainer
      implements ServerApplication
  {
      protected HashMap                  m_phases           = new HashMap();
      protected BlockDAG                 m_dag              = new BlockDAG();
  
      //the following are used for setting up facilities
      protected Context                  m_context;
      protected Configuration            m_configuration;
      protected ComponentManager         m_componentManager;
  
      protected DefaultLogManager        m_logManager;
      protected ThreadManager            m_threadManager;
      protected DefaultPolicy            m_policy;
      protected SarClassLoader           m_classLoader;
  
      //these are the facilities (internal components) of ServerApplication
      protected ComponentBuilder         m_componentBuilder;
      protected LoggerBuilder            m_loggerBuilder;
      protected ContextBuilder           m_contextBuilder;
      protected ComponentManagerBuilder  m_componentManagerBuilder;
      protected ConfigurationRepository  m_configurationRepository;
  
      public DefaultServerApplication()
      {
          m_entryClass = BlockEntry.class;
      }
  
      public void contextualize( final Context context )
      {
          //save it to contextualize policy/logManager/etc
          final DefaultContext newContext = new DefaultContext( context );
          newContext.put( "name", context.get( SarContextResources.APP_NAME ) );
          newContext.put( "directory", context.get( SarContextResources.APP_HOME_DIR ) );
          m_context = newContext;
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          m_configuration = configuration;
      }
  
      public void init()
          throws Exception
      {
          createComponents();
  
          //setup the component manager
          m_componentManager = createComponentManager();
  
          setupComponents();
  
          initPhases();
          setupPhases();
      }
  
      protected void initPhases()
          throws ApplicationException
      {
          Phase phase = null;
  
          phase = new DefaultPhase( Phase.FORWARD,
                                    new StartupPipeline(),
                                    AvalonState.BASE,
                                    AvalonState.RUNNING );
          m_phases.put( "startup", phase );
  
          phase = new DefaultPhase( Phase.REVERSE,
                                    new ShutdownPipeline(),
                                    AvalonState.RUNNING,
                                    AvalonState.DISPOSED );
          m_phases.put( "shutdown", phase );
      }
  
      protected void setupPhases()
          throws Exception
      {
          final Iterator phases = m_phases.values().iterator();
          while( phases.hasNext() )
          {
              final Phase phase = (Phase)phases.next();
              setupComponent( phase );
          }
      }
  
      public void start()
          throws Exception
      {
          // load blocks
          try
          {
              getLogger().info( "Number of blocks to load: " + m_entries.size() );
              final Phase phase = (Phase)m_phases.get( "startup" );
              runPhase( phase );
          }
          catch( final ApplicationException ae )
          {
              getLogger().warn( "Error loading blocks: " + ae.getMessage(), ae );
              throw ae;
          }
      }
  
      public void stop()
          throws Exception
      {
      }
  
      public void dispose()
          throws Exception
      {
          getLogger().info( "Number of blocks to unload: " + m_entries.size() );
  
          final Phase phase = (Phase)m_phases.get( "shutdown" );
          runPhase( phase );
  
          m_entries.clear();
      }
  
      /**
       * Create all required components.
       *
       * @exception Exception if an error occurs
       */
      protected void createComponents()
          throws Exception
      {
          //TODO: Refactor logManager so it does more useful managing
          // possibly including setting up rolling etc
          m_logManager = new DefaultLogManager();
  
          m_contextBuilder = new DefaultContextBuilder();
          m_componentManagerBuilder = new DefaultComponentManagerBuilder();
          m_configurationRepository = new DefaultConfigurationRepository();
          m_loggerBuilder = new DefaultLoggerBuilder();
          m_componentBuilder = new DefaultComponentBuilder();
  
          m_classLoader = new SarClassLoader();
          m_threadManager = new DefaultThreadManager();
          m_policy = new DefaultPolicy();
      }
  
      /**
       * Setup all the components. (ir run all required lifecycle methods).
       *
       * @exception Exception if an error occurs
       */
      protected void setupComponents()
          throws Exception
      {
          Configuration configuration = null;
  
          configuration = m_configuration.getChild( "logs" );
          setupComponent( m_logManager, "<core>.logs", configuration );
  
          configuration = m_configuration.getChild( "threads" );
          setupComponent( m_threadManager, "<core>.threads", configuration );
  
          configuration = m_configuration.getChild( "policy" );
          setupComponent( (Component)m_policy, "<policy>", configuration );
  
          setupComponent( m_classLoader );
  
          setupComponent( m_componentBuilder );
          setupComponent( m_loggerBuilder );
          setupComponent( m_contextBuilder );
          setupComponent( m_componentManagerBuilder );
          setupComponent( m_configurationRepository );
  
          setupComponent( m_dag, "<core>.dag", null );
      }
  
      protected void setupComponent( final Component object )
          throws Exception
      {
          setupComponent( object, null, null );
      }
  
      protected void setupComponent( final Component object,
                                     final String logName,
                                     final Configuration configuration )
          throws Exception
      {
          setupLogger( object, logName );
  
          if( object instanceof Contextualizable )
          {
              ((Contextualizable)object).contextualize( m_context );
          }
  
          if( object instanceof Composer )
          {
              ((Composer)object).compose( m_componentManager );
          }
  
          if( object instanceof Configurable )
          {
              ((Configurable)object).configure( configuration );
          }
  
          if( object instanceof Initializable )
          {
              ((Initializable)object).init();
          }
      }
  
      protected void runPhase( final Phase phase )
          throws Exception
      {
  
          if( Phase.FORWARD == phase.getTraversal() )
          {
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  m_dag.walkGraph( name, phase );
              }
          }
          else if( Phase.REVERSE == phase.getTraversal() )
          {
              //TODO:
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  //m_dag.reverseWalkGraph( name, phase );
              }
          }
          else
          {
              //TODO: Does this make sense ????
              final Iterator entries = list();
              while( entries.hasNext() )
              {
                  final String name = (String)entries.next();
                  final BlockEntry entry = (BlockEntry)getEntry( name );
                  phase.visitBlock( name, entry );
              }
          }
      }
  
      /**
       * This method is called before entry is added to give chance for
       * sub-class to veto addition.
       *
       * @param name the name of entry
       * @param entry the entry
       * @exception ContainerException to stop removal of entry
       */
      protected void preAdd( final String name, final Entry entry )
          throws ContainerException
      {
          final BlockEntry blockEntry = (BlockEntry)entry;
          verifyDependenciesMap( name, blockEntry );
      }
  
      /**
       * Retrieve a list of RoleEntry objects that were specified
       * in configuration file and verify they were expected based
       * on BlockInfo file. Also verify that all entries specified
       * in BlockInfo file have been provided.
       *
       * @param entry the BlockEntry describing block
       * @return the list of RoleEntry objects
       */
      protected void verifyDependenciesMap( final String name, final BlockEntry entry )
          throws ContainerException
      {
          //Make sure all role entries specified in config file are valid
          final RoleEntry[] roleEntrys = entry.getRoleEntrys();
          for( int i = 0; i < roleEntrys.length; i++ )
          {
              final String role = roleEntrys[ i ].getRole();
              final DependencyInfo info = entry.getBlockInfo().getDependency( role );
  
              if( null == info )
              {
                  final String message = "Unknown dependency " + roleEntrys[ i ].getName() +
                      " with role " + role + " declared for Block " + name;
  
                  getLogger().warn( message );
                  throw new ContainerException( message );
              }
          }
  
          //Make sure all dependencies in BlockInfo file are satisfied
          final DependencyInfo[] dependencies = entry.getBlockInfo().getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              final RoleEntry roleEntry =
                  entry.getRoleEntry( dependencies[ i ].getRole() );
  
              if( null == roleEntry )
              {
                  final String message = "Dependency " + dependencies[ i ].getRole() +
                      " not provided in configuration for Block " + name;
  
                  getLogger().warn( message );
                  throw new ContainerException( message );
              }
          }
      }
  
      /**
       * Create a ComponentManager containing all components in engine.
       *
       * @return the ComponentManager
       */
      protected ComponentManager createComponentManager()
      {
          final DefaultComponentManager componentManager = new DefaultComponentManager();
          componentManager.put( "org.apache.phoenix.engine.ServerApplication", this );
          componentManager.put( "java.security.Policy", m_policy );
          componentManager.put( "java.lang.ClassLoader", m_classLoader );
          componentManager.put( "NOT_DONE_YET", m_logManager );
          componentManager.put( "org.apache.avalon.util.thread.ThreadManager", m_threadManager );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ContextBuilder", m_contextBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.LoggerBuilder", m_loggerBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentBuilder",
                                m_componentBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentManagerBuilder",
                                m_componentManagerBuilder );
          componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository",
                                m_configurationRepository );
  
          return componentManager;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/DefaultSarDeployer.java
  
  Index: DefaultSarDeployer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipFile;
  import org.apache.avalon.ComponentManager;
  import org.apache.avalon.ComponentManagerException;
  import org.apache.framework.component.Composer;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.DefaultComponentManager;
  import org.apache.avalon.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.DefaultContext;
  import org.apache.avalon.camelot.AbstractCamelotDeployer;
  import org.apache.avalon.camelot.CamelotUtil;
  import org.apache.avalon.camelot.ContainerException;
  import org.apache.avalon.camelot.DefaultLocatorRegistry;
  import org.apache.avalon.camelot.DefaultRegistry;
  import org.apache.avalon.camelot.Deployer;
  import org.apache.avalon.camelot.DeployerUtil;
  import org.apache.avalon.camelot.DeploymentException;
  import org.apache.avalon.camelot.Locator;
  import org.apache.avalon.camelot.LocatorRegistry;
  import org.apache.avalon.camelot.Registry;
  import org.apache.avalon.camelot.RegistryException;
  import org.apache.avalon.util.io.FileUtil;
  import org.apache.avalon.util.io.IOUtil;
  import org.apache.phoenix.BlockContext;
  import org.apache.phoenix.metainfo.BlockInfo;
  import org.apache.phoenix.engine.blocks.BlockEntry;
  import org.apache.phoenix.engine.blocks.RoleEntry;
  import org.apache.phoenix.engine.blocks.DefaultBlockDeployer;
  
  /**
   * This class deploys a .sar file.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultSarDeployer
      extends AbstractCamelotDeployer
  {
      protected File            m_deployDirectory;
  
      /**
       * Default constructor.
       */
      public DefaultSarDeployer()
      {
          m_deployToContainer = true;
          m_autoUndeploy = true;
          m_type = "Sar";
      }
  
      protected void deployFromFile( final String name, final File file )
          throws DeploymentException
      {
          if( file.isDirectory() )
          {
              throw new DeploymentException( "Deploying directories is not supported" );
          }
          else
          {
              final File destination = getDestinationFor( name, file );
              expandTo( file, destination );
              deployFromDirectory( file, name, destination );
          }
      }
  
      protected void expandTo( final File file, final File directory )
          throws DeploymentException
      {
          final ZipFile zipFile = DeployerUtil.getZipFileFor( file );
  
          if( !needsExpanding( zipFile, directory ) )
          {
              return;
          }
  
          directory.mkdirs();
  
          final Enumeration entries = zipFile.entries();
          while( entries.hasMoreElements() )
          {
              final ZipEntry entry = (ZipEntry)entries.nextElement();
              if( entry.isDirectory() ) continue;
  
              final String name = entry.getName().replace( '/', File.separatorChar );
              if( !shouldExpandEntry( entry.getName() ) ) continue;
  
              final File destination = new File( directory, name );
  
              InputStream input = null;
              OutputStream output = null;
  
              try
              {
                  destination.getParentFile().mkdirs();
                  output = new FileOutputStream( destination );
                  input = zipFile.getInputStream( entry );
                  IOUtil.copy( input, output );
              }
              catch( final IOException ioe )
              {
                  throw new DeploymentException( "Error extracting " + name, ioe );
              }
              finally
              {
                  IOUtil.shutdownStream( input );
                  IOUtil.shutdownStream( output );
              }
          }
      }
  
      protected boolean shouldExpandEntry( final String name )
      {
          if( name.startsWith( "META-INF" ) ) return false;
          else return true;
      }
  
      protected boolean needsExpanding( final ZipFile zipFile, final File directory )
      {
          return !directory.exists();
      }
  
      protected File getDestinationFor( final String location, final File file )
      {
          final String name =
              FileUtil.removeExtention( FileUtil.removePath( file.getName() ) );
  
          if( null != m_deployDirectory )
          {
              return (new File( m_deployDirectory, name )).getAbsoluteFile();
          }
          else
          {
              return (new File( file.getParentFile(), name )).getAbsoluteFile();
          }
      }
  
      protected ServerKernel getKernel()
          throws DeploymentException
      {
          if( !(m_container instanceof ServerKernel) )
          {
              throw new DeploymentException( "Can only deploy to a kernel container" );
          }
          else
          {
              return (ServerKernel)m_container;
          }
      }
  
      protected void buildEntry( final String name,
                                 final ServerApplicationEntry entry,
                                 final File archive,
                                 final File directory )
          throws DeploymentException
      {
          //final File file = new File( directory, "SAR-INF" + File.separator + "sar-inf.xml" );
  
          //setup the ServerApplications context
          final DefaultContext context = new DefaultContext();
          context.put( SarContextResources.APP_ARCHIVE, archive );
          context.put( SarContextResources.APP_HOME_DIR, directory );
          context.put( SarContextResources.APP_NAME, name );
          entry.setContext( context );
  
          //setup the ServerApplications component manager
          final DefaultComponentManager componentManager = new DefaultComponentManager();
          componentManager.put( "org.apache.avalon.camelot.Registry",
                                new DefaultRegistry( BlockInfo.class ) );
          componentManager.put( "org.apache.avalon.camelot.LocatorRegistry",
                                new DefaultLocatorRegistry() );
          entry.setComponentManager( componentManager );
  
          //setup the ServerApplications configuration manager
          final File file = new File( directory, "conf" + File.separator + "server.xml" );
          final Configuration configuration = getConfigurationFor( file );
          entry.setConfiguration( configuration );
      }
  
      protected void deployFromDirectory( final File archive,
                                          final String name,
                                          final File directory )
          throws DeploymentException
      {
          getLogger().info( "deploying from archive (" + archive +
                            ") expanded into directory " + directory );
  
          final ServerApplicationEntry entry = new ServerApplicationEntry();
          buildEntry( name, entry, archive, directory );
          addEntry( name, entry );
  
          final ServerKernel kernel = getKernel();
          ServerApplication serverApplication = null;
          try
          {
              serverApplication = (ServerApplication)kernel.getApplication( name );
          }
          catch( final ContainerException ce )
          {
              throw new DeploymentException( "Error preparingserver application", ce );
          }
  
          //rework next bit so it grabs deployments from archive
          final Deployer deployer = getBlockDeployer( entry );
          final File blocksDirectory = new File( directory, "blocks" );
          CamelotUtil.deployFromDirectory( deployer, blocksDirectory, ".bar" );
  
          final File file =
              new File( directory, "conf" + File.separator + "assembly.xml" );
  
          try
          {
              final Configuration configuration = getConfigurationFor( file );
              final Configuration[] blocks = configuration.getChildren( "block" );
              handleBlocks( serverApplication, entry, blocks );
          }
          catch( final ComponentManagerException cme )
          {
              throw new DeploymentException( "Error setting up registries", cme );
          }
          catch( final ConfigurationException ce )
          {
              throw new DeploymentException( "Error in assembly.xml", ce );
          }
      }
  
      protected Configuration getConfigurationFor( final File file )
          throws DeploymentException
      {
          try
          {
              final FileInputStream input = new FileInputStream( file );
              return DeployerUtil.buildConfiguration( input );
          }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error reading " + file, ioe );
          }
      }
  
      protected Deployer getBlockDeployer( final ServerApplicationEntry entry )
          throws DeploymentException
      {
          final Deployer deployer = new DefaultBlockDeployer();
          setupLogger( deployer );
  
          if( deployer instanceof Composer )
          {
              try { ((Composer)deployer).compose( entry.getComponentManager() ); }
              catch( final Exception e )
              {
                  throw new DeploymentException( "Error composing block deployer", e );
              }
          }
  
          return deployer;
      }
  
      protected void handleBlocks( final ServerApplication serverApplication,
                                   final ServerApplicationEntry saEntry,
                                   final Configuration[] blocks )
          throws ComponentManagerException, ConfigurationException, DeploymentException
      {
          final ComponentManager componentManager = saEntry.getComponentManager();
  
          final Registry infoRegistry =
              (Registry)componentManager.lookup( "org.apache.avalon.camelot.Registry" );
  
          final LocatorRegistry locatorRegistry = (LocatorRegistry)componentManager.
              lookup( "org.apache.avalon.camelot.LocatorRegistry" );
  
          for( int i = 0; i < blocks.length; i++ )
          {
              final Configuration block = blocks[ i ];
              final String name = block.getAttribute("name");
              final String className = block.getAttribute("class");
  
              BlockInfo info = null;
  
              try { info = (BlockInfo)infoRegistry.getInfo( className ); }
              catch( final RegistryException re )
              {
                  throw new DeploymentException( "Failed to aquire BlockInfo for " + className,
                                                 re );
              }
  
              Locator locator = null;
              try { locator = locatorRegistry.getLocator( className ); }
              catch( final RegistryException re )
              {
                  throw new DeploymentException( "Failed to aquire Locator for " + className,
                                                 re );
              }
  
              final Configuration[] provides = block.getChildren( "provide" );
              final ArrayList roleList = new ArrayList();
              for( int j = 0; j < provides.length; j++ )
              {
                  final Configuration provide = provides[ j ];
                  final String requiredName = provide.getAttribute("name");
                  final String role = provide.getAttribute("role");
  
                  roleList.add( new RoleEntry( requiredName, role ) );
              }
  
              final RoleEntry[] roles = (RoleEntry[]) roleList.toArray( new RoleEntry[ 0 ] );
              final BlockEntry entry = new BlockEntry( locator, roles );
  
              entry.setBlockInfo( info );
              entry.setConfiguration( block.getChild( "configuration" ) );
  
              try { serverApplication.add( name, entry ); }
              catch( final ContainerException ce )
              {
                  throw new DeploymentException( "Error adding component to container", ce );
              }
  
              getLogger().debug( "Adding " + m_type + "Entry " + name + " as " + entry );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockDAG.java
  
  Index: BlockDAG.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  import java.util.Iterator;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.framework.component.ComponentManager;
  import org.apache.framework.component.ComponentException;
  import org.apache.framework.component.Composer;
  import org.apache.framework.container.ContainerException;
  import org.apache.phoenix.Block;
  import org.apache.phoenix.engine.ServerApplication;
  import org.apache.phoenix.metainfo.DependencyInfo;
  import org.apache.phoenix.metainfo.ServiceInfo;
  
  /**
   * This is the dependency graph for blocks.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class BlockDAG
      extends AbstractLoggable
      implements Composer
  {
      protected ServerApplication       m_serverApplication;
  
      public void compose( final ComponentManager componentManager )
          throws ComponentException
      {
          m_serverApplication = (ServerApplication)componentManager.
              lookup( "org.apache.phoenix.engine.ServerApplication" );
      }
  
      public void walkGraph( final String root, final BlockVisitor visitor )
          throws Exception
      {
          visitBlock( root, getBlockEntry( root ), visitor, true );
      }
  
      public void reverseWalkGraph( final String root, final BlockVisitor visitor )
          throws Exception
      {
          visitBlock( root, getBlockEntry( root ), visitor, false );
      }
  
      protected BlockEntry getBlockEntry( final String name )
          throws Exception
      {
          return (BlockEntry)m_serverApplication.getEntry( name );
          //catch( final ContainerException ce )
      }
  
      /**
       * Traverse dependencies of specified entry.
       *
       * @param name name of BlockEntry
       * @param entry the BlockEntry
       */
      protected void visitDependencies( final String name,
                                        final BlockEntry entry,
                                        final BlockVisitor visitor )
          throws Exception
      {
          getLogger().debug( "Traversing dependencies for " + name );
  
          final DependencyInfo[] infos = entry.getBlockInfo().getDependencies();
          for( int i = 0; i < infos.length; i++ )
          {
              final ServiceInfo serviceInfo = infos[ i ].getService();
              final String role = infos[ i ].getRole();
  
              getLogger().debug( "Traversing dependency of " + name + " with role " + role +
                                 " to provide service " + serviceInfo.getName() );
  
              //roleEntry should NEVER be null as it is checked when
              //entry is added to container
              final RoleEntry roleEntry = entry.getRoleEntry( role );
              final String dependencyName = roleEntry.getName();
              final BlockEntry dependency = getBlockEntry( dependencyName );
              visitBlock( dependencyName, dependency, visitor, true );
          }
      }
  
      /**
       * Traverse all reverse dependencies of specified entry.
       * A reverse dependency are those that dependend on entry.
       *
       * @param name name of BlockEntry
       * @param entry the BlockEntry
       */
      protected void visitReverseDependencies( final String name, final BlockVisitor visitor )
          throws Exception
      {
          getLogger().debug( "Traversing reverse dependencies for " + name );
  
          final Iterator entries = m_serverApplication.list();
          while( entries.hasNext() )
          {
              final String blockName = (String)entries.next();
              final BlockEntry entry = getBlockEntry( blockName );
              final RoleEntry[] roles = entry.getRoleEntrys();
  
              for( int i = 0; i < roles.length; i++ )
              {
                  final String depends = roles[ i ].getName();
  
                  if( depends.equals( name ) )
                  {
                      getLogger().debug( "Attempting to unload block " + blockName +
                                         " as it depends on " + depends );
  
                      //finally try to traverse block
                      visitBlock( blockName, entry, visitor, false );
                  }
              }
          }
      }
  
      protected void visitBlock( final String name,
                                 final BlockEntry entry,
                                 final BlockVisitor visitor,
                                 final boolean forward )
          throws Exception
      {
          if( forward )
          {
              visitDependencies( name, entry, visitor );
          }
          else
          {
              visitReverseDependencies( name, visitor );
          }
  
          visitor.visitBlock( name, entry );
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockEntry.java
  
  Index: BlockEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  import org.apache.avalon.camelot.Entry;
  import org.apache.framework.container.Locator;
  import org.apache.avalon.camelot.AvalonState;
  import org.apache.framework.configuration.Configuration;
  import org.apache.phoenix.Block;
  import org.apache.phoenix.metainfo.BlockInfo;
  
  /**
   * This is the structure describing each block before it is loaded.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class BlockEntry
      extends Entry
  {
      protected final Locator               m_locator;
      protected final RoleEntry[]           m_roleEntrys;
  
      //UGLY HACK should be stored in another server Facility (ie ConfigurationRepository)
      protected Configuration               m_configuration;
  
      public BlockEntry( final Locator locator, final RoleEntry[] roleEntrys )
      {
          setState( AvalonState.BASE );
          m_locator = locator;
          m_roleEntrys = roleEntrys;
      }
  
      public Locator getLocator()
      {
          return m_locator;
      }
  
      public BlockInfo getBlockInfo()
      {
          return (BlockInfo)getInfo();
      }
  
      public void setBlockInfo( final BlockInfo blockInfo )
      {
          setInfo(  blockInfo );
      }
  
      /**
       * Get a RoleEntry from entry with a particular role.
       *
       * @param role the role of RoleEntry to look for
       * @return the matching deendency else null
       */
      public RoleEntry getRoleEntry( final String role )
      {
          for( int i = 0; i < m_roleEntrys.length; i++ )
          {
              if( m_roleEntrys[ i ].getRole().equals( role ) )
              {
                  return m_roleEntrys[ i ];
              }
          }
  
          return null;
      }
  
      public RoleEntry[] getRoleEntrys()
      {
          return m_roleEntrys;
      }
  
      public Configuration getConfiguration()
      {
          return m_configuration;
      }
  
      public void setConfiguration( final Configuration configuration )
      {
          m_configuration = configuration;
      }
  
      public Block getBlock()
      {
          return (Block)getInstance();
      }
  
      public void setBlock( final Block block )
      {
          setInstance( block );
      }
      public void setInfo( final BlockInfo info )
      {
          //m_info = info;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockVisitor.java
  
  Index: BlockVisitor.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  import org.apache.avalon.atlantis.ApplicationException;
  
  /**
   * Visitor interface that objects implement to walk the DAG.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface BlockVisitor
  {
      /**
       * This is called when a block is reached whilst walking the tree.
       *
       * @param name the name of block
       * @param entry the BlockEntry
       * @exception ApplicationException if walking is to be stopped
       */
      void visitBlock( String name, BlockEntry entry )
          throws ApplicationException;
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/DefaultBlockContext.java
  
  Index: DefaultBlockContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  import java.io.File;
  import org.apache.framework.context.Context;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.framework.thread.ThreadManager;
  import org.apache.framework.thread.ThreadPool;
  import org.apache.log.Logger;
  import org.apache.phoenix.BlockContext;
  
  /**
   * Context via which Blocks communicate with container.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultBlockContext
      extends DefaultContext
      implements BlockContext
  {
      protected ThreadManager  m_threadManager;
      protected Logger         m_baseLogger;
  
      public DefaultBlockContext( final Logger logger, final ThreadManager threadManager )
      {
          this( logger, threadManager, null );
      }
  
      public DefaultBlockContext( final Logger logger,
                                  final ThreadManager threadManager,
                                  final Context context )
      {
          super( context );
          m_baseLogger = logger;
          m_threadManager = threadManager;
      }
  
      /**
       * Base directory of .sar application.
       *
       * @return the base directory
       */
      public File getBaseDirectory()
      {
          return (File)get( APP_HOME_DIR );
      }
  
      /**
       * Retrieve name of block.
       *
       * @return the name of block
       */
      public String getName()
      {
          return (String)get( NAME );
      }
  
      /**
       * Retrieve thread manager by category.
       * ThreadManagers are given names so that you can manage different thread
       * count to different components.
       *
       * @param category the category
       * @return the ThreadManager
       */
      public ThreadPool getThreadPool( final String category )
      {
          return m_threadManager.getThreadPool( category );
      }
  
      /**
       * Retrieve the default thread pool.
       * Equivelent to getThreadPool( "default" );
       * @return the ThreadPool
       */
      public ThreadPool getDefaultThreadPool()
      {
          return getThreadPool( "default" );
      }
  
      /**
       * Retrieve logger coresponding to root category of application.
       *
       * @return the base logger
       */
      public Logger getBaseLogger()
      {
          return m_baseLogger;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/DefaultBlockDeployer.java
  
  Index: DefaultBlockDeployer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.util.zip.ZipFile;
  import org.apache.avalon.camelot.AbstractZipDeployer;
  import org.apache.avalon.camelot.DeployerUtil;
  import org.apache.framework.container.DeploymentException;
  import org.apache.framework.container.LocatorRegistry;
  import org.apache.framework.container.Registry;
  import org.apache.framework.container.RegistryException;
  import org.apache.aut.io.IOUtil;
  import org.apache.phoenix.metainfo.BlockInfo;
  import org.apache.phoenix.metainfo.BlockInfoBuilder;
  
  /**
   * This class deploys a .bar file into a registry.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultBlockDeployer
      extends AbstractZipDeployer
  {
      protected BlockInfoBuilder    m_builder;
  
      /**
       * Default constructor.
       */
      public DefaultBlockDeployer()
      {
          m_builder = new BlockInfoBuilder();
  
          //Indicate that this deployer should deploy to respective types
          m_deployToLocatorRegistry = true;
          m_deployToInfoRegistry = true;
  
          m_autoUndeploy = true;
          m_type = "Block";
      }
  
      /**
       * Load resources from jar required to deploy file.
       *
       * @param zipFile the zipFile
       * @param location the location deploying to
       * @param url the URL
       * @exception DeploymentException if an error occurs
       */
      protected void loadResources( final ZipFile zipFile, final String location, final URL url )
          throws DeploymentException
      {
          handleBlocks( zipFile, DeployerUtil.loadManifest( zipFile ), url );
      }
  
      /**
       * Create and register Infos for all blocks stored in deployment.
       *
       * @param properties the properties
       * @param url the url of deployment
       * @exception DeploymentException if an error occurs
       */
      protected void handleBlocks( final ZipFile zipFile, final Manifest manifest, final URL url )
          throws DeploymentException
      {
          final Map entries = manifest.getEntries();
          final Iterator sections = entries.keySet().iterator();
  
          //for every section (aka resource)
          // check to see if the attribute "Avalon-Block" is set to true
          while( sections.hasNext() )
          {
              final String section = (String)sections.next();
              final Attributes attributes = manifest.getAttributes( section );
              final String blockValue = attributes.getValue( "Avalon-Block" );
              final boolean isBlock = Boolean.valueOf( blockValue ).booleanValue();
  
              if( isBlock )
              {
                  handleBlock( zipFile, section, url );
              }
          }
      }
  
      /**
       * Handle the addition of a block from .bar file.
       *
       * @param zipFile the .bar zip
       * @param block the block filename
       * @param url the url of .bar file
       * @exception DeploymentException if an error occurs
       */
      protected void handleBlock( final ZipFile zipFile, final String block, final URL url )
          throws DeploymentException
      {
          final String classname = block.substring( 0, block.length() - 6 ).replace('/','.');
          addLocator( classname, classname, url );
  
          final BlockInfo info = loadBlockInfo( zipFile, classname, url );
          addInfo( classname, info );
      }
  
      /**
       * Create a blockinfo object by loading a .xinfo file.
       *
       * @param zipFile the zipFile to load it from
       * @param classname the name of the block class
       * @param url the url for zip
       * @return the created block info
       * @exception DeploymentException if an error occurs
       */
      protected BlockInfo loadBlockInfo( final ZipFile zipFile,
                                         final String classname,
                                         final URL url )
          throws DeploymentException
      {
          final String resource = classname.replace( '.', '/' ) + ".xinfo";
          final InputStream inputStream = DeployerUtil.loadResourceStream( zipFile, resource );
  
          try { return m_builder.build( inputStream ); }
          catch( final Exception e )
          {
              throw new DeploymentException( "Failed to build BlockInfo for " + classname +
                                             " in location " + url, e );
          }
          finally
          {
              IOUtil.shutdownStream( inputStream );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/RoleEntry.java
  
  Index: RoleEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.blocks;
  
  /**
   * This is the structure describing the instances of roles provided to each block.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class RoleEntry
  {
      protected final String        m_name;
      protected final String        m_role;
  
      public RoleEntry( final String name, final String role )
      {
          m_name = name;
          m_role = role;
      }
  
      public String getRole()
      {
          return m_role;
      }
      
      public String getName()
      {
          return m_name;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ApplicationManager.java
  
  Index: ApplicationManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.loader;
  
  import java.io.File;
  import java.lang.reflect.Method;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.security.AccessControlContext;
  import java.security.AccessController;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Policy;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.security.ProtectionDomain;
  import java.security.Security;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.StringTokenizer;
  
  /**
   * PhoenixLoader is the class that bootstraps and installs the security manager.
   * It also a default policy that gives all code all permssions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class PhoenixLoader
  {
      protected final static boolean         ENABLE_SECURITY_MANAGER =
          !Boolean.getBoolean("phoenix.insecure");
  
      protected final static String          RESTRICTED_PACKAGES = 
          System.getProperty( "phoenix.restricted.packages", 
                              Security.getProperty("package.access") );
  
      protected final static String          MAIN_JAR =
          System.getProperty( "phoenix.mainJar", "phoenix-engine.jar" );
  
      protected final static String          MAIN_CLASS =
          System.getProperty( "phoenix.mainClass", "org.apache.phoenix.engine.Main" );
  
      public final static void main( final String args[] )
          throws Exception
      {
          //setup restricted packages
          Security.setProperty( "phoenix.access", RESTRICTED_PACKAGES );
  
          //setup new Policy manager
          Policy.setPolicy( new FreeNEasyPolicy() );
  
          final File loaderDir = findLoaderDir();
          final String avalonHome = 
              loaderDir.getAbsoluteFile().getParentFile() + File.separator;
          System.setProperty( "phoenix.home", avalonHome );
  
          final File mainJar = new File( loaderDir, MAIN_JAR );
  
          //load main jar
          final URL archive = mainJar.toURL();
          final URLClassLoader classLoader = new URLClassLoader( new URL[] { archive } );
  
          runSystem( classLoader, args );
      }
  
      /**
       * load class and retrieve appropriate main method.
       */
      protected static void runSystem( final ClassLoader classLoader, final String[] args )
      {
          try
          {
              final Class clazz = classLoader.loadClass( MAIN_CLASS );
              final Method method = clazz.getMethod( "main", new Class[] { args.getClass() } );
  
              final Object instance = clazz.newInstance();
  
              // Set security manager unless it has been disabled by system property
              if( ENABLE_SECURITY_MANAGER )
              {
                  System.setSecurityManager( new SecurityManager() );
              }
  
              //kick the tires and light the fires....
              try
              {
                  final PrivilegedExceptionAction action = new PrivilegedExceptionAction() 
                  {
                      public Object run() throws Exception
                      {        
                          method.invoke( instance, new Object[] { args } );
                          return null;
                      }
                  };
                  
                  AccessController.doPrivileged( action );
              } 
              catch( final PrivilegedActionException pae )
              {
                  // only "checked" exceptions will be "wrapped" in a PrivilegedActionException.
                  throw pae.getException();
              }
          }
          catch( final Exception throwable ) 
          {
              throwable.printStackTrace( System.err );
          }
      }
  
      /**
       *  Finds the avalon-loader.jar file in the classpath.
       */
      protected final static File findLoaderDir() 
          throws Exception
      {
          final String classpath = System.getProperty( "java.class.path" );
          final String pathSeparator = System.getProperty( "path.separator" );
          final StringTokenizer tokenizer = new StringTokenizer( classpath, pathSeparator );
          
          while( tokenizer.hasMoreTokens() )
          {
              final String element = tokenizer.nextToken();
              
              if( element.endsWith( "phoenix-loader.jar" ) )
              {
                  File file = (new File( element )).getCanonicalFile();
                  file = file.getParentFile();
                  return file;                
              }
          }
          
          throw new Exception( "Unable to locate avalon-loader.jar in classpath" );
      }
  
      /**
       * Default polic class to give every code base all permssions. 
       * Will be replaced once the kernel loads.
       */
      private static class FreeNEasyPolicy
          extends Policy
      {
          public PermissionCollection getPermissions( final CodeSource codeSource )
          {
              final Permissions permissions = new Permissions();
              permissions.add( new java.security.AllPermission() );
              return permissions;
          }
  
          public void refresh() {}
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ClassLoader.java
  
  Index: ClassLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import java.io.File;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.security.Policy;
  import org.apache.framework.component.ComponentManager;
  import org.apache.framework.component.ComponentException;
  import org.apache.framework.component.Composer;
  import org.apache.framework.context.Context;
  import org.apache.framework.context.Contextualizable;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.avalon.atlantis.Facility;
  import org.apache.aut.io.ExtensionFileFilter;
  import org.apache.aut.security.PolicyClassLoader;
  import org.apache.phoenix.engine.SarContextResources;
  
  /**
   * This component creates blocks and blockInfos.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class SarClassLoader
      extends PolicyClassLoader
      implements Facility, Contextualizable, Composer, Initializable
  {
      protected File              m_baseDirectory;
  
      public SarClassLoader()
      {
          super( new URL[ 0 ], Thread.currentThread().getContextClassLoader(), null );
      }
  
      public void contextualize( final Context context )
      {
          m_baseDirectory = (File)context.get( SarContextResources.APP_HOME_DIR );
      }
  
      public void compose( final ComponentManager componentManager )
          throws ComponentException
      {
          m_policy = (Policy)componentManager.lookup( "java.security.Policy" );
      }
  
      public void init()
          throws Exception
      {
          final File blockDir =
              (new File( m_baseDirectory, "blocks" )).getAbsoluteFile();
          final File libDir =
              (new File( m_baseDirectory, "lib" )).getAbsoluteFile();
  
          addURLs( blockDir, new String[] { ".bar" } );
          addURLs( libDir, new String[] { ".jar", ".zip" } );
      }
  
      protected void addURLs( final File directory, final String[] extentions )
          throws MalformedURLException
      {
          final ExtensionFileFilter filter = new ExtensionFileFilter( extentions );
          final File[] files = directory.listFiles( filter );
          if( null == files ) return;
          addURLs( files );
      }
  
      protected void addURLs( final File[] files )
          throws MalformedURLException
      {
          for( int i = 0; i < files.length; i++ )
          {
              addURL( files[ i ].toURL() );
          }
      }
  
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "ClassLoader[" );
  
          final URL[] urls = getURLs();
  
          for( int i = 0; i < urls.length; i++ )
          {
              sb.append( ' ' );
              sb.append( urls[ i ] );
          }
  
          sb.append( " ]" );
          return sb.toString();
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ConfigurationManager.java
  
  Index: ConfigurationManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import org.apache.avalon.atlantis.Facility;
  import org.apache.avalon.camelot.Entry;
  import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.phoenix.engine.blocks.BlockEntry;
  
  /**
   * Repository from which all configuration data is retrieved.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultConfigurationRepository
      implements Facility
  {
      public Configuration getConfiguration( String name, Entry entry )
          throws ConfigurationException
      {
          final BlockEntry blockEntry = (BlockEntry)entry;
          return blockEntry.getConfiguration();
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/LogManager.java
  
  Index: LogManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import java.io.File;
  import java.io.IOException;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.Iterator;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.framework.context.Context;
  import org.apache.framework.context.Contextualizable;
  import org.apache.avalon.atlantis.Facility;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.log.format.AvalonLogFormatter;
  import org.apache.log.Category;
  import org.apache.log.LogKit;
  import org.apache.log.LogTarget;
  import org.apache.log.output.FileOutputLogTarget;
  
  /**
   * Component responsible for managing logs.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultLogManager
      extends AbstractLoggable
      implements Facility, Contextualizable, Configurable
  {
      protected String        m_baseName;
      protected File          m_baseDirectory;
  
      public void contextualize( final Context context )
      {
          m_baseName = (String)context.get( "name" );
          if( null == m_baseName ) m_baseName = "<base>";
  
          m_baseDirectory = (File)context.get( "directory" );
          if( null == m_baseDirectory ) m_baseDirectory = new File( "." );
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Iterator targets = configuration.getChildren( "log-target" );
          configureTargets( m_baseName, m_baseDirectory, targets );
  
          final Iterator categories = configuration.getChildren( "category" );
          configureCategories( m_baseName, categories );
  
          /*
            final String logPriority = configuration.getChild( "global-priority" ).getValue();
            final Priority.Enum priority = LogKit.getPriorityForName( logPriority );
            LogKit.setGlobalPriority( priority );
          */
      }
  
      protected void configureTargets( final String baseName,
                                       final File baseDirectory,
                                       final Iterator targets )
          throws ConfigurationException
      {
          while(targets.hasNext())
          {
              final Configuration target = (Configuration)targets.next();
              final String name = baseName + '.' + target.getAttribute( "name" );
              String location = target.getAttribute( "location" ).trim();
              final String format = target.getAttribute( "format", null );
  
              if( '/' == location.charAt( 0 ) )
              {
                  location = location.substring( 1 );
              }
  
              final File file = new File( baseDirectory, location );
  
              final FileOutputLogTarget logTarget = new FileOutputLogTarget();
              final AvalonLogFormatter formatter = new AvalonLogFormatter();
              formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
                                   "(%{context}): %{message}\\n%{throwable}" );
              logTarget.setFormatter( formatter );
  
              try { logTarget.setFilename( file.getAbsolutePath() ); }
              catch( final IOException ioe )
              {
                  throw new ConfigurationException( "Error initializing log files", ioe );
              }
  
              if( null != format )
              {
                  logTarget.setFormat( format );
              }
  
              LogKit.addLogTarget( name, logTarget );
          }
      }
  
      protected void configureCategories( final String baseName, final Iterator categories )
          throws ConfigurationException
      {
          while(categories.hasNext())
          {
              final Configuration category = (Configuration)categories.next();
              String name = category.getAttribute( "name" );
              final String target = baseName + '.' + category.getAttribute( "target" );
              final String priority = category.getAttribute( "priority" );
  
              if( name.trim().equals( "" ) )
              {
                  name = baseName;
              }
              else
              {
                  name = baseName + '.' + name;
              }
  
              final Category logCategory =
                  LogKit.createCategory( name, LogKit.getPriorityForName( priority ) );
              final LogTarget logTarget = LogKit.getLogTarget( target );
              LogTarget logTargets[] = null;
  
              if( null != target ) logTargets = new LogTarget[] { logTarget };
  
              LogKit.createLogger( logCategory, logTargets );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/SecurityManager.java
  
  Index: SecurityManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import java.io.File;
  import java.io.InputStream;
  import java.lang.reflect.Constructor;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.UnresolvedPermission;
  import java.security.cert.Certificate;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.PropertyPermission;
  import java.util.StringTokenizer;
  import org.apache.framework.component.Component;
  import org.apache.framework.context.Context;
  import org.apache.framework.context.Contextualizable;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.framework.lifecycle.Initializable;
  import org.apache.avalon.atlantis.Facility;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.aut.PropertyException;
  import org.apache.aut.PropertyUtil;
  import org.apache.aut.security.AbstractPolicy;
  
  /**
   * Policy that extracts information from policy files.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultPolicy
      extends AbstractPolicy
      implements Facility, Contextualizable, Configurable, Initializable
  {
      protected DefaultContext    m_context;
  
      public void contextualize( final Context context )
      {
          m_context = new DefaultContext( System.getProperties(), context );
          m_context.put( "/", File.separator );
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Iterator it = configuration.getChildren( "keystore" );
          final HashMap keyStores = configureKeyStores( it );
  
          final Iterator grants = configuration.getChildren( "grant" );
          configureGrants( grants, keyStores );
  
  //        final Configuration[] grants = configuration.getChildren( "grant" );
  //        configureGrants( grants, keyStores );
      }
  
      public void init()
          throws Exception
      {
          //these properties straight out ot ${java.home}/lib/security/java.policy
          final Permissions permissions = createPermissionSetFor( "file:/-", null );
  
          permissions.add( new PropertyPermission( "os.name", "read" ) );
          permissions.add( new PropertyPermission( "os.arch", "read" ) );
          permissions.add( new PropertyPermission( "os.version", "read" ) );
          permissions.add( new PropertyPermission( "file.separator", "read" ) );
          permissions.add( new PropertyPermission( "path.separator", "read" ) );
          permissions.add( new PropertyPermission( "line.separator", "read" ) );
  
          permissions.add( new PropertyPermission( "java.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vendor.url", "read" ) );
  
          permissions.add( new PropertyPermission( "java.class.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.name", "read" ) );
  
          permissions.add( new PropertyPermission( "java.specification.version", "read" ) );
          permissions.add( new PropertyPermission( "java.specification.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.specification.name", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.name", "read" ) );
      }
  
      protected HashMap configureKeyStores( final Iterator it )
          throws ConfigurationException
      {
          final HashMap keyStores = new HashMap();
  
          while(it.hasNext())
          {
              final Configuration configuration = (Configuration)it.next();
              final String type = configuration.getAttribute( "type" );
              final String location = configuration.getAttribute( "location" );
              final String name = configuration.getAttribute( "name" );
  
              try
              {
                  final KeyStore keyStore = KeyStore.getInstance( type );
                  final URL url = new URL( location );
                  final InputStream ins = url.openStream();
  
                  keyStore.load( ins, null );
  
                  keyStores.put( name, keyStore );
              }
              catch( final Exception e )
              {
                  throw new ConfigurationException( "Error configuring keystore " + name, e );
              }
          }
  
          return keyStores;
      }
  
      protected void configureGrants( final Iterator it,
                                      final HashMap keyStores )
          throws ConfigurationException
      {
          while(it.hasNext())
          {
              configureGrant( (Configuration)it.next(), keyStores );
          }
      }
  
      protected void configureGrant( final Configuration configuration, final HashMap keyStores )
          throws ConfigurationException
      {
          //<grant signed-by="Fred" code-base="file:${sar.home}/blocks/*" key-store="foo-keystore">
          //<permission class="java.io.FilePermission" target="/tmp/*" action="read,write" />
          //</grant>
  
          final String signedBy = configuration.getAttribute( "signed-by", null );
          final String keyStoreName = configuration.getAttribute( "key-store", null );
  
          String codeBase = configuration.getAttribute( "code-base", null );
          if( null != codeBase )
          {
              codeBase = expand( codeBase );
          }
  
          final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
  
          Permissions permissions = null;
  
          try { permissions = createPermissionSetFor( codeBase, signers ); }
          catch( final MalformedURLException mue )
          {
              throw new ConfigurationException( "Malformed code-base " + codeBase, mue );
          }
  
  
          configurePermissions( configuration.getChildren( "permission" ),
                                permissions,
                                keyStores );
      }
  
      protected void configurePermissions( final Iterator it,
                                           final Permissions permissions,
                                           final HashMap keyStores )
          throws ConfigurationException
      {
          while(it.hasNext())
          {
              configurePermission( (Configuration)it.next(), permissions, keyStores );
          }
      }
  
      protected void configurePermission( final Configuration configuration,
                                          final Permissions permissions,
                                          final HashMap keyStores )
          throws ConfigurationException
      {
          final String type = configuration.getAttribute( "class" );
          final String actions = configuration.getAttribute( "actions", null );
          final String signedBy = configuration.getAttribute( "signed-by", null );
          final String keyStoreName = configuration.getAttribute( "key-store", null );
  
          String target = configuration.getAttribute( "target", null );
          if( null != target )
          {
              target = expand( target );
          }
  
          final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
          final Permission permission = createPermission( type, target, actions, signers );
  
          permissions.add( permission );
      }
  
      protected String expand( final String value )
          throws ConfigurationException
      {
          try
          {
              final Object resolvedValue = PropertyUtil.resolveProperty( value, m_context, false );
              return resolvedValue.toString();
          }
          catch( final PropertyException pe )
          {
              throw new ConfigurationException( "Error resolving property " + value, pe );
          }
      }
  
      protected Permission createPermission( final String type,
                                             final String target,
                                             final String actions,
                                             final Certificate[] signers )
          throws ConfigurationException
      {
          if( null != signers )
          {
              return createUnresolvedPermission( type, target, actions, signers );
          }
  
          try
          {
              final Class c = Class.forName( type );
  
              Class paramClasses[] = null;
              Object params[] = null;
  
              if( null == actions && null == target )
              {
                  paramClasses = new Class[ 0 ];
                  params = new Object[ 0 ];
              }
              else if( null == actions )
              {
                  paramClasses = new Class[1];
                  paramClasses[0] = String.class;
                  params = new Object[1];
                  params[0] = target;
              }
              else
              {
                  paramClasses = new Class[2];
                  paramClasses[0] = String.class;
                  paramClasses[1] = String.class;
                  params = new Object[2];
                  params[0] = target;
                  params[1] = actions;
              }
  
              final Constructor constructor = c.getConstructor( paramClasses );
              final Object o = constructor.newInstance( params );
              return (Permission)o;
          }
          catch( final ClassNotFoundException cnfe )
          {
              return createUnresolvedPermission( type, target, actions, signers );
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create permission " + type +
                                                " due to " + e, e );
          }
      }
  
      protected Permission createUnresolvedPermission( final String type,
                                                       final String target,
                                                       final String actions,
                                                       final Certificate[] signers )
      {
          return new UnresolvedPermission( type, target, actions, signers );
      }
  
      protected Certificate[] getSigners( final String signedBy,
                                          String keyStoreName,
                                          final HashMap keyStores )
          throws ConfigurationException
      {
          if( null != signedBy && null == keyStoreName )
          {
              keyStoreName = "default";
          }
  
          Certificate[] signers = null;
  
          if( null != signedBy )
          {
              signers = getCertificates( signedBy, keyStoreName, keyStores );
          }
  
          return signers;
      }
  
      protected Certificate[] getCertificates( final String signedBy,
                                               final String keyStoreName,
                                               final HashMap keyStores )
          throws ConfigurationException
      {
          final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName );
  
          if( null == keyStore )
          {
              throw new ConfigurationException( "Unable to aquire keyStore " + keyStoreName );
          }
  
          final ArrayList certificateSet = new ArrayList();
  
          final StringTokenizer tokenizer = new StringTokenizer( signedBy, "," );
  
          while( tokenizer.hasMoreTokens() )
          {
              final String alias = ((String)tokenizer.nextToken()).trim();
              Certificate certificate = null;
  
              try { certificate = keyStore.getCertificate( alias ); }
              catch( final KeyStoreException kse )
              {
                  throw new ConfigurationException( "Error aquiring certificate " + alias,
                                                    kse );
              }
  
              if( null == certificate )
              {
                  throw new ConfigurationException( "Unable to locate alias " + alias +
                                                    " in keystore named " + keyStoreName );
              }
  
              if( !certificateSet.contains( certificate ) )
              {
                  if( DEBUG ) getLogger().debug( "Certificate " + certificate );
                  certificateSet.add( certificate );
              }
          }
  
          return (Certificate[])certificateSet.toArray( new Certificate[ 0 ] );
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ThreadManager.java
  
  Index: ThreadManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.avalon.atlantis.Facility;
  import org.apache.framework.configuration.Configurable;
  import org.apache.framework.configuration.Configuration;
  import org.apache.framework.configuration.ConfigurationException;
  import org.apache.avalon.thread.DefaultThreadPool;
  import org.apache.framework.thread.ThreadManager;
  import org.apache.framework.thread.ThreadPool;
  
  /**
   *
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultThreadManager
      extends AbstractLoggable
      implements Facility, ThreadManager, Configurable
  {
      protected final Hashtable       m_pools = new Hashtable();
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Iterator it = configuration.getChildren( "thread-group" );
          while(it.hasNext())
          {
              final Configuration group = (Configuration)it.next();
  
              final String name = group.getChild( "name" ).getValue();
              final int priority = group.getChild( "priority" ).getValueAsInt( 5 );
              final boolean isDaemon = group.getChild( "is-daemon" ).getValueAsBoolean( false );
  
              final int minThreads = group.getChild( "min-threads" ).getValueAsInt( 5 );
              final int maxThreads = group.getChild( "max-threads" ).getValueAsInt( 10 );
              final int minSpareThreads = group.getChild( "min-spare-threads" ).
                  getValueAsInt( maxThreads - minThreads );
  
              try
              {
                  final DefaultThreadPool threadPool = new DefaultThreadPool( name, maxThreads );
                  threadPool.setDaemon( isDaemon );
                  //setupLogger( threadPool );
                  m_pools.put( name, threadPool );
              }
              catch( final Exception e )
              {
                  throw new ConfigurationException( "Error creating thread pool " + name,
                                                    e );
              }
          }
      }
  
      public ThreadPool getDefaultThreadPool()
      {
          return getThreadPool( "default" );
      }
  
      public ThreadPool getThreadPool( final String name )
      {
          final ThreadPool threadPool = (ThreadPool)m_pools.get( name );
  
          if( null == threadPool )
          {
              //Should this be a ComponentNotFoundException ????
              throw new IllegalArgumentException( "No such thread group " + name );
          }
  
          return threadPool;
      }
  }
  
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/jmx/Manager.java
  
  Index: Manager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.phoenix.engine.facilities;
  
  import javax.management.MBeanServer;
  
  /**
   *
   * @author <a href="mail@leosimons.com">Leo Simons</a>
   */
  public class AvalonMBeanServer
  {
      private MBeanServer server;
  
      public AvalonMBeanServer( MBeanServer server )
      {
          this.server = server;
      }
  }
  
  
  1.1                  jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/facilities/Facility.java
  
  Index: Facility.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.atlantis;
  
  import org.apache.avalon.Component;
  
  /**
   * A Facility is a horizontal cut through the kernel. 
   * Unlike Components which offer a Service/Content interface, Facilitys 
   * are used to facilitate the non-Service/Form interface or life-cycle orientated
   * methods of Components. See documentation for a clearer explanation.
   *
   * Example Facilities would be 
   * <ul>
   *   <li>ConfigurationRepository that stores configuration data for components</li>
   *   <li>ThreadFacility that allows components to run in threads</li>
   *   <li>ContextUtility that builds context information for components</li>
   *   <li>ExportFacility that exports components to external users (perhaps via RMI)</li>
   *   <li>NamingFacility that binds compoents to a name in a directory</li>
   *   <li>ManagementFacility that manages components via JMX</li>
   * </ul>
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Facility 
      extends Component
  {
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org