You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by do...@apache.org on 2002/08/18 08:39:01 UTC

cvs commit: jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/xdoclet AvalonTagHandler.java AvalonXDoclet.java ComponentInfoSubTask.java componentinfo.xdt

donaldp     2002/08/17 23:39:01

  Modified:    containerkit build.xml
               containerkit/src/java/org/apache/excalibur/containerkit/factory
                        DefaultComponentFactory.java
  Added:       containerkit/src/java/org/apache/excalibur/containerkit/tools/ant
                        SerializeInfoTask.java
               containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder
                        ComponentInfoBuilder.java ConfigurationBuilder.java
                        DTDInfo.java DTDResolver.java InfoCreator.java
                        Resources.properties SerializedInfoCreator.java
                        XMLInfoCreator.java componentinfo.dtd package.html
               containerkit/src/java/org/apache/excalibur/containerkit/tools/xdoclet
                        AvalonTagHandler.java AvalonXDoclet.java
                        ComponentInfoSubTask.java componentinfo.xdt
  Removed:     containerkit/src/java/org/apache/excalibur/containerkit/ant
                        SerializeInfoTask.java
               containerkit/src/java/org/apache/excalibur/containerkit/infobuilder
                        ComponentInfoBuilder.java ConfigurationBuilder.java
                        DTDInfo.java DTDResolver.java InfoCreator.java
                        Resources.properties SerializedInfoCreator.java
                        XMLInfoCreator.java componentinfo.dtd package.html
               containerkit/src/java/org/apache/excalibur/containerkit/infobuilder/doc-files
                        ComponentInfoBuilder.gif
               containerkit/src/java/org/apache/excalibur/containerkit/xdoclet
                        AvalonTagHandler.java AvalonXDoclet.java
                        ComponentInfoSubTask.java componentinfo.xdt
  Log:
  Move tool related code into a separate hierarchy.
  
  Revision  Changes    Path
  1.12      +2 -2      jakarta-avalon-excalibur/containerkit/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/containerkit/build.xml,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- build.xml	10 Aug 2002 21:14:34 -0000	1.11
  +++ build.xml	18 Aug 2002 06:39:00 -0000	1.12
  @@ -264,14 +264,14 @@
   
       <target name="xdoclet" depends="main" description="Generates the XML descriptors">
           <taskdef name="avalon-xinfo"
  -            classname="org.apache.excalibur.containerkit.xdoclet.AvalonXDoclet">
  +            classname="org.apache.excalibur.containerkit.tools.xdoclet.AvalonXDoclet">
               <classpath>
                   <path refid="project.class.path"/>
                   <pathelement location="${build.classes}"/>
               </classpath>
           </taskdef>
           <taskdef name="serialize-info"
  -            classname="org.apache.excalibur.containerkit.ant.SerializeInfoTask">
  +            classname="org.apache.excalibur.containerkit.tools.ant.SerializeInfoTask">
               <classpath>
                   <path refid="project.class.path"/>
                   <pathelement location="${build.classes}"/>
  
  
  
  1.8       +2 -2      jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/factory/DefaultComponentFactory.java
  
  Index: DefaultComponentFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/factory/DefaultComponentFactory.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- DefaultComponentFactory.java	18 Aug 2002 03:46:07 -0000	1.7
  +++ DefaultComponentFactory.java	18 Aug 2002 06:39:00 -0000	1.8
  @@ -11,7 +11,7 @@
   import java.util.WeakHashMap;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.logger.Logger;
  -import org.apache.excalibur.containerkit.infobuilder.ComponentInfoBuilder;
  +import org.apache.excalibur.containerkit.tools.infobuilder.ComponentInfoBuilder;
   import org.apache.avalon.framework.info.ComponentInfo;
   
   /**
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/ant/SerializeInfoTask.java
  
  Index: SerializeInfoTask.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.containerkit.tools.ant;
  
  import org.apache.avalon.framework.info.ComponentInfo;
  import org.apache.excalibur.containerkit.tools.infobuilder.XMLInfoCreator;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.avalon.framework.logger.ConsoleLogger;
  import java.util.ArrayList;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.ObjectOutputStream;
  import java.io.FileOutputStream;
  import java.io.OutputStream;
  
  /**
   * Simple task to load an XML descriptor into {@link org.apache.avalon.framework.info.ComponentInfo}
   * object and then serialize object to file.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public class SerializeInfoTask
      extends Task
  {
      private final ArrayList m_fileSets = new ArrayList();
      private File m_destDir;
  
      public void setDestDir( final File destDir )
      {
          m_destDir = destDir;
      }
  
      public void addFileset( final FileSet fileSet )
      {
          m_fileSets.add( fileSet );
      }
  
      public void execute()
        throws BuildException
      {
          if( null == m_destDir )
          {
              m_destDir = getProject().resolveFile( "." );
          }
  
          final XMLInfoCreator infoCreator = new XMLInfoCreator();
          infoCreator.enableLogging( new ConsoleLogger() );
  
          final int count = m_fileSets.size();
          for( int i = 0; i < count; i++ )
          {
              final FileSet fileSet = (FileSet)m_fileSets.get( i );
              final DirectoryScanner scanner = fileSet.getDirectoryScanner( getProject() );
              final File baseDir = fileSet.getDir( getProject() );
  
              final String[] srcFiles = scanner.getIncludedFiles();
              for( int j = 0; j < srcFiles.length; j++ )
              {
                  final String srcFilename = srcFiles[ j ];
                  final String baseName =
                      srcFilename.substring( 0, srcFilename.length() - 5 );
                  final String classname = baseName.replace( File.separatorChar, '.' );
                  final String destFilename = baseName + "-info.ser";
                  final File src = new File( baseDir, srcFilename );
                  final File dest = new File( m_destDir, destFilename );
                  FileInputStream inputStream = null;
                  OutputStream outputStream = null;
                  try
                  {
                      inputStream = new FileInputStream( src );
                      final ComponentInfo info =
                          infoCreator.createComponentInfo( classname, inputStream );
                      inputStream.close();
                      outputStream = new FileOutputStream( dest );
                      final ObjectOutputStream oos = new ObjectOutputStream( outputStream );
                      oos.writeObject( info );
                      oos.close();
  
                  }
                  catch( Exception e )
                  {
                      throw new BuildException( e.getMessage(), e );
                  }
                  finally
                  {
                      if( null != inputStream )
                      {
                          try
                          {
                              inputStream.close();
                          }
                          catch( IOException e )
                          {
                          }
                      }
                      if( null != outputStream )
                      {
                          try
                          {
                              outputStream.close();
                          }
                          catch( IOException e )
                          {
                          }
                      }
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/ComponentInfoBuilder.java
  
  Index: ComponentInfoBuilder.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.containerkit.tools.infobuilder;
  
  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.avalon.framework.info.ComponentInfo;
  
  /**
   * A ComponentInfoBuilder is responsible for building {@link org.apache.avalon.framework.info.ComponentInfo}
   * objects from Configuration objects. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public final class ComponentInfoBuilder
      extends AbstractLogEnabled
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( ComponentInfoBuilder.class );
  
      private final InfoCreator m_xmlInfoCreator = createXMLInfoCreator();
      private final InfoCreator m_serialInfoCreator = new SerializedInfoCreator();
  
      /**
       * Setup logging for all subcomponents
       */
      public void enableLogging( final Logger logger )
      {
          super.enableLogging( logger );
          setupLogger( m_serialInfoCreator );
          if( null != m_xmlInfoCreator )
          {
              setupLogger( m_xmlInfoCreator );
          }
      }
  
      /**
       * Create a {@link org.apache.avalon.framework.info.ComponentInfo} object for specified Class.
       *
       * @param clazz The class of Component
       * @return the created ComponentInfo
       * @throws ConfigurationException if an error occurs
       */
      public ComponentInfo build( final Class clazz )
          throws Exception
      {
          return build( clazz.getName(), clazz.getClassLoader() );
      }
  
      /**
       * Create a {@link org.apache.avalon.framework.info.ComponentInfo} object for specified
       * classname, in specified ClassLoader.
       *
       * @param classname The classname of Component
       * @param classLoader the ClassLoader to load info from
       * @return the created ComponentInfo
       * @throws ConfigurationException if an error occurs
       */
      public ComponentInfo build( final String classname,
                                  final ClassLoader classLoader )
          throws Exception
      {
          final ComponentInfo info = buildFromSerDescriptor( classname, classLoader );
          if( null != info )
          {
              return info;
          }
          else
          {
              return buildFromXMLDescriptor( classname, classLoader );
          }
      }
  
      /**
       * Build ComponentInfo from the XML descriptor format.
       *
       * @param classname The classname of Component
       * @param classLoader the ClassLoader to load info from
       * @return the created ComponentInfo
       * @throws Exception if an error occurs
       */
      private ComponentInfo buildFromSerDescriptor( final String classname,
                                                    final ClassLoader classLoader )
          throws Exception
      {
          final String xinfo =
              classname.replace( '.', '/' ) + "-info.ser";
          final InputStream inputStream =
              classLoader.getResourceAsStream( xinfo );
          if( null == inputStream )
          {
              return null;
          }
  
          return m_serialInfoCreator.createComponentInfo( classname, inputStream );
      }
  
      /**
       * Build ComponentInfo from the XML descriptor format.
       *
       * @param classname The classname of Component
       * @param classLoader the ClassLoader to load info from
       * @return the created ComponentInfo
       * @throws Exception if an error occurs
       */
      private ComponentInfo buildFromXMLDescriptor( final String classname,
                                                    final ClassLoader classLoader )
          throws Exception
      {
          final String xinfo =
              classname.replace( '.', '/' ) + "-info.xml";
          final InputStream inputStream =
              classLoader.getResourceAsStream( xinfo );
          if( null == inputStream )
          {
              final String message =
                  REZ.getString( "builder.missing-info.error",
                                 classname );
              throw new Exception( message );
          }
  
          final InfoCreator xmlInfoCreator = getXMLInfoCreator( classname );
          return xmlInfoCreator.createComponentInfo( classname, inputStream );
      }
  
      /**
       * Utility to get xml info builder, else throw
       * an exception if missing descriptor.
       *
       * @return the InfoCreator
       */
      private InfoCreator getXMLInfoCreator( final String classname )
          throws Exception
      {
          if( null != m_xmlInfoCreator )
          {
              return m_xmlInfoCreator;
          }
          else
          {
              final String message =
                  REZ.getString( "builder.missing-xml-creator.error",
                                 classname );
              throw new Exception( message );
          }
      }
  
      /**
       * Utility to get XMLInfoCreator if XML files are on
       * ClassPath.
       *
       * @return the XML {@link InfoCreator}
       */
      private static InfoCreator createXMLInfoCreator()
      {
          InfoCreator xmlInfoCreator = null;
          try
          {
              xmlInfoCreator = new XMLInfoCreator();
          }
          catch( final Exception e )
          {
              //Ignore it if ClassNot found due to no
              //XML Classes on classpath
          }
          return xmlInfoCreator;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/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.containerkit.tools.infobuilder;
  
  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 at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  class ConfigurationBuilder
  {
      private static final DTDInfo[] c_dtdInfo = new DTDInfo[]
      {
          new DTDInfo( "-//AVALON/Component Info DTD Version 1.0//EN",
                       "http://jakarta.apache.org/avalon/componentinfo_1_0.dtd",
                       "org/apache/excalibur/containerkit/tools/infobuilder/componentinfo.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
      {
          final XMLReader reader = createXMLReader();
          final SAXConfigurationHandler handler = new SAXConfigurationHandler();
          setupXMLReader( reader, handler );
          reader.parse( input );
          return handler.getConfiguration();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/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.containerkit.tools.infobuilder;
  
  /**
   * Holds information about a given DTD.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  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/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/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.containerkit.tools.infobuilder;
  
  import java.io.IOException;
  import java.io.InputStream;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.apache.excalibur.containerkit.tools.infobuilder.DTDInfo;
  
  /**
   * A Class to help to resolve Entitys for items such as DTDs or
   * Schemas.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  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/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/InfoCreator.java
  
  Index: InfoCreator.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.containerkit.tools.infobuilder;
  
  import org.apache.avalon.framework.info.ComponentInfo;
  import java.io.InputStream;
  
  /**
   * Simple interface used to create {@link org.apache.avalon.framework.info.ComponentInfo}
   * from stream. This abstraction was primarily created so
   * that the ComponentInfo could be built from non-XML
   * sources and no XML classes need be in the classpath.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public interface InfoCreator
  {
      /**
       * Create a {@link org.apache.avalon.framework.info.ComponentInfo} from stream
       *
       * @param implementationKey the name of component type that we are looking up
       * @param inputStream the stream that the resource is loaded from
       * @return the newly created {@link org.apache.avalon.framework.info.ComponentInfo}
       * @throws Exception
       */
      ComponentInfo createComponentInfo( String implementationKey,
                                         InputStream inputStream )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  builder.redundent-role.notice=Warning: ComponentInfo 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 ComponentInfo for class "{0}".
  builder.created-info.notice=Constructed ComponentInfo object for class {0}. ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and {4} loggers.
  builder.bad-toplevel-element.error=Error the component implemented by "{0}" has an invalid element at top level of component info descriptor. Expected: "component-info". Actual: "{1}"
  builder.missing-info.error=Unable to locate resource from which to load info for component implemented by class "{0}".
  builder.missing-xml-creator.error=Unable to create XMLInfoCreator, usually due to not having XML classes on Classpath. Thus unable to lookup XML descriptor for component type "{0}".
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/SerializedInfoCreator.java
  
  Index: SerializedInfoCreator.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.containerkit.tools.infobuilder;
  
  import org.apache.avalon.framework.info.ComponentInfo;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  
  /**
   * Create {@link org.apache.avalon.framework.info.ComponentInfo} from stream made up of
   * serialized object.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public class SerializedInfoCreator
      implements InfoCreator
  {
      public ComponentInfo createComponentInfo( final String implementationKey,
                                                final InputStream inputStream )
          throws Exception
      {
          final ObjectInputStream ois = new ObjectInputStream( inputStream );
          return (ComponentInfo)ois.readObject();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/XMLInfoCreator.java
  
  Index: XMLInfoCreator.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.containerkit.tools.infobuilder;
  
  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.avalon.framework.info.ComponentDescriptor;
  import org.apache.avalon.framework.info.ComponentInfo;
  import org.apache.avalon.framework.info.ContextDescriptor;
  import org.apache.avalon.framework.info.DependencyDescriptor;
  import org.apache.avalon.framework.info.EntryDescriptor;
  import org.apache.avalon.framework.info.LoggerDescriptor;
  import org.apache.avalon.framework.info.ServiceDescriptor;
  import org.apache.avalon.framework.info.ServiceDesignator;
  import org.xml.sax.InputSource;
  
  /**
   * A ComponentInfoBuilder is responsible for building {@link ComponentInfo}
   * objects from Configuration objects. The format for Configuration object
   * is specified in the <a href="package-summary.html#external">package summary</a>.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public final class XMLInfoCreator
      extends AbstractLogEnabled
      implements InfoCreator
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( XMLInfoCreator.class );
  
      /**
       * Create a {@link ComponentInfo} object for specified
       * classname, loaded from specified {@link InputStream}.
       *
       * @param implementationKey The classname of Component
       * @param inputStream the InputStream to load ComponentInfo from
       * @return the created ComponentInfo
       * @throws ConfigurationException if an error occurs
       */
      public ComponentInfo createComponentInfo( final String implementationKey,
                                                final InputStream inputStream )
          throws Exception
      {
          final InputSource input = new InputSource( inputStream );
          final Configuration configuration = ConfigurationBuilder.build( input );
          return build( implementationKey, configuration );
      }
  
      /**
       * Create a {@link ComponentInfo} object for specified classname from
       * specified configuration data.
       *
       * @param classname The classname of Component
       * @param info the ComponentInfo configuration
       * @return the created ComponentInfo
       * @throws ConfigurationException if an error occurs
       */
      private ComponentInfo 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( "component-info" ) )
          {
              final String message =
                  REZ.getString( "builder.bad-toplevel-element.error",
                                 classname,
                                 topLevelName );
              throw new ConfigurationException( message );
          }
  
          Configuration configuration = null;
  
          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( "component" );
          final ComponentDescriptor descriptor =
              buildComponentDescriptor( classname, configuration );
  
          if( getLogger().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "builder.created-info.notice",
                                 classname,
                                 new Integer( services.length ),
                                 new Integer( dependencies.length ),
                                 new Integer( context.getEntrys().length ),
                                 new Integer( loggers.length ) );
              getLogger().debug( message );
          }
  
          return new ComponentInfo( descriptor, loggers, context, services, dependencies );
      }
  
      /**
       * 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
       */
      private 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
       */
      private 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
       */
      private DependencyDescriptor buildDependency( final String classname,
                                                    final Configuration dependency )
          throws ConfigurationException
      {
          final ServiceDesignator service =
              buildServiceDesignator( dependency.getChild( "service-ref" ) );
          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
       */
      private ContextDescriptor buildContext( final Configuration context )
          throws ConfigurationException
      {
          final EntryDescriptor[] entrys =
              buildEntrys( 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
       */
      private EntryDescriptor[] buildEntrys( 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
       */
      private EntryDescriptor buildEntry( final Configuration config )
          throws ConfigurationException
      {
          final String key = config.getAttribute( "key" );
          final String type = config.getAttribute( "type" );
          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
       */
      private 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 {@link ServiceDesignator}
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ServiceDesignator
       * @throws ConfigurationException if an error occurs
       */
      private ServiceDesignator buildServiceDesignator( final Configuration service )
          throws ConfigurationException
      {
          final String name = service.getAttribute( "type" );
          final String versionString = service.getAttribute( "version", "1.0" );
          final Version version = buildVersion( versionString );
          return new ServiceDesignator( name, version );
      }
  
      /**
       * A utility method to build a {@link ServiceDescriptor}
       * object from specified configuraiton data.
       *
       * @param service the service Configuration
       * @return the created ServiceDescriptor
       * @throws ConfigurationException if an error occurs
       */
      private ServiceDescriptor buildService( final Configuration service )
          throws ConfigurationException
      {
          final Configuration serviceRef = service.getChild( "service-ref" );
          final ServiceDesignator designator = buildServiceDesignator( 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
       */
      private 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
       */
      private 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
       */
      private Version buildVersion( final String version )
      {
          return Version.getVersion( version );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/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/containerkit/src/java/org/apache/excalibur/containerkit/tools/infobuilder/package.html
  
  Index: package.html
  ===================================================================
  <html><body>
  <p>Component information builder that handels internalization of an component type description supplied as a configuration instance.</P>
  
  <h3>Package Structure (UML)</h3>
  <p><img src=doc-files/ComponentInfoBuilder.gif border=0></p>
  
  <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;component-info&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;!-- 
    Declaration of the context constraints for the component 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;service-ref 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;service-ref 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;/component-info&gt;
  
  </pre>
  
  </body></html>
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/xdoclet/AvalonTagHandler.java
  
  Index: AvalonTagHandler.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.containerkit.tools.xdoclet;
  
  import java.util.Properties;
  import xdoclet.XDocletException;
  import xdoclet.tags.AbstractProgramElementTagsHandler;
  import xjavadoc.XClass;
  import xjavadoc.XMethod;
  import xjavadoc.XPackage;
  import xjavadoc.XTag;
  
  /**
   * A simpler tag handler to walk over attributes in a class.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public class AvalonTagHandler
      extends AbstractProgramElementTagsHandler
  {
      private static String c_attribute;
  
      public void setCurrentClassTag( final Properties atributes )
          throws XDocletException
      {
          final String property = atributes.getProperty( "name", "" );
          final XClass currentClass = getCurrentClass();
          final XTag xTag = currentClass.doc().tag( property );
          setCurrentClassTag( xTag );
      }
  
      public void setCurrentMethodTag( final Properties attributes )
          throws XDocletException
      {
          final String attribute = attributes.getProperty( "name", "" );
          final XMethod method = getCurrentMethod();
          if( null == method )
          {
              return;
          }
          final XTag xTag = method.doc().tag( attribute );
          setCurrentMethodTag( xTag );
      }
  
      public void unsetCurrentMethodTag()
          throws XDocletException
      {
          setCurrentMethodTag( (XTag)null );
      }
  
      public void setCurrentAttribute( final Properties atributes )
          throws XDocletException
      {
          final String attribute = atributes.getProperty( "name", "" );
          c_attribute = attribute;
      }
  
      public void unsetCurrentAttribute()
          throws XDocletException
      {
          c_attribute = null;
      }
  
      /**
       * Iterates over the attributes of current tag.
       */
      public void forAllAttributes( final String template,
                                    final Properties attributes )
          throws XDocletException
      {
          final XTag tag = getCurrentTag( attributes );
          final String[] attributeNames = tag.attributeValueNames();
          for( int i = 0; i < attributeNames.length; i++ )
          {
              c_attribute = attributeNames[ i ];
              generate( template );
          }
          c_attribute = null;
      }
  
      public String attributeName()
      {
          return c_attribute;
      }
  
      public String attributeValueAsType( final Properties attributes )
      {
          final String typeName = attributeValue( attributes );
          if( -1 != typeName.indexOf( '.' ) )
          {
              //User has specified full
              return typeName;
          }
          else
          {
              XClass xClass = null;
  
              xClass = findClass( typeName, getCurrentClass().importedClasses() );
              if( null != xClass )
              {
                  return xClass.qualifiedName();
              }
  
              final XClass[] classes = getCurrentClass().containingPackage().classes();
              xClass = findClass( typeName, classes );
              if( null != xClass )
              {
                  return xClass.qualifiedName();
              }
  
              final XPackage[] xPackages = getCurrentClass().importedPackages();
              for( int i = 0; i < xPackages.length; i++ )
              {
                  xClass = findClass( typeName, xPackages[ i ].classes() );
                  if( null != xClass )
                  {
                      return xClass.qualifiedName();
                  }
              }
  
              xClass = findClass( typeName, getDefaultPackage().classes() );
              if( null != xClass )
              {
                  return xClass.qualifiedName();
              }
  
              return typeName;
          }
      }
  
      private XPackage getDefaultPackage()
      {
          XClass xClass = getCurrentClass().superclass();
          XClass newXClass = xClass;
          while( null != newXClass &&
              !newXClass.qualifiedName().equals( "java.lang.Object" ) )
          {
              xClass = newXClass;
              newXClass = getCurrentClass().superclass();
          }
          return xClass.containingPackage();
      }
  
      private XClass findClass( final String name,
                                final XClass[] classes )
      {
          XClass xClass = null;
          for( int i = 0; i < classes.length; i++ )
          {
              final XClass singleImport = classes[ i ];
              final String classname = singleImport.name();
              if( classname.equals( name ) )
              {
                  xClass = singleImport;
                  break;
              }
          }
          return xClass;
      }
  
      public String attributeValue( final Properties attributes )
      {
          final XTag tag = getCurrentTag( attributes );
          if( null == c_attribute )
          {
              return "";
          }
          else
          {
              return tag.attributeValue( c_attribute );
          }
      }
  
      public void ifAttributeNameNotEquals( final String template,
                                            final Properties attributes )
          throws XDocletException
      {
          final String value = attributes.getProperty( "value", "" );
          if( !value.equals( c_attribute ) )
          {
              generate( template );
          }
      }
  
      private XTag getCurrentTag( final Properties attributes )
      {
          final String isMethodProp = attributes.getProperty( "isMethod", null );
          if( null == isMethodProp )
          {
              final XTag tag = getCurrentMethodTag();
              if( null != tag )
              {
                  return tag;
              }
              else
              {
                  return getCurrentClassTag();
              }
          }
          else if( isMethodProp.equalsIgnoreCase( "false" ) )
          {
              return getCurrentClassTag();
          }
          else
          {
              return getCurrentMethodTag();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/xdoclet/AvalonXDoclet.java
  
  Index: AvalonXDoclet.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.containerkit.tools.xdoclet;
  
  import xdoclet.DocletTask;
  import java.util.List;
  
  /**
   * A simple XDoclet task that generates the .xinfo files for
   * services.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public class AvalonXDoclet
      extends DocletTask
  {
      private ComponentInfoSubTask m_componentInfoSubTask;
  
      public ComponentInfoSubTask createComponentInfo()
      {
          m_componentInfoSubTask = new ComponentInfoSubTask();
          return m_componentInfoSubTask;
      }
  
      protected List getSubTasks()
      {
          final List subtasks = super.getSubTasks();
          subtasks.add( m_componentInfoSubTask );
          return subtasks;
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/xdoclet/ComponentInfoSubTask.java
  
  Index: ComponentInfoSubTask.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.containerkit.tools.xdoclet;
  
  import xdoclet.TemplateSubTask;
  import xdoclet.XDocletException;
  import xdoclet.template.TemplateException;
  import java.net.URL;
  import java.io.File;
  import xjavadoc.XClass;
  
  /**
   * Generates ComponentInfo 'xinfo' files for Components.
   *
   * @author <a href="mailto:vinay_chandran@users.sourceforge.net">Vinay Chandrasekharan</a>
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/18 06:39:00 $
   */
  public class ComponentInfoSubTask
      extends TemplateSubTask
  {
      public static final String SUBTASK_NAME = "componentinfo";
  
      private static final String GENERATED_FILE_NAME = "{0}-info.xml";
      private static final String DEFAULT_TEMPLATE_FILE =
          "/org/apache/excalibur/containerkit/xdoclet/componentinfo.xdt";
  
      private static String c_classPattern;
  
      private String m_templatePath;
  
      public ComponentInfoSubTask()
      {
          final URL resource = getClass().getResource( DEFAULT_TEMPLATE_FILE );
          setTemplateURL( resource );
          setDestinationFile( GENERATED_FILE_NAME );
          setHavingClassTag( "avalon.component" );
  
          final TemplateSubTask.ExtentTypes extent = new TemplateSubTask.ExtentTypes();
          extent.setValue( "hierarchy" );
          setExtent( extent );
      }
  
      /**
       * Initialises the subtask.  Add a tag handler for avalon type tags.
       */
      public void init() throws XDocletException
      {
          super.init();
          try
          {
              final AvalonTagHandler tagHandler = new AvalonTagHandler();
              getEngine().setTagHandlerFor( "Avalon", tagHandler );
          }
          catch( final TemplateException e )
          {
              throw new XDocletException( e, e.getMessage() );
          }
      }
  
      public void setTemplatePath( final String templatePath )
      {
          m_templatePath = templatePath;
          setTemplateFile( new File( templatePath ) );
      }
  
      public static String getClassPattern()
      {
          return c_classPattern;
      }
  
      public String getSubTaskName()
      {
          return SUBTASK_NAME;
      }
  
      public void setPattern( final String classPattern )
      {
          c_classPattern = classPattern;
      }
  
      /**
       * Called to validate configuration parameters.
       */
      public void validateOptions()
          throws XDocletException
      {
          super.validateOptions();
  
          if( null == m_templatePath )
          {
              throw new XDocletException( "'templatePath' attribute is missing ." );
          }
  
          final URL template = getTemplateURL();
          if( null == template )
          {
              throw new XDocletException( "'template' is missing." );
          }
  
          if( null == getClassPattern() || getClassPattern().trim().equals( "" ) )
          {
              throw new XDocletException( "'pattern' parameter missing or empty." );
          }
  
          if( -1 == getClassPattern().indexOf( "{0}" ) )
          {
              throw new XDocletException( "'pattern' parameter does not have a " +
                                          "'{0}' in it. '{0}' is replaced by Component " +
                                          "name of the class under processing." );
          }
      }
  
      protected boolean matchesGenerationRules( final XClass clazz )
          throws XDocletException
      {
          if( !super.matchesGenerationRules( clazz ) )
          {
              return false;
          }
          else if( clazz.isAbstract() )
          {
              return false;
          }
          else
          {
              return true;
          }
      }
  }
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/tools/xdoclet/componentinfo.xdt
  
  Index: componentinfo.xdt
  ===================================================================
  <?xml version="1.0" encoding="utf-8" ?>
  
  <!DOCTYPE component-info
        PUBLIC "-//AVALON/Component Info DTD Version 1.0//EN"
        "http://jakarta.apache.org/avalon/componentinfo_1.0.dtd" >
  
  <!-- Autogenerated by XDoclet. Do not Edit! -->
  <component-info>
    <!-- section to describe Component -->
    <component>
      <XDtClass:ifHasClassTag tagName="avalon.component" paramName="name"><name><XDtClass:classTagValue tagName="avalon.component" paramName="name"/></name></XDtClass:ifHasClassTag>
      <version><XDtClass:classTagValue tagName="avalon.component" paramName="version" default="1.0"/></version>
      <XDtAvalon:setCurrentClassTag name="avalon.component"/>
      <attributes>
        <XDtAvalon:forAllAttributes isMethod="false">
          <XDtAvalon:ifAttributeNameNotEquals value="name">
            <XDtAvalon:ifAttributeNameNotEquals value="version">
        <attribute key="<XDtAvalon:attributeName/>" value="<XDtAvalon:attributeValue/>"/>
            </XDtAvalon:ifAttributeNameNotEquals>
          </XDtAvalon:ifAttributeNameNotEquals>
        </XDtAvalon:forAllAttributes>
      </attributes>
    </component>
  
    <!-- Context in which this Component operates -->
    <XDtMethod:ifHasMethod name="contextualize"
                           parameters="org.apache.avalon.framework.context.Context">
      <XDtMethod:setCurrentMethod name="contextualize"
                                  parameters="org.apache.avalon.framework.context.Context">
    <context<XDtMethod:ifHasMethodTag tagName="avalon.context" paramName="type"><XDtAvalon:setCurrentMethodTag name="avalon.context"/><XDtAvalon:setCurrentAttribute name="type"/> type="<XDtAvalon:attributeValueAsType/>"<XDtAvalon:unsetCurrentAttribute/><XDtAvalon:unsetCurrentMethodTag/></XDtMethod:ifHasMethodTag>>
        <XDtMethod:forAllMethodTags tagName="avalon.entry">
      <entry key="<XDtMethod:methodTagValue tagName="avalon.entry" paramName="key"/>" <XDtAvalon:setCurrentAttribute name="type"/>type="<XDtAvalon:attributeValueAsType/>"<XDtMethod:ifHasMethodTag tagName="avalon.entry" paramName="isOptional"> optional="<XDtMethod:methodTagValue tagName="avalon.entry" paramName="isOptional"/>"</XDtMethod:ifHasMethodTag>/>
        </XDtMethod:forAllMethodTags>
      <XDtMethod:ifHasMethodTag tagName="avalon.context">
        <XDtAvalon:setCurrentMethodTag name="avalon.context"/>
      <attributes>
          <XDtAvalon:forAllAttributes isMethod="true">
            <XDtAvalon:ifAttributeNameNotEquals value="type">
          <attribute key="<XDtAvalon:attributeName/>" value="<XDtAvalon:attributeValue/>"/>
            </XDtAvalon:ifAttributeNameNotEquals>
          </XDtAvalon:forAllAttributes>
      </attributes>
        <XDtAvalon:unsetCurrentMethodTag/>
      </XDtMethod:ifHasMethodTag>
    </context>
      </XDtMethod:setCurrentMethod>
    </XDtMethod:ifHasMethod>
  
    <!-- services that are offered by this Component -->
    <services>
      <XDtClass:forAllClassTags tagName="avalon.service">
      <service>
        <XDtAvalon:setCurrentAttribute name="interface"/>
        <service-ref type="<XDtAvalon:attributeValueAsType/>"<XDtClass:ifHasClassTag tagName="avalon.service" paramName="version"> version="<XDtClass:classTagValue tagName="avalon.service" paramName="version"/>"</XDtClass:ifHasClassTag>/>
        <XDtAvalon:unsetCurrentAttribute/>
        <attributes>
        <XDtAvalon:forAllAttributes isMethod="false">
          <XDtAvalon:ifAttributeNameNotEquals value="interface">
            <XDtAvalon:ifAttributeNameNotEquals value="version">
          <attribute key="<XDtAvalon:attributeName/>" value="<XDtAvalon:attributeValue/>"/>
            </XDtAvalon:ifAttributeNameNotEquals>
          </XDtAvalon:ifAttributeNameNotEquals>
        </XDtAvalon:forAllAttributes>
        </attributes>
      </service>
      </XDtClass:forAllClassTags>
    </services>
  
    <!-- services that are required by this Component -->
    <dependencies>
      <XDtMethod:ifHasMethod name="compose"
                             parameters="org.apache.avalon.framework.component.ComponentManager">
        <XDtMethod:setCurrentMethod name="compose"
                                    parameters="org.apache.avalon.framework.component.ComponentManager">
          <XDtMethod:forAllMethodTags tagName="avalon.dependency">
      <dependency<XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="optional"> optional="<XDtMethod:methodTagValue tagName="avalon.dependency" paramName="optional"/>"</XDtMethod:ifHasMethodTag>>
        <XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="role"><role><XDtMethod:methodTagValue tagName="avalon.dependency" paramName="role"/></role></XDtMethod:ifHasMethodTag>
        <XDtAvalon:setCurrentAttribute name="interface"/>
        <service-ref type="<XDtAvalon:attributeValueAsType/>"<XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="version"> version="<XDtMethod:methodTagValue tagName="avalon.dependency" paramName="version"/>"</XDtMethod:ifHasMethodTag>/>
        <XDtAvalon:unsetCurrentAttribute/>
        <attributes>
        <XDtAvalon:forAllAttributes isMethod="true">
          <XDtAvalon:ifAttributeNameNotEquals value="interface">
            <XDtAvalon:ifAttributeNameNotEquals value="version">
              <XDtAvalon:ifAttributeNameNotEquals value="role">
                <XDtAvalon:ifAttributeNameNotEquals value="optional">
          <attribute key="<XDtAvalon:attributeName/>" value="<XDtAvalon:attributeValue/>"/>
                </XDtAvalon:ifAttributeNameNotEquals>
              </XDtAvalon:ifAttributeNameNotEquals>
            </XDtAvalon:ifAttributeNameNotEquals>
          </XDtAvalon:ifAttributeNameNotEquals>
        </XDtAvalon:forAllAttributes>
        </attributes>
      </dependency>
          </XDtMethod:forAllMethodTags>
        </XDtMethod:setCurrentMethod>
      </XDtMethod:ifHasMethod>
      <XDtMethod:ifHasMethod name="service"
                             parameters="org.apache.avalon.framework.service.ServiceManager">
        <XDtMethod:setCurrentMethod name="service"
                                    parameters="org.apache.avalon.framework.service.ServiceManager">
          <XDtMethod:forAllMethodTags tagName="avalon.dependency">
      <dependency<XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="optional"> optional="<XDtMethod:methodTagValue tagName="avalon.dependency" paramName="optional"/>"</XDtMethod:ifHasMethodTag>>
        <XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="role"><role><XDtMethod:methodTagValue tagName="avalon.dependency" paramName="role"/></role></XDtMethod:ifHasMethodTag>
        <XDtAvalon:setCurrentAttribute name="interface"/>
        <service-ref type="<XDtAvalon:attributeValueAsType/>"<XDtMethod:ifHasMethodTag tagName="avalon.dependency" paramName="version"> version="<XDtMethod:methodTagValue tagName="avalon.dependency" paramName="version"/>"</XDtMethod:ifHasMethodTag>/>
        <XDtAvalon:unsetCurrentAttribute/>
        <attributes>
        <XDtAvalon:forAllAttributes isMethod="true">
          <XDtAvalon:ifAttributeNameNotEquals value="interface">
            <XDtAvalon:ifAttributeNameNotEquals value="version">
              <XDtAvalon:ifAttributeNameNotEquals value="role">
                <XDtAvalon:ifAttributeNameNotEquals value="optional">
          <attribute key="<XDtAvalon:attributeName/>" value="<XDtAvalon:attributeValue/>"/>
                </XDtAvalon:ifAttributeNameNotEquals>
              </XDtAvalon:ifAttributeNameNotEquals>
            </XDtAvalon:ifAttributeNameNotEquals>
          </XDtAvalon:ifAttributeNameNotEquals>
        </XDtAvalon:forAllAttributes>
        </attributes>
      </dependency>
          </XDtMethod:forAllMethodTags>
        </XDtMethod:setCurrentMethod>
      </XDtMethod:ifHasMethod>
    </dependencies>
  
  </component-info>
  
  
  

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