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/07/12 10:05:35 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier AssemblyVerifier.java MetaDataVerifier.java Resources.properties package.html

mcconnell    2002/07/12 01:05:35

  Added:       assembly/src/java/org/apache/excalibur/merlin/meta/data
                        AbstractContainer.java Association.java
                        CategoryDescriptor.java ClasspathDescriptor.java
                        ComponentDescriptor.java ContainerDescriptor.java
                        DefaultProfile.java DirsetDescriptor.java
                        ExtensionsDescriptor.java FileTargetProvider.java
                        FilesetDescriptor.java IncludeDescriptor.java
                        KernelDescriptor.java LoggingDescriptor.java
                        Profile.java TargetDescriptor.java
                        TargetProvider.java package.html
               assembly/src/java/org/apache/excalibur/merlin/meta/data/builder
                        ContainerCreator.java KernelCreator.java
                        ProfileBuilder.java ProfileCreator.java
                        Resources.properties TypeManager.java
                        XMLContainerCreator.java XMLKernelCreator.java
                        XMLProfileCreator.java package.html
               assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle
                        LifecycleException.java LifecycleHelper.java
                        ResourceProvider.java Resources.properties
                        package.html
               assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier
                        AssemblyVerifier.java MetaDataVerifier.java
                        Resources.properties package.html
  Log:
  population of a realistic meta-data model
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/AbstractContainer.java
  
  Index: AbstractContainer.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * Interface implemeted by objects capable of acting as a container.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public interface AbstractContainer
  {
  
      /**
       * Return the container name.
       *
       * @return the name of the container
       */
      String getName();
  
      /**
       * Return the logging descriptor.
       *
       * @return the {@link CategoryDescriptor} for the component loggers.
       */
      CategoryDescriptor getCategoryDescriptor();
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/Association.java
  
  Index: Association.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  
  
  /**
   * The Association is the mapping of a component as a dependency
   * of another component. Each component declares dependencies (via Type)
   * and for each dependency there must be a coressponding Association which
   * has a matching role. The name value in Association object must refer
   * to another Component that implements a service as specified in DependencyInfo.
   *
   * <p>Note that it is invalid to have circular dependencies.</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/07/12 08:05:34 $
   */
  public final class Association
  {
      /**
       * The name that the client component will use to access a dependency.
       */
      private final String m_role;
  
      /**
       * the name of the component metadata instance that represents a component
       * type that is capable of fullfilling the dependency.
       */
      private final Profile m_provider;
  
      /**
       * Create Profile with specified name and role.
       *
       * @param role the name client uses to access component
       * @param providerName the name of <code>ComponentProfile</code> instance
       *   that is associated as a service provider
       */
      public Association( final String role,
                                 final Profile provider )
      {
          m_role = role;
          m_provider = provider;
      }
  
      /**
       * Return the name that will be used by a component instance to access a
       * dependent service.
       *
       * @return the name that the client component will use to access dependency.
       * @see org.apache.avalon.framework.service.ServiceManager#lookup( String )
       */
      public String getRole()
      {
          return m_role;
      }
  
      /**
       * Return the name of a <code>ComponentProfile</code> instance that will used to
       * fulfill the dependency.
       *
       * @return the name of the Component that will provide the dependency.
       */
      public Profile getProvider()
      {
          return m_provider;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/CategoryDescriptor.java
  
  Index: CategoryDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  import java.util.Hashtable;
  
  /**
   * A logging category descriptor hierachy.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class CategoryDescriptor 
  {
  
       public static final String DEBUG = "DEBUG";
       public static final String INFO = "INFO";
       public static final String WARN = "WARN";
       public static final String ERROR = "ERROR";
  
       public static final String DEFAULT_LOGGING_TARGET = "default";
       public static final String DEFAULT_LOGGING_PRIORITY = INFO;
  
      /**
       * The logging category name.
       */
      private String m_name;
  
      /**
       * The default logging priority.
       */
      private final String m_priority;
  
      /**
       * The default logging target.
       */
      private final String m_target;
  
      /**
       * The loggers descriptor parent.
       */
      protected CategoryDescriptor m_parent;
  
      /**
       * Subsidiary categories.
       */
      private final Hashtable m_categories = new Hashtable();
  
  
      /**
       */
      public CategoryDescriptor( CategoryDescriptor parent, final String name )
      {
          this( parent, name, null, null, new CategoryDescriptor[0] );
      }
  
      /**
       */
      public CategoryDescriptor( final String name, final String priority, final String target )
      {
          this( null, name, priority, target, new CategoryDescriptor[0] );
      }
  
      /**
       */
      public CategoryDescriptor( 
        final String name, final String priority, final String target,
          final CategoryDescriptor[] categories  )
      {
          this( null, name, priority, target, categories  );
      }
  
      /**
       */
      public CategoryDescriptor( 
        CategoryDescriptor parent, final String name, final String priority, final String target,
          final CategoryDescriptor[] categories  )
      {
          m_name = name;
          m_target = target;
          m_priority = priority;
          m_parent = parent;
          for( int i=0; i<categories.length; i++ )
          {
              CategoryDescriptor category = categories[i];
              m_categories.put( category.getName(), category );
              category.setParent( this );
          }
  
      }
  
      /**
       * Return the category name.
       *
       * @return the category name
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the default logging priority for the group of categories.
       *
       * @return the default logging priority
       */
      public String getPriority( )
      {
          if( m_priority == null )
          {
              if( m_parent != null )
              {
                  return m_parent.getPriority();
              }
              else
              {
                  return DEFAULT_LOGGING_PRIORITY;
              }
          }
          return m_priority;
      }
  
      /**
       * Return the default log target for the group of categories.
       *
       * @return the default target name
       */
      public String getTarget( )
      {
          if( m_target == null )
          {
              if( m_parent != null )
              {
                  return m_parent.getTarget();
              }
              else
              {
                  return DEFAULT_LOGGING_TARGET;
              }
          }
          return m_target;
      }
  
      public void setParent( CategoryDescriptor parent )
      {
          m_parent = parent;
      }
  
      /**
       * Return the category path.
       *
       * @return the category path
       */
      public String getPath()
      {
          if( m_parent != null )
          {
              String path = m_parent.getPath();
              if( path.equals("") )
              {
                  return getName();
              }
              else
              {
                  return path + "." + getName();
              }
          }
          else
          {
              return getName();
          }
      }
  
      /**
       * Return the set of logging categories.
       *
       * @return the set of service provider assignments.
       */
      public CategoryDescriptor[] getCategories()
      {
          return (CategoryDescriptor[]) m_categories.values().toArray( new CategoryDescriptor[0] );
      }
  
      /**
       * Return a named category.
       * @param name the category name
       * @return the named category of null if unknown
       */
      public CategoryDescriptor getCategory( String name )
      {
          CategoryDescriptor category = (CategoryDescriptor) m_categories.get( name );
          if( category == null )
          {
              category = new CategoryDescriptor( this, name );
              m_categories.put( name, category );
          }
          return category;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ClasspathDescriptor.java
  
  Index: ClasspathDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * A classpath descriptor.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class ClasspathDescriptor 
  {
      /**
       * The base directory
       */
      private final FilesetDescriptor[] m_filesets;
  
  
      /**
       * Create a ClasspathDescriptor instance.
       *
       * @param filesets the set of filesets to include in the classpath
       */
      public ClasspathDescriptor( final FilesetDescriptor[] filesets )
      {
          m_filesets = filesets;
      }
  
      /**
       * Return the filesets held within the classpath descriptor.
       *
       * @return the filesets
       */
      public FilesetDescriptor[] getFilesetDescriptors()
      {
          return m_filesets;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ComponentDescriptor.java
  
  Index: ComponentDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  import java.io.Serializable;
  import java.util.Hashtable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.context.Context;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.Association;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  
  /**
   * A component profile description.
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class ComponentDescriptor extends DefaultProfile 
  {
  
      /**
       * Create a Profile instance.
       *
       * @param name the abstract name of component meta data instance
       * @param dependencies the meta data for any dependencies
       * @param type the component type
       */
      public ComponentDescriptor( final String name,
                             final Parameters parameters,
                             final Configuration configuration,
                             final Context context,
                             final CategoryDescriptor loggers,
                             final Type type,
                             final int mode )
      {
          super( name, parameters, configuration, context, loggers, type, mode );
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ContainerDescriptor.java
  
  Index: ContainerDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  import java.util.ArrayList;
  
  /**
   * A container profile.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class ContainerDescriptor implements AbstractContainer
  {
      /**
       * The parent.
       */
      private AbstractContainer m_parent;
  
      /**
       * The container name.
       */
      private final String m_name;
  
      /**
       * The loggers defintion.
       */
      private final CategoryDescriptor m_loggers;
  
      /**
       * The container classpath descriptor.
       */
      private final ClasspathDescriptor m_classpath;
  
      /**
       * The component described within the scope of the container.
       */
      //private final ArrayList m_components = new ArrayList();
      private final ComponentDescriptor[] m_components;
  
      /**
       * The component described within the scope of the container.
       */
      private final ContainerDescriptor[] m_containers;
  
      /**
       * Create a ContainerDescriptor instance.
       *
       */
      public ContainerDescriptor( final String name,
                             final CategoryDescriptor loggers,
                             final ClasspathDescriptor classpath,
                             final ComponentDescriptor[] components,
                             final ContainerDescriptor[] containers )
      {
          if( name == null ) 
            throw new NullPointerException("name");
          if( loggers == null ) 
            throw new NullPointerException("loggers");
          if( classpath == null ) 
            throw new NullPointerException("classpath");
  
          m_name = name;
          m_loggers = loggers;
          m_classpath = classpath;
          m_components = components;
          m_containers = containers;
  
          for( int i=0; i<containers.length; i++ )
          {
              containers[i].getCategoryDescriptor().setParent( loggers );
          }
          for( int i=0; i<components.length; i++ )
          {
              components[i].getCategoryDescriptor().setParent( loggers );
          }
      }
  
      /**
       * Return the container name.
       *
       * @return the name of the container
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the logging descriptor.
       *
       * @return the {@link CategoryDescriptor} for the component loggers.
       */
      public CategoryDescriptor getCategoryDescriptor()
      {
          return m_loggers;
      }
  
      /**
       * Return the classpath descriptor.
       *
       * @return the {@link ClasspathDescriptor} for the container.
       */
      public ClasspathDescriptor getClasspathDescriptor()
      {
          return m_classpath;
      }
  
      /**
       * Add a container to this container.
       *
       * @parent the container to add
       */
      //public void addComponent( ComponentDescriptor component )
      //{
      //    m_components.add( component );
      //    component.getCategoryDescriptor().setParent( getCategoryDescriptor() );
      //}
  
      /**
       * Return the set of component descriptors contained within this container.
       *
       * @return the target descriptors
       */
      public ComponentDescriptor[] getComponentDescriptors()
      {
          //return (ComponentDescriptor[]) m_components.toArray( new ComponentDescriptor[0] );
          return m_components;
      }
  
      /**
       * Return the set of subsidiary containers contained within this container.
       *
       * @return the target descriptors
       */
      public ContainerDescriptor[] getContainers()
      {
          return m_containers;
      }
  
  
      /**
       * Set the parent container.
       *
       * @param the container containing this container.
       * @exception IllegalStateException if the parent is already set
       */
      public void setParent( AbstractContainer parent ) throws IllegalStateException
      {
         if( m_parent != null )
           throw new IllegalStateException("parent");
  
         m_parent = parent;
  
         ContainerDescriptor[] containers = getContainers();
         for( int i=0; i<containers.length; i++ )
         {
            containers[i].setParent( this );
         }
      }
  
      /**
       * Return the parent container.
       *
       * @return the container containing this container.
       */
      public AbstractContainer getParent()
      {
          return m_parent;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/DefaultProfile.java
  
  Index: DefaultProfile.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  import java.io.Serializable;
  import java.util.Hashtable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.context.Context;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.Association;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  
  /**
   * Abstract defintion of a compoent profile. 
   *
   * @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/07/12 08:05:34 $
   */
  public class DefaultProfile 
    implements Profile, Serializable
  {
      /**
       * The name of the component metadata instance. This is an
       * abstract name used during assembly.
       */
      private final String m_name;
  
      /**
       * The dependencies keyed by role name.
       */
      private final Hashtable m_dependencies = new Hashtable();
  
      /**
       * The info object for component type.
       */
      private final Type m_type;
  
      /**
       * The parameters for component (if any).
       */
      private final Parameters m_parameters;
  
      /**
       * The configuration for component (if any).
       */
      private final Configuration m_configuration;
  
      /**
       * The configuration for component (if any).
       */
      private final Context m_context;
  
      /**
       * The logging descriptor.
       */
      private final CategoryDescriptor m_loggers;
  
      /**
       * The creation mode.
       */
      private final int m_mode;
  
  
      /**
       * Create a Profile instance.
       *
       * @param name the abstract name of component meta data instance
       * @param dependencies the meta data for any dependencies
       * @param type the component type
       */
      public DefaultProfile( final String name,
                             final Parameters parameters,
                             final Configuration configuration,
                             final Context context,
                             final CategoryDescriptor loggers,
                             final Type type,
                             final int mode )
      {
          if( null == name )
          {
              m_name = "" + System.identityHashCode( this );
          }
          else
          {
              m_name = name;
          }
  
          if( null == type )
          {
              throw new NullPointerException( "type" );
          }
  
          m_parameters = parameters;
          m_configuration = configuration;
          m_type = type;
          m_context = context;
          m_loggers = loggers;
          m_mode = mode;
      }
  
      /**
       * Return the name of component metadata instance.
       *
       * @return the name of the component.
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the info for component.
       *
       * @return the info for component type.
       */
      public Type getType()
      {
          return m_type;
      }
  
      /**
       * Return the assigned service providers.
       *
       * @return the set of service provider assignments.
       */
      public Association[] getAssociations()
      {
          return (Association[])m_dependencies.values().toArray( new Association[0] );
      }
  
      /**
       * Return the Context for component (if any).
       *
       * @return the Context  for component (if any).
       */
      public Context getContext()
      {
          return m_context;
      }
  
      /**
       * Return the Parameters for Component (if any).
       *
       * @return the Parameters for Component (if any).
       */
      public Parameters getParameters()
      {
          return m_parameters;
      }
  
      /**
       * Return the Configuration for Component (if any).
       *
       * @return the Configuration for Component (if any).
       */
      public Configuration getConfiguration()
      {
          return m_configuration;
      }
  
      /**
       * Return the logging descriptor.
       *
       * @return the {@link CategoryDescriptor} for the component loggers.
       */
      public CategoryDescriptor getCategoryDescriptor()
      {
          return m_loggers;
      }
  
      /**
       * Return the dependency metadata for component type with specified role.
       *
       * @return the dependency metadata for component with specified role.
       */
      public Association getAssociation( final String role )
      {
          return (Association) m_dependencies.get( role );
      }
  
      /**
       * Returns the creation mode for this profile.
       * @return a value of EXPLICIT, PACKAGED or IMPLICIT
       */
      public int getMode()
      {
          return m_mode;
      }
  
     /**
      * Add a provider for a service dependecy role.
      * @param provider the compenont provider profile
      * @param role the dependent role
      */
      public void addProvider( Profile provider, String role )
      {
          m_dependencies.put( role, new Association( role, provider ) );
      }
  
      public String toString()
      {
          return "Profile name: " + getName() 
            + ", type: " + getType().getInfo().getName() 
            + ", mode: " + modeToString( getMode() );
      }
  
      private String modeToString( int mode )
      {
          if( mode == IMPLICIT )
          {
              return "IMPLICIT";
          }
          else if( mode == PACKAGED )
          {
              return "PACKAGED";
          }
          else if( mode == EXPLICIT )
          {
              return "EXPLICIT";
          }
          else
          {
              return "?";
          }
      }
  
     /**
      * Provide a textual report on the profile.
      * @return the formatted profile report
      */
      public String list()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append( "PROFILE REPORT\n" );
          buffer.append( "\n  name: " + getName() );
          buffer.append( "\n  base: " + getType().getInfo().getName() );
          buffer.append( "\n  key: " + getType().getInfo().getImplementationKey() );
          buffer.append( "\n  context: " + getContext( ) );
          buffer.append( "\n  configuration:" );
          if( getConfiguration() != null )
          {
              buffer.append( ConfigurationUtil.list( getConfiguration() ) );
          }
          else
          {
              buffer.append( " null" );
          }
          buffer.append( "\n  parameters: " + getParameters() );
          buffer.append( "\n  dependecies" );
  
          Association[] dependencies = getAssociations();
          if( dependencies.length == 0 )
          {
              buffer.append( " (none)\n\n" );
              return buffer.toString();
          }
  
          for( int i=0; i<dependencies.length; i++ )
          {
              buffer.append( "\n  dependency " + i );
              buffer.append( "\n    role: " + dependencies[i].getRole() );
              buffer.append( "\n    provider: " + dependencies[i].getProvider() );
          }
  
          buffer.append( "\n\n" );
          return buffer.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/DirsetDescriptor.java
  
  Index: DirsetDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  
  /**
   * A description of a directory set.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class DirsetDescriptor 
  {
      /**
       * The base directory
       */
      private final String m_base;
  
      /**
       * The set of include directives.
       */
      private final IncludeDescriptor[] m_includes;
  
      /**
       * Create a FilesetDescriptor instance.
       *
       * @param filesets the set of filesets to include in the classpath
       */
      public DirsetDescriptor( final String base, final IncludeDescriptor[] includes )
      {
          m_base = base;
          m_includes = includes;
      }
  
      /**
       * Return the base directory.
       *
       * @return the directory
       */
      public String getBaseDirectory()
      {
          return m_base;
      }
  
  
      /**
       * Return the filesets held within the classpath descriptor.
       *
       * @return the filesets
       */
      public IncludeDescriptor[] getIncludeDescriptors()
      {
          return m_includes;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/ExtensionsDescriptor.java
  
  Index: ExtensionsDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * An extensions descriptor.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class ExtensionsDescriptor 
  {
      /**
       * The base directory
       */
      private final DirsetDescriptor[] m_dirs;
  
  
      /**
       * Create a ExtensionsDescriptor instance.
       *
       * @param filesets the set of filesets to include in the classpath
       */
      public ExtensionsDescriptor( final DirsetDescriptor[] dirs )
      {
          m_dirs = dirs;
      }
  
      /**
       * Return the dirset held within the extensions descriptor.
       *
       * @return the directory set
       */
      public DirsetDescriptor[] getDirsetDescriptors()
      {
          return m_dirs;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/FileTargetProvider.java
  
  Index: FileTargetProvider.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * File target provider type.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class FileTargetProvider extends TargetProvider
  {
      private final String m_location;
  
      public FileTargetProvider( final String location )
      {
          m_location = location;
      }
  
      public String getLocation()
      {
          return m_location;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/FilesetDescriptor.java
  
  Index: FilesetDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * A fileset descriptor.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class FilesetDescriptor 
  {
      /**
       * The base directory
       */
      private final String m_base;
  
      /**
       * The set of include directives.
       */
      private final IncludeDescriptor[] m_includes;
  
      /**
       * Create a FilesetDescriptor instance.
       *
       * @param filesets the set of filesets to include in the classpath
       */
      public FilesetDescriptor( final String base, final IncludeDescriptor[] includes )
      {
          m_base = base;
          m_includes = includes;
      }
  
      /**
       * Return the base directory.
       *
       * @return the directory
       */
      public String getBaseDirectory()
      {
          return m_base;
      }
  
      /**
       * Return the filesets held within the classpath descriptor.
       *
       * @return the filesets
       */
      public IncludeDescriptor[] getIncludeDescriptors()
      {
          return m_includes;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/IncludeDescriptor.java
  
  Index: IncludeDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  
  /**
   * An file include directive.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class IncludeDescriptor 
  {
      /**
       * The base directory
       */
      private final String m_file;
  
      /**
       * Create a FilesetDescriptor instance.
       *
       * @param filesets the set of filesets to include in the classpath
       */
      public IncludeDescriptor( final String file )
      {
          m_file = file;
      }
  
      /**
       * Return the included filename.
       *
       * @return the file
       */
      public String getFile()
      {
          return m_file;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/KernelDescriptor.java
  
  Index: KernelDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * Kernel creation profile.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public class KernelDescriptor implements AbstractContainer
  {
      /**
       * The kernel name
       */
      private final String m_name;
  
      /**
       * The logging defintion.
       */
      private final LoggingDescriptor m_logging;
  
      /**
       * The extensions defintion.
       */
      private final ExtensionsDescriptor m_extensions;
  
      /**
       * The root container.
       */
      private ClasspathDescriptor m_classpath;
  
      /**
       * The root container.
       */
      private ContainerDescriptor m_container;
  
      /**
       * Create a KernelDescriptor instance.
       *
       */
      public KernelDescriptor( final String name,
                             final LoggingDescriptor logging,
                             final ExtensionsDescriptor extensions,
                             final ContainerDescriptor container )
      {
  
          if( name == null ) 
            throw new NullPointerException("name");
          if( logging == null ) 
            throw new NullPointerException("logging");
          if( extensions == null ) 
            throw new NullPointerException("extensions");
  
          m_name = name;
          m_logging = logging;
          m_extensions = extensions;
          m_container = container;
      }
  
      /**
       * Return the container name.
       *
       * @return the name of the container
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the logging descriptor.
       *
       * @return the {@link LoggingDescriptor} for the component loggers.
       */
      public LoggingDescriptor getLoggingDescriptor()
      {
          return m_logging;
      }
  
      /**
       * Return the root logging descriptor. 
       *
       * @return the {@link CategoryDescriptor} for the component loggers.
       */
      public CategoryDescriptor getCategoryDescriptor()
      {
          return getLoggingDescriptor().getCategoryDescriptor();
      }
  
      /**
       * Return the classpath descriptor.
       *
       * @return the {@link ClasspathDescriptor} for the container.
       */
      public ExtensionsDescriptor getExtensionsDescriptor()
      {
          return m_extensions;
      }
  
      /**
       * Return the classpath descriptor.
       *
       * @return the {@link ClasspathDescriptor} for the container.
       */
      public ClasspathDescriptor getClasspathDescriptor()
      {
          return m_classpath;
      }
  
      /**
       * Sets the root container for the kernel.
       *
       * @param root the root {@link ContainerDescriptor} of the container hierachy.
       */
      //public void setContainerDescriptor( ContainerDescriptor container )
      //{
      //    if( container == null ) 
      //      throw new NullPointerException("container");
      //    m_container = container;
      //    container.setParent( this );
      //}
      
      /**
       * Return the root container.
       *
       * @return the root {@link ContainerDescriptor}.
       */
      public ContainerDescriptor getContainerDescriptor()
      {
          return m_container;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/LoggingDescriptor.java
  
  Index: LoggingDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * Description of a top level logging environment.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public final class LoggingDescriptor 
  {
      /**
       * The root category hierachy.
       */
      private CategoryDescriptor m_category;
  
      /**
       * The defaulr priority.
       */
      private String m_priority;
  
      /**
       * The default target.
       */
      private String m_target;
  
      /**
       * The dependencies keyed by role name.
       */
      private final TargetDescriptor[] m_targets;
  
      /**
       * Create a LoggingDescriptor instance.
       */
      public LoggingDescriptor( final String priority,
                             final String target,
                             final TargetDescriptor[] targets,
                             final CategoryDescriptor category )
      {
          m_targets = targets;
          m_priority = priority;
          m_target = target;
          m_category = category;
      }
  
      /**
       * Return the default logging priority for the group of categories.
       *
       * @return the default logging priority
       */
      public String getPriority( )
      {
          return m_priority;
      }
  
      /**
       * Return the default log target for the group of categories.
       *
       * @return the default target name
       */
      public String getTarget( )
      {
         return m_target;
      }
  
      /**
       * Return the set of logging target descriptors.
       *
       * @return the target descriptors
       */
      public TargetDescriptor[] getTargetDescriptors()
      {
          return m_targets;
      }
  
      /**
       * Return the root catagory descriptor.
       *
       * @return the target descriptors
       */
      public CategoryDescriptor getCategoryDescriptor()
      {
          return m_category;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/Profile.java
  
  Index: Profile.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.context.Context;
  import org.apache.excalibur.meta.info.Type;
  
  /**
   * Each component declared in the application is represented by
   * a Profile. Note that this does not necessarily imply
   * that there is only one instance of actual component. The
   * ComponentProfile could represent a pool of components, a single
   * component or a component prototype that is reused to create
   * new components as needed.
   *
   * @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/07/12 08:05:34 $
   */
  public interface Profile
  {
  
       static final int IMPLICIT = 0;
       static final int PACKAGED = 1;
       static final int EXPLICIT = 2;
  
      /**
       * Return the name of component metadata instance.
       *
       * @return the name of the component.
       */
      String getName();
  
      /**
       * Return the info for component.
       *
       * @return the info for component type.
       */
      Type getType();
  
      /**
       * Return the Parameters for component (if any).
       *
       * @return the Parameters for Component (if any).
       */
      Parameters getParameters();
  
      /**
       * Return the Configuration for component(if any).
       *
       * @return the Configuration for component
       */
      Configuration getConfiguration();
  
      /**
       * Return the Context for component (if any).
       *
       * @return the Context for component
       */
      Context getContext();
  
      /**
       * Return the logging descriptor.
       *
       * @return the {@link CategoryDescriptor} for the component loggers.
       */
      public CategoryDescriptor getCategoryDescriptor();
  
      /**
       * Return the assigned service providers.
       *
       * @return the dependency metadata for component.
       */
      Association[] getAssociations();
  
      /**
       * Return the Association for specified role.
       *
       * @return the Association for specified role.
       */
      Association getAssociation( final String role );
  
      /**
       * Returns the creation mode for this profile.
       * @return a value of EXPLICIT, PACKAGED or IMPLICIT
       */
       int getMode();
  
     /**
      * Add a provider for a service dependency role.
      * @param provider the compenont provider profile
      * @param role the dependent role
      */
      void addProvider( Profile provider, String role );
  
     /**
      * Provide a textual report on the profile.
      * @return the formatted profile report
      */
      String list();
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/TargetDescriptor.java
  
  Index: TargetDescriptor.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * A logging target descriptor.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public final class TargetDescriptor 
  {
      /**
       * The target name.
       */
      private final String m_name;
  
      /**
       * The target provider descriptor.
       */
      private final TargetProvider m_provider;
  
      /**
       * Create a LoggingDescriptor instance.
       *
       * @param name the abstract name of component meta data instance
       * @param dependencies the meta data for any dependencies
       * @param type the component type
       */
      public TargetDescriptor( final String name,
                             final TargetProvider provider )
      {
          m_name = name;
          m_provider = provider;
      }
  
      /**
       * Return the target name.
       *
       * @return the target name.
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the target provider descriptor
       *
       * @return the provider descriptor
       */
      public TargetProvider getProvider()
      {
          return m_provider;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/TargetProvider.java
  
  Index: TargetProvider.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data;
  
  /**
   * Abstract logging target provider type.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:34 $
   */
  public abstract class TargetProvider 
  {
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  Profile is the assembly of object instances that collectively defines a potential instantiation state for the type including information about the references to provider components capable of servicing declared dependecies, together with logging, configuration, parameterization, and contextualization state.
  </p>
  </body>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ContainerCreator.java
  
  Index: ContainerCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
  
  /**
   * Simple interface used to create {@link ContainerDescriptor}
   * from a Configuration sorce.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public interface ContainerCreator
  {
      /**
       * Create a {@link Profile} from configuration
       *
       * @param config the confiugration source
       * @return the newly created {@link ContainerDescriptor}
       * @throws Exception
       */
      ContainerDescriptor createContainerDescriptor( Configuration config, TypeManager manager )
          throws Exception;
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/KernelCreator.java
  
  Index: KernelCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.excalibur.merlin.meta.data.KernelDescriptor;
  import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
  
  /**
   * Simple interface used to create {@link ContainerDescriptor}
   * from a Configuration sorce.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public interface KernelCreator
  {
      /**
       * Create a {@link KernelDescriptor} from configuration
       *
       * @param config the confiugration source
       * @return the newly created {@link ContainerDescriptor}
       * @throws Exception
       */
      KernelDescriptor createKernelDescriptor( Configuration config, TypeManager manager )
          throws Exception;
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ProfileBuilder.java
  
  Index: ProfileBuilder.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import java.io.InputStream;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.builder.TypeBuilder;
  import org.apache.excalibur.merlin.meta.data.Profile;
  
  /**
   * A ProfileBuilder is responsible for building {@link Profile}
   * objects from Configuration objects. 
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public final class ProfileBuilder
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( TypeBuilder.class );
  
      private final ProfileCreator m_xmlProfileCreator = createXMLProfileCreator();
  
      /**
       * Build Profile from the XML descriptor format.
       *
       * @param classname The classname of Component
       * @param classLoader the ClassLoader to load info from
       * @return the created Type
       * @throws Exception if an error occurs
       */
      public Profile[] build( Type type, final ClassLoader classLoader )
          throws Exception
      {
          final String xprofile =
              type.getInfo().getImplementationKey().replace( '.', '/' ) + ".xprofile";
          final InputStream inputStream =
              classLoader.getResourceAsStream( xprofile );
          final ProfileCreator creator = getXMLProfileCreator( xprofile );
          if( null == inputStream )
          {
              return creator.createProfiles( type, new DefaultConfiguration("profiles", null ) );
          }
          else
          {
              return creator.createProfiles( type, inputStream );
          }
      }
  
      public Profile build( Type type, Configuration profile )
          throws Exception
      {
          final ProfileCreator creator = getXMLProfileCreator( "implicit" );
          return creator.createProfile( type, profile );
      }
  
      /**
       * Utility to get xml info builder, else throw
       * an exception if missing descriptor.
       *
       * @return the TypeCreator
       */
      private ProfileCreator getXMLProfileCreator( final String classname )
          throws Exception
      {
          if( null != m_xmlProfileCreator )
          {
              return m_xmlProfileCreator;
          }
          else
          {
              final String message =
                  REZ.getString( "builder.missing-xml-creator.error",
                                 classname );
              throw new Exception( message );
          }
      }
  
      /**
       * Utility to get XMLProfileCreator if XML files are on
       * ClassPath.
       *
       * @return the XML {@link TypeCreator}
       */
      private static ProfileCreator createXMLProfileCreator()
      {
          ProfileCreator xmlProfileCreator = null;
          try
          {
              xmlProfileCreator = new XMLProfileCreator();
          }
          catch( final Exception e )
          {
              //Ignore it if ClassNot found due to no
              //XML Classes on classpath
          }
          return xmlProfileCreator;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/ProfileCreator.java
  
  Index: ProfileCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import java.io.InputStream;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.merlin.meta.data.Profile;
  
  /**
   * Simple interface used to create {@link Profile}
   * from stream or Configuration sorce.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public interface ProfileCreator
  {
      /**
       * Create a {@link Profile} from stream
       *
       * @param key the name of component type that we are looking up
       * @param inputStream the stream that the resource is loaded from
       * @return the newly created {@link Type}
       * @throws Exception
       */
      Profile[] createProfiles( Type type, InputStream inputStream )
          throws Exception;
  
      /**
       * Create a {@link Profile} from a configuration
       *
       * @param key the name of component type that we are looking up
       * @param inputStream the stream that the resource is loaded from
       * @return the newly created {@link Type}
       * @throws Exception
       */
      Profile[] createProfiles( Type type, Configuration config )
          throws Exception;
  
      Profile createProfile( Type type, Configuration config )
          throws Exception;
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  builder.redundent-role.notice=Warning: Type for class {0} redundently specifies role name "{1}" in dependency when it is identical to the name of service. It is recomended that the <role/> section be elided.
  builder.creating-info.notice=Creating a Type for class "{0}".
  builder.created-info.notice=Constructed Type object for class {0}. ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and {4} loggers.
  builder.bad-toplevel-element.error=Error the component implemented by "{0}" has an invalid element at top level of component info descriptor. Expected: "component-info". Actual: "{1}"
  builder.missing-info.error=Unable to locate resource from which to load info for component implemented by class "{0}".
  builder.missing-xml-creator.error=Unable to create XMLTypeCreator, usually due to not having XML classes on Classpath. Thus unable to lookup XML descriptor for component type "{0}".
  
  builder.creating-profile.notice=Creating Profiles for class "{0}".
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/TypeManager.java
  
  Index: TypeManager.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.ServiceDesignator;
  import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
  
  /**
   * Interface implemented by resources capable a resolving a Type form a classname.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public interface TypeManager
  {
  
     /**
      * Add classes to the manager declared within a classpath structure.
      * @param classpath the classpath descriptor
      * @exception Exception if an exception occurs during class loading
      */
      void addClasspath( ClasspathDescriptor classpath ) throws Exception;
  
     /**
      * Resolve a {@link Type} from a classname.
      *
      * @param classname the component type
      * @return the component type
      */
      Type lookup( String classname ) throws Exception;
  
     /**
      * Register a potential supplier component type.  The implementation will
      * create a component type instance for the entry if not already known and 
      * return the existing or new instance to the invoking client.
      *
      * @param classname the component class name
      * @return the component type
      */
      Type register( String classname ) throws Exception;
  
     /**
      * Returns the set of component types know to the registry.
      * @return the set of component types registered with the registry
      */
      Type[] getTypes();
  
     /**
      * Returns the set of component types know to the registry that are capable of 
      * supporting the supplied service.
      * @return the set of candidate component types
      */
      Type[] getTypes( ServiceDesignator service );
  
     /**
      * Returns a registered component type.
      * @return the component type from the registry or null if the type is unknown
      */
      Type getType( String classname );
  
  
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLContainerCreator.java
  
  Index: XMLContainerCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Properties;
  import java.util.Vector;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.configuration.ContextFactory;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.DefaultProfile;
  import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
  import org.apache.excalibur.merlin.meta.data.IncludeDescriptor ;
  import org.apache.excalibur.merlin.meta.data.FilesetDescriptor;
  import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
  import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
  import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
  import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
  
  /**
   * Handles internalization of an XML based description of a {@link Profile}
   * from a Configuration object. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public class XMLContainerCreator extends XMLProfileCreator
      implements ContainerCreator
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( XMLContainerCreator.class );
  
  
      public ContainerDescriptor[] createContainerDescriptors( Configuration[] configs, TypeManager manager )
        throws Exception
      {
          ArrayList list = new ArrayList();
          for( int i=0; i<configs.length; i++ )
          {
              Configuration config = configs[i];
              list.add( createContainerDescriptor( config, manager ) );
          }
          return (ContainerDescriptor[]) list.toArray( new ContainerDescriptor[0] );
      }
  
      /**
       * Create a {@link ContainerDescriptor} from configuration
       *
       * @param config the confiugration source
       * @return the newly created {@link ContainerDescriptor}
       * @throws Exception
       */
      public ContainerDescriptor createContainerDescriptor( Configuration config, TypeManager manager )
          throws Exception
      {
          final String name = config.getAttribute("name");
          CategoryDescriptor loggers = createCategoryDescriptor( config.getChild("loggers"), name );
          ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
  
          manager.addClasspath( classpath );
          ComponentDescriptor[] components = createComponentDescriptors( 
            manager, config.getChildren("component") );
  
          ContainerDescriptor[] containers = createContainerDescriptors( 
            config.getChildren("container"), manager );
  
          return new ContainerDescriptor( name, loggers, classpath, components, containers );
      }
  
      public ComponentDescriptor[] createComponentDescriptors( TypeManager manager, Configuration[] configs )
        throws Exception
      {
          ArrayList list = new ArrayList();
          for( int i=0; i<configs.length; i++ )
          {
              Configuration config = configs[i];
              Type type = manager.lookup( config.getAttribute("class") );
              list.add( super.createProfile( type, config ) );
          }
          return (ComponentDescriptor[]) list.toArray( new ComponentDescriptor[0] );
      }
  
      public ClasspathDescriptor createClasspathDescriptor( Configuration config )
        throws ConfigurationException
      {
          ArrayList list = new ArrayList();
          Configuration[] configs = config.getChildren("fileset");
          for( int i=0; i<configs.length; i++ )
          {
              Configuration c = configs[i];
              list.add( createFilesetDescriptor( c ) );
          }
          FilesetDescriptor[] filesets = (FilesetDescriptor[]) list.toArray( new FilesetDescriptor[0] );
          return new ClasspathDescriptor( filesets );
      }
  
      public FilesetDescriptor createFilesetDescriptor( Configuration config ) 
        throws ConfigurationException
      {
          String base = config.getAttribute("dir");
          ArrayList list = new ArrayList();
          Configuration[] includeConfigs = config.getChildren("include");
          for( int i=0; i<includeConfigs.length; i++ )
          {
              Configuration includeConfig = includeConfigs[i];
              list.add( createIncludeDescriptor( includeConfig ) );
          }
          IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray( new IncludeDescriptor[0] );
          return new FilesetDescriptor( base, includes );
      }
  
      public IncludeDescriptor createIncludeDescriptor( Configuration config ) 
        throws ConfigurationException
      {
          String filename = config.getAttribute("name");
          return new IncludeDescriptor( filename );
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLKernelCreator.java
  
  Index: XMLKernelCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Properties;
  import java.util.Vector;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.DefaultProfile;
  import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
  import org.apache.excalibur.merlin.meta.data.IncludeDescriptor ;
  import org.apache.excalibur.merlin.meta.data.FilesetDescriptor;
  import org.apache.excalibur.merlin.meta.data.ClasspathDescriptor;
  import org.apache.excalibur.merlin.meta.data.ContainerDescriptor;
  import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
  import org.apache.excalibur.merlin.meta.data.DirsetDescriptor;
  import org.apache.excalibur.merlin.meta.data.ExtensionsDescriptor;
  import org.apache.excalibur.merlin.meta.data.KernelDescriptor;
  import org.apache.excalibur.merlin.meta.data.TargetDescriptor;
  import org.apache.excalibur.merlin.meta.data.FileTargetProvider;
  import org.apache.excalibur.merlin.meta.data.TargetProvider;
  import org.apache.excalibur.merlin.meta.data.LoggingDescriptor;
  import org.apache.excalibur.merlin.meta.data.builder.TypeManager;
  
  /**
   * Handles internalization of an XML based description of a {@link Profile}
   * from a Configuration object. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public final class XMLKernelCreator extends XMLContainerCreator
      implements KernelCreator
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( XMLKernelCreator.class );
  
      /**
       * Create a {@link KernelDescriptor} from configuration
       *
       * @param config the confiugration source
       * @return the newly created {@link ContainerDescriptor}
       * @throws Exception
       */
      public KernelDescriptor createKernelDescriptor( Configuration config, TypeManager manager )
          throws Exception
      {
          final String name = config.getName();
          LoggingDescriptor logging = createLoggingDescriptor( config.getChild("logging"), name );
          ExtensionsDescriptor extensions = createExtensionsDescriptor( config.getChild("extensions") );
          ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
          ContainerDescriptor container = createContainerDescriptor( config.getChild("container"), manager );
          return new KernelDescriptor( name, logging, extensions, container );
      }
  
      public LoggingDescriptor createLoggingDescriptor( Configuration config, String name )
        throws ConfigurationException
      {
          final String target = config.getAttribute( 
             "target", CategoryDescriptor.DEFAULT_LOGGING_TARGET );
          final String priority = config.getAttribute( "priority", null );
  
          ArrayList list = new ArrayList();
          Configuration[] configs = config.getChildren("target");
          for( int i=0; i<configs.length; i++ )
          {
              Configuration c = configs[i];
              list.add( createTargetDescriptor( c ) );
          }
          TargetDescriptor[] targets = (TargetDescriptor[]) list.toArray( new TargetDescriptor[0] );
          CategoryDescriptor loggers = super.createCategoryDescriptor( config.getChild("loggers"), name );
          return new LoggingDescriptor( priority, target, targets, loggers );
      }
  
      public TargetDescriptor createTargetDescriptor( Configuration config )
        throws ConfigurationException
      {
          final String name = config.getAttribute("name");
          if( config.getChildren().length == 0 )
            throw new ConfigurationException(
              "missing target provider elememt in '" + config.getName() + "'.");
          final Configuration c = config.getChildren()[0];
          TargetProvider provider = null;
          if( c.getName().equals("file") )
          {
              provider = createFileTargetProvider( c );
          }
          else
          {
              throw new ConfigurationException(
                "Unrecognized provider: " + c.getName() + " in " + config.getName() );
          }
          return new TargetDescriptor( name, provider );
      }
  
      public FileTargetProvider createFileTargetProvider( Configuration config )
        throws ConfigurationException
      {
          String file = config.getAttribute("location");
          return new FileTargetProvider( file );
      }
  
      public ExtensionsDescriptor createExtensionsDescriptor( Configuration config )
        throws ConfigurationException
      {
          ArrayList list = new ArrayList();
          Configuration[] configs = config.getChildren("dirset");
          for( int i=0; i<configs.length; i++ )
          {
              Configuration c = configs[i];
              list.add( createDirsetDescriptor( c ) );
          }
          DirsetDescriptor[] dirs = (DirsetDescriptor[]) list.toArray( new DirsetDescriptor[0] );
          return new ExtensionsDescriptor( dirs );
      }
  
      public DirsetDescriptor createDirsetDescriptor( Configuration config ) 
        throws ConfigurationException
      {
          String base = config.getAttribute("dir");
          ArrayList list = new ArrayList();
          Configuration[] includeConfigs = config.getChildren("include");
          for( int i=0; i<includeConfigs.length; i++ )
          {
              Configuration includeConfig = includeConfigs[i];
              list.add( createIncludeDescriptor( includeConfig ) );
          }
          IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray( new IncludeDescriptor[0] );
          return new DirsetDescriptor( base, includes );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/XMLProfileCreator.java
  
  Index: XMLProfileCreator.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.builder;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Properties;
  import java.util.Vector;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.builder.XMLTypeCreator;
  import org.apache.excalibur.meta.ConfigurationBuilder;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.DefaultProfile;
  import org.apache.excalibur.merlin.meta.data.CategoryDescriptor;
  import org.apache.excalibur.merlin.meta.data.ComponentDescriptor;
  import org.apache.excalibur.configuration.ContextFactory;
  import org.xml.sax.InputSource;
  
  /**
   * Handles internalization of an XML based description of a {@link Profile}
   * from a Configuration object. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public class XMLProfileCreator
      implements ProfileCreator
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( XMLTypeCreator.class );
  
      /**
       * Create a {@link Type} object for specified
       * classname, loaded from specified {@link InputStream}.
       *
       * @param implementationKey The classname of Component
       * @param inputStream the InputStream to load Type from
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Profile[] createProfiles( Type type, InputStream inputStream )
          throws Exception
      {
          final InputSource input = new InputSource( inputStream );
          final Configuration configuration = ConfigurationBuilder.build( input );
          return createProfiles( type, configuration );
      }
  
      /**
       * Create a {@link Profile} object for specified classname from
       * specified configuration data associated with a single type.
       *
       * @param classname The classname of Component
       * @param info the Type configuration
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Profile[] createProfiles( Type type, final Configuration info )
          throws Exception
      {
          Vector vector = new Vector();
          Configuration[] profiles = info.getChildren("component");
          if( profiles.length == 0 )
          {
              //
              // build a default profile
              //
  
              CategoryDescriptor loggers = new CategoryDescriptor( 
                type.getInfo().getName(), null, null );
  
              return new Profile[]{ 
                 new ComponentDescriptor( null, null, null, null, loggers, type, Profile.IMPLICIT  ) };
          }
          for( int i=0; i<profiles.length; i++ )
          {
             vector.add( buildProfile( type, profiles[i], Profile.PACKAGED ) );
          }
          return (Profile[]) vector.toArray( new Profile[0] );
      }
  
      public Profile createProfile( Type type, Configuration config )
          throws Exception
      {
          return buildProfile( type, config, Profile.EXPLICIT );
      }
  
      private Profile buildProfile( Type type, Configuration profile, int mode ) throws Exception
      {
          String name = null;
          if( mode == Profile.EXPLICIT )
          {
              name = profile.getAttribute("name");
          }
          Parameters params = Parameters.fromConfiguration( profile.getChild("parameters") );
          Configuration config = profile.getChild("configuration");
          Configuration loggersConfig = profile.getChild("loggers");
          CategoryDescriptor loggers = createCategoryDescriptor( loggersConfig, name );
          Context context = ContextFactory.createContextFromConfiguration( 
            null, profile.getChild("context") );
          return new ComponentDescriptor( name, params, config, context, loggers, type, mode  );
      }
  
      public CategoryDescriptor createCategoryDescriptor( Configuration config, String fallback ) 
        throws ConfigurationException
      {
          final String name = config.getAttribute( "name", fallback );
          final String priority = config.getAttribute( "priority", null );
          final String target = config.getAttribute( "target", null );
          CategoryDescriptor[] categories = createCategoryDescriptors( config );
          return new CategoryDescriptor( name, priority, target, categories );
      }
  
      private CategoryDescriptor[] createCategoryDescriptors( Configuration config )
        throws ConfigurationException
      {
          ArrayList list = new ArrayList();
          Configuration[] categories = config.getChildren( "category" );
          for( int i=0; i<categories.length; i++ )
          {
              CategoryDescriptor category = createCategoryDescriptor( categories[i], null );
              list.add( category );
          }
          return (CategoryDescriptor[]) list.toArray( new CategoryDescriptor[0] );
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/builder/package.html
  
  Index: package.html
  ===================================================================
  <html><body>
  <p>Component meta data information builders that handle internalization of an component profile descriptions supplied as a configuration instance.</P>
  </body></html>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/LifecycleException.java
  
  Index: LifecycleException.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.lifecycle;
  
  import org.apache.avalon.framework.CascadingException;
  import org.apache.excalibur.meta.verifier.VerifyException;
  
  /**
   * Exception to indicate error processing a component through its lifecycle.
   *
   * @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/07/12 08:05:35 $
   */
  public final class LifecycleException
      extends CascadingException
  {
      /**
       * Construct a new <code>VerifyException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public LifecycleException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>VerifyException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public LifecycleException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/LifecycleHelper.java
  
  Index: LifecycleHelper.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.lifecycle;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.container.ContainerUtil;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.Serviceable;
  
  import org.apache.excalibur.merlin.meta.data.Profile;
  
  /**
   * This is a class to help an Application manage the lifecycle of a component.
   * The implementation provides support for the processing of a component through
   * each lifecycle stage, and manage errors in a consistent way.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   */
  public class LifecycleHelper
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( LifecycleHelper.class );
  
      //Constants to designate stages
      private static final int STAGE_CREATE = 0;
      private static final int STAGE_LOGGER = 1;
      private static final int STAGE_CONTEXT = 2;
      private static final int STAGE_COMPOSE = 3;
      private static final int STAGE_CONFIG = 4;
      private static final int STAGE_PARAMETER = 5;
      private static final int STAGE_INIT = 6;
      private static final int STAGE_START = 7;
      private static final int STAGE_STOP = 8;
      private static final int STAGE_DISPOSE = 9;
      private static final int STAGE_DESTROY = 10;
  
      /**
       * Method to run a component through it's startup phase.
       * Errors that occur during startup will be logged appropriately and
       * cause exceptions with useful messages to be raised.
       *
       * @param name the name of the component
       * @param profile representing the instance criteria
       * @param provider the resource provider
       * @throws LifecycleException if an error occurs when the component passes
       *     through a specific lifecycle stage
       */
      public Object startup( final String name,
                             final Profile profile,
                             final ResourceProvider provider )
          throws LifecycleException
      {
          int stage = 0;
          try
          {
              //Creation stage
              stage = STAGE_CREATE;
              notice( name, stage );
              final Object object = provider.createObject( profile );
  
              //LogEnabled stage
              stage = STAGE_LOGGER;
              if( object instanceof LogEnabled )
              {
                  notice( name, stage );
                  final Logger logger = provider.createLogger( profile );
                  ContainerUtil.enableLogging( object, logger );
              }
  
              //Contextualize stage
              stage = STAGE_CONTEXT;
              if( object instanceof Contextualizable )
              {
                  notice( name, stage );
                  final Context context = provider.createContext( profile );
                  ContainerUtil.contextualize( object, context );
              }
  
              //Composition stage
              stage = STAGE_COMPOSE;
              if( object instanceof Serviceable )
              {
                  notice( name, stage );
                  final ServiceManager manager =
                      provider.createServiceManager( profile);
                  ContainerUtil.service( object, manager );
              }
              else if( object instanceof Composable )
              {
                  notice( name, stage );
                  final ComponentManager componentManager =
                      provider.createComponentManager( profile );
                  ContainerUtil.compose( object, componentManager );
              }
  
              //Configuring stage
              stage = STAGE_CONFIG;
              if( object instanceof Configurable )
              {
                  notice( name, stage );
                  final Configuration configuration =
                      provider.createConfiguration( profile );
                  ContainerUtil.configure( object, configuration );
              }
  
              //Parameterizing stage
              stage = STAGE_PARAMETER;
              if( object instanceof Parameterizable )
              {
                  notice( name, stage );
                  final Parameters parameters =
                      provider.createParameters( profile );
                  ContainerUtil.parameterize( object, parameters );
              }
  
              //Initialize stage
              stage = STAGE_INIT;
              if( object instanceof Initializable )
              {
                  notice( name, stage );
                  ContainerUtil.initialize( object );
              }
  
              //Start stage
              stage = STAGE_START;
              if( object instanceof Startable )
              {
                  notice( name, stage );
                  ContainerUtil.start( object );
              }
  
              return object;
          }
          catch( final Throwable t )
          {
              fail( name, stage, t );
  
              //fail() throws an exception so next
              //line will never be executed
              return null;
          }
      }
  
      /**
       * Method to run a component through it's shutdown phase.
       * Errors that occur during shutdown will be logged appropraitely.
       *
       * @param name the name of the component
       * @param object the component to shutdown
       */
      public void shutdown( final String name,
                            final Object object )
          throws LifecycleException
      {
  
          //Stage at which failure occured
          int stage = 0;
  
          //Failure exception
          Throwable failure = null;
  
          //Stoppable stage
          if( object instanceof Startable )
          {
              notice( name, STAGE_STOP );
              try
              {
                  ContainerUtil.stop( object );
              }
              catch( final Throwable t )
              {
                  safeFail( name, STAGE_STOP, t );
                  failure = t;
                  stage = STAGE_STOP;
              }
          }
  
          //Disposable stage
          if( object instanceof Disposable )
          {
              notice( name, STAGE_DISPOSE );
              try
              {
                  ContainerUtil.dispose( object );
              }
              catch( final Throwable t )
              {
                  safeFail( name, STAGE_DISPOSE, t );
                  failure = t;
                  stage = STAGE_DISPOSE;
              }
          }
  
          notice( name, STAGE_DESTROY );
  
          if( null != failure )
          {
              fail( name, stage, failure );
          }
      }
  
      /**
       * Utility method to report that a lifecycle stage is about to be processed.
       *
       * @param name the name of component that is the subject of the notice
       * @param stage the lifecycle processing stage
       */
      private void notice( final String name, final int stage )
      {
          if( getLogger().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "lifecycle.stage.notice",
                                 name,
                                 new Integer( stage ) );
              getLogger().debug( message );
          }
      }
  
      /**
       * Utility method to report that there was an error processing
       * specified lifecycle stage.
       *
       * @param name the name of component that caused failure
       * @param stage the lefecycle stage
       * @param t the exception thrown
       */
      private void safeFail( final String name,
                             final int stage,
                             final Throwable t )
      {
          //final String reason = t.getMessage();
          final String reason = t.toString();
          final String message =
              REZ.getString( "lifecycle.fail.error",
                             name,
                             new Integer( stage ),
                             reason );
          getLogger().error( message );
      }
  
      /**
       * Utility method to report that there was an error processing
       * specified lifecycle stage. It will also re-throw an exception
       * with a better error message.
       *
       * @param name the name of block that caused failure
       * @param stage the stage
       * @param t the exception thrown
       * @throws LifecycleException containing error
       */
      private void fail( final String name,
                         final int stage,
                         final Throwable t )
          throws LifecycleException
      {
          //final String reason = t.getMessage();
          final String reason = t.toString();
          final String message =
              REZ.getString( "lifecycle.fail.error",
                             name,
                             new Integer( stage ), reason );
          getLogger().error( message );
          throw new LifecycleException( message, t );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/ResourceProvider.java
  
  Index: ResourceProvider.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.lifecycle;
  
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.service.ServiceManager;
  
  import org.apache.excalibur.merlin.meta.data.Profile;
  
  /**
   * The interface via which resources required for a component
   * are aquired based on a supplied {@link Profile}.
   *
   * @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/07/12 08:05:35 $
   */
  public interface ResourceProvider
  {
      /**
       * Create an object specified by profile.
       *
       * @param profile the profile
       * @return the new object
       * @throws Exception if unable to create resource
       */
      Object createObject( Profile profile )
          throws Exception;
  
      /**
       * Create a new Logger for component.
       *
       * @param profile the profile
       * @return a new Logger for component
       * @throws Exception if unable to create resource
       */
      Logger createLogger( Profile profile )
          throws Exception;
  
      /**
       * Create a new Context for component.
       *
       * @param profile the profile
       * @return a new Context for component
       * @throws Exception if unable to create resource
       */
      Context createContext( Profile profile )
          throws Exception;
  
      /**
       * Create a new ComponentManager for component.
       *
       * @param profile the profile
       * @return a new ComponentManager for component
       * @throws Exception if unable to create resource
       */
      ComponentManager createComponentManager( Profile profile )
          throws Exception;
  
      /**
       * Create a new ServiceManager for component.
       *
       * @param profile the profile
       * @return a new ServiceManager for component
       * @throws Exception if unable to create resource
       */
      ServiceManager createServiceManager( Profile profile )
          throws Exception;
  
      /**
       * Create a new Configuration object for component.
       *
       * @param profile the profile
       * @return a new Configuration object for component
       * @throws Exception if unable to create resource
       */
      Configuration createConfiguration( Profile profile )
          throws Exception;
  
      /**
       * Create a new Parameters object for component.
       *
       * @param profile the profile
       * @return a new Parameters object for component
       * @throws Exception if unable to create resource
       */
      Parameters createParameters( Profile profile )
          throws Exception;
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  lifecycle.stage.notice=Component named "{0}" is passing through the {1,choice,0#Creation|1#Logger initialization|2#Contextualization|3#Composing|4#Configuration|5#Parameterizing|6#Initialization|7#Starting|8#Stopping|9#Disposing|10#Destruction} stage.
  lifecycle.fail.error=Component named "{0}" failed to pass through the {1,choice,0#Creation|1#Logger initialization|2#Contextualization|3#Composing|4#Configuration|5#Parameterizing|6#Initialization|7#Starting|8#Stopping|9#Disposing|10#Destruction} stage. (Reason: {2}).
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/lifecycle/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  Helpers classes and interfaces supporting the declaration of a resource provider to a component during lifecycle processing.
  
  <h3>Package Structure (UML)</h3>
  <p><img src=doc-files/lifecycle.gif border=0></p>
  
  
  </body>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/AssemblyVerifier.java
  
  Index: AssemblyVerifier.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.verifier;
  
  import java.util.ArrayList;
  import java.util.Stack;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.verifier.VerifyException;
  import org.apache.excalibur.meta.info.DependencyDescriptor;
  import org.apache.excalibur.meta.info.ServiceDescriptor;
  import org.apache.excalibur.meta.info.ServiceDesignator;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.merlin.meta.data.Association;
  
  /**
   * This Class verifies that a set of profiles are valid. It performs a number
   * of checks to make sure that the profile set represents a valid
   * application and excluding runtime errors will start up normally.
   * Some of the checks performed include;
   *
   * <ul>
   *   <li>Verify names of Components contain only
   *       letters, digits or the '_' character.</li>
   *   <li>Verify that the names of the Components are unique to the
   *       Assembly.</li>
   *   <li>Verify that the specified dependeny mapping correspond to
   *       dependencies specified in Type files.</li>
   *   <li>Verify that the inter-Component dependendencies are valid.
   *       This essentially means that if Component A requires Service S
   *       from Component B then Component B must provide Service S.</li>
   *   <li>Verify that there are no circular dependendencies between
   *       components.</li>
   *   <li>Verify that the Class objects for Component implement the
   *       service interfaces.</li>
   *   <li>Verify that the Class is a valid Avalon Component as per the
   *       rules in {@link ComponentVerifier} object.</li>
   * </ul>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public class AssemblyVerifier
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( AssemblyVerifier.class );
  
      /**
       * Validate and Verify the specified assembly (ie organization
       * of components). See the Class Javadocs for the rules and
       * regulations of assembly.
       *
       * @param components the Components that make up assembly
       * @throws VerifyException if an error occurs
       */
      public void verifyAssembly( final Profile[] components )
          throws VerifyException
      {
          String message = null;
  
          message = REZ.getString( "assembly.valid-names.notice" );
          getLogger().debug( message );
          verifyValidNames( components );
  
          message = REZ.getString( "assembly.unique-names.notice" );
          getLogger().debug( message );
          checkNamesUnique( components );
  
          message = REZ.getString( "assembly.dependencies-mapping.notice" );
          getLogger().debug( message );
          verifyValidDependencies( components );
  
          message = REZ.getString( "assembly.dependency-references.notice" );
          getLogger().debug( message );
          verifyDependencyReferences( components );
  
          message = REZ.getString( "assembly.nocircular-dependencies.notice" );
          getLogger().debug( message );
          verifyNoCircularDependencies( components );
      }
  
      /**
       * Verfiy that all Components have the needed dependencies specified correctly.
       *
       * @param components the Profile objects for the components
       * @throws VerifyException if an error occurs
       */
      public void verifyValidDependencies( final Profile[] components )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              verifyDependenciesMap( components[ i ] );
          }
      }
  
      /**
       * Verfiy that there are no circular references between Components.
       *
       * @param components the Profile objects for the components
       * @throws VerifyException if an circular dependency error occurs
       */
      protected void verifyNoCircularDependencies( final Profile[] components )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              final Profile component = components[ i ];
  
              final Stack stack = new Stack();
              stack.push( component );
              verifyNoCircularDependencies( component, components, stack );
              stack.pop();
          }
      }
  
      /**
       * Verfiy that there are no circular references between Components.
       *
       * @param component ???
       * @param components the Profile objects for the components
       * @param stack the ???
       * @throws VerifyException if an error occurs
       */
      protected void verifyNoCircularDependencies( final Profile component,
                                                   final Profile[] components,
                                                   final Stack stack )
          throws VerifyException
      {
          final Profile[] dependencies = getDependencies( component, components );
          for( int i = 0; i < dependencies.length; i++ )
          {
              final Profile dependency = dependencies[ i ];
              if( stack.contains( dependency ) )
              {
                  final String trace = getDependencyTrace( dependency, stack );
                  final String message =
                      REZ.getString( "assembly.circular-dependency.error",
                                     component.getName(),
                                     trace );
                  throw new VerifyException( message );
              }
  
              stack.push( dependency );
              verifyNoCircularDependencies( dependency, components, stack );
              stack.pop();
          }
      }
  
      /**
       * Get a string defining path from top of stack till
       * it reaches specified component.
       *
       * @param component the component
       * @param stack the Stack
       * @return the path of dependency
       */
      protected String getDependencyTrace( final Profile component,
                                           final Stack stack )
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "[ " );
  
          final String name = component.getName();
          final int size = stack.size();
          final int top = size - 1;
          for( int i = top; i >= 0; i-- )
          {
              final Profile other = (Profile)stack.get( i );
              if( top != i )
              {
                  sb.append( ", " );
              }
              sb.append( other.getName() );
  
              if( other.getName().equals( name ) )
              {
                  break;
              }
          }
  
          sb.append( ", " );
          sb.append( name );
  
          sb.append( " ]" );
          return sb.toString();
      }
  
      /**
       * Get array of dependencies for specified Component from specified
       * Component array.
       *
       * @param component the component to get dependencies of
       * @param components the total set of components in application
       * @return the dependencies of component
       */
      protected Profile[] getDependencies( final Profile component,
                                                     final Profile[] components )
      {
          final ArrayList dependencies = new ArrayList();
          final Association[] deps = component.getAssociations();
  
          for( int i = 0; i < deps.length; i++ )
          {
              final String name = deps[ i ].getProvider().getName();
              final Profile other = getProfile( name, components );
              dependencies.add( other );
          }
  
          return (Profile[])dependencies.toArray( new Profile[ 0 ] );
      }
  
      /**
       * Verfiy that the inter-Component dependencies are valid.
       *
       * @param components the Profile objects for the components
       * @throws VerifyException if an error occurs
       */
      protected void verifyDependencyReferences( final Profile[] components )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              verifyDependencyReferences( components[ i ], components );
          }
      }
  
      /**
       * Verfiy that the inter-Component dependencies are valid for specified Component.
       *
       * @param component the Profile object for the component
       * @param others the Profile objects for the other components
       * @throws VerifyException if an error occurs
       */
      protected void verifyDependencyReferences( final Profile component,
                                                 final Profile[] others )
          throws VerifyException
      {
          final Type info = component.getType();
          final Association[] roles = component.getAssociations();
  
          for( int i = 0; i < roles.length; i++ )
          {
              final String providerName = roles[ i ].getProvider().getName();
              final String roleName = roles[ i ].getRole();
              final ServiceDesignator service =
                  info.getDependency( roleName ).getService();
  
              //Get the other component that is providing service
              final Profile provider = getProfile( providerName, others );
              if( null == provider )
              {
                  final String message =
                      REZ.getString( "assembly.missing-dependency.error",
                                     roleName,
                                     providerName,
                                     component.getName() );
                  throw new VerifyException( message );
              }
  
              //make sure that the component offers service
              //that user expects it to be providing
              final ServiceDescriptor[] services = provider.getType().getServices();
              if( !hasMatchingService( service, services ) )
              {
                  final String message =
                      REZ.getString( "assembly.dependency-missing-service.error",
                                     component.getName(),
                                     providerName,
                                     roleName,
                                     service );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Get component with specified name from specified Component array.
       *
       * @param name the name of component to get
       * @param components the array of components to search
       * @return the Component if found, else null
       */
      protected Profile getProfile( final String name,
                                                        final Profile[] components )
      {
          for( int i = 0; i < components.length; i++ )
          {
              if( components[ i ].getName().equals( name ) )
              {
                  return components[ i ];
              }
          }
  
          return null;
      }
  
      /**
       * Verify that the names of the specified Components are valid.
       *
       * @param components the Components metadata
       * @throws VerifyException if an error occurs
       */
      protected void verifyValidNames( final Profile[] components )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              final String name = components[ i ].getName();
              if( !isValidName( name ) )
              {
                  final String message =
                      REZ.getString( "assembly.bad-name.error", name );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Return true if specified name is valid.
       * Valid names consist of letters, digits or the '_' character.
       *
       * @param name the name to check
       * @return true if valid, false otherwise
       */
      protected boolean isValidName( final String name )
      {
          final int size = name.length();
          for( int i = 0; i < size; i++ )
          {
              final char ch = name.charAt( i );
  
              if( !Character.isLetterOrDigit( ch ) && '-' != ch )
              {
                  return false;
              }
          }
  
          return true;
      }
  
      /**
       * Verify that the names of the specified components and listeners are unique.
       * It is not valid for the same name to be used in multiple components.
       *
       * @param components the Components
       * @throws VerifyException if an error occurs
       */
      protected void checkNamesUnique( final Profile[] components )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              final String name = components[ i ].getName();
              verifyUniqueName( components, name, i );
          }
      }
  
      /**
       * Verfify that specified name is unique among the specified components.
       *
       * @param components the array of components to check
       * @param name the name of component
       * @param index the index of component in array (so we can skip it)
       * @throws VerifyException if names are not unique
       */
      private void verifyUniqueName( final Profile[] components,
                                     final String name,
                                     final int index )
          throws VerifyException
      {
          for( int i = 0; i < components.length; i++ )
          {
              final String other = components[ i ].getName();
              if( index != i && other.equals( name ) )
              {
                  final String message =
                      REZ.getString( "assembly.duplicate-name.error", name );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Retrieve a list of Association objects for Profile
       * and verify that there is a 1 to 1 map with dependencies specified
       * in Type.
       *
       * @param component the Profile describing the component
       * @throws VerifyException if an error occurs
       */
      protected void verifyDependenciesMap( final Profile component )
          throws VerifyException
      {
          //Make sure all role entries specified in config file are valid
          final Association[] dependencySet = component.getAssociations();
  
          for( int i = 0; i < dependencySet.length; i++ )
          {
              final String roleName = dependencySet[ i ].getRole();
              final DependencyDescriptor descriptor = component.getType().getDependency( roleName );
  
              //If there is no dependency descriptor in Type then
              //user has specified an uneeded dependency.
              if( null == descriptor )
              {
                  final String message =
                      REZ.getString( "assembly.unknown-dependency.error",
                                     roleName,
                                     roleName,
                                     component.getName() );
                  throw new VerifyException( message );
              }
          }
  
          //Make sure all dependencies in Type file are satisfied
          final DependencyDescriptor[] dependencies = component.getType().getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              final DependencyDescriptor dependency = dependencies[ i ];
              final Association role = component.getAssociation( dependency.getRole() );
  
              //If there is no Role then the user has failed
              //to specify a needed dependency.
              if( null == role && !dependency.isOptional() )
              {
                  final String message =
                      REZ.getString( "assembly.unspecified-dependency.error",
                                     dependency.getRole(),
                                     component.getName() );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Return true if specified service reference matches any of the
       * candidate services.
       *
       * @param service the service descriptor reference
       * @param candidates an array of candidate services
       * @return true if candidate services contains a service that matches
       *         specified service, false otherwise
       */
      protected boolean hasMatchingService( final ServiceDesignator service,
                                            final ServiceDescriptor[] candidates )
      {
          for( int i = 0; i < candidates.length; i++ )
          {
              final ServiceDesignator other = candidates[ i ].getService();
              if( service.matches( other ) )
              {
                  return true;
              }
          }
  
          return false;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/MetaDataVerifier.java
  
  Index: MetaDataVerifier.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.txt file.
   */
  package org.apache.excalibur.merlin.meta.data.verifier;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.excalibur.merlin.meta.data.Profile;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.ContextDescriptor;
  import org.apache.excalibur.meta.info.ServiceDescriptor;
  import org.apache.excalibur.meta.info.ServiceDesignator;
  import org.apache.excalibur.meta.verifier.VerifyException;
  import org.apache.excalibur.meta.verifier.ComponentVerifier;
  
  /**
   * This Class verifies that an implementation is valid wrt the
   * Profile. It performs a number of checks to make sure
   * that the implementation class is consistent with MetaData.
   * Some of the checks it performs include;
   *
   * <ul>
   *   <li>Verify that the Class objects for Component implement the
   *       service interfaces.</li>
   *   <li>Verify that the Class is a valid Avalon Component as per the
   *       rules in {@link ComponentVerifier} object.</li>
   *   <li>Verify that the Class is Composable/Serviceable if and only if
   *       dependencies are declared.</li>
   *   <li>Verify that the Class is Contextualizable if and context
   *       entrys are declared.</li>
   * </ul>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/12 08:05:35 $
   */
  public class MetaDataVerifier
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( MetaDataVerifier.class );
  
      /**
       * The verifier for components in assembly.
       */
      private final ComponentVerifier m_verifier;
  
      /**
       * Create an MetaDataVerifier using base Componert ComponentVerifier.
       */
      public MetaDataVerifier()
      {
          this( new ComponentVerifier() );
      }
  
      /**
       * Create an AssemblyVerifier using specified Component ComponentVerifier.
       */
      public MetaDataVerifier( final ComponentVerifier verifier )
      {
          if( null == verifier )
          {
              throw new NullPointerException( "verifier" );
          }
  
          m_verifier = verifier;
      }
  
      public void enableLogging( final Logger logger )
      {
          super.enableLogging( logger );
          setupLogger( m_verifier );
      }
      /**
       * Verfiy that specified components designate classes that implement the
       * advertised interfaces. And confrorm to expectations of MetaData.
       *
       * @param component the Profile object for the components
       * @param classLoader the ClassLoader to load component from
       * @throws VerifyException if an error occurs
       */
      public void verifyType( final Profile component,
                                 final ClassLoader classLoader )
          throws VerifyException
      {
          final Class clazz = getClass( classLoader, component );
          verifyType( component, clazz );
      }
  
      /**
       * Verfiy that specified components designate classes that implement the
       * advertised interfaces. And confrorm to expectations of MetaData.
       *
       * @param component the Profile object for the components
       * @throws VerifyException if an error occurs
       */
      public void verifyType( final Profile component,
                                 final Class clazz )
          throws VerifyException
      {
          final String name = component.getName();
          final Class[] interfaces =
              getServiceClasses( name,
                                 component.getType().getServices(),
                                 clazz.getClassLoader() );
  
          m_verifier.verifyComponent( name, clazz, interfaces );
  
          verifyDependencyPresence( component, clazz );
          verifyContextPresence( component, clazz );
      }
  
      /**
       * Verify that the if  the component is not Contextualizable that it
       * does not declare Context Entrys.
       *
       * @param component the component metadata
       * @param clazz the class implementing component
       * @throws VerifyException if fails verification check
       */
      protected void verifyContextPresence( final Profile component,
                                            final Class clazz )
          throws VerifyException
      {
          final Type info = component.getType();
          final ContextDescriptor context = info.getContextDescriptor();
          final int count = context.getEntrys().length;
  
          if( !Contextualizable.class.isAssignableFrom( clazz ) )
          {
              if( 0 != count )
              {
                  final String message =
                      REZ.getString( "metadata.declare-uneeded-entrys.error",
                                     component.getName(),
                                     getClassname( component ) );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Verify the component assembly logic.
       * The implications verifies that the component:
       * <p>Is not Composable/Serviceable and does not declare dependencys</p>
       * <p>or</p>
       * <p>Is Composable/Serviceable and does declare dependencys</p>
       *
       * @param component the component metadata
       * @param clazz the class implementing component
       * @throws VerifyException if fails verification check
       */
      protected void verifyDependencyPresence( final Profile component,
                                               final Class clazz )
          throws VerifyException
      {
          final int count = component.getAssociations().length;
          final boolean aquiresServices =
              Composable.class.isAssignableFrom( clazz ) ||
              Serviceable.class.isAssignableFrom( clazz );
          if( !aquiresServices )
          {
              if( 0 != count )
              {
                  final String message =
                      REZ.getString( "metadata.declare-uneeded-deps.error",
                                     component.getName(),
                                     getClassname( component ) );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Retrieve an array of Classes for all the services that a Component
       * offers. This method also makes sure all services offered are
       * interfaces.
       *
       * @param name the name of component
       * @param services the services the component offers
       * @param classLoader the classLoader
       * @return an array of Classes for all the services
       * @throws VerifyException if an error occurs
       */
      protected Class[] getServiceClasses( final String name,
                                           final ServiceDescriptor[] services,
                                           final ClassLoader classLoader )
          throws VerifyException
      {
          final Class[] classes = new Class[ services.length ];
          for( int i = 0; i < services.length; i++ )
          {
              final ServiceDesignator service = services[ i ].getService();
              final String classname = service.getClassname();
              try
              {
                  classes[ i ] = classLoader.loadClass( classname );
              }
              catch( final Throwable t )
              {
                  final String message =
                      REZ.getString( "metadata.bad-service-class.error",
                                     name,
                                     classname,
                                     t.toString() );
                  throw new VerifyException( message, t );
              }
          }
  
          return classes;
      }
  
      /**
       * Load class object for specified Profile.
       *
       * @param classLoader the ClassLoader to use
       * @param component the meta data associate with component
       * @return the Class object
       * @throws VerifyException if unable to aquire class object
       */
      private Class getClass( final ClassLoader classLoader,
                              final Profile component )
          throws VerifyException
      {
          Class clazz = null;
          try
          {
              clazz = classLoader.loadClass( getClassname( component ) );
          }
          catch( final Exception e )
          {
              final String message =
                  REZ.getString( "assembly.bad-class.error",
                                 component.getName(),
                                 getClassname( component ),
                                 e.toString() );
              throw new VerifyException( message );
          }
          return clazz;
      }
  
      /**
       * Utility method to aquire classname for component.
       *
       * @param component the component
       * @return the classname for component
       */
      private String getClassname( final Profile component )
      {
          return component.getType().getInfo().getImplementationKey();
      }
  }
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  
  #Assembly Verifier
  assembly.valid-names.notice=Verifying that the names specified for Component are valid.
  assembly.unique-names.notice=Verifying that the names specified for the Components are unique.
  assembly.dependencies-mapping.notice=Verifying that the dependency mapping is valid according to ComponentInfos.
  assembly.dependency-references.notice=Verifying that the dependency mapping for every Component is valid with respect to other components.
  assembly.nocircular-dependencies.notice=Verifying that there are no circular dependencies between Components.
  assembly.component-type.notice=Verifying that the specified Components have valid types.
  assembly.circular-dependency.error=Component named "{0}" has a circular dependency via path: {1}.
  assembly.missing-dependency.error=Component "{1}" that satisfies the dependency with role "{0}" of Component "{2}" does not exist.
  assembly.dependency-missing-service.error=Profile {0}" is associated to profile "{1}" under the role "{2}" however, the provider does not supply the required service "{3}".
  
  assembly.bad-class.error=Unable to load class "{1}" for Component named "{0}". (Reason: {2}).
  assembly.bad-name.error=The Component name "{0}" is invalid. Valid names contain only letters, digits and the '-' character.
  assembly.duplicate-name.error=The name "{0}" is used by multiple Components in assembly.
  assembly.unknown-dependency.error=Unknown dependency named "{0}" with role "{1}" declared for Component {2}.
  assembly.unspecified-dependency.error=Dependency for role "{0}" not specified for the Component named "{1}".
  
  #MetaData Verifier
  metadata.bad-service-class.error=Unable to load service class "{1}" for Component named "{0}". (Reason: {2}).
  metadata.nodeclare-deps.error=Component named "{0}" of type "{1}" is Composable or Serviceable but does not declare any dependencies.
  metadata.declare-uneeded-deps.error=Component named "{0}" of type "{1}" is not Composable or Serviceable but declares dependencies.
  metadata.declare-uneeded-entrys.error=Component named "{0}" of type "{1}" is not Contextualizable but declares Context Entrys.
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/meta/data/verifier/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  A set of classes supporting verification of components and component
  assemblies using class and component meta-data information.
  
  <h3>Overview</h3>
  <p>This package includes a set of classes supporting the verification of the
  integrity of a component class and the verification of the integrity of a
  relationships and inter-dependecies based on supplied meta-data. The
  {@link org.apache.excalibur.merlin.meta.data.verifier.ComponentVerifier} provides
  support for the validation of a component class.  It includes validation
  functions that check for structural and best-practice integrity related to
  the class, lifecycle patterns and service. The
  {@link org.apache.excalibur.merlin.meta.data.verifier.AssemblyVerifier} performs
  validation of the structural integrity of a set component assembly based on
  assembly meta-data.
  </body>
  
  
  

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