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/09/01 07:54:59 UTC

cvs commit: jakarta-avalon-excalibur/loader/src/xdocs/stylesheets project.xml

donaldp     2002/08/31 22:54:59

  Added:       loader   .cvsignore ant.properties.sample build.xml
                        default.properties
               loader/src/java/org/apache/excalibur/loader/builder
                        ClassLoaderSetBuilder.java classloader.dtd
               loader/src/java/org/apache/excalibur/loader/metadata
                        ClassLoaderDef.java ClassLoaderSetDef.java
                        EntryDef.java FileSetDef.java JoinDef.java
               loader/src/java/org/apache/excalibur/loader/verifier
                        ClassLoaderVerifier.java Resources.properties
               loader/src/xdocs index.xml menu.xml
               loader/src/xdocs/stylesheets project.xml
  Log:
  First drop of code for ClassLoader management.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/loader/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  ant.properties
  build
  checkstyle.cache
  distributions
  dist
  excalibur-*
  *.el
  *.ipr
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/ant.properties.sample
  
  Index: ant.properties.sample
  ===================================================================
  # -----------------------------------------------------------------------------
  # Component ant.properties.sample
  #
  # This is an example "ant.properties" file, used to customize the building of
  # the component for your local environment.  It defines the location of all
  # external modules that this component depend on.  Copy this file to
  # "ant.properties" in the source directory, and customize it as needed.
  #
  # The ant.properties values in this directory apply only to this component.
  # It is overridden by ../ant.properties and ~/build.properties
  # It overrides all default.properties files and ~/.ant.properties
  #
  # $Id: ant.properties.sample,v 1.1 2002/09/01 05:54:59 donaldp Exp $
  # -----------------------------------------------------------------------------
  
  # ----- Compile Control Flags -----
  build.debug=on
  build.optimize=off
  build.deprecation=off
  #build.compiler=jikes
  
  # ----- Base Directory in which all the packages are stored -----
  base.path=${basedir}/../..
  
  # --------------------------------------------------
  #                REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  
  # --------------------------------------------------
  #                OPTIONAL LIBRARIES
  # --------------------------------------------------
  
  # ----- JUnit Unit Test Suite, version 3.7 or later. -----
  #  Not needed if junit.jar is in $ANT_HOME/lib 
  junit.home=${base.path}/junit3.7
  junit.lib=${junit.home}
  junit.jar=${junit.lib}/junit.jar
  
  
  # ----- Checkstyle, version 2.1 or later -----
  # Uncomment the 'do.checkstyle' flag property to enable checkstyle
  # do.checkstyle=
  checkstyle.home=${base.path}/checkstyle-2.1
  checkstyle.lib=${checkstyle.home}
  checkstyle.jar=${checkstyle.lib}/checkstyle-all-2.1.jar
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <project name="Excalibur Loader" default="main" basedir=".">
  
      <property file="${user.home}/build.properties"/>
      <property file="${basedir}/../ant.properties"/>
      <property file="${basedir}/ant.properties"/>
      <property file="${user.home}/.ant.properties"/>
      <property file="${basedir}/../default.properties"/>
      <property file="${basedir}/default.properties"/>
  
      <!-- Classpath for product -->
      <path id="project.class.path">
          <pathelement location="${build.classes}"/>
          <pathelement location="${avalon-framework.jar}"/>
          <pathelement location="${excalibur-i18n.jar}"/>
          <pathelement location="${excalibur-extension.jar}"/>
          <pathelement location="${checkstyle.jar}"/>
          <pathelement location="${xml-apis.jar}"/>
          <pathelement path="${java.class.path}"/>
      </path>
  
      <path id="tools.class.path">
          <pathelement location="${junit.jar}"/>
          <fileset dir="${jakarta-site.dir}/lib"/>
      </path>
  
      <path id="test.class.path">
          <pathelement location="${build.testclasses}"/>
          <pathelement location="${junit.jar}"/>
          <path refid="project.class.path"/>
      </path>
      <property name="cp" refid="test.class.path"/>
  
      <target name="main" depends="jar" description="Build the project"/>
      <target name="rebuild" depends="clean,main" description="Rebuild the project"/>
  
      <target name="dependencies" description="Check dependencies" unless="skip.dependencies">
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkCommon"/>
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkFramework"/>
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkI18N"/>
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkExtension"/>
      </target>
  
      <target name="dependencies-test" depends="dist-jar, dependencies"
          description="Check unit test dependencies" unless="skip.dependencies">
          <!-- Need the jar to prevent recursive deps. -->
  
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkJUnit"/>
      </target>
  
  
      <!-- Compiles the source code -->
      <target name="compile" depends="dependencies" description="Compiles the source code">
  
          <mkdir dir="${build.classes}"/>
  
          <!-- Compile all classes excluding the tests. -->
          <javac srcdir="${java.dir}"
              destdir="${build.classes}"
              debug="${build.debug}"
              optimize="${build.optimize}"
              deprecation="${build.deprecation}"
              target="1.2">
              <classpath refid="project.class.path" />
              <include name="**/*.java"/>
          </javac>
  
          <!-- copy resources to same location as .class files -->
          <copy todir="${build.classes}">
              <fileset dir="${java.dir}">
                  <exclude name="**/*.java"/>
                  <exclude name="**/package.html"/>
              </fileset>
          </copy>
  
      </target>
  
      <!-- Compiles the unit test source code -->
      <target name="compile-test" depends="compile, dependencies-test" description="Compiles the source code">
          <mkdir dir="${build.testsrc}"/>
  
          <!-- Copy over all of the tests applying test filters -->
          <copy todir="${build.testsrc}">
              <fileset dir="${test.dir}"/>
          </copy>
  
          <mkdir dir="${build.testclasses}"/>
  
          <!-- Compile all test classes. -->
          <javac srcdir="${build.testsrc}"
              destdir="${build.testclasses}"
              debug="${build.debug}"
              optimize="${build.optimize}"
              deprecation="${build.deprecation}"
              target="1.2">
              <classpath refid="test.class.path" />
              <include name="**/*.java"/>
          </javac>
  
          <copy todir="${build.testclasses}">
              <fileset dir="${test.dir}">
                  <exclude name="**/*.java"/>
                  <exclude name="**/package.html"/>
              </fileset>
          </copy>
  
      </target>
  
      <!-- Copies and filters the license. Used by jar and dist -->
      <target name="prepare-conf">
          <mkdir dir="${build.conf}"/>
          <copy todir="${build.conf}" flatten="true">
              <fileset dir="../" includes="LICENSE.txt"/>
              <filterset>
                  <filter token="year" value="${year}"/>
              </filterset>
          </copy>
      </target>
  
      <!-- Creates all the .jar file -->
      <target name="jar" depends="compile, prepare-conf" description="Generates the jar files">
  
          <mkdir dir="${build.lib}"/>
  
          <jar jarfile="${build.lib}/${jar.name}"
              basedir="${build.classes}"
              compress="${build.compress}">
              <manifest>
                  <attribute name="Extension-Name" value="${name}"/>
                  <attribute name="Specification-Vendor" value="Apache Software Foundation"/>
                  <attribute name="Specification-Version" value="1.0"/>
                  <attribute name="Implementation-Vendor" value="Apache Software Foundation"/>
                  <attribute name="Implementation-Version" value="${package-version}"/>
              </manifest>
              <exclude name="**/test/**"/>
              <zipfileset dir="${build.conf}" prefix="META-INF/">
                  <include name="LICENSE.txt"/>
              </zipfileset>
          </jar>
      </target>
  
      <!-- Creates all the Javadocs -->
      <target name="javadocs" depends="compile" description="Generates the javadocs" unless="skip.javadocs">
  
          <mkdir dir="${dist.javadocs}"/>
          <javadoc packagenames="org.apache.*"
              sourcepath="${java.dir}"
              destdir="${dist.javadocs}">
              <classpath refid="project.class.path" />
              <group title="${Name} API" packages="org.apache.excalibur.*" />
              <doclet name="com.sun.tools.doclets.standard.Standard">
                  <param name="-author"/>
                  <param name="-version"/>
                  <param name="-doctitle" value="${Name}"/>
                  <param name="-windowtitle" value="${Name} API"/>
                  <param name="-link" value="http://java.sun.com/j2se/1.4/docs/api/"/>
                  <param name="-link" value="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/>
                  <param name="-link" value="http://jakarta.apache.org/avalon/api/"/>
                  <param name="-bottom"
                      value="&quot;Copyright &#169; ${year} Apache Jakarta Project. All Rights Reserved.&quot;"/>
              </doclet>
  
          </javadoc>
      </target>
  
      <target name="test" depends="compile-test" description="Perform the unit tests" unless="skip.tests">
  
          <echo message="Performing Unit Tests" />
  
          <mkdir dir="${build.tests}"/>
  
          <junit fork="true"
              haltonfailure="${junit.failonerror}"
              printsummary="yes"
              dir="${build.tests}">
              <classpath refid="test.class.path"/>
  
              <formatter type="xml"/>    <!-- xml reports for junitreport -->
              <formatter type="plain" usefile="false"/>  <!-- text reports for humans     -->
  
              <batchtest todir="${build.tests}">
                  <fileset dir="${build.testclasses}">
                      <include name="**/test/*TestCase.class"/>
                      <exclude name="**/Abstract*"/>
                  </fileset>
              </batchtest>
          </junit>
  
      </target>
  
      <target name="test-reports" depends="test" description="Generate Reports for the unit tests">
  
          <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkBSF"/>
  
          <mkdir dir="${build.reports}/junit"/>
  
          <junitreport todir="${build.reports}/junit">
              <fileset dir="${build.tests}">
                  <include name="TEST-*.xml"/>
              </fileset>
              <report format="frames" todir="${build.reports}/junit"/>
          </junitreport>
  
          <!-- Clean up the xml reports used by the junitreport task -->
          <!--
          <delete>
              <fileset dir="${build.tests}" includes="TEST-*.xml"/>
              <fileset dir="${build.tests}" includes="TESTS-*.xml"/>
          </delete>
          -->
  
      </target>
  
      <target name="checkstyle" if="do.checkstyle" description="Checkstyle">
  
          <!-- this invocation of checkstyle requires that checkstyle be downloaded and setup -->
          <!-- thats why you are required to define do.checkstyle property to generate the report -->
          <taskdef name="checkstyle"
              classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
              <classpath refid="project.class.path"/>
          </taskdef>
          <checkstyle
              lcurlyType="nl"
              lcurlyMethod="nl"
              lcurlyOther="nl"
              rcurly="ignore"
              allowProtected="false"
              allowPackage="false"
              allowNoAuthor="false"
              maxLineLen="100"
              maxMethodLen="100"
              maxConstructorLen="100"
              memberPattern="^m_[a-z][a-zA-Z0-9]*$"
              staticPattern="^c_[a-z][a-zA-Z0-9]*$"
              constPattern="(^c_[a-z][a-zA-Z0-9]*$)|([A-Z_]*$)"
              ignoreImportLen="true"
              allowTabs="false"
              javadocScope="protected"
              ignoreWhitespace="true"
              cacheFile="checkstyle.cache"
              failOnViolation="false"
              ignoreCastWhitespace="true">
              <fileset dir="${java.dir}">
                  <include name="**/*.java"/>
              </fileset>
              <formatter type="plain"/>
              <formatter type="xml" toFile="${build.dir}/checkstyle-results.xml"/>
          </checkstyle>
      </target>
  
      <target name="checkstyle-report"
          depends="checkstyle"
          if="do.checkstyle"
          description="Generate Checkstyle Report">
  
          <mkdir dir="${build.reports}/checkstyle"/>
          <property name="checkstyle.pathhack" location="."/>
          <style style="${tools.dir}/etc/checkstyle-frames.xsl" in="${build.dir}/checkstyle-results.xml"
              out="${build.reports}/checkstyle/delete-me.html">
              <param name="pathhack" expression="${checkstyle.pathhack}"/>
          </style>
  
      </target>
  
      <target name="xdoclet" depends="main" description="Generates the XML descriptors">
          <taskdef name="avalon-xinfo"
              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.tools.ant.SerializeInfoTask">
              <classpath>
                  <path refid="project.class.path"/>
                  <pathelement location="${build.classes}"/>
              </classpath>
          </taskdef>
  
          <mkdir dir="gen"/>
          <avalon-xinfo force="true" destdir="gen" >
              <fileset dir="${java.dir}">
                  <include name="**/demo/components/*.java" />
              </fileset>
              <componentinfo/>
          </avalon-xinfo>
  
          <serialize-info destDir="gen">
              <fileset dir="gen">
                  <include name="**/*.xinfo" />
              </fileset>
          </serialize-info>
      </target>
  
      <!-- Creates the distribution -->
      <target name="dist"
          depends="dist-jar, test-reports, checkstyle-report, docs, javadocs"
          description="Generates a distribution (jar + docs + javadocs + unit tests + checkstyle reports)">
  
          <copy file="${build.conf}/LICENSE.txt" todir="${dist.dir}"/>
          <copy file="../KEYS" todir="${dist.dir}"/>
          <copy file="README.txt" todir="${dist.dir}"/>
  
          <zip zipfile="${dist.dir}/src.zip" compress="false">
              <zipfileset dir="src/java"/>
          </zip>
  
          <mkdir dir="${dist.base}"/>
  
          <zip zipfile="${dist.base}/${dist.name}.zip" compress="true">
              <zipfileset dir="${dist.dir}" prefix="${dist.name}"/>
              <zipfileset dir="${docs.dir}" prefix="${dist.name}/docs"/>
          </zip>
      </target>
  
      <!-- Creates a mini jar-only distribution -->
      <target name="dist-jar" depends="jar">
          <mkdir dir="${dist.dir}"/>
          <copy todir="${dist.dir}">
              <fileset dir="${build.lib}">
                  <include name="*.jar"/>
              </fileset>
          </copy>
      </target>
  
      <!-- Creates a minimal distribution -->
      <target name="dist.lite"
          depends="dist-jar, test, javadocs"
          description="Generates a minimal distribution (jar + javadocs)">
  
          <copy file="../LICENSE.txt" todir="${dist.dir}"/>
          <copy file="../KEYS" todir="${dist.dir}"/>
          <copy file="README.txt" todir="${dist.dir}"/>
  
      </target>
  
      <target name="anakia-avail">
          <available classname="org.apache.velocity.anakia.AnakiaTask"
              property="AnakiaTask.present">
              <classpath refid="tools.class.path"/>
          </available>
      </target>
  
      <target name="anakia-check" depends="anakia-avail" unless="AnakiaTask.present">
          <echo>
              AnakiaTask is not present! Please check to make sure that
              velocity.jar is in your classpath. The easiest way to build
              the documentation is to checkout jakarta-site CVS and specify
              jakarta-site.dir property.
          </echo>
      </target>
  
      <target name="docs" depends="anakia-check" description="Generate documentation and website">
          <taskdef name="anakia"
              classname="org.apache.velocity.anakia.AnakiaTask">
              <classpath refid="tools.class.path"/>
          </taskdef>
  
          <anakia basedir="${xdocs.dir}"
              destdir="${docs.dir}"
              style="docs.vsl"
              projectfile="menu.xml"
              includes="**/*.xml"
              excludes="menu.xml"
              velocitypropertiesfile="../site/src/stylesheets/velocity.properties"
              />
  
       <copy todir="${docs.dir}" filtering="off">
        <fileset dir="../site/src" includes="css/*.css" />
        <fileset dir="${xdocs.dir}">
          <include name="**/images/**"/>
          <include name="**/*.gif"/>
          <include name="**/*.jpg"/>
          <include name="**/*.png"/>
          <include name="**/*.css"/>
          <include name="**/*.js"/>
        </fileset>
      </copy>
      </target>
  
      <target name="site" depends="javadocs, docs" description=" Places Docs ready for hosting on website">
  
          <mkdir dir="../site/dist/docs/${dir-name}"/>
          <copy todir="../site/dist/docs/${dir-name}">
              <fileset dir="${docs.dir}">
                  <include name="**"/>
              </fileset>
          </copy>
  
      </target>
  
      <!-- Cleans up build and distribution directories -->
      <target name="clean" description="Cleans up the project">
          <delete file="checkstyle.cache"/>
          <delete dir="${build.dir}" />
          <delete dir="${dist.dir}" />
          <delete dir="${docs.dir}" />
          <delete dir="test" /> <!-- unit testing output directory -->
          <delete>
              <fileset dir="." includes="velocity.*"/>
              <fileset dir="." includes="**/*~" defaultexcludes="no"/>
          </delete>
      </target>
  
      <target name="real-clean" depends="clean" description="Cleans up the project, including distributions">
          <delete dir="${dist.base}" />
      </target>
  
  </project>
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/default.properties
  
  Index: default.properties
  ===================================================================
  # -------------------------------------------------------------------
  # B U I L D  P R O P E R T I E S
  # -------------------------------------------------------------------
  # Specifies default property values
  # Overridden by ../default.properties and all ant.properties
  # Not user-editable; use ant.properties files instead
  
  name=excalibur-loader
  Name=Excalibur Loader
  dir-name=info
  version=1.0a
  package-version=0.99
  year=2002
  
  # --------------------------------------------------
  #                REQUIRED LIBRARIES
  # --------------------------------------------------
  
  # ----- Avalon Framework, version 4.1 or later -----
  avalon-framework.home=${basedir}/../../jakarta-avalon
  avalon-framework.lib=${avalon-framework.home}/build/lib
  avalon-framework.jar=${avalon-framework.lib}/avalon-framework.jar
  
  # ----- Excalibur i18n, version 1.0 or later -----
  excalibur-i18n.home=${basedir}/../i18n/dist
  excalibur-i18n.lib=${excalibur-i18n.home}
  excalibur-i18n.jar=${excalibur-i18n.lib}/excalibur-i18n-1.0.jar
  
  # ----- Excalibur Extension, version 1.0 or later -----
  excalibur-extension.home=${basedir}/../extension/dist
  excalibur-extension.lib=${excalibur-extension.home}
  excalibur-extension.jar=${excalibur-extension.lib}/excalibur-extension-1.0a.jar
  
  # --------------------------------------------------
  
  #  Settings used to configure compile environment
  build.debug = on
  build.optimize = off
  build.deprecation = off
  build.compress = false
  junit.failonerror = false
  
  #  location of intermediate products
  build.dir = build
  build.testsrc = ${build.dir}/testsrc
  build.testclasses = ${build.dir}/testclasses
  build.lib = ${build.dir}/lib
  build.conf = ${build.dir}/conf
  build.classes = ${build.dir}/classes
  build.tests = ${build.dir}/tests
  build.reports = ${build.dir}/reports
  
  #  Set the properties for source directories
  src.dir = src
  java.dir = ${src.dir}/java
  conf.dir = ${src.dir}/conf
  test.dir = ${src.dir}/test
  
  #  needed by Cocoon
  build.context = ${build.dir}/documentation
  build.docs = ${build.dir}/docs
  build.xdocs = ${build.dir}/xdocs
  context.dir = ../../jakarta-avalon/src/documentation
  tools.dir = ../../jakarta-avalon/tools
  tools.jar = ${java.home}/../lib/tools.jar
  docs.dir = docs
  xdocs.dir = src/xdocs
  
  #  Set the properties for distribution directories
  dist.dir = dist
  dist.javadocs = ${docs.dir}/api
  
  #  name of .zip/.tar.gz/.bz2 files and their top-level directory
  dist.name = ${name}-${version}
  
  #  name of jar file
  jar.name = ${name}-${version}.jar
  
  #  property indicating directory where all distribution archives are placed
  dist.base = distributions
  
  depchecker.prefix=.
  
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/ClassLoaderSetBuilder.java
  
  Index: ClassLoaderSetBuilder.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.loader.builder;
  
  import java.util.ArrayList;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.excalibur.loader.metadata.ClassLoaderDef;
  import org.apache.excalibur.loader.metadata.ClassLoaderSetDef;
  import org.apache.excalibur.loader.metadata.EntryDef;
  import org.apache.excalibur.loader.metadata.FileSetDef;
  import org.apache.excalibur.loader.metadata.JoinDef;
  
  /**
   * This class builds a {@link ClassLoaderSetDef} object from
   * specified configuration.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class ClassLoaderSetBuilder
  {
      public ClassLoaderSetDef build( final Configuration config,
                                      final String[] predefined )
          throws ConfigurationException
      {
          final String defaultClassLoader =
              config.getAttribute( "default" );
  
          final String version =
              config.getAttribute( "version" );
          if( !"1.0".equals( version ) )
          {
              final String message = "Bad version:" + version;
              throw new ConfigurationException( message );
          }
  
          final Configuration[] joinConfigs =
              config.getChildren( "join" );
          final JoinDef[] joins = buildJoins( joinConfigs );
  
          final Configuration[] clConfigs =
              config.getChildren( "classloader" );
  
          final ClassLoaderDef[] classloaders =
              buildClassLoaders( clConfigs );
  
          return new ClassLoaderSetDef( defaultClassLoader,
                                        predefined,
                                        classloaders,
                                        joins );
      }
  
      private ClassLoaderDef[] buildClassLoaders( Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList loaders = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final ClassLoaderDef loader = buildLoader( configs[ i ] );
              loaders.add( loader );
          }
  
          return (ClassLoaderDef[])loaders.toArray( new ClassLoaderDef[ loaders.size() ] );
      }
  
      private ClassLoaderDef buildLoader( final Configuration config )
          throws ConfigurationException
      {
          final String name = config.getAttribute( "name" );
          final String parent = config.getAttribute( "parent" );
  
          final EntryDef[] entrys =
              buildEntrys( config.getChildren( "entry" ) );
          final Extension[] extensions =
              buildExtensions( config.getChildren( "extension" ) );
          final FileSetDef[] fileSets =
              buildFileSets( config.getChildren( "fileset" ) );
          return new ClassLoaderDef( name, parent, entrys,
                                     extensions, fileSets );
      }
  
      private Extension[] buildExtensions( final Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList extensions = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final Extension extension =
                  buildExtension( configs[ i ] );
              extensions.add( extension );
          }
  
          return (Extension[])extensions.toArray( new Extension[ extensions.size() ] );
      }
  
      private Extension buildExtension( final Configuration config )
          throws ConfigurationException
      {
          final String name =
              config.getChild( "name" ).getValue();
          final String specVersion =
              config.getChild( "specification-version" ).getValue( null );
          final String specVendor =
              config.getChild( "specification-vendor" ).getValue( null );
          final String implVersion =
              config.getChild( "implementation-version" ).getValue( null );
          final String implVendor =
              config.getChild( "implementation-vendor" ).getValue( null );
          final String implVendorID =
              config.getChild( "implementation-vendor-id" ).getValue( null );
          final String implURL =
              config.getChild( "implementation-url" ).getValue( null );
  
          return new Extension( name, specVersion, specVendor,
                                implVersion, implVendor, implVendorID,
                                implURL );
      }
  
      private FileSetDef[] buildFileSets( final Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList fileSets = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final FileSetDef fileSet =
                  buildFileSet( configs[ i ] );
              fileSets.add( fileSet );
          }
  
          return (FileSetDef[])fileSets.toArray( new FileSetDef[ fileSets.size() ] );
      }
  
      private FileSetDef buildFileSet( Configuration config )
          throws ConfigurationException
      {
          final String dir = config.getAttribute( "dir" );
          final String[] includes =
              buildSelectors( config.getChildren( "include" ) );
          final String[] excludes =
              buildSelectors( config.getChildren( "exclude" ) );
          return new FileSetDef( dir, includes, excludes );
      }
  
      private String[] buildSelectors( Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList selectors = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final String name =
                  configs[ i ].getAttribute( "name" );
              selectors.add( name );
          }
  
          return (String[])selectors.toArray( new String[ selectors.size() ] );
      }
  
      private EntryDef[] buildEntrys( final Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList entrys = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final EntryDef entry = buildEntry( configs[ i ] );
              entrys.add( entry );
          }
  
          return (EntryDef[])entrys.toArray( new EntryDef[ entrys.size() ] );
      }
  
      private EntryDef buildEntry( final Configuration config )
          throws ConfigurationException
      {
          final String location = config.getAttribute( "location" );
          return new EntryDef( location );
      }
  
      private JoinDef[] buildJoins( final Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList joins = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final JoinDef join = buildJoin( configs[ i ] );
              joins.add( join );
          }
  
          return (JoinDef[])joins.toArray( new JoinDef[ joins.size() ] );
      }
  
      private JoinDef buildJoin( final Configuration config )
          throws ConfigurationException
      {
          final String name = config.getAttribute( "name" );
          final Configuration[] children =
              config.getChildren( "classloader-ref" );
          final String[] classloaders =
              buildClassLoaderRefs( children );
          return new JoinDef( name, classloaders );
      }
  
      private String[] buildClassLoaderRefs( final Configuration[] configs )
          throws ConfigurationException
      {
          final ArrayList refs = new ArrayList();
  
          for( int i = 0; i < configs.length; i++ )
          {
              final String ref = configs[ i ].getAttribute( "name" );
              refs.add( ref );
          }
  
          return (String[])refs.toArray( new String[ refs.size() ] );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/classloader.dtd
  
  Index: classloader.dtd
  ===================================================================
  <!--
  
     This is the DTD defining the ClassLoader 1.0
     descriptor (XML) file format/syntax.
  
     Author: Peter Donald <peter at apache.org>
  
     This descriptor is used to describe a mechanism of defining
     a set of ClassLoaders and the arrangment of specified ClassLoaders.
  
     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 classloaders is the document root, it defines:
  
  join 	       the join classloaders
  classloader  the regular classloaders
  -->
  <!ELEMENT classloaders (classloader*,join*)>
    <!ATTLIST classloaders id ID #IMPLIED
            xmlns CDATA #FIXED "http://jakarta.apache.org/phoenix/classloaders_1_0.dtd" >
    <!ATTLIST classloaders
          default CDATA #REQUIRED
          version CDATA #REQUIRED >
  
  <!--
  The classloader element describes a regular classloader It defines:
  
  Attributes:
  name	        the name of classloader type. Must be a string
               containing alphanumeric characters, '.', '-', '_' and
               starting with a letter or a '_'.
  parent 	     the name of the parent classloader
  
  Elements:
  entry 	      an entry in classloader
  fileset 	    an fileset in classloader
  extension    an extension in classloader
  -->
  <!ELEMENT classloader          (entry*,fileset*,extension*)>
    <!ATTLIST classloader
         name CDATA #REQUIRED
         parent CDATA #REQUIRED >
  
  <!--
  The classloader element describes a regular classloader It defines:
  
  Attributes:
  name	        the name of classloader type. Must be a string
               containing alphanumeric characters, '.', '-', '_' and
               starting with a letter or a '_'.
  
  Elements:
  classloader-ref  a reference to all classloaders that are joined
  -->
  <!ELEMENT join          (classloader-ref*)>
    <!ATTLIST join name CDATA #REQUIRED >
  
  <!--
  The classloader-ref defines a ClassLoader that are part of join.
  It defines:
  
  Attributes:
  name     the name of other classloader that will join with
  -->
  <!ELEMENT classloader-ref EMPTY>
    <!ATTLIST classloader-ref name CDATA #REQUIRED>
  
  <!--
  The entry describes a entry in ClassLoader. It defines:
  
  Attributes:
  location     the location (URL) to add to classloader
  -->
  <!ELEMENT entry EMPTY>
    <!ATTLIST entry location CDATA #REQUIRED>
  
  <!--
  The classloader element describes a regular classloader It defines:
  
  Attributes:
  name	        the name of classloader type. Must be a string
               containing alphanumeric characters, '.', '-', '_' and
               starting with a letter or a '_'.
  
  Elements:
  classloader-ref  a reference to all classloaders that are joined
  -->
  <!ELEMENT fileset          ((include|exclude)*)>
    <!ATTLIST fileset dir CDATA #REQUIRED >
  
  <!--
  The entry describes a include for fileset. It defines:
  
  Attributes:
  name     the pattern to include
  -->
  <!ELEMENT include EMPTY>
    <!ATTLIST include name CDATA #REQUIRED>
  
  <!--
  The entry describes a exclude for fileset. It defines:
  
  Attributes:
  name     the pattern to exclude
  -->
  <!ELEMENT exclude EMPTY>
    <!ATTLIST exclude name CDATA #REQUIRED>
  
  
  <!--
  The extension describes a extension for ClassLoader.
  -->
  <!ELEMENT extension (name,specification-version?,specification-vendor?,implementation-version?implementation-vendor?,implementation-vendor-id?,implementation-url)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT specification-version (#PCDATA)>
    <!ELEMENT specification-vendor (#PCDATA)>
    <!ELEMENT implementation-version (#PCDATA)>
    <!ELEMENT implementation-vendor (#PCDATA)>
    <!ELEMENT implementation-vendor-id (#PCDATA)>
    <!ELEMENT implementation-url (#PCDATA)>
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/metadata/ClassLoaderDef.java
  
  Index: ClassLoaderDef.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.loader.metadata;
  
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * This class defines a specific classloader, made up of
   * {@link EntryDef}, {@link Extension} and
   * {@link FileSetDef} objects.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class ClassLoaderDef
  {
      /**
       * The name of the current classloader.
       * This may be used by other ClassLoader definitions to refer
       * to this ClassLoader.
       */
      private final String m_name;
  
      /**
       * The name of the parent classloader.
       */
      private final String m_parent;
  
      /**
       * The Entrys that are added to this ClassLoader.
       */
      private final EntryDef[] m_entrys;
  
      /**
       * The Entrys that are required by this ClassLoader.
       */
      private final Extension[] m_extensions;
  
      /**
       * The Filesets that are added to this ClassLoader.
       */
      private final FileSetDef[] m_filesets;
  
      public ClassLoaderDef( final String name,
                                  final String parent,
                                  final EntryDef[] elements,
                                  final Extension[] extensions,
                                  final FileSetDef[] filesets )
      {
          m_name = name;
          m_parent = parent;
          m_entrys = elements;
          m_extensions = extensions;
          m_filesets = filesets;
      }
  
      /**
       * Return the name of Classloader.
       *
       * @return the name of Classloader.
       * @see #m_name
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the name of parent Classloader.
       *
       * @return the name of parent Classloader.
       * @see #m_parent
       */
      public String getParent()
      {
          return m_parent;
      }
  
      /**
       * Return the elements added to Classloader.
       *
       * @return the elements added to Classloader.
       * @see #m_entrys
       */
      public EntryDef[] getEntrys()
      {
          return m_entrys;
      }
  
      /**
       * Return the extensions added to Classloader.
       *
       * @return the extensions added to Classloader.
       * @see #m_extensions
       */
      public Extension[] getExtensions()
      {
          return m_extensions;
      }
  
      /**
       * Return the filesets added to Classloader.
       *
       * @return the filesets added to Classloader.
       * @see #m_filesets
       */
      public FileSetDef[] getFilesets()
      {
          return m_filesets;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/metadata/ClassLoaderSetDef.java
  
  Index: ClassLoaderSetDef.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.loader.metadata;
  
  /**
   * This class defines a set of ClassLoaders and
   * the default ClassLoader to use.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class ClassLoaderSetDef
  {
      /**
       * The name of the current classloader.
       * This may be used by other ClassLoader definitions to refer
       * to this ClassLoader.
       */
      private final String m_default;
  
      /**
       * The set of ClassLoaders predefined by the application.
       */
      private final String[] m_predefined;
  
      /**
       * The classloaders defined in set.
       */
      private final ClassLoaderDef[] m_classLoaders;
  
      /**
       * The joining classloaders defined in set.
       */
      private final JoinDef[] m_joins;
  
      /**
       * Construct set with specified set and ClassLoaders.
       *
       * @param aDefault the name of default ClassLoader
       * @param classLoaders the ClassLoaders in set
       */
      public ClassLoaderSetDef( final String aDefault,
                                final String[] predefined,
                                final ClassLoaderDef[] classLoaders,
                                final JoinDef[] joins )
      {
          if( null == aDefault )
          {
              throw new NullPointerException( "aDefault" );
          }
          if( null == classLoaders )
          {
              throw new NullPointerException( "classLoaders" );
          }
          if( null == joins )
          {
              throw new NullPointerException( "joins" );
          }
          if( null == predefined )
          {
              throw new NullPointerException( "predefined" );
          }
  
          m_default = aDefault;
          m_predefined = predefined;
          m_classLoaders = classLoaders;
          m_joins = joins;
      }
  
      /**
       * Return the default ClassLoader name.
       *
       * @return the default ClassLoader name.
       * @see #m_default
       */
      public String getDefault()
      {
          return m_default;
      }
  
      /**
       * Return the set of predefined ClassLoaders.
       *
       * @return the set of predefined ClassLoaders.
       * @see #m_predefined
       */
      public String[] getPredefined()
      {
          return m_predefined;
      }
  
      /**
       * Return the classloaders in set.
       *
       * @return the classloaders in set.
       * @see #m_classLoaders
       */
      public ClassLoaderDef[] getClassLoaders()
      {
          return m_classLoaders;
      }
  
      /**
       * Return the "join" classloaders in set.
       *
       * @return the "join" classloaders in set.
       * @see #m_joins
       */
      public JoinDef[] getJoins()
      {
          return m_joins;
      }
  
      /**
       * Return true if specified name, designates a
       * predefined ClassLoader.
       *
       * @return true if specified name, designates a
       *              predefined ClassLoader.
       */
      public boolean isPredefined( final String name )
      {
          for( int i = 0; i < m_predefined.length; i++ )
          {
              if( m_predefined[ i ].equals( name ) )
              {
                  return true;
              }
          }
          return false;
      }
  
      /**
       * Return the classloader with specified name.
       *
       * @return the classloader with specified name
       */
      public ClassLoaderDef getClassLoader( final String name )
      {
          for( int i = 0; i < m_classLoaders.length; i++ )
          {
              final ClassLoaderDef classLoader = m_classLoaders[ i ];
              if( classLoader.getName().equals( name ) )
              {
                  return classLoader;
              }
          }
          return null;
      }
  
      /**
       * Return the "join" classloader with specified name.
       *
       * @return the "join" classloader with specified name
       */
      public JoinDef getJoin( final String name )
      {
          for( int i = 0; i < m_joins.length; i++ )
          {
              final JoinDef join = m_joins[ i ];
              if( join.getName().equals( name ) )
              {
                  return join;
              }
          }
          return null;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/metadata/EntryDef.java
  
  Index: EntryDef.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.loader.metadata;
  
  /**
   * This class defines a specific URL to add to a ClassLoader.
   * It uses the same resolution semantics as the
   * {@link java.security.CodeSource} class. In other words,
   * locations that end with a '/' character are considered to
   * be a directory in which .class files are stored. All other
   * locations are considered to be jar files.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class EntryDef
  {
      private final String m_location;
  
      /**
       * Construct a entry with specified location.
       *
       * @param location the location (must not be null)
       */
      public EntryDef( final String location )
      {
          if( null == location )
          {
              throw new NullPointerException( "location" );
          }
          m_location = location;
      }
  
      /**
       * Return the location associated with Entry.
       *
       * @return  the location associated with Entry.
       */
      public String getLocation()
      {
          return m_location;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/metadata/FileSetDef.java
  
  Index: FileSetDef.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.loader.metadata;
  
  /**
   * This class represent a set of files anchored in a base
   * directory. The set of files is determined by the include and
   * excludes that are specified for fileset. If no includes or
   * excludes are specified then all files in base directory
   * are added to fileset.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class FileSetDef
  {
      /**
       * The base directory from which to apply all the
       * includes/excludes.
       */
      private final String m_baseDirectory;
  
      /**
       * The set of patterns to include in fileset.
       */
      private final String[] m_includes;
  
      /**
       * The set of patterns to exclude from fileset.
       */
      private final String[] m_excludes;
  
      public FileSetDef( final String baseDirectory,
                         final String[] includes,
                         final String[] excludes )
      {
          if( null == baseDirectory )
          {
              throw new NullPointerException( "baseDirectory" );
          }
          if( null == includes )
          {
              throw new NullPointerException( "includes" );
          }
          if( null == excludes )
          {
              throw new NullPointerException( "excludes" );
          }
  
          m_baseDirectory = baseDirectory;
          m_includes = includes;
          m_excludes = excludes;
      }
  
      /**
       * Return the base directory of fileset.
       *
       * @return the base directory of fileset.
       */
      public String getBaseDirectory()
      {
          return m_baseDirectory;
      }
  
      /**
       * Return the list of includes for fileset.
       *
       * @return the list of includes for fileset.
       */
      public String[] getIncludes()
      {
          return m_includes;
      }
  
      /**
       * Return the list of excludes for fileset.
       *
       * @return the list of excludes for fileset.
       */
      public String[] getExcludes()
      {
          return m_excludes;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/metadata/JoinDef.java
  
  Index: JoinDef.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.loader.metadata;
  
  /**
   * This class defines a classloader that "merges" multiple
   * classloaders. For this to be successful, it is required that
   * the ClassLoaders contain disjoint sets of classes (with the
   * exception of classes loaded from the system classpath).
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class JoinDef
  {
      /**
       * The name of the current classloader.
       * This may be used by other ClassLoader definitions to refer
       * to this ClassLoader.
       */
      private final String m_name;
  
      /**
       * The list of classloaders that are merged in
       * this classloader.
       */
      private final String[] m_classloaders;
  
      /**
       * The definition for set of classloaders
       *
       * @param name
       * @param classloaders
       */
      public JoinDef( final String name,
                      final String[] classloaders )
      {
          m_name = name;
          m_classloaders = classloaders;
      }
  
      /**
       * Return the name of Classloader.
       *
       * @return the name of Classloader.
       * @see #m_name
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Return the list of classloaders that are merged in
       * this classloader
       *
       * @return the list of classloaders that are merged
       *         in this classloader
       */
      public String[] getClassloaders()
      {
          return m_classloaders;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/verifier/ClassLoaderVerifier.java
  
  Index: ClassLoaderVerifier.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.loader.verifier;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.excalibur.loader.metadata.ClassLoaderDef;
  import org.apache.excalibur.loader.metadata.ClassLoaderSetDef;
  import org.apache.excalibur.loader.metadata.EntryDef;
  import org.apache.excalibur.loader.metadata.JoinDef;
  
  /**
   * Verify ClassLoader set is valid. Validity is defined as
   * <ul>
   *   <li>With exception of predefined names, all ClassLoader
   *       names should be defined starting with letters or '_'
   *       and then continuing with Alpha-Numeric characters,
   *       '-', '.' or '_'.</li>
   *   <li>No ClassLoader can have a parent ClassLoader that is
   *       not predefined or not defined in ClassLoaderSet.</li>
   *   <li>No "join" ClassLoader can link against a non-existent
   *       ClassLoader.</li>
   *   <li>No "join" ClassLoader can join multiple instances
   *       of same ClassLoader.</li>
   *   <li>No ClassLoader can have multiple entrys that point
   *       to the same location.</li>
   *   <li>No ClassLoader (either predefined, join or regular)
   *       can have the same name.</li>
   *   <li>The default ClassLoader must exist.</li>
   *   <li>There must be no circular dependencies between join
   *       classloaders.</li>
   * </ul>
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/01 05:54:59 $
   */
  public class ClassLoaderVerifier
      extends AbstractLogEnabled
  {
      private final static Resources REZ =
          ResourceManager.getPackageResources( ClassLoaderVerifier.class );
  
      public void verifyClassLoaderSet( final ClassLoaderSetDef set )
          throws Exception
      {
          String message = null;
  
          message = REZ.getString( "valid-names.notice" );
          getLogger().info( message );
          verifyNames( set );
  
          message = REZ.getString( "valid-parents.notice" );
          getLogger().info( message );
          verifyParents( set );
  
          message = REZ.getString( "valid-links.notice" );
          getLogger().info( message );
          verifyLinks( set );
  
          message = REZ.getString( "default-loader.notice" );
          getLogger().info( message );
          verifyDefaultLoaderExists( set );
  
          message = REZ.getString( "unique-classloader.notice" );
          getLogger().info( message );
          verifyUniqueClassLoaderNames( set );
  
          message = REZ.getString( "unique-joins.notice" );
          getLogger().info( message );
          verifyUniqueJoinNames( set );
  
          message = REZ.getString( "unique-predefined.notice" );
          getLogger().info( message );
          verifyUniquePredefinedNames( set );
  
          message = REZ.getString( "unique-joins-entrys.notice" );
          getLogger().info( message );
          verifyUniqueJoinEntrys( set );
  
          message = REZ.getString( "unique-classpath-entrys.notice" );
          getLogger().info( message );
          verifyUniqueClassLoaderEntrys( set );
  
          //TODO: Verify that the joins form a directed graph with no loops
      }
  
      /**
       * Verify that all the classloaders have valid names.
       *
       * @throws Exception if validity check fails
       */
      private void verifyNames( ClassLoaderSetDef set )
          throws Exception
      {
          final ClassLoaderDef[] classLoaders = set.getClassLoaders();
          for( int i = 0; i < classLoaders.length; i++ )
          {
              final String name = classLoaders[ i ].getName();
              verifyName( name );
          }
  
          final JoinDef[] joins = set.getJoins();
          for( int i = 0; i < joins.length; i++ )
          {
              final String name = joins[ i ].getName();
              verifyName( name );
          }
      }
  
      /**
       * Verify that all the classloaders have valid parents.
       *
       * @throws Exception if validity check fails
       */
      private void verifyParents( ClassLoaderSetDef set )
          throws Exception
      {
          final ClassLoaderDef[] classLoaders = set.getClassLoaders();
          for( int i = 0; i < classLoaders.length; i++ )
          {
              final ClassLoaderDef classLoader = classLoaders[ i ];
              final String parent = classLoader.getParent();
              if( isLoaderDefined( parent, set ) )
              {
                  final String message =
                      REZ.getString( "invalid-parent.error",
                                     classLoader.getName(),
                                     parent );
                  throw new Exception( message );
              }
          }
      }
  
      /**
       * Verify that each join ClassLoader only
       * links to ClassLoaders that exist.
       *
       * @throws Exception if validity check fails
       */
      private void verifyLinks( final ClassLoaderSetDef set )
          throws Exception
      {
          final JoinDef[] joins = set.getJoins();
          for( int i = 0; i < joins.length; i++ )
          {
              verifyLinks( joins[ i ], set );
          }
      }
  
      /**
       * Verify that each join ClassLoader only
       * links to ClassLoaders that exist.
       *
       * @throws Exception if validity check fails
       */
      private void verifyLinks( final JoinDef join,
                                final ClassLoaderSetDef set )
          throws Exception
      {
          final String[] classloaders = join.getClassloaders();
          for( int i = 0; i < classloaders.length; i++ )
          {
              final String classloader = classloaders[ i ];
              if( !isLoaderDefined( classloader, set ) )
              {
                  final String message =
                      REZ.getString( "bad-join-link.error",
                                     join.getName(),
                                     classloader );
                  throw new Exception( message );
              }
          }
      }
  
      /**
       * Verify that all the classloaders have valid names.
       *
       * @throws Exception if validity check fails
       */
      private void verifyName( final String name )
          throws Exception
      {
          final int size = name.length();
          if( 0 == size )
          {
              final String message =
                  REZ.getString( "empty-name.error",
                                 name );
              throw new Exception( message );
          }
          final char ch = name.charAt( 0 );
          if( !Character.isLetter( ch ) &&
              '_' != ch )
          {
              final String message =
                  REZ.getString( "name-invalid-start.error",
                                 name );
              throw new Exception( message );
          }
  
          for( int i = 1; i < size; i++ )
          {
              final char c = name.charAt( i );
              if( !Character.isLetterOrDigit( c ) &&
                  '_' != c &&
                  '-' != c &&
                  '.' != c )
              {
                  final String message =
                      REZ.getString( "name-invalid-char.error",
                                     name,
                                     String.valueOf( c ) );
                  throw new Exception( message );
              }
          }
      }
  
      /**
       * Verify that each regular ClassLoader only
       * contains unique entrys.
       *
       * @throws Exception if validity check fails
       */
      private void verifyUniqueClassLoaderEntrys( final ClassLoaderSetDef set )
          throws Exception
      {
          final ClassLoaderDef[] classLoaders = set.getClassLoaders();
          for( int i = 0; i < classLoaders.length; i++ )
          {
              verifyUniqueClassLoaderEntrys( classLoaders[ i ] );
          }
      }
  
      /**
       * Verify that each regular ClassLoader only
       * contains unique entrys.
       *
       * @throws Exception if validity check fails
       */
      private void verifyUniqueClassLoaderEntrys( final ClassLoaderDef classLoader )
          throws Exception
      {
          final EntryDef[] entrys = classLoader.getEntrys();
          for( int i = 0; i < entrys.length; i++ )
          {
              final EntryDef entry = entrys[ i ];
              final String location = entry.getLocation();
              for( int j = i + 1; j < entrys.length; j++ )
              {
                  final EntryDef other = entrys[ j ];
                  if( location.equals( other.getLocation() ) )
                  {
                      final String message =
                          REZ.getString( "classloader-dup-entrys.error",
                                         classLoader.getName(),
                                         location );
                      throw new Exception( message );
                  }
              }
          }
      }
  
      /**
       * Verify that each join only contains unique classloaders.
       *
       * @throws Exception if validity check fails
       */
      private void verifyUniqueJoinEntrys( final ClassLoaderSetDef set )
          throws Exception
      {
          final JoinDef[] joins = set.getJoins();
          for( int i = 0; i < joins.length; i++ )
          {
              verifyUniqueJoinEntrys( joins[ i ] );
          }
      }
  
      /**
       * Verify that specified join only contains unique classloaders.
       *
       * @throws Exception if validity check fails
       */
      private void verifyUniqueJoinEntrys( final JoinDef join )
          throws Exception
      {
          final String[] classloaders = join.getClassloaders();
          for( int j = 0; j < classloaders.length; j++ )
          {
              final String name = classloaders[ j ];
              for( int k = j + 1; k < classloaders.length; k++ )
              {
                  final String other = classloaders[ k ];
                  if( other.equals( name ) )
                  {
                      final String message =
                          REZ.getString( "join-dup-entrys.error",
                                         join.getName(),
                                         name );
                      throw new Exception( message );
                  }
              }
          }
      }
  
      /**
       * Verify that the Predefined names are unique set.
       *
       * @throws Exception if validity check fails
       */
      private void verifyUniquePredefinedNames( final ClassLoaderSetDef set )
          throws Exception
      {
          final String[] predefined = set.getPredefined();
          for( int i = 0; i < predefined.length; i++ )
          {
              final String name = predefined[ i ];
              for( int j = i + 1; j < predefined.length; j++ )
              {
                  final String other = predefined[ j ];
                  if( other.equals( name ) )
                  {
                      final String message =
                          REZ.getString( "duplicate-name.error",
                                         "predefined",
                                         "predefined",
                                         name );
                      throw new Exception( message );
                  }
              }
          }
      }
  
      /**
       * Verify that the ClassLoader names are unique throughout the set.
       *
       * @param set the set of ClassLoader defs to search in
       * @throws Exception if validity check fails
       */
      private void verifyUniqueClassLoaderNames( final ClassLoaderSetDef set )
          throws Exception
      {
          final ClassLoaderDef[] classLoaders = set.getClassLoaders();
          for( int i = 0; i < classLoaders.length; i++ )
          {
              final ClassLoaderDef classLoader = classLoaders[ i ];
              verifyUniqueName( set,
                                classLoader.getName(),
                                "classloader",
                                classLoader );
          }
      }
  
      /**
       * Verify that the specified name is unique in set
       * except for specified entity.
       *
       * @param set the set of classloaders
       * @param name the name
       * @param type the type of classloder (used for exception messages)
       * @param entity the entity to skip (ie the one the name refers to)
       * @throws Exception if validity check fails
       */
      private void verifyUniqueName( final ClassLoaderSetDef set,
                                     final String name,
                                     final String type,
                                     final Object entity )
          throws Exception
      {
          //Make sure our join does not have same name as a
          //predefined ClassLoader
          if( set.isPredefined( name ) )
          {
              final String message =
                  REZ.getString( "duplicate-name.error",
                                 type,
                                 "predefined",
                                 name );
              throw new Exception( message );
          }
  
          //Make sure no joins have same name as our join
          final JoinDef[] joins = set.getJoins();
          for( int j = 0; j < joins.length; j++ )
          {
              final JoinDef other = joins[ j ];
              if( other == entity )
              {
                  continue;
              }
              if( other.getName().equals( name ) )
              {
                  final String message =
                      REZ.getString( "duplicate-name.error",
                                     type,
                                     "join",
                                     name );
                  throw new Exception( message );
              }
          }
  
          final ClassLoaderDef[] classLoaders = set.getClassLoaders();
          for( int j = 0; j < classLoaders.length; j++ )
          {
              final ClassLoaderDef other = classLoaders[ j ];
              if( other == entity )
              {
                  continue;
              }
              if( other.getName().equals( name ) )
              {
                  final String message =
                      REZ.getString( "duplicate-name.error",
                                     type,
                                     "classloader",
                                     name );
                  throw new Exception( message );
              }
          }
      }
  
      /**
       * Verify that the join names are unique throughout the set.
       *
       * @param set the set of ClassLoader defs to search in
       * @throws Exception if validity check fails
       */
      private void verifyUniqueJoinNames( final ClassLoaderSetDef set )
          throws Exception
      {
          final JoinDef[] joins = set.getJoins();
          for( int i = 0; i < joins.length; i++ )
          {
              final JoinDef join = joins[ i ];
              verifyUniqueName( set,
                                join.getName(),
                                "join",
                                join );
          }
      }
  
      /**
       * Verify that the default loader is defined.
       *
       * @param set the set of ClassLoader defs to search in
       * @throws Exception if validity check fails
       */
      private void verifyDefaultLoaderExists( final ClassLoaderSetDef set )
          throws Exception
      {
          final String name = set.getDefault();
          if( !isLoaderDefined( name, set ) )
          {
              final String message =
                  REZ.getString( "missing-default-loader.error",
                                 name );
              throw new Exception( message );
          }
      }
  
      /**
       * Return true if specified loader is defined in set.
       *
       * @param name the name of loader
       * @param set the set to search
       * @return true if specified loader is defined in set.
       */
      private boolean isLoaderDefined( final String name,
                                       final ClassLoaderSetDef set )
      {
          if( set.isPredefined( name ) )
          {
              return true;
          }
          else if( null != set.getClassLoader( name ) )
          {
              return true;
          }
          else if( null != set.getJoin( name ) )
          {
              return true;
          }
          else
          {
              return false;
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/verifier/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  valid-names.notice=Verifying that all ClassLoaders have valid names.
  valid-parents.notice=Verifying that all ClassLoaders have valid parents.
  valid-links.notice=Verifying that all "Join" ClassLoaders link against existing ClassLoaders.
  default-loader.notice=Verifying that the default ClassLoader exists.
  unique-classloader.notice=Verifying that all Regular ClassLoaders have a unique name.
  unique-joins.notice=Verifying that all Join ClassLoaders have a unique name.
  unique-predefined.notice=Verifying that all predefined ClassLoaders have a unique name.
  unique-joins-entrys.notice=Verifying that all "Join" ClassLoaders link with other classLoaders no more than once.
  unique-classpath-entrys.notice=Verifying that all Regular ClassLoaders have unique entrys.
  unique-classpath-entrys.notice=Verifying that all Regular ClassLoaders have unique entrys.
  
  
  invalid-parent.error=ClassLoader named "{0}" specified a non-existent parent "{1}".
  bad-join-link.error="Join" ClassLoader named "{0}" specified a non-existent classloader-ref "{1}".
  empty-name.error=Invalid empty ClassLoader name.
  name-invalid-start.error=ClassLoader name "{0}" begins with invalid name. Must begin with a letter or the '_' character.
  name-invalid-char.error=ClassLoader name "{0}" contains invalid character "{0}".
  name-invalid-char.error=ClassLoader name "{0}" contains invalid character "{0}".
  classloader-dup-entrys.error=Duplicate entry "{1}" detected for regular ClassLoader named "{0}".
  join-dup-entrys.error=Duplicate classloader-ref "{1}" detected for "Join" ClassLoader named "{0}".
  join-dup-entrys.error=Duplicate classloader-ref "{1}" detected for "Join" ClassLoader named "{0}".
  missing-default-loader.error=Unable to locate default ClassLoader named "{0}".
  duplicate-name.error=Multiple ClassLoaders exist with name "{2}". (One is a {0,choice,classloader#Regular|predefined#Predefined|join#Join} ClassLoader, the other is a {1,choice,classloader#Regular|predefined#Predefined|join#Join} ClassLoader).
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
      <properties>
          <title>Excalibur Loader - Overview</title>
          <author email="peter at apache.org">Peter Donald</author>
      </properties>
      <body>
          <section name="Introduction">
              <p>The Loader toolkit is a set of utility classes that enable
              ClassLoader hierarchies to be constructed from xml
              configurations.</p>
              <p>Each ClassLoader can be defined in terms of;</p>
              <ul>
                  <li><a href="api/org/apache/excalibur/loader/metadata/EntryDef.html">
                  Entrys</a>: URLs designating either a directory or a file</li>
                  <li><a href="api/org/apache/excalibur/loader/metadata/FileSetDef.html">
                  FileSets</a>: Sets of files defined in a manner similar
                  to Ants Filests.</li>
                  <li><a href="http://jakarta.apache.org/avalon/excalibur/extension/api/org/apache/avalon/excalibur/extension/Extension.html">
                  Extensions</a>: Definitions of Extensions, aka "Optional Packages".</li>
              </ul>
              <p>Each ClassLoader also has a name and a parent. The parent is the
              name of the parent ClassLoader. Usually the parent ClassLoaders are
              one of the predefined ClassLoaders. The predefined and passed into
              the Loader toolkit from external application code.</p>
              <p>The predefined ClassLoaders are generally named according to
              a pattern that places the '*' at start and end of name. ie
              "*myPredefinedClassLoader*". Many containers pass in the following
              predefined Classloaders.</p>
              <ul>
                  <li>*system*: The System ClassLoader.</li>
                  <li>*common*: Common between container and client code.</li>
                  <li>*shared*: Shared between all client code.</li>
              </ul>
              <p>For an example ClassLoader hierarchy see the website for
              <a href="http://jakarta.apache.org/ant/myrmidon/classloader.html">
              Myrmidon</a>, an Ant2 proposal.</p>
          </section>
      </body>
  </document>
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/xdocs/menu.xml
  
  Index: menu.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <project
      href="http://jakarta.apache.org/avalon/excalibur/info/"
      name="Avalon Info">
  
      <title>Avalon Info</title>
      <body>
          <menu name="About">
              <item name="Overview" href="index.html"/>
              <item name="Excalibur Home" href="http://jakarta.apache.org/avalon/excalibur/index.html"/>
              <item name="Download" href="http://jakarta.apache.org/builds/jakarta-avalon-excalibur/release"/>
              <item name="API Docs" href="api/"/>
          </menu>
      </body>
  </project>
  
  
  
  1.1                  jakarta-avalon-excalibur/loader/src/xdocs/stylesheets/project.xml
  
  Index: project.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <project
      href="http://jakarta.apache.org/avalon/excalibur/loader"
      name="Excalibur Loader">
  
      <title>Excalibur Loader</title>
      <body>
          <item href="/../index.html" name="Back to Excalibur"/>
          <menu name="About">
              <item name="Overview" href="/index.html"/>
              <item name="Excalibur Home" href="http://jakarta.apache.org/avalon/excalibur/index.html"/>
              <item name="Download" href="http://jakarta.apache.org/builds/jakarta-avalon-excalibur/release/loader"/>
              <item name="API Docs" href="/api/index.html"/>
          </menu>
      </body>
  </project>
  
  

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