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/08/20 17:03:37 UTC

cvs commit: jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/verifier ComponentVerifier.java Resources.properties VerifyException.java package.html

mcconnell    2002/08/20 08:03:37

  Added:       meta/src/org/apache/excalibur/meta ConfigurationBuilder.java
                        DTDInfo.java DTDResolver.java blockinfo.dtd
                        componentinfo.dtd package.html type.dtd
               meta/src/org/apache/excalibur/meta/info
                        ComponentDescriptor.java ContextDescriptor.java
                        DependencyDescriptor.java Descriptor.java
                        EntryDescriptor.java ExtensionDescriptor.java
                        LoggerDescriptor.java PhaseDescriptor.java
                        ReferenceDescriptor.java Resources.properties
                        ServiceDescriptor.java Type.java package.html
               meta/src/org/apache/excalibur/meta/info/builder
                        BlockBuilder.java Resources.properties
                        SerializedTypeCreator.java TypeBuilder.java
                        TypeCreator.java XMLBlockCreator.java
                        XMLTypeCreator.java package.html
               meta/src/org/apache/excalibur/meta/info/builder/doc-files
                        TypeBuilder.gif
               meta/src/org/apache/excalibur/meta/info/doc-files Type.gif
               meta/src/org/apache/excalibur/meta/verifier
                        ComponentVerifier.java Resources.properties
                        VerifyException.java package.html
  Log:
  Avalon Meta Model - container neutral meta model resources.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/ConfigurationBuilder.java
  
  Index: ConfigurationBuilder.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.meta;
  
  import java.io.IOException;
  import javax.xml.parsers.ParserConfigurationException;
  import javax.xml.parsers.SAXParser;
  import javax.xml.parsers.SAXParserFactory;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.XMLReader;
  
  /**
   * Utility class used to load Configuration trees from XML files.
   *
   * @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/08/20 15:03:36 $
   */
  public class ConfigurationBuilder
  {
      private static final DTDInfo[] c_dtdInfo = new DTDInfo[]
      {
          new DTDInfo( "-//AVALON/Component Type DTD Version 1.0//EN",
                       "http://jakarta.apache.org/avalon/type_1_0.dtd",
                       "org/apache/excalibur/meta/type.dtd" ),
          new DTDInfo( "-//AVALON/Component Info DTD Version 1.0//EN",
                       "http://jakarta.apache.org/avalon/componentinfo_1_0.dtd",
                       "org/apache/excalibur/meta/componentinfo.dtd" ),
          new DTDInfo( "-//PHOENIX/Block Info DTD Version 1.0//EN",
                       "http://jakarta.apache.org/avalon/type_1_0.dtd",
                       "org/apache/excalibur/meta/blockinfo.dtd" ),
      };
  
      private static final DTDResolver c_resolver =
          new DTDResolver( c_dtdInfo, ConfigurationBuilder.class.getClassLoader() );
  
      /**
       * Private constructor to block instantiation.
       */
      private ConfigurationBuilder()
      {
      }
  
      /**
       * Utility method to create a new XML reader.
       */
      private static XMLReader createXMLReader()
          throws SAXException, ParserConfigurationException
      {
          final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
          saxParserFactory.setNamespaceAware( false );
          final SAXParser saxParser = saxParserFactory.newSAXParser();
          return saxParser.getXMLReader();
      }
  
      /**
       * Internally sets up the XMLReader
       */
      private static void setupXMLReader( final XMLReader reader,
                                          final SAXConfigurationHandler handler )
      {
          reader.setEntityResolver( c_resolver );
          reader.setContentHandler( handler );
          reader.setErrorHandler( handler );
      }
  
      /**
       * Build a configuration object using an URI
       * @param uri an input source system identifier
       * @exception SAXException is a parser exception is encountered
       * @exception ParserConfigurationException if a parser configuration failure occurs
       * @exception IOException if an IO exception occurs while attempting to read the
       *    resource identified by the system identifier
       */
      public static Configuration build( final String uri )
          throws SAXException, ParserConfigurationException, IOException
      {
          return build( new InputSource( uri ) );
      }
  
      /**
       * Build a configuration object using an XML InputSource object
       * @param input an input source
       * @exception SAXException is a parser exception is encountered
       * @exception ParserConfigurationException if a parser configuration failure occurs
       * @exception IOException if an IO exception occurs while attempting to read the
       *    resource associated with the input source
       */
      public static Configuration build( final InputSource input )
          throws SAXException, ParserConfigurationException, IOException
      {
          if( input == null ) 
            throw new NullPointerException("input");
  
          final XMLReader reader = createXMLReader();
          final SAXConfigurationHandler handler = new SAXConfigurationHandler();
          setupXMLReader( reader, handler );
          reader.parse( input );
          return handler.getConfiguration();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/DTDInfo.java
  
  Index: DTDInfo.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.meta;
  
  /**
   * Holds information about a given DTD.
   *
   * @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/08/20 15:03:36 $
   */
  class DTDInfo
  {
      /**
       * The public identifier. Null if unknown.
       */
      private final String m_publicId;
  
      /**
       * The system identifier.  Null if unknown.
       */
      private final String m_systemId;
  
      /**
       * The resource name, if a copy of the document is available.
       */
      private final String m_resource;
  
      public DTDInfo( final String publicId,
                      final String systemId,
                      final String resource )
      {
          m_publicId = publicId;
          m_systemId = systemId;
          m_resource = resource;
      }
  
      public String getPublicId()
      {
          return m_publicId;
      }
  
      public String getSystemId()
      {
          return m_systemId;
      }
  
      public String getResource()
      {
          return m_resource;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/DTDResolver.java
  
  Index: DTDResolver.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.meta;
  
  import java.io.IOException;
  import java.io.InputStream;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  /**
   * A Class to help to resolve Entitys for items such as DTDs or
   * Schemas.
   *
   * @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/08/20 15:03:36 $
   */
  class DTDResolver
      implements EntityResolver
  {
      /**
       * The list of DTDs that can be resolved by this class.
       */
      private final DTDInfo[] m_dtdInfos;
  
      /**
       * The ClassLoader to use when loading resources for DTDs.
       */
      private final ClassLoader m_classLoader;
  
      /**
       * Construct a resolver using specified DTDInfos where resources are loaded
       * from specified ClassLoader.
       */
      public DTDResolver( final DTDInfo[] dtdInfos, final ClassLoader classLoader )
      {
          m_dtdInfos = dtdInfos;
          m_classLoader = classLoader;
      }
  
      /**
       * Resolve an entity in the XML file.
       * Called by parser to resolve DTDs.
       */
      public InputSource resolveEntity( final String publicId, final String systemId )
          throws IOException, SAXException
      {
          for( int i = 0; i < m_dtdInfos.length; i++ )
          {
              final DTDInfo info = m_dtdInfos[ i ];
  
              if( ( publicId != null && publicId.equals( info.getPublicId() ) ) ||
                  ( systemId != null && systemId.equals( info.getSystemId() ) ) )
              {
                  final ClassLoader classLoader = getClassLoader();
                  final InputStream inputStream =
                      classLoader.getResourceAsStream( info.getResource() );
                  return new InputSource( inputStream );
              }
          }
  
          return null;
      }
  
      /**
       * Return CLassLoader to load resource from.
       * If a ClassLoader is specified in the constructor use that,
       * else use ContextClassLoader unless that is null in which case
       * use the current classes ClassLoader.
       */
      private ClassLoader getClassLoader()
      {
          ClassLoader classLoader = m_classLoader;
          if( null == classLoader )
          {
              classLoader = Thread.currentThread().getContextClassLoader();
          }
          if( null == classLoader )
          {
              classLoader = getClass().getClassLoader();
          }
          return classLoader;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/blockinfo.dtd
  
  Index: blockinfo.dtd
  ===================================================================
  <!--
  
     This is the DTD defining the Phoenix BlockInfo 1.0
     descriptor (XML) file format/syntax.
  
     Author: Peter Donald <pe...@apache.org>
  
     A BlockInfo is an XML file used to describe Blocks and located side-by-side with
     the Block .class file. It describes the services the Block requires to operate,
     the services the Block is capable of offerring other Blocks and other support
     meta data.
  
     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.
  
    -->
  
  <!--
  The blockinfo is the document root, it defines:
  
  block	     the specifc details about this block
  services     the services offered by this block
  dependencies the services that this block require to operate
  -->
  <!ELEMENT blockinfo (block, services?, management-access-points?, dependencies?)>
  <!ATTLIST blockinfo id ID #IMPLIED
            xmlns CDATA #FIXED "http://jakarta.apache.org/phoenix/blockinfo_1_0.dtd" >
  
  <!--
  The block element describes the block, it defines:
  
  name	        the human readable name of block type. Must be a string
               containing alphanumeric characters, '.', '_' and starting
               with a letter.
  version	     the version of the block in (in the format #.#.#, #.# or # where
               # is a integer
  schema-type  string representing the type of schema information available
               to validate block configuration
  -->
  <!ELEMENT block          (name?,version)>
    <!ELEMENT name         (#PCDATA) >
    <!ELEMENT version      (#PCDATA) >
    <!ELEMENT schema-type  (#PCDATA) >
  
  <!--
  The service element describes a service that the block
  can provide to other blocks, or this block depends upon.
  It defines:
  
  name         the name of the service. This must be equal to the class name of the
               interface that defines the service.
  version	     the version of the block in (in the format #.#.#, #.# or # where
               # is a integer
  -->
  <!ELEMENT service   EMPTY >
    <!ATTLIST service
         name CDATA #REQUIRED
         version CDATA #IMPLIED
    >
  
  <!--
  The service dependency describes a service that the block
  requires. It defines:
  
  role         the role of the service. This is the value that is used to lookup the
               service in the ComponentManager. If not provided it defaults to the
               value specified in the name attribute of service element
  service	     the service that is required
  -->
  <!ELEMENT dependency  (role?,service) >
    <!ELEMENT role        (#PCDATA) >
  
  <!--
  The services element contains a list of services that this Block supports.
  It contains service elements.
  -->
  <!ELEMENT services    (service*)>
  
  <!--
  The services element contains a list of services that this
  Block exports to the Management system. It contains service
  elements.
  -->
  <!ELEMENT management-access-points    (service*)>
  
  <!--
  The dependencies element contains a list of services that this Block requires.
  It contains dependency elements.
  -->
  <!ELEMENT dependencies    (dependency*)>
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/componentinfo.dtd
  
  Index: componentinfo.dtd
  ===================================================================
  <!--
  
     This is the DTD defining the Avalon ComponentInfo 1.0
     descriptor (XML) file format/syntax.
  
     Author: Peter Donald <peter at apache.org>
  
     A BlockInfo is an XML file used to describe Components and located side-by-side with
     the Component .class file. It describes the services the Component requires to operate,
     the services the Component is capable of offerring other Component, the context entrys
     that Component requires and other support meta data.
  
     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.
  
    -->
  
  <!--
  The component-info is the document root, it defines:
  
  component    the specifc details about this component
  loggers      the loggers used by this component
  context      the context required by this component
  services     the services offered by this component
  dependencies the services that this component require to operate
  -->
  <!ELEMENT component-info (component, loggers?, context?, services?, dependencies?)>
  <!--
    !ATTLIST component-info id ID #IMPLIED
            xmlns CDATA #FIXED "http://jakarta.apache.org/avalon/componentinfo_1_0.dtd"
   -->
  
  <!--
  The component element describes the component, it defines:
  
  name	        the human readable name of component type. Must be a string
               containing alphanumeric characters, '.', '_' and starting
               with a letter.
  version	     the version of the component in (in the format #.#.#, #.# or # where
               # is a integer
  -->
  <!ELEMENT component      (name?,version,attributes?)>
    <!ELEMENT name         (#PCDATA) >
    <!ELEMENT version      (#PCDATA) >
  
  <!--
  The logger element defines the loggers that are available to component.
  The element has one attribute specifying name of Logger. It contains:
  
  attributes	  Optional attributes about logger
  -->
  <!ELEMENT logger   (attributes?) >
    <!ATTLIST logger name CDATA #IMPLIED >
  
  <!--
  The context element defines what values and type of context
  is available to component.
  It contains:
  
  entrys    	  Key value pairs that component uses
  attributes	  Optional attributes about service
  -->
  <!ELEMENT context   (entry*,attributes?) >
    <!ATTLIST context type CDATA #IMPLIED >
  
  <!--
  The service element defines a service that the component
  can provide to other component.
  It contains:
  
  service-ref  the reference to service.
  attributes	  Optional attributes about service
  -->
  <!ELEMENT service   (service-ref,attributes?) >
  
  <!--
  The service element defines a reference to a service that the component
  can provide to other component, or this component depends upon.
  It defines:
  
  type         the name of the service. This must be equal to the class name of the
               interface that defines the service.
  version	     the version of the block in (in the format #.#.#, #.# or # where
               # is a integer
  -->
  <!ELEMENT service-ref   EMPTY >
    <!ATTLIST service-ref
         type CDATA #REQUIRED
         version CDATA #IMPLIED >
  
  <!--
  The service dependency describes a service that the component
  requires. It defines:
  
  role         the role of the service. This is the value that is used to lookup the
               service in the ComponentManager. If not provided it defaults to the
               value specified in the name attribute of service element
  service-ref  the service that is required
  -->
  <!ELEMENT dependency  (role?,service-ref,attributes?) >
    <!ATTLIST dependency optional CDATA #IMPLIED >
    <!ELEMENT role        (#PCDATA) >
  
  <!--
  The loggers element contains a list of loggers that component uses.
  -->
  <!ELEMENT loggers    (logger*)>
  
  <!--
  The services element contains a list of services that this component supports.
  It contains service elements.
  -->
  <!ELEMENT services    (service*)>
  
  <!--
  The dependencies element contains a list of services that this component requires.
  It contains dependency elements.
  -->
  <!ELEMENT dependencies    (dependency*)>
  
  <!--
  The attributes element contains a list of attributes for feature.
  -->
  <!ELEMENT attributes    (attribute*)>
  
  <!--
  The attribute element defines an attribute (an opaque key-value pair for a feature).
  It defines:
  
  key          the key for attribute.
  value  	     the value of attribute.
  -->
  <!ELEMENT attribute   EMPTY >
    <!ATTLIST attribute
         key CDATA #REQUIRED
         value CDATA #REQUIRED
    >
  
  <!--
  The entry element defines entry in context.
  It defines:
  
  key          the key for entry.
  value  	     the value of entry.
  optional     is entry optional
  -->
  <!ELEMENT entry   EMPTY >
    <!ATTLIST entry
         key CDATA #REQUIRED
         type CDATA #REQUIRED
         optional CDATA #IMPLIED
    >
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  Generic build resources related to meta content generation.
  </p>
  </body>
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/type.dtd
  
  Index: type.dtd
  ===================================================================
  <!--
  
     This is the DTD defining the Avalon Meta Model Type 1.0
     descriptor (XML) file format/syntax.
  
     Author: Stephen McConnell <mc...@apache.org>
     Author: Peter Donald <pe...@apache.org>
  
     An xinfo file is an XML file used to describe component types and is located side-by-side with
     the .class file of the component. It describes the services the component requires to operate
     (its dependecies), the services the component is capable of offerring other component, the 
     context entrys that component requires, logging catagories that the compoent may use, stage 
     depedencies, supplied extension haddlers, and management control points and other support meta 
     data in the form of attributes.
  
     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.
  
    -->
  
  <!--
  A type element is the document root, it defines:
  
  component    the specifc details about this component
  loggers      the loggers used by this component
  context      the context required by this component
  services     the services offered by this component
  dependencies the services that this component require to operate
  stages       the lifecycle stage extensions that this component is depenent on
  extensions   the lifecycle extensions that this component provides
  controls     the set of management control points
  
  -->
  
  <!ELEMENT type (component, loggers?, context?, services?, dependencies?, stages?, extensions?)>
  
  <!--
  The component element describes the component, it defines:
  
  name	        the human readable name of component type. Must be a string
               containing alphanumeric characters, '.', '_' and starting
               with a letter.
  version	     the version of the component in (in the format #.#.#, #.# or # where
               # is a integer
  -->
  <!ELEMENT component      (name?,version,attributes?)>
    <!ELEMENT name         (#PCDATA) >
    <!ELEMENT version      (#PCDATA) >
  
  <!--
  The logger element defines the loggers that are available to component.
  The element has one attribute specifying name of Logger. It contains:
  
  attributes	  Optional attributes about logger
  -->
  <!ELEMENT logger   (attributes?) >
    <!ATTLIST logger name CDATA #IMPLIED >
  
  <!--
  The context element defines what values and type of context
  is available to component.
  It contains:
  
  entrys    	  Key value pairs that component uses
  attributes	  Optional attributes about service
  -->
  <!ELEMENT context   (entry*,attributes?) >
    <!ATTLIST context type CDATA #IMPLIED >
  
  <!--
  The service element defines a service that the component
  can provide to other component.
  It contains:
  
  reference     the reference to service.
  attributes	  Optional attributes about service
  -->
  <!ENTITY % ref "(service-ref|reference)">
  <!ELEMENT service   (%ref;,attributes?) >
  
  <!--
  The reference element defines a reference to a versioned interface.
  It defines:
  
  type         the class of the interface. This must be equal to the class name of the
               interface.
  version	 the version of the interface in (in the format #.#.#, #.# or # where
               # is a integer
  -->
  <!ELEMENT reference   EMPTY >
    <!ATTLIST reference
         type CDATA #REQUIRED
         version CDATA #IMPLIED >
  
  <!--
  The extension element defines a lifecycle extension stage supplied by a type:
  
  name  the extension name.
  reference  the version lifecycle interface supported
  attributes	  Optional attributes about the extension
  -->
  <!ENTITY % stage.attribute "stage (CREATE|ACCESS|RELEASE|DESTROY|ALL|INNER|OUTER) 'ALL'">
  <!ELEMENT extension      (name,reference,attributes?)>
  <!ATTLIST extension
         %stage.attribute; >
  
  <!--
  The control element defines an optional management access point that a component may provide.
  It contains:
  
  reference     a reference to a version management interface
  attributes	  Optional attributes about the management access point
  -->
  <!ELEMENT control      (reference,attributes?)>
  
  <!--
  The controls element contains a list of control elements that this component proivides.
  -->
  <!ELEMENT controls    (control*)>
  
  
  <!--
  The stage element defines a lifecycle extension stage that this component is dependent on.
  It contains:
  
  name  the stage name.
  interface  the client stage interface
  attributes	  Optional attributes about the stage
  -->
  <!ELEMENT stage      (reference,attributes?)>
  
  <!--
  The stages element contains a list of stages that this component id dependent on.
  It contains stage elements.
  -->
  <!ELEMENT stages    (stage*)>
  
  <!--
  The extensions element contains a list of extensions that the component provides.
  -->
  <!ELEMENT extensions    (extension*)>
  
  <!--
  The service dependency describes a service that the component
  requires. It defines:
  
  role         the role of the service. This is the value that is used to lookup the
               service in the ComponentManager. If not provided it defaults to the
               value specified in the name attribute of service element
  service-ref  the service that is required
  -->
  <!ELEMENT dependency  (role?,%ref;,attributes?) >
    <!ATTLIST dependency optional CDATA #IMPLIED >
    <!ELEMENT role        (#PCDATA) >
  
  
  <!--
  The loggers element contains a list of loggers that component uses.
  -->
  <!ELEMENT loggers    (logger*)>
  
  <!--
  The services element contains a list of services that this component supports.
  It contains service elements.
  -->
  <!ELEMENT services    (service*)>
  
  <!--
  The dependencies element contains a list of services that this component requires.
  It contains dependency elements.
  -->
  <!ELEMENT dependencies    (dependency*)>
  
  <!--
  The attributes element contains a list of attributes for feature.
  -->
  <!ELEMENT attributes    (attribute*)>
  
  <!--
  The attribute element defines an attribute (an opaque key-value pair for a feature).
  It defines:
  
  key          the key for attribute.
  value  	     the value of attribute.
  -->
  <!ELEMENT attribute   EMPTY >
    <!ATTLIST attribute
         key CDATA #REQUIRED
         value CDATA #REQUIRED
    >
  
  <!--
  The entry element defines entry in context.
  It defines:
  
  key          the key for entry.
  value  	     the value of entry.
  optional     is entry optional
  -->
  <!ELEMENT entry   EMPTY >
    <!ATTLIST entry
         key CDATA #REQUIRED
         type CDATA #REQUIRED
         optional CDATA #IMPLIED
    >
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/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.meta.info;
  
  import java.util.Properties;
  import org.apache.avalon.framework.Version;
  
  /**
   * This class is used to provide explicit information to assembler
   * and administrator about the Component. It includes information
   * such as;
   *
   * <ul>
   *   <li>a symbolic name</li>
   *   <li>classname</li>
   *   <li>version</li>
   * </ul>
   *
   * <p>The ComponentDescriptor also includes an arbitrary set
   * of attributes about component. Usually these are container
   * specific attributes that can store arbitrary information.
   * The attributes should be stored with keys based on package
   * name of container. 
   *
   * @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/08/20 15:03:36 $
   */
  public final class ComponentDescriptor extends Descriptor 
  {
      /**
       * The short name of the Component Type. Useful for displaying
       * human readable strings describing the type in
       * assembly tools or generators.
       */
      private final String m_name;
  
      /**
       * The implementation key for component (usually classname).
       */
      private final String m_implementationKey;
  
      /**
       * The version of component that descriptor describes.
       */
      private final Version m_version;
  
      public ComponentDescriptor( final String name,
                                  final String key,
                                  final Version version,
                                  final Properties attributes )
      {
          super( attributes );
  
          if( key.indexOf("/") > -1 )
          {
              throw new IllegalArgumentException( "implementationKey: " + key );
          }
  
          m_name = name;
          m_implementationKey = key;
          m_version = version;
      }
  
      /**
       * Return the symbolic name of component.
       *
       * @return the symbolic name of component.
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the implementation key for component (usually classname).
       *
       * @return the implementation key for component (usually classname).
       */
      public String getImplementationKey()
      {
          return m_implementationKey;
      }
  
      /**
       * Return the version of component.
       *
       * @return the version of component.
       */
      public Version getVersion()
      {
          return m_version;
      }
  }
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/ContextDescriptor.java
  
  Index: ContextDescriptor.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.meta.info;
  
  import java.util.Properties;
  
  import org.apache.excalibur.meta.info.EntryDescriptor;
  
  /**
   * A descriptor describing the Context that the Component
   * is passed to describe information about Runtime environment
   * of Component. It contains information such as;
   * <ul>
   *   <li>classname: the classname of the Context type if it
   *       differs from base Context class (ie BlockContext).</li>
   *   <li>entrys: a list of entrys contained in context</li>
   * </ul>
   *
   * <p>Also associated with each Context is a set of arbitrary
   * attributes that can be used to store extra information
   * about Context requirements.</p>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:36 $
   */
  public class ContextDescriptor extends Descriptor 
  {
      private final String m_type;
      private final EntryDescriptor[] m_entrys;
  
      /**
       * Create a descriptor sans attributes.
       */
      public ContextDescriptor( final String type,
                                final EntryDescriptor[] entrys )
      {
          this( type, entrys, null );
      }
  
      /**
       * Create a descriptor.
       * @exception NullPointerException if type or entrys argument is null
       * @exception IllegalArgumentException if the classname format is invalid
       */
      public ContextDescriptor( final String type,
                                final EntryDescriptor[] entrys,
                                final Properties attributes )
      {
          super( attributes );
  
          if( null == type )
          {
              throw new NullPointerException( "type" );
          }
  
          if( null == entrys )
          {
              throw new NullPointerException( "entrys" );
          }
  
          if( type.indexOf("/") > -1 )
          {
              throw new IllegalArgumentException( "classname: " + type );
          }
  
          m_type = type;
          m_entrys = entrys;
      }
  
      /**
       * Return the type of Context class.
       *
       * @return the type of Context class.
       */
      public String getType()
      {
          return m_type;
      }
  
      /**
       * Return the entrys contained in the context.
       *
       * @return the entrys contained in the context.
       */
      public EntryDescriptor[] getEntrys()
      {
          return m_entrys;
      }
  
      /**
       * Return the entry with specified key.
       *
       * @return the entry with specified key.
       */
      public EntryDescriptor getEntry( final String key )
      {
          for( int i = 0; i < m_entrys.length; i++ )
          {
              final EntryDescriptor entry = m_entrys[ i ];
              if( entry.getKey().equals( key ) )
              {
                  return entry;
              }
          }
          return null;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/DependencyDescriptor.java
  
  Index: DependencyDescriptor.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.meta.info;
  
  import java.util.Properties;
  
  /**
   * A descriptor that describes dependency information for
   * a particular Component. This class contains information
   * about;
   * <ul>
   *   <li>role: the name component uses to look up dependency</li>
   *   <li>service: the class/interface that the dependency must provide</li>
   * </ul>
   *
   * <p>Also associated with each dependency is a set of arbitrary
   * attributes that can be used to store extra information
   * about dependency. See {@link ComponentDescriptor} for example
   * of how to declare the container specific attributes.</p>
   *
   * <p>Possible uses for the attributes are to declare container
   * specific constraints of component. For example a dependency on
   * a Corba ORB may also require that the Corba ORB contain the
   * TimeServer and PersistenceStateService at initialization. Or it
   * may require that the componenet be multi-thread safe or that
   * it is persistent etc. These are all container specific
   * demands.</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/08/20 15:03:36 $
   */
  public final class DependencyDescriptor extends Descriptor
  {
      /**
       * The name the component uses to lookup dependency.
       */
      private final String m_role;
  
      /**
       * The service class/interface that the dependency must provide.
       */
      private final ReferenceDescriptor m_service;
  
      /**
       * True if dependency is optional, false otherwise.
       */
      private final boolean m_optional;
  
      /**
       * Constructor a dependency sans Attributes.
       */
      public DependencyDescriptor( final String role,
                                   final ReferenceDescriptor service )
      {
          this( role, service, false, null );
      }
  
      /**
       * Constructor that has all parts sans parent.
       */
      public DependencyDescriptor( final String role,
                                   final ReferenceDescriptor service,
                                   final boolean optional,
                                   final Properties attributes )
      {
          super( attributes );
  
          if( null == role )
          {
              throw new NullPointerException( "role" );
          }
  
          if( null == service )
          {
              throw new NullPointerException( "service" );
          }
  
          m_role = role;
          m_service = service;
          m_optional = optional;
      }
  
      /**
       * Return the name the component uses to lookup dependency.
       *
       * @return the name the component uses to lookup dependency.
       */
      public String getRole()
      {
          return m_role;
      }
  
      /**
       * Return the service class/interface descriptor that describes the
       * dependency must fulfilled by a provider.
       *
       * @return a reference to service reference that describes the fulfillment
       *  obligations that must be met by a service provider.
       */
      public ReferenceDescriptor getService()
      {
          return m_service;
      }
  
      /**
       * Return true if dependency is optional, false otherwise.
       *
       * @return true if dependency is optional, false otherwise.
       */
      public boolean isOptional()
      {
          return m_optional;
      }
  
      /**
       * Return true if dependency is required, false otherwise.
       *
       * @return true if dependency is required, false otherwise.
       */
      public boolean isRequired()
      {
          return !isOptional();
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/Descriptor.java
  
  Index: Descriptor.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.meta.info;
  
  import java.util.Properties;
  import java.io.Serializable;
  
  
  /**
   * This is the Abstract class for all feature feature descriptors.
   *
   * @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/08/20 15:03:36 $
   */
  public abstract class Descriptor
      implements Serializable
  {
      private static final String[] EMPTY_SET = new String[0];
  
      /**
       * The arbitrary set of attributes associated with Component.
       */
      private final Properties m_attributes;
  
      protected Descriptor( final Properties attributes )
      {
          m_attributes = attributes;
      }
  
      /**
       * Return the attribute for specified key.
       *
       * @return the attribute for specified key.
       */
      public String getAttribute( final String key )
      {
          if( null == m_attributes )
          {
              return null;
          }
          else
          {
              return m_attributes.getProperty( key );
          }
      }
  
      /**
       * Return the attribute for specified key.
       *
       * @return the attribute for specified key.
       */
      public String getAttribute( final String key,
                                  final String defaultValue )
      {
          if( null == m_attributes )
          {
              return defaultValue;
          }
          else
          {
              return m_attributes.getProperty( key, defaultValue );
          }
      }
  
      /**
      * Returns the set of attribute names available under this descriptor.
      *
      * @return an array of the properties names held by the descriptor.
      */
      public String[] getAttributeNames()
      {
          if( null == m_attributes )
          {
              return EMPTY_SET;
          }
          else
          {
              return (String[]) m_attributes.keySet().toArray( EMPTY_SET );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/EntryDescriptor.java
  
  Index: EntryDescriptor.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.meta.info;
  
  import java.io.Serializable;
  
  /**
   * A descriptor that describes a value that must be placed
   * in components Context. It contains information about;
   * <ul>
   *   <li>key: the key that component uses to look up entry</li>
   *   <li>type: the class/interface of the entry</li>
   *   <li>isOptional: true if entry is optional rather than required</li>
   * </ul>
   *
   * @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/08/20 15:03:36 $
   */
  public final class EntryDescriptor
      implements Serializable
  {
      /**
       * The name the component uses to lookup entry.
       */
      private final String m_key;
  
      /**
       * The class/interface of the Entry.
       */
      private final String m_type;
  
      /**
       * True if entry is optional, false otherwise.
       */
      private final boolean m_optional;
  
      /**
       * Construct an Entry.
       */
      public EntryDescriptor( final String key,
                              final String type )
      {
          this( key, type, false );
      }
  
      /**
       * Construct an Entry.
       */
      public EntryDescriptor( final String key,
                              final String type,
                              final boolean optional )
      {
          if( null == key )
          {
              throw new NullPointerException( "key" );
          }
  
          if( null == type )
          {
              throw new NullPointerException( "type" );
          }
  
          m_key = key;
          m_type = type;
          m_optional = optional;
      }
  
      /**
       * Return the key that Component uses to lookup entry.
       *
       * @return the key that Component uses to lookup entry.
       */
      public String getKey()
      {
          return m_key;
      }
  
      /**
       * Return the key type of value that is stored in Context.
       *
       * @return the key type of value that is stored in Context.
       */
      public String getType()
      {
          return m_type;
      }
  
      /**
       * Return true if entry is optional, false otherwise.
       *
       * @return true if entry is optional, false otherwise.
       */
      public boolean isOptional()
      {
          return m_optional;
      }
  
      /**
       * Return true if entry is required, false otherwise.
       *
       * @return true if entry is required, false otherwise.
       */
      public boolean isRequired()
      {
          return !isOptional();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/ExtensionDescriptor.java
  
  Index: ExtensionDescriptor.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.meta.info;
  
  import java.util.Properties;
  
  /**
   * A descriptor that describes a name and inteface of a lifecycle stage.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:36 $
   */
  public final class ExtensionDescriptor extends Descriptor
  {
      /**
       * The name of the lifecycle phase.
       */
      private final String m_name;
  
      /**
       * The interface that represents the client view of the lifecycle phase.
       */
      private final ReferenceDescriptor m_reference;
  
      /**
       * Context dependecies declared by the extension.
       */
      private final ContextDescriptor m_context;
  
      /**
       * Constructor a phase descriptor without attributes.
       * @param name the phase name
       * @param interface the phase type
       */
      public ExtensionDescriptor( final String name,
                                  final ContextDescriptor context,
                                  final ReferenceDescriptor reference )
      {
          this( name, reference, context, null );
      }
  
      /**
       * Constructor a phase descriptor with attributes.
       * @param name the phase name
       * @param interface the phase type
       */
      public ExtensionDescriptor( final String name,
                                  final ReferenceDescriptor reference,
                                  final ContextDescriptor context,
                                  final Properties attributes )
      {
          super( attributes );
  
          if( null == name )
              throw new NullPointerException( "name" );
          if( null == reference )
              throw new NullPointerException( "reference" );
          if( null == context )
              throw new NullPointerException( "context" );
  
          m_name = name;
          m_reference = reference;
          m_context = context;
      }
  
      /**
       * Return the name of the lifecycle extension.
       *
       * @return the name the lifecycle phase.
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the versioned interface reference.
       *
       * @return the reference.
       */
      public ReferenceDescriptor getReference()
      {
          return m_reference;
      }
  
      /**
       * Return the context constraints.
       *
       * @return the context descriptor
       */
      public ContextDescriptor getContext()
      {
          return m_context;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/LoggerDescriptor.java
  
  Index: LoggerDescriptor.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.meta.info;
  
  import java.util.Properties;
  
  /**
   * A descriptor describing the Loggers that the Component
   * will use. The name of each Logger is relative to the
   * Logger passed to the component (namespace separator is '.').
   * "" names root logger.
   *
   * <p>Also associated with each Logger is a set of arbitrary
   * attributes that can be used to store extra information
   * about Logger requirements.</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/08/20 15:03:36 $
   */
  public class LoggerDescriptor
      extends Descriptor
  {
      private final String m_name;
  
      /**
       * Create a descriptor for Logger.
       * 
       * @param name the logging category name
       * @param attributes a set of attributes associated with the declaration
       *
       * @exception NullPointerException if name argument is null
       */
      public LoggerDescriptor( final String name,
                               final Properties attributes )
      {
          super( attributes );
          if( null == name )
          {
              throw new NullPointerException( "name" );
          }
  
          m_name = name;
      }
  
      /**
       * Return the name of logger.
       *
       * @return the name of Logger.
       */
      public String getName()
      {
          return m_name;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/PhaseDescriptor.java
  
  Index: PhaseDescriptor.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.meta.info;
  
  import java.util.Properties;
  
  /**
   * A descriptor that describes a name and inteface of a lifecycle phase.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:36 $
   */
  public class PhaseDescriptor extends Descriptor
  {
  
      /**
       * The interface that represents the client view of the lifecycle phase.
       */
      private final ReferenceDescriptor m_reference;
  
      /**
       * Constructor a phase descriptor without attributes.
       * @param name the phase name
       * @param interface the phase type
       */
      public PhaseDescriptor( final ReferenceDescriptor reference )
      {
          this( reference, null );
      }
  
      /**
       * Constructor a phase descriptor with attributes.
       * @param name the phase name
       * @param interface the phase type
       */
      public PhaseDescriptor( final ReferenceDescriptor reference,
                              final Properties attributes )
      {
          super( attributes );
  
          if( null == reference )
              throw new NullPointerException( "reference" );
  
          m_reference = reference;
      }
  
      /**
       * Return the version interface reference.
       *
       * @return the version interface reference.
       */
      public ReferenceDescriptor getReference()
      {
          return m_reference;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/ReferenceDescriptor.java
  
  Index: ReferenceDescriptor.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.meta.info;
  
  import java.io.Serializable;
  import org.apache.avalon.framework.Version;
  
  /**
   * This reference defines the type of interface required
   * by a component. The type corresponds to the class name of the
   * interface implemented by component. Associated with each
   * classname is a version object so that different versions of same
   * interface can be represented.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:36 $
   */
  public final class ReferenceDescriptor
      implements Serializable
  {
      /**
       * The name of service class.
       */
      private final String m_classname;
  
      /**
       * The version of service class.
       */
      private final Version m_version;
  
      /**
       * Construct a service with specified name, version and attributes.
       *
       * @param classname the name of the service
       * @param version the version of service
       */
      public ReferenceDescriptor( final String classname )
      {
          this( classname, Version.getVersion( "1.0" ) );
      }
  
      /**
       * Construct a service with specified name, version and attributes.
       *
       * @param classname the name of the service
       * @param version the version of service
       */
      public ReferenceDescriptor( final String classname,
                                final Version version )
      {
          if( null == classname )
          {
              throw new NullPointerException( "classname" );
          }
  
          if( null == version )
          {
              throw new NullPointerException( "version" );
          }
  
          m_classname = classname;
          m_version = version;
      }
  
      /**
       * Return classname of interface this reference refers to.
       *
       * @return the classname of the Service
       */
      public String getClassname()
      {
          return m_classname;
      }
  
      /**
       * Return the version of interface.
       *
       * @return the version of interface
       */
      public Version getVersion()
      {
          return m_version;
      }
  
      /**
       * Determine if specified service will match this service.
       * To match a service has to have same name and must comply with version.
       *
       * @param other the other ServiceInfo
       * @return true if matches, false otherwise
       */
      public boolean matches( final ReferenceDescriptor other )
      {
          return
              other.getClassname().equals( getClassname() ) &&
              other.getVersion().complies( getVersion() );
      }
  
      /**
       * Convert to a string of format name/version
       *
       * @return string describing service
       */
      public String toString()
      {
          return getClassname() + "/" + getVersion();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  #From ComponentDescriptor and ContextDescriptor classes
  component.invalid-classname.error=Invalid classname {1}.
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/ServiceDescriptor.java
  
  Index: ServiceDescriptor.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.meta.info;
  
  import java.util.Properties;
  import org.apache.avalon.framework.Version;
  
  
  /**
   * This descriptor defines the type of service offerend or required
   * by a component. The type corresponds to the class name of the
   * class/interface implemented by component. Associated with each
   * classname is a version object so that different versions of same
   * interface can be represented.
   *
   * <p>Also associated with each service is a set of arbitrary
   * attributes that can be used to store extra information
   * about service. See {@link ComponentDescriptor} for example
   * of how to declare the container specific attributes.</p>
   *
   * <p>Possible uses for the attributes are to declare a service
   * as "stateless", "pass-by-value", "remotable" or even to attach
   * attributes such as security or transaction constraints. These
   * attributes are container specific and should not be relied
   * upon to work in all containers.</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/08/20 15:03:36 $
   */
  public final class ServiceDescriptor
      extends Descriptor
  {
      /**
       * The service reference that descriptor is describing.
       */
      private final ReferenceDescriptor m_designator;
  
      /**
       * Construct a service descriptor for specified ReferenceDescriptor
       *
       * @param service reference 
       */
      public ServiceDescriptor( final ReferenceDescriptor designator )
      {
          this( designator, null );
      }
  
      /**
       * Construct a service with specified name, version and attributes.
       *
       * @param designator the ReferenceDescriptor
       * @param attributes the attributes of service
       */
      public ServiceDescriptor( final ReferenceDescriptor designator,
                                final Properties attributes )
      {
          super( attributes );
  
          if( null == designator )
          {
              throw new NullPointerException( "designator" );
          }
  
          m_designator = designator;
      }
  
      /**
       * Retrieve the service that service descriptor refers to.
       *
       * @return the service that service descriptor refers to.
       */
      public ReferenceDescriptor getService()
      {
          return m_designator;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/Type.java
  
  Index: Type.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.meta.info;
  
  import java.io.Serializable;
  import org.xml.sax.InputSource;
  import java.io.InputStream;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.excalibur.meta.ConfigurationBuilder;
  import org.apache.excalibur.meta.info.ComponentDescriptor;
  import org.apache.excalibur.meta.info.ContextDescriptor;
  import org.apache.excalibur.meta.info.DependencyDescriptor;
  import org.apache.excalibur.meta.info.LoggerDescriptor;
  import org.apache.excalibur.meta.info.ServiceDescriptor;
  import org.apache.excalibur.meta.info.PhaseDescriptor;
  
  /**
   * This class contains the meta information about a particular
   * component type. It describes;
   *
   * <ul>
   *   <li>Human presentable meta data such as name, version, description etc
   *   useful when assembling the system.</li>
   *   <li>the context object capabilities that this component requires</li>
   *   <li>the services that this component type is capable of providing</li>
   *   <li>the services that this component type requires to operate (and the
   *   names via which services are accessed)</li>
   *   <li>extended lifecycle phases that this component uses</li>
   * </ul>
   *
   * <p><b>UML</b></p>
   * <p><image src="doc-files/Type.gif" border="0"/></p>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:36 $
   */
  public class Type implements Serializable
  {
      private final ComponentDescriptor m_descriptor;
      private final ContextDescriptor m_context;
      private final ServiceDescriptor[] m_services;
      private final DependencyDescriptor[] m_dependencies;
      private final LoggerDescriptor[] m_loggers;
      private final PhaseDescriptor[] m_phases;
      private final ExtensionDescriptor[] m_extensions;
  
      private transient Configuration m_configuration;
      private transient boolean m_loaded = false;
  
      /**
       * Basic constructor that takes as parameters all parts.
       */
      public Type( final ComponentDescriptor descriptor,
                            final LoggerDescriptor[] loggers,
                            final ContextDescriptor context,
                            final ServiceDescriptor[] services,
                            final DependencyDescriptor[] dependencies,
                            final PhaseDescriptor[] phases,
                            final ExtensionDescriptor[] extensions )
      {
          if( null == descriptor )
          {
              throw new NullPointerException( "descriptor" );
          }
          if( null == loggers )
          {
              throw new NullPointerException( "loggers" );
          }
          if( null == context )
          {
              throw new NullPointerException( "context" );
          }
          if( null == services )
          {
              throw new NullPointerException( "services" );
          }
          if( null == dependencies )
          {
              throw new NullPointerException( "dependencies" );
          }
          if( null == phases )
          {
              throw new NullPointerException( "phases" );
          }
          if( null == extensions )
          {
              throw new NullPointerException( "extensions" );
          }
  
          m_descriptor = descriptor;
          m_loggers = loggers;
          m_context = context;
          m_services = services;
          m_dependencies = dependencies;
          m_phases = phases;
          m_extensions = extensions;
      }
  
      /**
       * Return the Component descriptor.
       *
       * @return the Component descriptor.
       */
      public ComponentDescriptor getInfo()
      {
          return m_descriptor;
      }
  
      /**
       * Return the set of Logger that this Component will use.
       *
       * @return the set of Logger that this Component will use.
       */
      public LoggerDescriptor[] getLoggers()
      {
          return m_loggers;
      }
  
      /**
       * Return TRUE if the set of Logger descriptors includes the supplied name. 
       *
       * @param name the logging subcategory name
       * @return TRUE if the logging subcategory is declared.
       */
      public boolean isaLogger( String name )
      {
          LoggerDescriptor[] loggers = getLoggers();
          for( int i=0; i<loggers.length; i++ )
          {
              LoggerDescriptor logger = loggers[i];
              if( logger.getName().equals( name ) )
                return true;
          }
          return false;
      }
  
      /**
       * Return the ContextDescriptor for component, may be null.
       * If null then this component does not implement Contextualizable.
       *
       * @return the ContextDescriptor for component, may be null.
       */
      public ContextDescriptor getContext()
      {
          return m_context;
      }
  
      /**
       * Return the set of Services that this component is capable of providing.
       *
       * @return the set of Services that this component is capable of providing.
       */
      public ServiceDescriptor[] getServices()
      {
          return m_services;
      }
  
      /**
       * Return the set of Dependencies that this component requires to operate.
       *
       * @return the set of Dependencies that this component requires to operate.
       */
      public DependencyDescriptor[] getDependencies()
      {
          return m_dependencies;
      }
  
      /**
       * Retrieve a dependency with a particular role.
       *
       * @param role the role
       * @return the dependency or null if it does not exist
       */
      public DependencyDescriptor getDependency( final String role )
      {
          for( int i = 0; i < m_dependencies.length; i++ )
          {
              if( m_dependencies[ i ].getRole().equals( role ) )
              {
                  return m_dependencies[ i ];
              }
          }
  
          return null;
      }
  
      /** 
       * Returns the default configuration supplied with the type.
       *
       * @return the default configuration or null if no packaged defaults
       */
      public Configuration getConfiguration( ClassLoader loader ) throws Exception
      {
          if( m_loaded )
            return m_configuration;
  
          final String xconfig =
              getInfo().getImplementationKey().replace( '.', '/' ) + ".xconfig";
          final InputStream stream =
              loader.getResourceAsStream( xconfig );
          if( stream == null )
          {
              m_loaded = true;
          }
          else
          {
              final InputSource source = new InputSource( stream );
              m_configuration = ConfigurationBuilder.build( source );
              m_loaded = true;
          }
          return m_configuration;
      }
  
      /**
       * Return the lifecycle phases extensions required by this extension.
       *
       * @return an array of phase descriptors.
       */
      public PhaseDescriptor[] getPhases()
      {
          return m_phases;
      }
  
      /**
       * Return the phases supported by this extension.
       *
       * @return an array of extension descriptors.
       */
      public ExtensionDescriptor[] getExtensions()
      {
          return m_extensions;
      }
  
      /**
       * Return the extension supporting the supplied phase.
       *
       * @return a matching extension or null if no matching extension
       */
      public ExtensionDescriptor getExtension( PhaseDescriptor phase )
      {
          ReferenceDescriptor reference = phase.getReference();
          ExtensionDescriptor[] extensions = getExtensions();
          for( int i=0; i<extensions.length; i++ )
          {
              ExtensionDescriptor extension = extensions[i];
              ReferenceDescriptor ref = extension.getReference();
              if( reference.matches( ref ) )
                 return extension;
          }
          return null;
      }
  
     /**
      * Return a string representation of the type.
      * @return the stringified type
      */
      public String toString()
      {
          return "Type name: " + getInfo().getName() + " key: " + getInfo().getImplementationKey();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  Type is an assembly of descriptors of the constraints a component
  type declares towards a container and includes declaration of service 
  dependencies, Logger establishment criteria, Configuration, Parameters 
  and Context establishment criteria, in addition to human-readable 
  information about the component type.
  </p>
  
  <h3>Package Structure (UML)</h3>
  <p><img src=doc-files/Type.gif border=0></p>
  </body>
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/BlockBuilder.java
  
  Index: BlockBuilder.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.meta.info.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.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.excalibur.meta.info.Type;
  
  /**
   * A BlockBuilder provides backwards compatibility with Phoenix blocks.
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public final class BlockBuilder
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( BlockBuilder.class );
  
      private final TypeCreator m_xmlBlockCreator = new XMLBlockCreator();
      private final TypeCreator m_xmlTypeCreator = new XMLTypeCreator();
  
      /**
       * Setup logging for all subcomponents
       */
      public void enableLogging( final Logger logger )
      {
          super.enableLogging( logger );
          if( null != m_xmlBlockCreator )
          {
              setupLogger( m_xmlBlockCreator );
              setupLogger( m_xmlTypeCreator );
          }
      }
  
      /**
       * Create a {@link Type} object for specified Class.
       *
       * @param clazz The class of Component
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Type build( final Class clazz )
          throws Exception
      {
          return build( clazz.getName(), clazz.getClassLoader() );
      }
  
      /**
       * Create a {@link Type} object for specified
       * classname, in specified ClassLoader.
       *
       * @param classname The classname of block
       * @param classLoader the ClassLoader to load info from
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Type build( final String classname,
                                  final ClassLoader classLoader )
          throws Exception
      {
          //
          // get the input stream for the .xinfo resource
          //
  
          final String xtype =
              classname.replace( '.', '/' ) + ".xtype";
          InputStream input =
              classLoader.getResourceAsStream( xtype );
          if( null == input )
          {
              final String xinfo =
                 classname.replace( '.', '/' ) + ".xinfo";
              input =
                 classLoader.getResourceAsStream( xinfo );
              if( null == input )
              {
                  final String message =
                    REZ.getString( "builder.missing-info.error",
                                 classname );
                  throw new Exception( message );
              }
              else
              {
                  //
                  // build the type
                  //
  
                  return m_xmlBlockCreator.createType( classname, input );
  
              }
          }
          else
          {
              return m_xmlTypeCreator.createType( classname, input );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/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 from class "{0}".
  builder.created-info.notice=Constructed Type from class {0} with {1} services, {2} dependencies, {3} context entries, {4} loggers, and {5} extended phases depedencies.
  builder.bad-toplevel-element.error=Error the component implemented by "{0}" has an invalid element at top level of component info descriptor. Expected: "type". Actual: "{1}"
  builder.bad-toplevel-block-element.error=Error the component implemented by "{0}" has an invalid element at top level of component info descriptor. Expected: "blockinfo". 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-facility.notice=Creating a Facility from class "{0}".
  builder.created-facility.notice=Constructed Facility from class {0} with {1} services, {2} dependencies, {3} context entries, {4} loggers, {5} extended phases dependecies, and {6} phase extensions.
  
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/SerializedTypeCreator.java
  
  Index: SerializedTypeCreator.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.meta.info.builder;
  
  import org.apache.excalibur.meta.info.Type;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  
  /**
   * Create {@link Type} from stream made up of
   * serialized object.
   *
   * @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/08/20 15:03:37 $
   */
  public class SerializedTypeCreator
      implements TypeCreator
  {
      public Type createType( final String key,
                                                final InputStream inputStream )
          throws Exception
      {
          final ObjectInputStream ois = new ObjectInputStream( inputStream );
          return (Type)ois.readObject();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/TypeBuilder.java
  
  Index: TypeBuilder.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.meta.info.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.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.excalibur.meta.info.Type;
  
  /**
   * A TypeBuilder is responsible for building {@link Type}
   * objects from Configuration objects. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * <p><b>UML</b></p>
   * <p><image src="doc-files/TypeBuilder.gif" border="0"/></p>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public final class TypeBuilder
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( TypeBuilder.class );
  
      private final TypeCreator m_xmlTypeCreator = createXMLTypeCreator();
      private final TypeCreator m_serialTypeCreator = new SerializedTypeCreator();
  
      /**
       * Setup logging for all subcomponents
       */
      public void enableLogging( final Logger logger )
      {
          super.enableLogging( logger );
          setupLogger( m_serialTypeCreator );
          if( null != m_xmlTypeCreator )
          {
              setupLogger( m_xmlTypeCreator );
          }
      }
  
      /**
       * Create a {@link Type} object for specified Class.
       *
       * @param clazz The class of Component
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Type build( final Class clazz )
          throws Exception
      {
          return build( clazz.getName(), clazz.getClassLoader() );
      }
  
      /**
       * Create a {@link Type} object for specified
       * classname, in specified ClassLoader.
       *
       * @param classname The classname of Component
       * @param classLoader the ClassLoader to load info from
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      public Type build( final String classname,
                                  final ClassLoader classLoader )
          throws Exception
      {
          final Type info = buildFromSerDescriptor( classname, classLoader );
          if( null != info )
          {
              return info;
          }
          else
          {
              return buildFromXMLDescriptor( classname, classLoader );
          }
      }
  
      /**
       * Build Type 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
       */
      private Type buildFromSerDescriptor( final String classname,
                                                    final ClassLoader classLoader )
          throws Exception
      {
          final String xinfo =
              classname.replace( '.', '/' ) + ".sinfo";
          final InputStream inputStream =
              classLoader.getResourceAsStream( xinfo );
          if( null == inputStream )
          {
              return null;
          }
  
          return m_serialTypeCreator.createType( classname, inputStream );
      }
  
      /**
       * Build Type 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
       */
      private Type buildFromXMLDescriptor( final String classname,
                                                    final ClassLoader classLoader )
          throws Exception
      {
          //
          // get the input stream for the .xinfo resource
          //
  
          final String xinfo =
              classname.replace( '.', '/' ) + ".xinfo";
          final InputStream inputStream =
              classLoader.getResourceAsStream( xinfo );
  
          if( null == inputStream )
          {
              //##############################################################//
              // Need to upgrade this to handle automated xinfo creation      //
              // using implemented interfaces for services, no dependecies,   //
              // no context, etc.                                             //
              //##############################################################//
  
              final String message =
                  REZ.getString( "builder.missing-info.error",
                                 classname );
              throw new Exception( message );
          }
  
          //
          // build the type
          //
  
          final TypeCreator xmlTypeCreator = getXMLTypeCreator( classname );
          return xmlTypeCreator.createType( classname, inputStream );
      }
  
      /**
       * Utility to get xml info builder, else throw
       * an exception if missing descriptor.
       *
       * @return the TypeCreator
       */
      private TypeCreator getXMLTypeCreator( final String classname )
          throws Exception
      {
          if( null != m_xmlTypeCreator )
          {
              return m_xmlTypeCreator;
          }
          else
          {
              final String message =
                  REZ.getString( "builder.missing-xml-creator.error",
                                 classname );
              throw new Exception( message );
          }
      }
  
      /**
       * Utility to get XMLTypeCreator if XML files are on
       * ClassPath.
       *
       * @return the XML {@link TypeCreator}
       */
      private static TypeCreator createXMLTypeCreator()
      {
          TypeCreator xmlTypeCreator = null;
          try
          {
              xmlTypeCreator = new XMLTypeCreator();
          }
          catch( final Exception e )
          {
              //Ignore it if ClassNot found due to no
              //XML Classes on classpath
          }
          return xmlTypeCreator;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/TypeCreator.java
  
  Index: TypeCreator.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.meta.info.builder;
  
  import org.apache.excalibur.meta.info.Type;
  import java.io.InputStream;
  
  /**
   * Simple interface used to create {@link Type}
   * from stream. This abstraction was primarily created so
   * that the Type could be built from non-XML
   * sources and no XML classes need be in the classpath.
   *
   * @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/08/20 15:03:37 $
   */
  public interface TypeCreator
  {
      /**
       * Create a {@link Type} from stream
       *
       * @param key the name of component type that we are looking up
       * @param input the input stream that the resource is loaded from
       * @return the newly created {@link Type}
       * @throws Exception
       */
      Type createType( String key, InputStream input )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/XMLBlockCreator.java
  
  Index: XMLBlockCreator.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.meta.info.builder;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Properties;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  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.context.Context;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.meta.info.ComponentDescriptor;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.ContextDescriptor;
  import org.apache.excalibur.meta.info.DependencyDescriptor;
  import org.apache.excalibur.meta.info.EntryDescriptor;
  import org.apache.excalibur.meta.info.LoggerDescriptor;
  import org.apache.excalibur.meta.info.ServiceDescriptor;
  import org.apache.excalibur.meta.info.ReferenceDescriptor;
  import org.apache.excalibur.meta.info.PhaseDescriptor;
  import org.apache.excalibur.meta.info.ExtensionDescriptor;
  import org.apache.excalibur.meta.ConfigurationBuilder;
  import org.xml.sax.InputSource;
  
  /**
   * Handles internalization of an XML based description of a {@link Type}
   * 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:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public class XMLBlockCreator
      extends XMLTypeCreator
      implements TypeCreator
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( XMLBlockCreator.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 Exception if an error occurs
       */
      public Type createType( String implementationKey,
                                                InputStream inputStream  )
          throws Exception
      {
          if( inputStream == null ) 
            throw new NullPointerException("input");
  
          final InputSource input = new InputSource( inputStream );
          final String classname = implementationKey;
          final Configuration xinfo = ConfigurationBuilder.build( input );
          return build( classname, xinfo );
      }
  
      /**
       * Create a {@link Type} object for specified classname from
       * specified configuration data.
       *
       * @param classname The classname of Component
       * @param info the Type configuration
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      private Type build( final String classname, final Configuration info )
          throws Exception
      {
          if( getLogger().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "builder.creating-info.notice",
                                 classname );
              getLogger().debug( message );
          }
  
          final String topLevelName = info.getName();
          if( !topLevelName.equals( "type" ) )
          {
              if( !topLevelName.equals( "blockinfo" ) )
              {
                  final String message =
                      REZ.getString( "builder.bad-toplevel-block-element.error",
                                 classname,
                                 topLevelName );
                  throw new ConfigurationException( message );
              }
          }
  
          Configuration configuration = null;
  
          configuration = info.getChild( "block" );
          final ComponentDescriptor descriptor =
              buildComponentDescriptor( classname, configuration );
  
          configuration = info.getChild( "loggers" );
          final LoggerDescriptor[] loggers = buildLoggers( configuration );
  
          configuration = info.getChild( "context" );
          final ContextDescriptor context = buildContext( configuration );
  
          configuration = info.getChild( "services" );
          final ServiceDescriptor[] services = buildBlockServices( configuration );
  
          configuration = info.getChild( "dependencies" );
          final DependencyDescriptor[] dependencies = buildDependencies( classname, configuration );
  
          configuration = info.getChild( "stages" );
          final PhaseDescriptor[] phases = buildPhases( configuration );
  
          configuration = info.getChild( "extensions" );
          final ExtensionDescriptor[] extensions = buildExtensions( configuration );
  
          if( getLogger().isInfoEnabled() )
          {
              final String message =
                  REZ.getString( "builder.created-facility.notice",
                                 classname,
                                 new Integer( services.length ),
                                 new Integer( dependencies.length ),
                                 new Integer( context.getEntrys().length ),
                                 new Integer( loggers.length ),
                                 new Integer( phases.length ),
                                 new Integer( extensions.length ) );
              getLogger().info( message );
          }
  
          return new Type( 
            descriptor, loggers, context, services, dependencies, phases, extensions );
      }
  
      /**
       * A utility method to build an array of {@link ServiceDescriptor}
       * objects from specified configuraiton.
       *
       * @param servicesSet the services configuration
       * @return the created ServiceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ServiceDescriptor[] buildBlockServices( final Configuration servicesSet )
          throws ConfigurationException
      {
          final Configuration[] elements = servicesSet.getChildren( "service" );
          final ArrayList services = new ArrayList();
  
          for( int i = 0; i < elements.length; i++ )
          {
              final ServiceDescriptor service = buildBlockService( elements[ i ] );
              services.add( service );
          }
  
          return (ServiceDescriptor[])services.toArray( new ServiceDescriptor[ 0 ] );
      }
  
  
      /**
       * A utility method to build a <code>ServiceDescriptor</code>
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ServiceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ServiceDescriptor buildBlockService( final Configuration service )
          throws ConfigurationException
      {
          final ReferenceDescriptor designator = buildReferenceDescriptor( service );
          final Properties attributes =
              buildAttributes( service.getChild( "attributes" ) );
          return new ServiceDescriptor( designator, attributes );
      }
  
      /**
       * A utility method to build a {@link ReferenceDescriptor}
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ReferenceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ReferenceDescriptor buildReferenceDescriptor( final Configuration service )
          throws ConfigurationException
      {
          final String type = service.getAttribute( "name" );
          final String versionString = service.getAttribute( "version", "1.0" );
          final Version version = buildVersion( versionString );
          return new ReferenceDescriptor( type, version );
      }
  
      /**
       * A utility method to build a {@link DependencyDescriptor}
       * object from specified configuraiton.
       *
       * @param classname The classname of Component (used for logging purposes)
       * @param dependency the dependency configuration
       * @return the created DependencyDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected DependencyDescriptor buildDependency( final String classname,
                                                    final Configuration dependency )
          throws ConfigurationException
      {
  
          Configuration serviceRef = dependency.getChild( "service" );
          final ReferenceDescriptor service =
              buildReferenceDescriptor( serviceRef );
          final boolean optional =
              dependency.getAttributeAsBoolean( "optional", false );
          final Properties attributes =
              buildAttributes( dependency.getChild( "attributes" ) );
          String role = dependency.getChild( "role" ).getValue( null );
  
          //default to name of service if role unspecified
          if( null == role )
          {
              role = service.getClassname();
          }
          else
          {
              //If role is specified and it is the same as
              //service name then warn that it is redundent.
              if( role.equals( service.getClassname() ) )
              {
                  final String message =
                      REZ.getString( "builder.redundent-role.notice",
                                     classname,
                                     role );
                  getLogger().warn( message );
              }
          }
  
          return new DependencyDescriptor( role, service, optional, attributes );
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/XMLTypeCreator.java
  
  Index: XMLTypeCreator.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.meta.info.builder;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Properties;
  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.context.Context;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.meta.info.ComponentDescriptor;
  import org.apache.excalibur.meta.info.Type;
  import org.apache.excalibur.meta.info.ContextDescriptor;
  import org.apache.excalibur.meta.info.DependencyDescriptor;
  import org.apache.excalibur.meta.info.EntryDescriptor;
  import org.apache.excalibur.meta.info.LoggerDescriptor;
  import org.apache.excalibur.meta.info.ServiceDescriptor;
  import org.apache.excalibur.meta.info.ReferenceDescriptor;
  import org.apache.excalibur.meta.info.PhaseDescriptor;
  import org.apache.excalibur.meta.info.ExtensionDescriptor;
  import org.apache.excalibur.meta.ConfigurationBuilder;
  import org.xml.sax.InputSource;
  
  /**
   * Handles internalization of an XML based description of a {@link Type}
   * 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:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public class XMLTypeCreator
      extends AbstractLogEnabled
      implements TypeCreator
  {
      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 Exception if an error occurs
       */
      public Type createType( String implementationKey,
                                                InputStream inputStream  )
          throws Exception
      {
          if( inputStream == null ) 
            throw new NullPointerException("input");
  
          final InputSource input = new InputSource( inputStream );
          final String classname = implementationKey;
          final Configuration xinfo = ConfigurationBuilder.build( input );
          return build( classname, xinfo );
      }
  
      /**
       * Create a {@link Type} object for specified classname from
       * specified configuration data.
       *
       * @param classname The classname of Component
       * @param info the Type configuration
       * @return the created Type
       * @throws ConfigurationException if an error occurs
       */
      private Type build( final String classname, final Configuration info )
          throws Exception
      {
          if( getLogger().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "builder.creating-info.notice",
                                 classname );
              getLogger().debug( message );
          }
  
          final String topLevelName = info.getName();
          if( !topLevelName.equals( "type" ) )
          {
              if( !topLevelName.equals( "component-info" ) )
              {
                  final String message =
                      REZ.getString( "builder.bad-toplevel-element.error",
                                 classname,
                                 topLevelName );
                  throw new ConfigurationException( message );
              }
          }
  
          Configuration configuration = null;
  
          configuration = info.getChild( "component" );
          final ComponentDescriptor descriptor =
              buildComponentDescriptor( classname, configuration );
  
          configuration = info.getChild( "loggers" );
          final LoggerDescriptor[] loggers = buildLoggers( configuration );
  
          configuration = info.getChild( "context" );
          final ContextDescriptor context = buildContext( configuration );
  
          configuration = info.getChild( "services" );
          final ServiceDescriptor[] services = buildServices( configuration );
  
          configuration = info.getChild( "dependencies" );
          final DependencyDescriptor[] dependencies = buildDependencies( classname, configuration );
  
          configuration = info.getChild( "stages" );
          final PhaseDescriptor[] phases = buildPhases( configuration );
  
          configuration = info.getChild( "extensions" );
          final ExtensionDescriptor[] extensions = buildExtensions( configuration );
  
          if( getLogger().isInfoEnabled() )
          {
              final String message =
                  REZ.getString( "builder.created-facility.notice",
                                 classname,
                                 new Integer( services.length ),
                                 new Integer( dependencies.length ),
                                 new Integer( context.getEntrys().length ),
                                 new Integer( loggers.length ),
                                 new Integer( phases.length ),
                                 new Integer( extensions.length ) );
              getLogger().info( message );
          }
  
          return new Type( 
            descriptor, loggers, context, services, dependencies, phases, extensions );
      }
  
     /**
      * Utility function to create a set of phase descriptor from a configuration.
      * @param config a configuration containing 0..n phase elements
      * @return an array of phase descriptors
      * @exception Exception if a build error occurs
      */
      protected PhaseDescriptor[] buildPhases( Configuration config ) throws Exception
      {
          ArrayList list = new ArrayList();
          Configuration[] phases = config.getChildren("stage");
          for( int i=0; i<phases.length; i++ )
          {
              Configuration phase = phases[i];
              ReferenceDescriptor reference = 
                buildReferenceDescriptor( phase.getChild("reference") );
              final Properties attributes =
                buildAttributes( phase.getChild( "attributes" ) );
              list.add( new PhaseDescriptor( reference, attributes ) );
          }
          return (PhaseDescriptor[]) list.toArray( new PhaseDescriptor[0] );
      }
  
      /**
       * A utility method to build a {@link ReferenceDescriptor}
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ReferenceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ReferenceDescriptor buildReferenceDescriptor( final Configuration service )
          throws ConfigurationException
      {
          final String type = service.getAttribute( "type" );
          final String versionString = service.getAttribute( "version", "1.0" );
          final Version version = buildVersion( versionString );
          return new ReferenceDescriptor( type, version );
      }
  
      /**
       * A utility method to build an array of {@link LoggerDescriptor} objects
       * from specified configuraiton.
       *
       * @param configuration the loggers configuration
       * @return the created LoggerDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected LoggerDescriptor[] buildLoggers( final Configuration configuration )
          throws ConfigurationException
      {
          final Configuration[] elements = configuration.getChildren( "logger" );
          final ArrayList loggers = new ArrayList();
  
          for( int i = 0; i < elements.length; i++ )
          {
              final LoggerDescriptor logger = buildLogger( elements[ i ] );
              loggers.add( logger );
          }
  
          return (LoggerDescriptor[])loggers.toArray( new LoggerDescriptor[ loggers.size() ] );
      }
  
      /**
       * A utility method to build a {@link LoggerDescriptor}
       * object from specified configuraiton.
       *
       * @param logger the Logger configuration
       * @return the created LoggerDescriptor
       * @throws ConfigurationException if an error occurs
       */
      private LoggerDescriptor buildLogger( Configuration logger )
          throws ConfigurationException
      {
          final Properties attributes = buildAttributes( logger.getChild( "attributes" ) );
          final String name = logger.getAttribute( "name", "" );
          return new LoggerDescriptor( name, attributes );
      }
  
      /**
       * A utility method to build an array of {@link DependencyDescriptor}
       * objects from specified configuration and classname.
       *
       * @param classname The classname of Component (used for logging purposes)
       * @param configuration the dependencies configuration
       * @return the created DependencyDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected DependencyDescriptor[] buildDependencies( final String classname,
                                                        final Configuration configuration )
          throws ConfigurationException
      {
          final Configuration[] elements = configuration.getChildren( "dependency" );
          final ArrayList dependencies = new ArrayList();
  
          for( int i = 0; i < elements.length; i++ )
          {
              final DependencyDescriptor dependency =
                  buildDependency( classname, elements[ i ] );
              dependencies.add( dependency );
          }
  
          return (DependencyDescriptor[])dependencies.toArray( new DependencyDescriptor[ 0 ] );
      }
  
      /**
       * A utility method to build a {@link DependencyDescriptor}
       * object from specified configuraiton.
       *
       * @param classname The classname of Component (used for logging purposes)
       * @param dependency the dependency configuration
       * @return the created DependencyDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected DependencyDescriptor buildDependency( final String classname,
                                                    final Configuration dependency )
          throws ConfigurationException
      {
          //
          // try both merlin and containerkit variants for this attribute
          //
  
          Configuration serviceRef = dependency.getChild( "service-ref", false );
          if( serviceRef == null ) serviceRef = dependency.getChild( "reference" );
          final ReferenceDescriptor service =
              buildReferenceDescriptor( serviceRef );
          final boolean optional =
              dependency.getAttributeAsBoolean( "optional", false );
          final Properties attributes =
              buildAttributes( dependency.getChild( "attributes" ) );
          String role = dependency.getChild( "role" ).getValue( null );
  
          //default to name of service if role unspecified
          if( null == role )
          {
              role = service.getClassname();
          }
          else
          {
              //If role is specified and it is the same as
              //service name then warn that it is redundent.
              if( role.equals( service.getClassname() ) )
              {
                  final String message =
                      REZ.getString( "builder.redundent-role.notice",
                                     classname,
                                     role );
                  getLogger().warn( message );
              }
          }
  
          return new DependencyDescriptor( role, service, optional, attributes );
      }
  
      /**
       * A utility method to build a {@link ContextDescriptor}
       * object from specified configuraiton.
       *
       * @param context the dependency configuration
       * @return the created ContextDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ContextDescriptor buildContext( final Configuration context )
          throws ConfigurationException
      {
          final EntryDescriptor[] entrys =
              buildEntries( context.getChildren( "entry" ) );
  
          final Properties attributes =
              buildAttributes( context.getChild( "attributes" ) );
  
          final String type =
              context.getAttribute( "type",
                                    Context.class.getName() );
  
          return new ContextDescriptor( type, entrys, attributes );
      }
  
      /**
       * A utility method to build an array of {@link EntryDescriptor}
       * objects from specified configuraiton.
       *
       * @param entrySet the set of entrys to build
       * @return the created {@link EntryDescriptor}s
       * @throws ConfigurationException if an error occurs
       */
      protected EntryDescriptor[] buildEntries( final Configuration[] entrySet )
          throws ConfigurationException
      {
          final ArrayList entrys = new ArrayList();
  
          for( int i = 0; i < entrySet.length; i++ )
          {
              final EntryDescriptor service = buildEntry( entrySet[ i ] );
              entrys.add( service );
          }
  
          return (EntryDescriptor[])entrys.toArray( new EntryDescriptor[ entrys.size() ] );
      }
  
      /**
       * Create a {@link EntryDescriptor} from configuration.
       *
       * @param config the configuration
       * @return the created {@link EntryDescriptor}
       * @throws ConfigurationException if an error occurs
       */
      protected EntryDescriptor buildEntry( final Configuration config )
          throws ConfigurationException
      {
          final String key = config.getAttribute( "key" );
          final String type = config.getAttribute( "type", "java.lang.String" );
          final boolean optional =
              config.getAttributeAsBoolean( "optional", false );
  
          return new EntryDescriptor( key, type, optional );
      }
  
      /**
       * A utility method to build an array of {@link ServiceDescriptor}
       * objects from specified configuraiton.
       *
       * @param servicesSet the services configuration
       * @return the created ServiceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ServiceDescriptor[] buildServices( final Configuration servicesSet )
          throws ConfigurationException
      {
          final Configuration[] elements = servicesSet.getChildren( "service" );
          final ArrayList services = new ArrayList();
  
          for( int i = 0; i < elements.length; i++ )
          {
              final ServiceDescriptor service = buildService( elements[ i ] );
              services.add( service );
          }
  
          return (ServiceDescriptor[])services.toArray( new ServiceDescriptor[ 0 ] );
      }
  
      /**
       * A utility method to build a <code>ServiceDescriptor</code>
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ServiceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ServiceDescriptor buildService( final Configuration service )
          throws ConfigurationException
      {
          Configuration serviceRef = service.getChild( "service-ref", false );
          if( serviceRef == null ) serviceRef = service.getChild( "reference" );
          final ReferenceDescriptor designator = buildReferenceDescriptor( serviceRef );
          final Properties attributes =
              buildAttributes( service.getChild( "attributes" ) );
          return new ServiceDescriptor( designator, attributes );
      }
  
      /**
       * Build up a list of attributes from specific config tree.
       *
       * @param config the attributes config
       * @return the Properties object representing attributes
       */
      protected Properties buildAttributes( final Configuration config )
          throws ConfigurationException
      {
          final Properties attributes = new Properties();
          final Configuration[] children = config.getChildren( "attribute" );
          for( int i = 0; i < children.length; i++ )
          {
              Configuration child = children[ i ];
              final String key = child.getAttribute( "key" );
              final String value = child.getAttribute( "value" );
              attributes.setProperty( key, value );
          }
          return attributes;
      }
  
      /**
       * A utility method to build a {@link ComponentDescriptor}
       * object from specified configuraiton data and classname.
       *
       * @param classname The classname of Component (used to create descriptor)
       * @param component the Component Configuration
       * @return the created ComponentDescriptor
       * @throws ConfigurationException if an error occurs
       */
      protected ComponentDescriptor buildComponentDescriptor( final String classname,
                                                            final Configuration component )
          throws ConfigurationException
      {
          final String name = component.getChild( "name" ).getValue( null );
          final Version version = buildVersion( component.getChild( "version" ).getValue( "1.0" ) );
          final Properties attributes =
              buildAttributes( component.getChild( "attributes" ) );
  
          return new ComponentDescriptor( name, classname, version, attributes );
      }
  
      /**
       * A utility method to parse a Version object from specified string.
       *
       * @param version the version string
       * @return the created Version object
       */
      protected Version buildVersion( final String version )
      {
          return Version.getVersion( version );
      }
  
     /**
      * Utility function to create a set of phase descriptor from a configuration.
      * @param config a configuration containing 0..n phase elements
      * @return an array of phase descriptors
      * @exception Exception if a build error occurs
      */
      protected ExtensionDescriptor[] buildExtensions( Configuration config ) throws Exception
      {
          ArrayList list = new ArrayList();
          Configuration[] extensions = config.getChildren("extension");
          for( int i=0; i<extensions.length; i++ )
          {
              Configuration extension = extensions[i];
              final String name = extension.getChild("name").getValue();
              ReferenceDescriptor reference = 
                buildReferenceDescriptor( extension.getChild("reference") );
              ContextDescriptor context = buildContext( extension.getChild("context") );
              final Properties attributes =
                  buildAttributes( extension.getChild( "attributes" ) );
              list.add( new ExtensionDescriptor( name, reference, context, attributes ) );
          }
          return (ExtensionDescriptor[]) list.toArray( new ExtensionDescriptor[0] );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  Resources supporting the creation of a {@link org.apache.excalibur.meta.info.Type} instance from a serialized form.
  <a name="external"><h3>External Form (XML)</h3></a>
  <p>Configuration instances supplied to the builder shall correspond to the <a href="http://home.osm.net/componentinfo.dtd">component-info DTD</a>.  
  The structure of a component-info XML document is is described below:</p>
  
  <pre>
  
  <font color="gray"><i>&lt;!--
  Example of a component meta info external XML form. 
  The element contains the information required to construct an instance of
  org.apache.excalibur.containerkit.metainfo.ComponentInfo.  It includes 
  information about the component type, the service it provides, and the 
  services it is dependent on.
  --&gt;</i></font>
  
  &lt;type&gt;
  
  
    <font color="gray"><i>&lt;!--
    Defintion of a single component descriptor.
    --&gt;</i></font>
  
    &lt;component&gt;
  
      <font color="gray"><i>&lt;!-- the name of the component (character restriction appply) --&gt;</i></font>
  
      &lt;name&gt;<font color="darkred">my-component</font>&lt;/name&gt;
  
      <font color="gray"><i>&lt;!-- the implementation version --&gt;</i></font>
  
      &lt;version&gt;</strong><font color="darkred">1.2.1</font>&lt;/version&gt;
  
      <font color="gray"><i>&lt;!-- the set of attribibutes associated with the type
           (attribute names and values are examples only) --&gt;</i></font>
  
      &lt;attributes&gt;
  
         &lt;attribute key="<font color="darkred">avalon:display-name-i18n</font>" value="<font color="darkred">display-name</font>"/&gt;
         &lt;attribute key="<font color="darkred">avalon:lifestyle</font>" value="<font color="darkred">THREAD_SAFE</font>"/&gt;
  
      &lt;/attributes&gt;
  
    &lt;/component&gt;
  
    <font color="gray"><i>&lt;!--
    The set of logging catagories the component uses. 
    --&gt;</i></font>
  
    &lt;loggers&gt;
  
      &lt;logger name=&quot;store&quot;/&gt;
      &lt;logger name=&quot;store.cache&quot;/&gt;
      &lt;logger name=&quot;verifier&quot;/&gt;
  
    &lt;/loggers&gt;
  
  
    <font color="gray"><i>&lt;!-- 
    Declaration of the context constraints for the compoent type. 
    The "type" attribute is the name of an interface derived from the default
    contenxt interface org.apache.avalon.framework.context.Context 
    --&gt;</i></font>
  
    &lt;context type="<font color="darkred">MyContextInterface</font>"&gt;
  
      <font color="gray"><i>&lt;!-- 
      Declaration of an entry in a context object, the "key" is
      the key used by a component to locate the context entry,
      the "type" is the classname of value (typically an interface)
      or primative type.  The default value is java.lang.String.
      The "optional" attribute is a boolean value derived from the 
      TRUE or FALSE that indicates if the context value must be 
      provided or not (default is FALSE). 
      --&gt;</i></font>
  
      &lt;entry key="<font color="darkred">base</font>" type="<font color="darkred">java.io.File</font>"/&gt;
      &lt;entry key="<font color="darkred">mode</font>" optional="<font color="darkred">TRUE</font>"/&gt;
  
    &lt;/context&gt;
  
    <font color="gray"><i>&lt;!--
    Declaration of the set of services that this component is capable 
    of supplying.  Each service declarared under the services element
    may be referenced by other component info descriptions as a 
    dependecy.  A container is responsible for the assemably of 
    components based on the connection of supply components to 
    consumer components via a common service description. 
    --&gt;</i></font>
  
    &lt;services&gt;
  
        <font color="gray"><i>&lt;!-- 
        The service type is the classname of an interface and the
        version identifier qualifes the interface version.  The 
        default version value is 1.0.
        --&gt;</i></font>
  
        &lt;service&gt;
  
          &lt;reference type="<font color="darkred">SimpleService</font>" version="<font color="darkred">3.2</font>"&gt;
  
          &lt;attributes&gt;
  
             <font color="gray"><i>&lt;!--
             Service type attributes go here.
             Need some relevant examples. 
             --&gt;</i></font>
  
          &lt;/attributes&gt;
  
        &lt;/service&gt;
  
    &lt;/services&gt;
  
  
    <font color="gray"><i>&lt;!-- 
    Declaration of the set of dependecies that this component type has on 
    component suppliers.  Dependency declarations define the role name 
    that the component will use to access a service via a service
    or component manager.  The service element identifies a service 
    descriptor that is publised by a potential supplier component. 
    A dependecy may be declared as optional by setting the optional 
    attribute value to TRUE.  The default value for optional is FALSE.
    --&gt;</i></font>
  
    &lt;dependencies&gt;
  
      <font color="gray"><i>&lt;!-- 
      A dependecy declaration. In the following example the optional 
      attribute is redundant as it is equivalent to the default value
      but is included here for completness.
      --&gt;</i></font>
  
      &lt;dependency optional="<font color="darkred">FALSE</font>"&gt;
  
        <font color="gray"><i>&lt;!-- 
        The role name that the component will use as the argument to 
        lookup. The default value is the value of the service type 
        attribute listed below.
        --&gt;</i></font>
  
        &lt;role&gt;<font color="darkred">my-transformer</font>&lt;/role&gt;
  
        <font color="gray"><i>&lt;!-- 
        service reference containing the classname of the service interface
        and the version value where version defaults to 1.0 
        --&gt;</i></font>
  
        &lt;reference type="<font color="darkred">org.apache.cocoon.api.Transformer</font>" version="<font color="darkred">1.1</font>"/&gt;
  
        <font color="gray"><i>&lt;!-- the set of attributes associated with the dependecy --&gt;</i></font>
  
        &lt;attributes&gt;
  
             <font color="gray"><i>&lt;!-- 
             Service type constraints go here.
             Need some relevant examples. 
             --&gt;</i></font>
  
        &lt;/attributes&gt;
  
      &lt;/dependency&gt;
  
    &lt;/dependencies&gt;
  
  &lt;/type&gt;
  
  </pre>
  
  </p>
  
  </body>
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/builder/doc-files/TypeBuilder.gif
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/info/doc-files/Type.gif
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/verifier/ComponentVerifier.java
  
  Index: ComponentVerifier.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.meta.verifier;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Modifier;
  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.activity.Suspendable;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.Recomposable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Reconfigurable;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.Recontextualizable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Reparameterizable;
  import org.apache.avalon.framework.service.Serviceable;
  
  /**
   * Utility class to help verify that component respects the
   * rules of an Avalon component.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public class ComponentVerifier
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( ComponentVerifier.class );
  
      private static final Class[] EMPTY_TYPES = new Class[ 0 ];
  
      /**
       * The interfaces representing lifecycle stages.
       */
      private static final Class[] FRAMEWORK_CLASSES = new Class[]
      {
          LogEnabled.class,
          Contextualizable.class,
          Recontextualizable.class,
          Composable.class,
          Recomposable.class,
          Serviceable.class,
          Configurable.class,
          Reconfigurable.class,
          Parameterizable.class,
          Reparameterizable.class,
          Initializable.class,
          Startable.class,
          Suspendable.class,
          Disposable.class
      };
      /**
       * Verify that the supplied implementation class
       * and service classes are valid for a component.
       *
       * @param name the name of component
       * @param implementation the implementation class of component
       * @param services the classes representing services
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyType( final String name,
                                   final Class implementation,
                                   final Class[] services, 
                                   final Class[] phases )
          throws VerifyException
      {
          verifyComponent( name, implementation, services );
          verifyImplementsPhases( name, implementation, phases );
      }
  
      /**
       * Verify that the supplied implementation class
       * and service classes are valid for a component.
       *
       * @param name the name of component
       * @param implementation the implementation class of component
       * @param services the classes representing services
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyComponent( final String name,
                                   final Class implementation,
                                   final Class[] services )
          throws VerifyException
      {
          verifyClass( name, implementation );
          verifyLifecycles( name, implementation );
          verifyServices( name, services );
          verifyImplementsServices( name, implementation, services );
      }
  
      /**
       * Verify that the supplied implementation implements the specified
       * phase interfaces.
       *
       * @param name the name of component
       * @param implementation the class representing the component
       * @param phases the phase interfaces that the implementation must provide
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyImplementsPhases( final String name,
                                            final Class implementation,
                                            final Class[] phases )
          throws VerifyException
      {
          for( int i = 0; i < phases.length; i++ )
          {
              if( !phases[ i ].isAssignableFrom( implementation ) )
              {
                  final String message =
                      REZ.getString( "verifier.noimpl-phase.error",
                                     name,
                                     implementation.getName(),
                                     phases[ i ].getName() );
                  throw new VerifyException( message );
              }
          }
      }
  
  
  
      /**
       * Verify that the supplied implementation implements the specified
       * services.
       *
       * @param name the name of component
       * @param implementation the class representign component
       * @param services the services that the implementation must provide
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyImplementsServices( final String name,
                                            final Class implementation,
                                            final Class[] services )
          throws VerifyException
      {
          for( int i = 0; i < services.length; i++ )
          {
              if( !services[ i ].isAssignableFrom( implementation ) )
              {
                  final String message =
                      REZ.getString( "verifier.noimpl-service.error",
                                     name,
                                     implementation.getName(),
                                     services[ i ].getName() );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Verify that the supplied class is a valid class for
       * a Component.
       *
       * @param name the name of component
       * @param clazz the class representing component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyClass( final String name,
                               final Class clazz )
          throws VerifyException
      {
          verifyNoArgConstructor( name, clazz );
          verifyNonAbstract( name, clazz );
          verifyNonArray( name, clazz );
          verifyNonInterface( name, clazz );
          verifyNonPrimitive( name, clazz );
          verifyPublic( name, clazz );
      }
  
      /**
       * Verify that the supplied classes are valid classes for
       * a service.
       *
       * @param name the name of component
       * @param classes the classes representign services
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyServices( final String name,
                                  final Class[] classes )
          throws VerifyException
      {
          for( int i = 0; i < classes.length; i++ )
          {
              verifyService( name, classes[ i ] );
          }
      }
  
      /**
       * Verify that the supplied class is a valid class for
       * a service.
       *
       * @param name the name of component
       * @param clazz the class representign service
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyService( final String name,
                                 final Class clazz )
          throws VerifyException
      {
          verifyServiceIsPublic( name, clazz );
  
          //
          // the following two validation points need more work
          // (a) it is valid to pass a class as a service because the class may be a proxy
          // (b) when (a) is a class, it may be implementing lifecycle interfaces which could
          // could be hidden under another proxy - i.e. this more work needed
          //
  
          //verifyServiceIsaInterface( name, clazz );
          //verifyServiceNotALifecycle( name, clazz );
      }
  
      /**
       * Verify that the implementation class does not
       * implement incompatible lifecycle interfaces.
       *
       * @param name the name of component
       * @param implementation the implementation class
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyLifecycles( final String name,
                                    final Class implementation )
          throws VerifyException
      {
          final boolean composable =
              Composable.class.isAssignableFrom( implementation ) ||
              Recomposable.class.isAssignableFrom( implementation );
          final boolean serviceable = Serviceable.class.isAssignableFrom( implementation );
          if( serviceable && composable )
          {
              final String message =
                  REZ.getString( "verifier.incompat-serviceable.error",
                                 name,
                                 implementation.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
  
          final boolean configurable =
              Configurable.class.isAssignableFrom( implementation ) ||
              Reconfigurable.class.isAssignableFrom( implementation );
          final boolean parameterizable =
              Parameterizable.class.isAssignableFrom( implementation ) ||
              Reparameterizable.class.isAssignableFrom( implementation );
          if( parameterizable && configurable )
          {
              final String message =
                  REZ.getString( "verifier.incompat-config.error",
                                 name,
                                 implementation.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the service implemented by
       * specified component is an interface.
       *
       * @param name the name of component
       * @param clazz the class representign service
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyServiceIsaInterface( final String name,
                                             final Class clazz )
          throws VerifyException
      {
          if( !clazz.isInterface() )
          {
              final String message =
                  REZ.getString( "verifier.non-interface-service.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the service implemented by
       * specified component is public.
       *
       * @param name the name of component
       * @param clazz the class representign service
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyServiceIsPublic( final String name,
                                         final Class clazz )
          throws VerifyException
      {
          final boolean isPublic =
              Modifier.isPublic( clazz.getModifiers() );
          if( !isPublic )
          {
              final String message =
                  REZ.getString( "verifier.non-public-service.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the service implemented by
       * specified component does not extend any lifecycle interfaces.
       *
       * @param name the name of component
       * @param clazz the class representign service
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyServiceNotALifecycle( final String name,
                                              final Class clazz )
          throws VerifyException
      {
          for( int i = 0; i < FRAMEWORK_CLASSES.length; i++ )
          {
              final Class lifecycle = FRAMEWORK_CLASSES[ i ];
              if( lifecycle.isAssignableFrom( clazz ) )
              {
                  final String message =
                      REZ.getString( "verifier.service-isa-lifecycle.error",
                                     name,
                                     clazz.getName(),
                                     lifecycle.getName() );
                  getLogger().error( message );
                  throw new VerifyException( message );
              }
          }
      }
  
      /**
       * Verify that the component has a no-arg aka default
       * constructor.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyNoArgConstructor( final String name,
                                          final Class clazz )
          throws VerifyException
      {
          try
          {
              final Constructor ctor = clazz.getConstructor( EMPTY_TYPES );
              if( !Modifier.isPublic( ctor.getModifiers() ) )
              {
                  final String message =
                      REZ.getString( "verifier.non-public-ctor.error",
                                     name,
                                     clazz.getName() );
                  getLogger().error( message );
                  throw new VerifyException( message );
              }
          }
          catch( final NoSuchMethodException nsme )
          {
              final String message =
                  REZ.getString( "verifier.missing-noargs-ctor.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the component is not represented by
       * abstract class.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyNonAbstract( final String name,
                                     final Class clazz )
          throws VerifyException
      {
          final boolean isAbstract =
              Modifier.isAbstract( clazz.getModifiers() );
          if( isAbstract )
          {
              final String message =
                  REZ.getString( "verifier.abstract-class.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the component is not represented by
       * abstract class.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyPublic( final String name,
                                final Class clazz )
          throws VerifyException
      {
          final boolean isPublic =
              Modifier.isPublic( clazz.getModifiers() );
          if( !isPublic )
          {
              final String message =
                  REZ.getString( "verifier.nonpublic-class.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the component is not represented by
       * primitive class.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyNonPrimitive( final String name,
                                      final Class clazz )
          throws VerifyException
      {
          if( clazz.isPrimitive() )
          {
              final String message =
                  REZ.getString( "verifier.primitive-class.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the component is not represented by
       * interface class.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyNonInterface( final String name,
                                      final Class clazz )
          throws VerifyException
      {
          if( clazz.isInterface() )
          {
              final String message =
                  REZ.getString( "verifier.interface-class.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  
      /**
       * Verify that the component is not represented by
       * an array class.
       *
       * @param name the name of component
       * @param clazz the class representign component
       * @throws VerifyException if error thrown on failure and
       *         component fails check
       */
      public void verifyNonArray( final String name,
                                  final Class clazz )
          throws VerifyException
      {
          if( clazz.isArray() )
          {
              final String message =
                  REZ.getString( "verifier.array-class.error",
                                 name,
                                 clazz.getName() );
              getLogger().error( message );
              throw new VerifyException( message );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/verifier/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  #From Verifier class
  verifier.non-public-ctor.error=The implementation class {1} for component named "{0}" does not have a public no-arg constructor.
  verifier.missing-noargs-ctor.error=The implementation class {1} for component named "{0}" does not have a no-arg constructor.
  verifier.abstract-class.error=The implementation class {1} for component named "{0}" is abstract.
  verifier.nonpublic-class.error=The implementation class {1} for component named "{0}" is not public.
  verifier.primitive-class.error=The implementation class {1} for component named "{0}" is primitive.
  verifier.interface-class.error=The implementation class {1} for component named "{0}" is an interface.
  verifier.array-class.error=The implementation class {1} for component named "{0}" is an array class.
  verifier.non-interface-service.error=The service class {1} for component named "{0}" is not an interface.
  verifier.non-public-service.error=The service class {1} for component named "{0}" is not public.
  verifier.incompat-serviceable.error=The implementation class {1} for component named "{0}" is both Serviceable and Composable (incompatible lifecycle interfaces).
  verifier.incompat-config.error=The implementation class {1} for component named "{0}" is both Configurable and Parameterizable (incompatible lifecycle interfaces).
  verifier.noimpl-service.error=The implementation class {1} for component named "{0}" does not implement the service interface {2} which it declares it supports.
  verifier.noimpl-phase.error=The implementation class {1} for component named "{0}" does not implement the phase interface {2} which it declares it supports.
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/verifier/VerifyException.java
  
  Index: VerifyException.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.meta.verifier;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate error verifying a Block or application.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/20 15:03:37 $
   */
  public final class VerifyException
      extends CascadingException
  {
      /**
       * Construct a new <code>VerifyException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public VerifyException( 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 VerifyException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/meta/src/org/apache/excalibur/meta/verifier/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  A set of classes supporting verification of components types using class and component meta 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 info. The
  {@link org.apache.excalibur.meta.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.
  </body>
  
  
  

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