You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/11/29 14:17:17 UTC

cvs commit: avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance UnresolvedProviderException.java UnresolvedManagerException.java DependencyGraph.java DefaultAssemblyService.java DefaultApplianceSelector.java AssemblyService.java AssemblyException.java

mcconnell    2002/11/29 05:17:16

  Added:       assembly/src/java/org/apache/avalon/assembly/appliance
                        UnresolvedProviderException.java
                        UnresolvedManagerException.java
                        DependencyGraph.java DefaultAssemblyService.java
                        DefaultApplianceSelector.java AssemblyService.java
                        AssemblyException.java
  Log:
  Classes and interfaces supported appliance assembly.
  
  Revision  Changes    Path
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/UnresolvedProviderException.java
  
  Index: UnresolvedProviderException.java
  ===================================================================
  /* ==================================================================== 
   * The Apache Software License, Version 1.1 
   * 
   * Copyright (c) 2002 The Apache Software Foundation. All rights 
   * reserved. 
   * 
   * Redistribution and use in source and binary forms, with or without 
   * modification, are permitted provided that the following conditions 
   * are met: 
   * 
   * 1. Redistributions of source code must retain the above copyright 
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software 
   *    itself, if and wherever such third-party acknowledgments  
   *    normally appear.
   *
   * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" 
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see 
   * <http://www.apache.org/>.
   */ 
  
  package org.apache.avalon.assembly.appliance;
  
  import org.apache.avalon.meta.info.DependencyDescriptor;
  
  /**
   * Exception to indicate that a service provider could not be found.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public final class UnresolvedProviderException
      extends AssemblyException
  {
  
      private DependencyDescriptor m_dependency;
  
      /**
       * Construct a new <code>UnresolvedProviderException</code> instance.
       *
       * @param dependency the unresolved dependency
       */
      public UnresolvedProviderException( DependencyDescriptor dependency )
      {
          this( dependency, null );
      }
  
      /**
       * Construct a new <code>UnresolvedProviderException</code> instance.
       *
       * @param dependency the unresolved dependency
       * @param cause the causal exception
       */
      public UnresolvedProviderException( DependencyDescriptor dependency, Throwable cause )
      {
          super( getStandardMessage( dependency ), cause );
          m_dependency = dependency;
      }
  
      /**
       * Return the dependency description.
       * @return the unresolved dependency.
       */
      public DependencyDescriptor getDependency()
      {
          return m_dependency;
      }
  
      private static String getStandardMessage( DependencyDescriptor dependency )
      {
          return "Unable to resolve a provider for the dependency '"
              + dependency.getReference() + "' for the role: " + dependency.getRole();
      }
  
  }
  
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/UnresolvedManagerException.java
  
  Index: UnresolvedManagerException.java
  ===================================================================
  /* ==================================================================== 
   * The Apache Software License, Version 1.1 
   * 
   * Copyright (c) 2002 The Apache Software Foundation. All rights 
   * reserved. 
   * 
   * Redistribution and use in source and binary forms, with or without 
   * modification, are permitted provided that the following conditions 
   * are met: 
   * 
   * 1. Redistributions of source code must retain the above copyright 
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software 
   *    itself, if and wherever such third-party acknowledgments  
   *    normally appear.
   *
   * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" 
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see 
   * <http://www.apache.org/>.
   */ 
  
  package org.apache.avalon.assembly.appliance;
  
  import org.apache.avalon.meta.info.StageDescriptor;
  
  /**
   * Exception to indicate that a service provider could not be found.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public final class UnresolvedManagerException
      extends AssemblyException
  {
  
      private StageDescriptor m_phase;
  
      /**
       * Construct a new <code>UnresolvedManagerException</code> instance.
       *
       * @param phase the unresolved phase
       */
      public UnresolvedManagerException( StageDescriptor phase )
      {
          this( phase, null );
      }
  
      /**
       * Construct a new <code>UnresolvedManagerException</code> instance.
       *
       * @param phase the unresolved phase
       * @param cause the causal exception
       */
      public UnresolvedManagerException( StageDescriptor phase, Throwable cause )
      {
          super( getStandardMessage( phase ), cause );
          m_phase = phase;
      }
  
      /**
       * Return the dependency description.
       * @return the unresolved dependency.
       */
      public StageDescriptor getPhase()
      {
          return m_phase;
      }
  
      private static String getStandardMessage( StageDescriptor phase )
      {
          return "Unable to resolve an extensions for the phase '"
              + phase.getReference();
      }
  
  }
  
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DependencyGraph.java
  
  Index: DependencyGraph.java
  ===================================================================
  /* ==================================================================== 
   * The Apache Software License, Version 1.1 
   * 
   * Copyright (c) 2002 The Apache Software Foundation. All rights 
   * reserved. 
   * 
   * Redistribution and use in source and binary forms, with or without 
   * modification, are permitted provided that the following conditions 
   * are met: 
   * 
   * 1. Redistributions of source code must retain the above copyright 
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software 
   *    itself, if and wherever such third-party acknowledgments  
   *    normally appear.
   *
   * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" 
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see 
   * <http://www.apache.org/>.
   */ 
  
  package org.apache.avalon.assembly.appliance;
  
  import java.util.ArrayList;
  import org.apache.avalon.meta.model.Profile;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.meta.info.StageDescriptor;
  import org.apache.avalon.assembly.appliance.Appliance;
  
  /**
   * <p>Utility class to help aquire a ordered graph of
   * consumers and providers for specific components.</p>
   * <p><b>UML</b></p>
   * <p><image src="doc-files/DependencyGraph.gif" border="0"/></p>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public class DependencyGraph
  {
      /**
       * Parent Map. Components in parent
       * Map are potential Providers for services
       * if no profile in current assembly satisfies dependency.
       */
      private final DependencyGraph m_parent;
  
      /**
       * The set of components declared by the container as available.,
       * Used when searching for providers/consumers.
       */
      private final ArrayList m_appliances = new ArrayList();
  
      /**
       * The child {@link DependencyGraph} objects.
       * Possible consumers of services in this assembly.
       */
      private final ArrayList m_children = new ArrayList();
  
      /**
       * Creation of a new empty dependecy graph.
       */
      public DependencyGraph()
      {
          this( null );
      }
  
      /**
       * Creation of a new dependecy graph holding a reference to a parent
       * graph.  Profiles in the parent graph are potential providers for services
       * if no profile in current assembly satisfies a dependency.
       *
       * @param parent the parent graph
       */
      public DependencyGraph( final DependencyGraph parent )
      {
          m_parent = parent;
      }
  
      /**
       * Addition of a consumer dependency graph.
       *
       * @param child the child map
       */
      public void addChild( final DependencyGraph child )
      {
          m_children.add( child );
      }
  
      /**
       * Removal of a consumer dependency graph.
       *
       * @param child the child map
       */
      public void removeChild( final DependencyGraph child )
      {
          m_children.remove( child );
      }
  
      /**
       * Add an appliance to current dependency graph.
       *
       * @param appliance the appliance
       */
      public void add( final Appliance appliance )
      {
          if( !m_appliances.contains( appliance ) )
          {
              m_appliances.add( appliance );
          }
      }
  
      /**
       * Get the serilized graph of {@link Appliance} objects
       * required when starting up all the target. This makes sure
       * that all providers are established before their coresponding
       * consumers in the graph.
       *
       * @return the ordered list of appliances
       */
      public Appliance[] getStartupGraph()
      {
          return walkGraph( true );
      }
  
      /**
       * Get the serilized graph of {@link Appliance} objects
       * required when shutting down all the components. This makes
       * sure that all consumer shutdows occur before their coresponding
       * providers in graph.
       *
       * @return the ordered list of components
       */
      public Appliance[] getShutdownGraph()
      {
          return walkGraph( false );
      }
  
      /**
       * Get the serilized graph of {@link Profile} objects
       * that use services of specified profile.
       *
       * @param profile the profile
       * @return the ordered list of consumers
       */
      public Appliance[] getConsumerGraph( final Appliance appliance )
      {
          return referencedAppliances( appliance, getComponentGraph( appliance, false ) );
      }
  
      /**
       * Get the serilized graph of {@link Profile} objects
       * that provide specified profile with services.
       *
       * @param profile the profile
       * @return the ordered list of providers
       */
      public Appliance[] getProviderGraph( final Appliance appliance )
      {
          return referencedAppliances( appliance, getComponentGraph( appliance, true ) );
      }
  
      /**
       * Return a profile array that does not include the provided profile.
       */
      private Appliance[] referencedAppliances( final Appliance appliance, Appliance[] appliances )
      {
          ArrayList list = new ArrayList();
          for( int i = 0; i < appliances.length; i++ )
          {
              if( !appliances[ i ].equals( appliance ) )
              {
                  list.add( appliances[ i ] );
              }
          }
          return (Appliance[])list.toArray( new Appliance[ 0 ] );
      }
  
      /**
       * Get the graph of a single appliance.
       *
       * @param profile the profile
       * @param providers true if traversing providers, false if consumers
       * @return the list of components in graph
       */
      private Appliance[] getComponentGraph( final Appliance appliance, final boolean providers )
      {
          final ArrayList result = new ArrayList();
          visitcomponent( appliance,
                          providers,
                          new ArrayList(),
                          result );
  
          final Appliance[] returnValue = new Appliance[ result.size() ];
          return (Appliance[])result.toArray( returnValue );
      }
  
      /**
       * Method to generate an ordering of nodes to traverse.
       * It is expected that the specified components have passed
       * verification tests and are well formed.
       *
       * @param providers true if forward dependencys traced, false if dependencies reversed
       * @return the ordered node names
       */
      private Appliance[] walkGraph( final boolean providers )
      {
          final ArrayList result = new ArrayList();
          final ArrayList done = new ArrayList();
  
          final int size = m_appliances.size();
          for( int i = 0; i < size; i++ )
          {
              final Appliance appliance =
                  (Appliance)m_appliances.get( i );
  
              visitcomponent( appliance,
                              providers,
                              done,
                              result );
          }
  
          final Appliance[] returnValue = new Appliance[ result.size() ];
          return (Appliance[])result.toArray( returnValue );
      }
  
      /**
       * Visit a appliance when traversing dependencies.
       *
       * @param appliance the appliance
       * @param providers true if walking tree looking for providers, else false
       * @param done those nodes already traversed
       * @param order the order in which nodes have already been
       *             traversed
       */
      private void visitcomponent( final Appliance appliance,
                                   final boolean providers,
                                   final ArrayList done,
                                   final ArrayList order )
      {
  
          //If already visited this profile return
  
          if( done.contains( appliance ) )
          {
              return;
          }
          done.add( appliance );
  
          if( providers )
          {
              visitProviders( appliance, done, order );
          }
          else
          {
              visitConsumers( appliance, done, order );
          }
  
          order.add( appliance );
      }
  
      /**
       * Traverse graph of components that provide services to
       * the specified appliance.
       *
       * @param appliance the appliance
       */
      private void visitProviders( final Appliance appliance,
                                   final ArrayList done,
                                   final ArrayList order )
      {
          //
          // get all of the extensions the provide extension
          // support to the subject profile
          //
  
          final StageDescriptor[] stages = appliance.getProfile().getType().getStages();
          for( int i = ( stages.length - 1 ); i > -1; i-- )
          {
              StageDescriptor stage = stages[ i ];
              Appliance extension = appliance.getExtensionProvider( stage );
              if( extension != null )
              {
                  visitcomponent( extension, true, done, order );
              }
          }
  
          //
          // get all of the profiles that are service providers
          // towards the target profile
          //
  
          final DependencyDescriptor[] descriptors =
              appliance.getProfile().getType().getDependencies();
  
          for( int i = 0; i < descriptors.length; i++ )
          {
  
              DependencyDescriptor dependency = descriptors[ i ];
              Appliance provider = appliance.getServiceProvider( dependency.getRole() );
  
              if( provider != null )
              {
                  visitcomponent( provider, true, done, order );
              }
              else
              {
                  if( dependency.isRequired() )
                  {
                      throw new IllegalStateException(
                          "unresolved service dependency for role: " + dependency.getRole()
                          + " in appliance: " + appliance );
                  }
              }
          }
      }
  
      /**
       * Traverse all Consumers of an appliance. ie Anyone that uses
       * service provided by the appliance.
       *
       * @param appliance the Appliance
       */
      private void visitConsumers( final Appliance appliance,
                                   final ArrayList done,
                                   final ArrayList order )
      {
  
          final String name = appliance.getProfile().getName();
  
          final int size = m_appliances.size();
          for( int i = 0; i < size; i++ )
          {
              final Appliance other =
                  (Appliance)m_appliances.get( i );
  
              //
              // check if the 'other' appliance is used by this 'appliance'
              // as a service provider
              //
  
              final Appliance[] providers = other.getServiceProviders();
              
              for( int j = 0; j < providers.length; j++ )
              {
                  Appliance provider = providers[j];
                  if( provider.equals( appliance ) )
                  {
                      visitcomponent( other, false, done, order );
                  }
              }
  
              //
              // check if the 'other' profile is used by this 'profile'
              // as an extension provider
              //
  
              final StageDescriptor[] stages = other.getProfile().getType().getStages();
              for( int j = 0; j < stages.length; j++ )
              {
                  StageDescriptor stage = stages[j];
                  Appliance extension = other.getExtensionProvider( stage );
                  if( extension.equals( appliance ) )
                  {
                      visitcomponent( other, false, done, order );
                  }
              }
          }
  
          final int childCount = m_children.size();
          for( int i = 0; i < childCount; i++ )
          {
              final DependencyGraph map = (DependencyGraph)m_children.get( i );
              map.visitConsumers( appliance, done, order );
          }
      }
  }
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultAssemblyService.java
  
  Index: DefaultAssemblyService.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.appliance;
  
  import java.util.List;
  import java.util.ArrayList;
  
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.assembly.engine.Engine;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.meta.info.StageDescriptor;
  
  /**
   * A assembly service is responsible for the resolution of a component 
   * service depedencies, and the construction supply of a component or
   * service manager to a target object.
   *
   * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public class DefaultAssemblyService extends AbstractLogEnabled implements AssemblyService, Contextualizable, Serviceable, Initializable
  {
      //==============================================================
      // state
      //==============================================================
  
      private ServiceManager m_manager;
  
      private boolean m_initialized = false;
  
      private DependencyGraph m_map;
  
      private Engine m_engine;
  
      private ArrayList m_visited = new ArrayList();
  
      //==============================================================
      // Contextualizable
      //==============================================================
  
     /**
      * <p>Application of a runtime context to this component.
      * Context entries that may be supplied to an appliance manager are detailed in the
      * following table.</p>
      * <table>
      *   <tr>
      *     <td>key</td><td>type</td><td>default</td>
      *   </tr>
      *   <tr>
      *     <td>assembly:dependency-map</td>
      *     <td>org.apache.avalon.assembly.appliance.DepedendencyGraph</td>
      *     <td>The depedency graph.</td> 
      *   </tr>
      * </table>
      * @param context the runtime context
      */
      public void contextualize( Context context )
      {
          try
          {
              m_map = (DependencyGraph) context.get( "assembly:dependency-map" );
          }
          catch( ContextException e )
          {
              m_map = new DependencyGraph();
          }
      }
  
      //==============================================================
      // Serviceable
      //==============================================================
  
     /**
      * <p>Supply of container based services that may be used by the 
      * assembly service as supplimentary resources.</p>
      * @param manager the service manager
      */
      public void service( ServiceManager manager ) throws ServiceException
      {
          m_engine = (Engine) manager.lookup( "assembly:engine" );
      }
  
      //==============================================================
      // Initializable
      //==============================================================
  
     /**
      * Initialization fo the component by the container.  The implementation
      * validates a logger has been assigned and that the context phase has 
      * been executed, following which it flags initialization as complete and 
      * marks the component as ready to serve requests.
      *
      * @exception Exception if the manager has not been suppied with a context
      */
      public void initialize() throws Exception
      {
          if( getLogger() == null )
          {
              throw new IllegalStateException("logger");
          }
          if( m_map == null )
          {
              throw new IllegalStateException("contextaulize");
          }
          if( m_engine == null )
          {
              throw new IllegalStateException("service");
          }
  
          m_initialized = true;
      }
  
      //==============================================================
      // AssemblyService
      //==============================================================
  
     /**
      * Contextualize the supplied object.
      * @param appliance the object to contextualize
      * @param object the object to contextualize
      */
      public void assemble( Appliance appliance ) throws AssemblyException
      {
          if( appliance == null )
          {
              throw new NullPointerException( "appliance" );
          }
          assembleAppliance( m_map, appliance, m_visited, "" );
      }
  
      /**
       * Assemble a single appliance.
       * @param map the current depedency map to populate
       * @param profile the profile to assemble
       * @param context the assembly context
       * @param visited the set of profiles already assessed
       * @param pad used in formatting log messages
       * @exception AssemblyException if an assembly related error occurs
       */
  
      private void assembleAppliance(
          DependencyGraph map, Appliance appliance, List visited, String pad )
          throws AssemblyException
      {
          String name = appliance.getProfile().getName();
          getLogger().debug( pad + "assemble: " + name );
          String pad2 = pad + "  ";
  
          //
          // for all of the declared depedencies - make sure the
          // dependency is satisfied
          //
  
          visited.add( appliance );
          DependencyDescriptor[] dependencies = appliance.getProfile().getType().getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              DependencyDescriptor dependency = dependencies[ i ];
              String role = dependency.getRole();
              if( appliance.getServiceProvider( role ) == null )
              {
  
                  getLogger().debug( "resolving role: " + role + " on " + name );
  
                  //
                  // select the preferred provider for the dependency - the dependency
                  // argument contains the selection policy to apply
                  //
  
                  Appliance supplier = null;
  
                  try
                  {
                      supplier = m_engine.resolve( dependency );
                  }
                  catch( Throwable e )
                  {
                      final String error =
                          "Unable to deploy a supplier for a service dependency: '"
                          + supplier
                          + "' within the appliance '" 
                          + appliance + "'.";
                      throw new AssemblyException( error, e );
                  }
  
                  if( supplier == null )
                  {
                      final String message =
                          "Unresolved supplied for the dependency: "
                          + dependency.getReference() + " in appliance: " + appliance
                          + ", for the role: " + dependency.getRole();
  
                      appliance.setEnabled( false );
                      final Exception problem = new Exception( message );
                      throw new UnresolvedProviderException( dependency, problem );
                  }
  
                  //
                  // associate the supplier to the appliance
                  //
  
                  appliance.addServiceProvider( role, supplier );
  
                  getLogger().debug( 
                    pad 
                    + "  associated supplier: " + supplier.getProfile().getName()
                    + " with appliance: " + name
                    + " under the role: " + role );
  
                  map.add( supplier );
              }
          }
  
          //
          // for all of the lifecycle phases - make sure we assign an extension
          // manager
          //
  
          StageDescriptor[] stages = appliance.getProfile().getType().getStages();
          for( int i = 0; i < stages.length; i++ )
          {
              StageDescriptor stage = stages[ i ];
              if( appliance.getExtensionProvider( stage ) == null )
              {
  
                  Appliance supplier = null;
  
                  try
                  {
                      supplier = m_engine.resolve( stage );
                  }
                  catch( Throwable e )
                  {
                      final String error =
                          "Unable to deploy a supplier for a stage dependency: '"
                          + supplier
                          + "' within the appliance '" 
                          + appliance + "'.";
                      throw new AssemblyException( error, e );
                  }
  
                  if( supplier == null )
                  {
                      final String message =
                          "Unresolved supplied for the stage dependency: "
                          + stage.getReference() + " in appliance: " + appliance;
  
                      appliance.setEnabled( false );
                      final Exception problem = new Exception( message );
                      throw new UnresolvedManagerException( stage, problem );
                  }
  
                  //
                  // associate the supplier to the appliance
                  //
  
                  appliance.addExtensionProvider( stage, supplier );
  
                  getLogger().debug( 
                    pad 
                    + "  associated extension provider: " + supplier.getProfile().getName()
                    + " with appliance: " + appliance.getProfile().getName() );
  
                  map.add( supplier );
              }
          }
      }
  
      private boolean assembleManagers(
          DependencyGraph map, Appliance appliance, StageDescriptor stage,
          List visited, String pad )
          throws AssemblyException
      {
          boolean ok = false;
          Appliance provider;
          try
          {
              provider = m_engine.resolve( stage );
          }
          catch( Throwable e )
          {
              final String error = 
                "Assembly error while resolving stage: " + stage 
                + " for the appliance: " + appliance;
              throw new AssemblyException( error, e );
          }
          if( provider != null )
          {
              assembleAppliance( map, appliance, visited, pad + "  " );
              ok = true;
          }
          return ok;
      }
  
      private boolean assembleProviders(
          DependencyGraph map, Appliance appliance,
          DependencyDescriptor dependency, List visited, String pad )
          throws AssemblyException
      {
          boolean ok = false;
          Appliance provider;
          try
          {
              provider = m_engine.resolve( dependency );
          }
          catch( Throwable e )
          {
              final String error = 
                "Assembly error while resolving dependency: " + dependency 
                + " for the appliance: " + appliance;
              throw new AssemblyException( error, e );
          }
          if( provider != null )
          {
              assembleAppliance( map, appliance, visited, pad + "  " );
              ok = true;
          }
          return ok;
      }
  }
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultApplianceSelector.java
  
  Index: DefaultApplianceSelector.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.appliance;
  
  import org.apache.avalon.meta.info.StageDescriptor;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.assembly.profile.ProfileSelector;
  
  /**
   * Interface implemented by a service selection implementation mechanism.  Classes
   * implementing the selector interface may be activated during the selection of
   * candidate service providers during assembly.  A component author may declare a 
   * selection class explicitly via a service dependency attribute with the attribute 
   * name of <code>avalon:appliance.selector</code>.
   *
   * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public class DefaultApplianceSelector implements ApplianceSelector
  {
      /**
       * Returns the preferred appliance form an available selection of 
       * candidate service providers.
       * @param appliances the set of candidate appliance instances
       * @param dependency the dependency for which the appliance is required
       * @return the preferred provider or null if no satisfactory provider can be established
       *    from the supplied appliance set.
       */
      public Appliance select( Appliance[] appliances, DependencyDescriptor dependency )
      {
          if( appliances.length == 0 )
          {
              return null;
          }
          return appliances[0];
      }
  
      /**
       * Returns the preferred appliance form an available selection of candidate 
       * extension providers
       * @param appliances the set of candidate appliance instances
       * @param stage the stage for which the appliance is required
       * @return the preferred provider or null if no satisfactory provider can be established
       *    from the supplied appliance set.
       */
      public Appliance select( Appliance[] appliances, StageDescriptor stage )
      {
          if( appliances.length == 0 )
          {
              return null;
          }
          return appliances[0];
      }
  
  }
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/AssemblyService.java
  
  Index: AssemblyService.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.appliance;
  
  import org.apache.avalon.assembly.appliance.Appliance;
  
  
  /**
   * A assembly service is responsible for the resolution of a component 
   * service depedencies, and the construction supply of a component or
   * service manager to a target object.
   *
   * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public interface AssemblyService
  {
     /**
      * Assemble the supplied appliance.
      * @param appliance the object to contextualize
      * @param object the object to contextualize
      */
      void assemble( Appliance appliance ) throws AssemblyException;
  
  }
  
  
  
  1.1                  avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/AssemblyException.java
  
  Index: AssemblyException.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.appliance;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate that there was a assembly related error.
   *
   * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/11/29 13:17:16 $
   */
  public class AssemblyException
      extends CascadingException
  {
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public AssemblyException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public AssemblyException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>