ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml DTDLocation.java LocalResolver.java TraxErrorListener.java ValidatorErrorHandler.java XMLValidateTask.java XSLTParam.java XSLTProcess.java
Date Sun, 14 Apr 2002 10:56:39 GMT
donaldp     02/04/14 03:56:39

  Added:       antlib/src/conf archive.mf empty-manifest.mf empty-roles.xml
                        selftest-extension1.mf selftest.mf tools.mf
               antlib/src/java/org/apache/antlib/security
                        DistinguishedName.java DnameParam.java
                        GenerateKey.java SignJar.java
               antlib/src/java/org/apache/antlib/selftest
                        ExtensionsTest.java PrimitiveTypesTest.java
               antlib/src/java/org/apache/antlib/selftest/extension1
                        ExtensionsLoadedClass.java
               antlib/src/java/org/apache/antlib/sound AntSoundPlayer.java
                        BuildAlert.java Resources.properties SoundTask.java
               antlib/src/java/org/apache/antlib/xml DTDLocation.java
                        LocalResolver.java TraxErrorListener.java
                        ValidatorErrorHandler.java XMLValidateTask.java
                        XSLTParam.java XSLTProcess.java
  Log:
  Add the remaining tasks and some manifests.
  
  Revision  Changes    Path
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/archive.mf
  
  Index: archive.mf
  ===================================================================
  Manifest-Version: 1.0
  Extension-List: bzip2
  bzip2-Extension-Name: excalibur-bzip2
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/empty-manifest.mf
  
  Index: empty-manifest.mf
  ===================================================================
  Manifest-version: 1.0
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/empty-roles.xml
  
  Index: empty-roles.xml
  ===================================================================
  <roles version="1.0">
  </roles>
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/selftest-extension1.mf
  
  Index: selftest-extension1.mf
  ===================================================================
  Manifest-Version: 1.0
  Extension-Name: cornerstone.test.extension
  Specification-Title: Avalon Cornerstone Test Extension
  Specification-Version: 1.1
  Specification-Vendor: Jakarta Apache
  Implementation-Vendor-Id: org.apache.avalon
  Implementation-Vendor: Apache Avalon Project
  Implementation-Version: 1.0.2
  Extension-List: tools
  tools-Extension-Name: com.sun.tools
  tools-Specification-Version: 1.0
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/selftest.mf
  
  Index: selftest.mf
  ===================================================================
  Manifest-Version: 1.0
  Created-By: Apache Avalon Project
  Extension-Name: cornerstone.demo.simple
  Specification-Title: Avalon Cornerstone SimpleServer Demo Extension
  Implementation-Vendor-Id: org.apache.avalon
  Implementation-Vendor: Apache Avalon Project
  Extension-List: required1 
  required1-Extension-Name: cornerstone.test.extension
  required1-Specification-Version: 1.0
  required1-Implementation-Version: 1.0.2
  required1-Implementation-Vendor-Id: org.apache.avalon
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/conf/tools.mf
  
  Index: tools.mf
  ===================================================================
  Manifest-Version: 1.0
  Extension-List: tools
  tools-Extension-Name: com.sun.tools
  tools-Specification-Version: 1.0
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/security/DistinguishedName.java
  
  Index: DistinguishedName.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.antlib.security;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  
  public class DistinguishedName
  {
      private ArrayList m_params = new ArrayList();
  
      public Iterator getParams()
      {
          return m_params.iterator();
      }
  
      public Object createParam()
      {
          final DnameParam param = new DnameParam();
          m_params.add( param );
          return param;
      }
  
      private String encode( final String string )
      {
          int end = string.indexOf( ',' );
          if( -1 == end )
          {
              return string;
          }
  
          final StringBuffer sb = new StringBuffer();
  
          int start = 0;
          while( -1 != end )
          {
              sb.append( string.substring( start, end ) );
              sb.append( "\\," );
              start = end + 1;
              end = string.indexOf( ',', start );
          }
  
          sb.append( string.substring( start ) );
  
          return sb.toString();
      }
  
      public String toString()
      {
          final int size = m_params.size();
          final StringBuffer sb = new StringBuffer();
          boolean firstPass = true;
  
          for( int i = 0; i < size; i++ )
          {
              if( !firstPass )
              {
                  sb.append( " ," );
              }
              firstPass = false;
  
              final DnameParam param = (DnameParam)m_params.get( i );
              sb.append( encode( param.getName() ) );
              sb.append( '=' );
              sb.append( encode( param.getValue() ) );
          }
  
          return sb.toString();
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/security/DnameParam.java
  
  Index: DnameParam.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.antlib.security;
  
  public final class DnameParam
  {
      private String m_name;
      private String m_value;
  
      public void setName( final String name )
      {
          m_name = name;
      }
  
      public void setValue( final String value )
      {
          m_value = value;
      }
  
      protected String getName()
      {
          return m_name;
      }
  
      protected String getValue()
      {
          return m_value;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/security/GenerateKey.java
  
  Index: GenerateKey.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.antlib.security;
  
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.nativelib.Commandline;
  
  /**
   * Generates a key.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @ant.task name="generate-key"
   */
  public class GenerateKey
      extends AbstractTask
  {
      /**
       * The alias of signer.
       */
      private String m_alias;
      private String m_dname;
      private DistinguishedName m_expandedDname;
      private String m_keyalg;
      private String m_keypass;
      private int m_keysize;
  
      /**
       * The name of keystore file.
       */
      private String m_keystore;
  
      private String m_sigalg;
      private String m_storepass;
      private String m_storetype;
      private int m_validity;
      private boolean m_verbose;
  
      public void setAlias( final String alias )
      {
          m_alias = alias;
      }
  
      public void setDname( final String dname )
          throws TaskException
      {
          m_dname = dname;
      }
  
      public void setKeyalg( final String keyalg )
      {
          m_keyalg = keyalg;
      }
  
      public void setKeypass( final String keypass )
      {
          m_keypass = keypass;
      }
  
      public void setKeysize( final int keysize )
      {
          m_keysize = keysize;
      }
  
      public void setKeystore( final String keystore )
      {
          m_keystore = keystore;
      }
  
      public void setSigalg( final String sigalg )
      {
          m_sigalg = sigalg;
      }
  
      public void setStorepass( final String storepass )
      {
          m_storepass = storepass;
      }
  
      public void setStoretype( final String storetype )
      {
          m_storetype = storetype;
      }
  
      public void setValidity( final int validity )
          throws TaskException
      {
          m_validity = validity;
      }
  
      public void setVerbose( final boolean verbose )
      {
          m_verbose = verbose;
      }
  
      public void addDname( final DistinguishedName distinguishedName )
          throws TaskException
      {
          if( null != m_expandedDname )
          {
              final String message = "DName sub-element can only be specified once.";
              throw new TaskException( message );
          }
          m_expandedDname = distinguishedName;
      }
  
      public void execute()
          throws TaskException
      {
          validate();
  
          final String message = "Generating Key for " + m_alias;
          getContext().info( message );
  
          final Execute exe = createCommand();
          exe.execute( getContext() );
      }
  
      private Execute createCommand()
      {
          final Execute cmd = new Execute();
          cmd.setExecutable( "keytool" );
  
          cmd.addArgument( "-genkey " );
  
          if( m_verbose )
          {
              cmd.addArgument( "-v " );
          }
  
          cmd.addArgument( "-alias" );
          cmd.addArgument( m_alias );
  
          if( null != m_dname )
          {
              cmd.addArgument( "-dname" );
              cmd.addArgument( m_dname );
          }
  
          if( null != m_expandedDname )
          {
              cmd.addArgument( "-dname" );
              cmd.addArgument( m_expandedDname.toString() );
          }
  
          if( null != m_keystore )
          {
              cmd.addArgument( "-keystore" );
              cmd.addArgument( m_keystore );
          }
  
          if( null != m_storepass )
          {
              cmd.addArgument( "-storepass" );
              cmd.addArgument( m_storepass );
          }
  
          if( null != m_storetype )
          {
              cmd.addArgument( "-storetype" );
              cmd.addArgument( m_storetype );
          }
  
          cmd.addArgument( "-keypass" );
          if( null != m_keypass )
          {
              cmd.addArgument( m_keypass );
          }
          else
          {
              cmd.addArgument( m_storepass );
          }
  
          if( null != m_sigalg )
          {
              cmd.addArgument( "-sigalg" );
              cmd.addArgument( m_sigalg );
          }
  
          if( null != m_keyalg )
          {
              cmd.addArgument( "-keyalg" );
              cmd.addArgument( m_keyalg );
          }
  
          if( 0 < m_keysize )
          {
              cmd.addArgument( "-keysize" );
              cmd.addArgument( "" + m_keysize );
          }
  
          if( 0 < m_validity )
          {
              cmd.addArgument( "-validity" );
              cmd.addArgument( "" + m_validity );
          }
  
          return cmd;
      }
  
      private void validate()
          throws TaskException
      {
          if( null == m_alias )
          {
              final String message = "alias attribute must be set";
              throw new TaskException( message );
          }
  
          if( null == m_storepass )
          {
              final String message = "storepass attribute must be set";
              throw new TaskException( message );
          }
  
          if( null == m_dname && null == m_expandedDname )
          {
              final String message = "dname must be set";
              throw new TaskException( message );
          }
          else if( null != m_expandedDname && null != m_dname )
          {
              final String message = "It is not possible to specify dname both " +
                  "as attribute and element.";
              throw new TaskException( message );
          }
  
      }
  }
  
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/security/SignJar.java
  
  Index: SignJar.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.antlib.security;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipFile;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  
  /**
   * Sign a archive.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:nick@ox.compsoc.net">Nick Fortescue</a>
   * @ant.task name="sign-jar"
   */
  public class SignJar
      extends AbstractTask
  {
      /**
       * the filesets of the jars to sign
       */
      private ArrayList m_filesets = new ArrayList();
  
      /**
       * The alias of signer.
       */
      private String m_alias;
      private boolean m_internalsf;
  
      /**
       * The name of the jar file.
       */
      private File m_jar;
      private String m_keypass;
  
      /**
       * The name of keystore file.
       */
      private File m_keystore;
  
      /**
       * Whether to assume a jar which has an appropriate .SF file in is already
       * signed.
       */
      private boolean m_lazy;
  
      private boolean m_sectionsonly;
      private File m_sigfile;
      private File m_signedjar;
  
      private String m_storepass;
      private String m_storetype;
      private boolean m_verbose;
  
      public void setAlias( final String alias )
      {
          m_alias = alias;
      }
  
      public void setInternalsf( final boolean internalsf )
      {
          m_internalsf = internalsf;
      }
  
      public void setJar( final File jar )
      {
          m_jar = jar;
      }
  
      public void setKeypass( final String keypass )
      {
          m_keypass = keypass;
      }
  
      public void setKeystore( final File keystore )
      {
          m_keystore = keystore;
      }
  
      public void setLazy( final boolean lazy )
      {
          m_lazy = lazy;
      }
  
      public void setSectionsonly( final boolean sectionsonly )
      {
          m_sectionsonly = sectionsonly;
      }
  
      public void setSigfile( final File sigfile )
      {
          m_sigfile = sigfile;
      }
  
      public void setSignedjar( final File signedjar )
      {
          m_signedjar = signedjar;
      }
  
      public void setStorepass( final String storepass )
      {
          m_storepass = storepass;
      }
  
      public void setStoretype( final String storetype )
      {
          m_storetype = storetype;
      }
  
      public void setVerbose( final boolean verbose )
      {
          m_verbose = verbose;
      }
  
      /**
       * Adds a set of files (nested fileset attribute).
       *
       * @param set The feature to be added to the Fileset attribute
       */
      public void addFileset( final FileSet set )
      {
          m_filesets.add( set );
      }
  
      public void execute()
          throws TaskException
      {
          validate();
  
          if( null != m_jar )
          {
              doOneJar( m_jar, m_signedjar );
          }
          else
          {
              //Assume null != filesets
  
              // deal with the filesets
              final int size = m_filesets.size();
              for( int i = 0; i < size; i++ )
              {
                  final FileSet fileSet = (FileSet)m_filesets.get( i );
                  final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
                  final String[] jarFiles = scanner.getIncludedFiles();
                  for( int j = 0; j < jarFiles.length; j++ )
                  {
                      final File file =
                          new File( fileSet.getDir(), jarFiles[ j ] );
                      doOneJar( file, null );
                  }
              }
          }
      }
  
      private void validate() throws TaskException
      {
          if( null == m_jar && null == m_filesets )
          {
              final String message = "jar must be set through jar attribute or nested filesets";
              throw new TaskException( message );
          }
          else if( null != m_jar )
          {
              if( null == m_alias )
              {
                  final String message = "alias attribute must be set";
                  throw new TaskException( message );
              }
  
              if( null == m_storepass )
              {
                  final String message = "storepass attribute must be set";
                  throw new TaskException( message );
              }
          }
      }
  
      private boolean isSigned( final File file )
      {
          final String SIG_START = "META-INF/";
          final String SIG_END = ".SF";
  
          if( !file.exists() )
          {
              return false;
          }
          ZipFile jarFile = null;
          try
          {
              jarFile = new ZipFile( file );
              if( null == m_alias )
              {
                  final Enumeration entries = jarFile.entries();
                  while( entries.hasMoreElements() )
                  {
                      final ZipEntry entry = (ZipEntry)entries.nextElement();
                      final String name = entry.getName();
                      if( name.startsWith( SIG_START ) && name.endsWith( SIG_END ) )
                      {
                          return true;
                      }
                  }
                  return false;
              }
              else
              {
                  final String name = SIG_START + m_alias.toUpperCase() + SIG_END;
                  final ZipEntry entry = jarFile.getEntry( name );
                  return ( entry != null );
              }
          }
          catch( final IOException ioe )
          {
              return false;
          }
          finally
          {
              if( null != jarFile )
              {
                  try
                  {
                      jarFile.close();
                  }
                  catch( final IOException ioe )
                  {
                  }
              }
          }
      }
  
      private boolean isUpToDate( final File jarFile, final File signedjarFile )
      {
          if( null == jarFile )
          {
              return false;
          }
          else if( null != signedjarFile )
          {
              if( !jarFile.exists() )
              {
                  return false;
              }
              else if( !signedjarFile.exists() )
              {
                  return false;
              }
              else if( jarFile.equals( signedjarFile ) )
              {
                  return false;
              }
              else if( signedjarFile.lastModified() > jarFile.lastModified() )
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
          else if( m_lazy )
          {
              return isSigned( jarFile );
          }
          else
          {
              return false;
          }
      }
  
      private void doOneJar( final File jarSource, final File jarTarget )
          throws TaskException
      {
          if( isUpToDate( jarSource, jarTarget ) )
          {
              return;
          }
  
          final String message = "Signing Jar : " + jarSource.getAbsolutePath();
          getContext().info( message );
  
          final Execute exe = buildCommand( jarTarget, jarSource );
          exe.execute( getContext() );
      }
  
      private Execute buildCommand( final File jarTarget,
                                    final File jarSource )
      {
          final Execute cmd = new Execute();
          cmd.setExecutable( "jarsigner" );
  
          if( null != m_keystore )
          {
              cmd.addArgument( "-keystore" );
              cmd.addArgument( m_keystore );
          }
  
          if( null != m_storepass )
          {
              cmd.addArgument( "-storepass" );
              cmd.addArgument( m_storepass );
          }
  
          if( null != m_storetype )
          {
              cmd.addArgument( "-storetype" );
              cmd.addArgument( m_storetype );
          }
  
          if( null != m_keypass )
          {
              cmd.addArgument( "-keypass" );
              cmd.addArgument( m_keypass );
          }
  
          if( null != m_sigfile )
          {
              cmd.addArgument( "-sigfile" );
              cmd.addArgument( m_sigfile );
          }
  
          if( null != jarTarget )
          {
              cmd.addArgument( "-signedjar" );
              cmd.addArgument( jarTarget );
          }
  
          if( m_verbose )
          {
              cmd.addArgument( "-verbose" );
          }
  
          if( m_internalsf )
          {
              cmd.addArgument( "-internalsf" );
          }
  
          if( m_sectionsonly )
          {
              cmd.addArgument( "-sectionsonly" );
          }
  
          cmd.addArgument( jarSource );
  
          cmd.addArgument( m_alias );
  
          return cmd;
      }
  }
  
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/selftest/ExtensionsTest.java
  
  Index: ExtensionsTest.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.antlib.selftest;
  
  import org.apache.antlib.selftest.extension1.ExtensionsLoadedClass;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * This is to test whether extension is loaded.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @ant.task name="extensions-test"
   */
  public class ExtensionsTest
      extends AbstractTask
  {
      public void execute()
          throws TaskException
      {
          ExtensionsLoadedClass.doSomething();
  
          Class clazz = null;
          try
          {
              clazz = Class.forName( "sun.tools.javac.Main" );
          }
          catch( ClassNotFoundException e )
          {
              try
              {
                  clazz = Class.forName( "com.sun.tools.javac.Main" );
              }
              catch( ClassNotFoundException e1 )
              {
                  throw new TaskException( "Unable to locate compilers from tools.jar" );
              }
          }
  
          System.out.println( "Compiler loaded from tools.jar = " + clazz );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/selftest/PrimitiveTypesTest.java
  
  Index: PrimitiveTypesTest.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.antlib.selftest;
  
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * Test conversion of all the primitive types.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @ant.task name="prim-test"
   */
  public class PrimitiveTypesTest
      extends AbstractTask
  {
      public void setInteger( final Integer value )
      {
          getContext().info( "setInteger( " + value + " );" );
      }
  
      public void setInteger2( final int value )
      {
          getContext().info( "setInteger2( " + value + " );" );
      }
  
      public void setShort( final Short value )
      {
          getContext().info( "setShort( " + value + " );" );
      }
  
      public void setShort2( final short value )
      {
          getContext().info( "setShort2( " + value + " );" );
      }
  
      public void setByte( final Byte value )
      {
          getContext().info( "setByte( " + value + " );" );
      }
  
      public void setByte2( final byte value )
      {
          getContext().info( "setByte2( " + value + " );" );
      }
  
      public void setLong( final Long value )
      {
          getContext().info( "setLong( " + value + " );" );
      }
  
      public void setLong2( final long value )
      {
          getContext().info( "setLong2( " + value + " );" );
      }
  
      public void setFloat( final Float value )
      {
          getContext().info( "setFloat( " + value + " );" );
      }
  
      public void setFloat2( final float value )
      {
          getContext().info( "setFloat2( " + value + " );" );
      }
  
      public void setDouble( final Double value )
      {
          getContext().info( "setDouble( " + value + " );" );
      }
  
      public void setDouble2( final double value )
      {
          getContext().info( "setDouble2( " + value + " );" );
      }
  
      public void setString( final String value )
      {
          getContext().info( "setString( " + value + " );" );
      }
  
      public void execute()
          throws TaskException
      {
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/selftest/extension1/ExtensionsLoadedClass.java
  
  Index: ExtensionsLoadedClass.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.antlib.selftest.extension1;
  
  /**
   * This is to test whether extension is loaded.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   */
  public class ExtensionsLoadedClass
  {
      public static void doSomething()
      {
          System.out.println( "This was loaded via an extension - yea!" );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/sound/AntSoundPlayer.java
  
  Index: AntSoundPlayer.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.antlib.sound;
  
  import java.io.File;
  import java.io.IOException;
  import javax.sound.sampled.AudioFormat;
  import javax.sound.sampled.AudioInputStream;
  import javax.sound.sampled.AudioSystem;
  import javax.sound.sampled.Clip;
  import javax.sound.sampled.DataLine;
  import javax.sound.sampled.Line;
  import javax.sound.sampled.LineEvent;
  import javax.sound.sampled.LineListener;
  import javax.sound.sampled.LineUnavailableException;
  import javax.sound.sampled.UnsupportedAudioFileException;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.myrmidon.listeners.AbstractProjectListener;
  import org.apache.myrmidon.listeners.LogEvent;
  import org.apache.myrmidon.listeners.ProjectEvent;
  
  /**
   * This class is designed to be used by any AntTask that requires audio output.
   * It implements the BuildListener interface to listen for BuildEvents and could
   * be easily extended to provide audio output upon any specific build events
   * occuring. I have only tested this with .WAV and .AIFF sound file formats.
   * Both seem to work fine.
   *
   * @author Nick Pellow
   * @version $Revision: 1.1 $, $Date: 2002/04/14 10:56:38 $
   */
  public class AntSoundPlayer
      extends AbstractProjectListener
      implements LineListener, LogEnabled
  {
      private File m_fileSuccess;
      private int m_loopsSuccess;
      private Long m_durationSuccess;
  
      private File m_fileFail;
      private int m_loopsFail;
      private Long m_durationFail;
  
      private Logger m_logger;
  
      /**
       * Provide component with a logger.
       *
       * @param logger the logger
       */
      public void enableLogging( final Logger logger )
      {
          m_logger = logger;
      }
  
      protected final Logger getLogger()
      {
          return m_logger;
      }
  
      /**
       * Notify listener of projectFinished event.
       */
      public void projectFinished( final ProjectEvent event )
      {
          success();
      }
  
      /**
       * Notify listener of log message event.
       */
      public void log( final LogEvent event )
      {
          if( event.getThrowable() != null )
          {
              failure();
          }
      }
  
      /**
       * @param fileFail The feature to be added to the BuildFailedSound attribute
       * @param loopsFail The feature to be added to the BuildFailedSound
       *      attribute
       * @param durationFail The feature to be added to the BuildFailedSound
       *      attribute
       */
      public void addBuildFailedSound( File fileFail, int loopsFail, Long durationFail )
      {
          m_fileFail = fileFail;
          m_loopsFail = loopsFail;
          m_durationFail = durationFail;
      }
  
      /**
       * @param loops the number of times the file should be played when the build
       *      is successful
       * @param duration the number of milliseconds the file should be played when
       *      the build is successful
       * @param file The feature to be added to the BuildSuccessfulSound attribute
       */
      public void addBuildSuccessfulSound( File file, int loops, Long duration )
      {
          m_fileSuccess = file;
          m_loopsSuccess = loops;
          m_durationSuccess = duration;
      }
  
      /**
       * This is implemented to listen for any line events and closes the clip if
       * required.
       */
      public void update( LineEvent event )
      {
          if( event.getType().equals( LineEvent.Type.STOP ) )
          {
              Line line = event.getLine();
              line.close();
          }
          else if( event.getType().equals( LineEvent.Type.CLOSE ) )
          {
              /*
               * There is a bug in JavaSound 0.90 (jdk1.3beta).
               * It prevents correct termination of the VM.
               * So we have to exit ourselves.
               */
              //System.exit(0);
          }
      }
  
      protected void success()
      {
          if( null != m_fileSuccess )
          {
              // build successfull!
              play( m_fileSuccess, m_loopsSuccess, m_durationSuccess );
          }
      }
  
      protected void failure()
      {
          if( null != m_fileFail )
          {
              play( m_fileFail, m_loopsFail, m_durationFail );
          }
      }
  
      /**
       * Plays the file for duration milliseconds or loops.
       */
      private void play( File file, int loops, Long duration )
      {
          Clip audioClip = null;
  
          AudioInputStream audioInputStream = null;
  
          try
          {
              audioInputStream = AudioSystem.getAudioInputStream( file );
          }
          catch( UnsupportedAudioFileException uafe )
          {
              final String message = "Audio format is not yet supported: " + uafe.getMessage();
              getLogger().info( message );
          }
          catch( IOException ioe )
          {
              ioe.printStackTrace();
          }
  
          if( audioInputStream != null )
          {
              AudioFormat format = audioInputStream.getFormat();
              DataLine.Info info = new DataLine.Info( Clip.class, format,
                                                      AudioSystem.NOT_SPECIFIED );
              try
              {
                  audioClip = (Clip)AudioSystem.getLine( info );
                  audioClip.addLineListener( this );
                  audioClip.open( audioInputStream );
              }
              catch( LineUnavailableException e )
              {
                  final String message = "The sound device is currently unavailable";
                  getLogger().info( message );
                  return;
              }
              catch( IOException e )
              {
                  e.printStackTrace();
              }
  
              if( duration != null )
              {
                  playClip( audioClip, duration.longValue() );
              }
              else
              {
                  playClip( audioClip, loops );
              }
              audioClip.drain();
              audioClip.close();
          }
          else
          {
              final String message = "Can't get data from file " + file.getName();
              getLogger().info( message );
          }
      }
  
      private void playClip( Clip clip, int loops )
      {
  
          clip.loop( loops );
          while( clip.isRunning() )
          {
          }
      }
  
      private void playClip( Clip clip, long duration )
      {
          clip.loop( Clip.LOOP_CONTINUOUSLY );
          try
          {
              Thread.sleep( duration );
          }
          catch( InterruptedException e )
          {
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/sound/BuildAlert.java
  
  Index: BuildAlert.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.antlib.sound;
  
  import java.io.File;
  
  /**
   * A class to be extended by any BuildAlert's that require the output of
   * sound.
   */
  public class BuildAlert
  {
      private File m_source;
      private int m_loops;
      private Long m_duration;
  
      /**
       * Sets the duration in milliseconds the file should be played.
       *
       * @param duration The new Duration value
       */
      public void setDuration( Long duration )
      {
          m_duration = duration;
      }
  
      /**
       * Sets the number of times the source file should be played.
       *
       * @param loops the number of loops to play the source file
       */
      public void setLoops( int loops )
      {
          m_loops = loops;
      }
  
      /**
       * Sets the location of the file to get the audio.
       *
       * @param source the name of a sound-file directory or of the audio file
       */
      public void setSource( final File source )
      {
          m_source = source;
      }
  
      /**
       * Gets the duration in milliseconds the file should be played.
       *
       * @return The Duration value
       */
      public Long getDuration()
      {
          return m_duration;
      }
  
      /**
       * Sets the number of times the source file should be played.
       *
       * @return the number of loops to play the source file
       */
      public int getLoops()
      {
          return m_loops;
      }
  
      /**
       * Gets the location of the file to get the audio.
       *
       * @return The Source value
       */
      public File getSource()
      {
          return m_source;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/sound/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  sound.missing-success.error=No nested success element found.
  sound.missing-failure.error=No nested failure element found.
  sound.empty.dir.error=No files found in directory {0}.
  sound.invalid-path.error={0}: invalid path.
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/sound/SoundTask.java
  
  Index: SoundTask.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.antlib.sound;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Random;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.interfaces.workspace.Workspace;
  
  /**
   * This is an example of an AntTask that makes of use of the AntSoundPlayer.
   * There are three attributes to be set: <code>source</code>: the location of
   * the audio file to be played <code>duration</code>: play the sound file
   * continuously until "duration" milliseconds has expired <code>loops</code>:
   * the number of times the sound file should be played until stopped I have only
   * tested this with .WAV and .AIFF sound file formats. Both seem to work fine.
   * plans for the future: - use the midi api to define sounds (or drum beat etc)
   * in xml and have Ant play them back
   *
   * @ant.task name="sound-listener"
   * @author Nick Pellow
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $, $Date: 2002/04/14 10:56:38 $
   */
  public class SoundTask
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( SoundTask.class );
  
      private BuildAlert m_success;
      private BuildAlert m_fail;
  
      public void addFail( final BuildAlert fail )
      {
          m_fail = fail;
      }
  
      public void addSuccess( final BuildAlert success )
      {
          m_success = success;
      }
  
      public void execute()
          throws TaskException
      {
          final AntSoundPlayer soundPlayer = new AntSoundPlayer();
          if( null == m_success )
          {
              final String message = REZ.getString( "sound.missing-success.error" );
              getContext().warn( message );
          }
          else
          {
              final File source = getRandomSource( m_success );
              soundPlayer.addBuildSuccessfulSound( source,
                                                   m_success.getLoops(),
                                                   m_success.getDuration() );
          }
  
          if( null == m_fail )
          {
              final String message = REZ.getString( "sound.missing-failure.error" );
              getContext().warn( message );
          }
          else
          {
              final File source = getRandomSource( m_fail );
              soundPlayer.addBuildFailedSound( source,
                                               m_fail.getLoops(),
                                               m_fail.getDuration() );
          }
  
          final Workspace workspace = (Workspace)getContext().getService( Workspace.class );
          workspace.addProjectListener( soundPlayer );
      }
  
      /**
       * Gets the location of the file to get the audio.
       */
      private File getRandomSource( final BuildAlert alert )
          throws TaskException
      {
          final File source = alert.getSource();
          // Check if source is a directory
          if( source.exists() )
          {
              if( source.isDirectory() )
              {
                  // get the list of files in the dir
                  final String[] entries = source.list();
                  final ArrayList files = new ArrayList();
                  for( int i = 0; i < entries.length; i++ )
                  {
                      final File file = new File( source, entries[ i ] );
                      if( file.isFile() )
                      {
                          files.add( file );
                      }
                  }
                  if( files.size() < 1 )
                  {
                      final String message = REZ.getString( "sound.empty.dir.error", source );
                      throw new TaskException( message );
                  }
                  final int numfiles = files.size();
                  // get a random number between 0 and the number of files
                  final Random random = new Random();
                  final int x = random.nextInt( numfiles );
                  // set the source to the file at that location
                  return (File)files.get( x );
              }
              else
              {
                  return null;
              }
          }
          else
          {
              final String message = REZ.getString( "sound.invalid-path.error", source );
              getContext().warn( message );
              return null;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/DTDLocation.java
  
  Index: DTDLocation.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.antlib.xml;
  
  public class DTDLocation
  {
      private String m_publicId;
      private String m_location;
  
      public void setLocation( final String location )
      {
          m_location = location;
      }
  
      public void setPublicId( final String publicId )
      {
          m_publicId = publicId;
      }
  
      public String getLocation()
      {
          return m_location;
      }
  
      public String getPublicId()
      {
          return m_publicId;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/LocalResolver.java
  
  Index: LocalResolver.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.antlib.xml;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.Hashtable;
  import org.apache.myrmidon.api.TaskContext;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  class LocalResolver
      implements EntityResolver
  {
      private final Hashtable m_fileDTDs = new Hashtable();
      private final Hashtable m_resourceDTDs = new Hashtable();
      private final Hashtable m_urlDTDs = new Hashtable();
      private final TaskContext m_context;
  
      public LocalResolver( final TaskContext context )
      {
          m_context = context;
      }
  
      public void registerDTD( String publicId, String location )
      {
          if( location == null )
          {
              return;
          }
  
          File fileDTD = new File( location );
          if( fileDTD.exists() )
          {
              if( publicId != null )
              {
                  m_fileDTDs.put( publicId, fileDTD );
                  final String message = "Mapped publicId " + publicId + " to file " + fileDTD;
                  m_context.debug( message );
              }
              return;
          }
  
          if( getClass().getResource( location ) != null )
          {
              if( publicId != null )
              {
                  m_resourceDTDs.put( publicId, location );
                  final String message = "Mapped publicId " + publicId +
                      " to resource " + location;
                  m_context.debug( message );
              }
          }
  
          try
          {
              if( publicId != null )
              {
                  URL urldtd = new URL( location );
                  m_urlDTDs.put( publicId, urldtd );
              }
          }
          catch( MalformedURLException e )
          {
              //ignored
          }
      }
  
      public void registerDTD( DTDLocation location )
      {
          registerDTD( location.getPublicId(), location.getLocation() );
      }
  
      public InputSource resolveEntity( String publicId, String systemId )
          throws SAXException
      {
          File dtdFile = (File)m_fileDTDs.get( publicId );
          if( dtdFile != null )
          {
              try
              {
                  final String message = "Resolved " + publicId + " to local file " + dtdFile;
                  m_context.debug( message );
                  return new InputSource( new FileInputStream( dtdFile ) );
              }
              catch( FileNotFoundException ex )
              {
                  // ignore
              }
          }
  
          String dtdResourceName = (String)m_resourceDTDs.get( publicId );
          if( dtdResourceName != null )
          {
              InputStream is = getClass().getResourceAsStream( dtdResourceName );
              if( is != null )
              {
                  m_context.debug( "Resolved " + publicId + " to local resource " + dtdResourceName );
                  return new InputSource( is );
              }
          }
  
          URL dtdUrl = (URL)m_urlDTDs.get( publicId );
          if( dtdUrl != null )
          {
              try
              {
                  InputStream is = dtdUrl.openStream();
                  final String message = "Resolved " + publicId + " to url " + dtdUrl;
                  m_context.debug( message );
                  return new InputSource( is );
              }
              catch( IOException ioe )
              {
                  //ignore
              }
          }
  
          final String message = "Could not resolve ( publicId: " + publicId +
              ", systemId: " + systemId + ") to a local entity";
          m_context.info( message );
  
          return null;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/TraxErrorListener.java
  
  Index: TraxErrorListener.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.antlib.xml;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  import javax.xml.transform.ErrorListener;
  import javax.xml.transform.SourceLocator;
  import javax.xml.transform.TransformerException;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  final class TraxErrorListener
      extends AbstractLogEnabled
      implements ErrorListener
  {
      private final boolean m_warn;
      private boolean m_failed;
  
      protected TraxErrorListener( final boolean warn )
      {
          m_warn = warn;
      }
  
      public void error( final TransformerException te )
      {
          m_failed = true;
          getLogger().error( getMessage( te ), te );
      }
  
      public void fatalError( final TransformerException te )
      {
          m_failed = true;
          getLogger().error( getMessage( te ), te );
      }
  
      public void warning( final TransformerException te )
      {
          // depending on implementation, XMLReader can yield hips of warning,
          // only output then if user explicitely asked for it
          if( m_warn )
          {
              getLogger().warn( getMessage( te ), te );
          }
      }
  
      protected void reset()
      {
          m_failed = false;
      }
  
      // did an error happen during last parsing ?
      protected boolean getFailure()
      {
          return m_failed;
      }
  
      private String getMessage( final TransformerException te )
      {
          final SourceLocator locator = te.getLocator();
          final String systemID = locator.getSystemId();
          if( null != systemID )
          {
              final int line = locator.getLineNumber();
              final int column = locator.getColumnNumber();
  
              try
              {
                  //Build a message using standard compiler
                  //error format
                  return new URL( systemID ).getFile() +
                      ( line == -1 ? "" : ( ":" + line +
                      ( column == -1 ? "" : ( ":" + column ) ) ) ) +
                      ": " + te.getMessage();
              }
              catch( final MalformedURLException mue )
              {
              }
          }
          return te.getMessage();
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/ValidatorErrorHandler.java
  
  Index: ValidatorErrorHandler.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.antlib.xml;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  import org.apache.myrmidon.api.TaskContext;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.SAXParseException;
  
  /*
   * ValidatorErrorHandler role :
   * <ul>
   * <li> log SAX parse exceptions,
   * <li> remember if an error occured
   * </ul>
   */
  final class ValidatorErrorHandler
      implements ErrorHandler
  {
      private final boolean m_warn;
      private final TaskContext m_context;
      private boolean m_failed;
  
      protected ValidatorErrorHandler( final boolean warn, final TaskContext context )
      {
          m_warn = warn;
          m_context = context;
      }
  
      public void error( final SAXParseException spe )
      {
          m_failed = true;
          m_context.error( getMessage( spe ), spe );
      }
  
      public void fatalError( final SAXParseException spe )
      {
          m_failed = true;
          m_context.error( getMessage( spe ), spe );
      }
  
      public void warning( final SAXParseException spe )
      {
          // depending on implementation, XMLReader can yield hips of warning,
          // only output then if user explicitely asked for it
          if( m_warn )
          {
              m_context.warn( getMessage( spe ), spe );
          }
      }
  
      protected void reset()
      {
          m_failed = false;
      }
  
      // did an error happen during last parsing ?
      protected boolean getFailure()
      {
          return m_failed;
      }
  
      private String getMessage( final SAXParseException spe )
      {
          final String systemID = spe.getSystemId();
          if( null != systemID )
          {
              final int line = spe.getLineNumber();
              final int col = spe.getColumnNumber();
  
              try
              {
                  //Build a message using standard compiler
                  //error format
                  return new URL( systemID ).getFile() +
                      ( line == -1 ? "" : ( ":" + line +
                      ( col == -1 ? "" : ( ":" + col ) ) ) ) +
                      ": " + spe.getMessage();
              }
              catch( final MalformedURLException mue )
              {
              }
          }
          return spe.getMessage();
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/XMLValidateTask.java
  
  Index: XMLValidateTask.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.antlib.xml;
  
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.file.Path;
  import org.apache.myrmidon.framework.file.FileListUtil;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.Parser;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXNotRecognizedException;
  import org.xml.sax.SAXNotSupportedException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.helpers.ParserAdapter;
  
  /**
   * The <code>XMLValidateTask</code> checks that an XML document is valid, with a
   * SAX validating parser.
   *
   * @author Raphael Pierquin <a href="mailto:raphael.pierquin@agisphere.com">
   *      raphael.pierquin@agisphere.com</a>
   */
  public class XMLValidateTask
      extends AbstractTask
  {
      /**
       * The default implementation parser classname used by the task to process
       * validation.
       */
      // The crimson implementation is shipped with ant.
      public static String DEFAULT_XML_READER_CLASSNAME = "org.apache.crimson.parser.XMLReaderImpl";
  
      private static String INIT_FAILED_MSG = "Could not start xml validation: ";
  
      // ant task properties
      // defaults
      private boolean m_warn = true;
      private boolean m_lenient;
      private String m_readerClassName = DEFAULT_XML_READER_CLASSNAME;
      private File m_file;// file to be validated
      private ArrayList m_filesets = new ArrayList();
  
      /**
       * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified,
       * it's wrapped in an adapter that make it behave as a XMLReader. a more
       * 'standard' way of doing this would be to use the JAXP1.1 SAXParser
       * interface.
       */
      private XMLReader m_xmlReader;// XMLReader used to validation process
  
      /**
       * to report sax parsing errors
       */
      private ValidatorErrorHandler m_errorHandler;
      private Hashtable m_features = new Hashtable();
  
      /**
       * The list of configured DTD locations
       */
      private ArrayList m_dtdLocations = new ArrayList();// sets of file to be validated
      private Path m_classpath = new Path();
  
      /**
       * Specify the class name of the SAX parser to be used. (optional)
       *
       * @param className should be an implementation of SAX2 <code>org.xml.sax.XMLReader</code>
       *      or SAX2 <code>org.xml.sax.Parser</code>. <p>
       *
       *      if className is an implementation of <code>org.xml.sax.Parser</code>
       *      , {@link #setLenient(boolean)}, will be ignored. <p>
       *
       *      if not set, the default {@link #DEFAULT_XML_READER_CLASSNAME} will
       *      be used.
       * @see org.xml.sax.XMLReader
       * @see org.xml.sax.Parser
       */
      public void setClassName( final String className )
      {
          m_readerClassName = className;
      }
  
      /**
       * Specify the classpath to be searched to load the parser (optional)
       */
      public void setClasspath( final String classpath )
          throws TaskException
      {
          m_classpath.add( classpath );
      }
  
      /**
       * specifify the file to be checked
       *
       * @param file The new File value
       */
      public void setFile( File file )
      {
          m_file = file;
      }
  
      /**
       * Specify whether the parser should be validating. Default is <code>true</code>
       * . <p>
       *
       * If set to false, the validation will fail only if the parsed document is
       * not well formed XML. <p>
       *
       * this option is ignored if the specified class with {@link
       * #setClassName(String)} is not a SAX2 XMLReader.
       */
      public void setLenient( final boolean bool )
      {
          m_lenient = bool;
      }
  
      /**
       * Specify how parser error are to be handled. <p>
       *
       * If set to <code>true
       *</true>
       *(default), log a warn message for each SAX warn event.
       */
      public void setWarn( final boolean warn )
      {
          m_warn = warn;
      }
  
      /**
       * specifify a set of file to be checked
       */
      public void addFileset( final FileSet fileSet )
      {
          m_filesets.add( fileSet );
      }
  
      /**
       * @see #setClasspath
       */
      public void addClasspath( final Path path )
          throws TaskException
      {
          m_classpath.add( path );
      }
  
      /**
       * Create a DTD location record. This stores the location of a DTD. The DTD
       * is identified by its public Id. The location may either be a file
       * location or a resource location.
       *
       * @return Description of the Returned Value
       */
      public DTDLocation createDTD()
      {
          final DTDLocation dtdLocation = new DTDLocation();
          m_dtdLocations.add( dtdLocation );
          return dtdLocation;
      }
  
      public void execute()
          throws TaskException
      {
          int fileProcessed = 0;
          final int size = m_filesets.size();
          if( m_file == null && ( size == 0 ) )
          {
              final String message = "Specify at least one source - a file or a fileset.";
              throw new TaskException( message );
          }
  
          initValidator();
  
          if( m_file != null )
          {
              if( m_file.exists() && m_file.canRead() && m_file.isFile() )
              {
                  doValidate( m_file );
                  fileProcessed++;
              }
              else
              {
                  final String message = "File " + m_file + " cannot be read";
                  throw new TaskException( message );
              }
          }
  
          for( int i = 0; i < size; i++ )
          {
              final FileSet fileSet = (FileSet)m_filesets.get( i );
              final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
              final String[] files = scanner.getIncludedFiles();
  
              for( int j = 0; j < files.length; j++ )
              {
                  final File srcFile = new File( fileSet.getDir(), files[ j ] );
                  doValidate( srcFile );
                  fileProcessed++;
              }
          }
          final String message = fileProcessed + " file(s) have been successfully validated.";
          getContext().info( message );
      }
  
      private EntityResolver buildEntityResolver()
      {
          final LocalResolver resolver = new LocalResolver( getContext() );
  
          final int size = m_dtdLocations.size();
          for( int i = 0; i < size; i++ )
          {
              final DTDLocation location = (DTDLocation)m_dtdLocations.get( i );
              resolver.registerDTD( location );
          }
  
          return resolver;
      }
  
      /*
       * set a feature on the parser.
       * TODO: find a way to set any feature from build.xml
       */
      private boolean setFeature( final String feature,
                                  final boolean value,
                                  final boolean warn )
      {
          boolean toReturn = false;
          try
          {
              m_xmlReader.setFeature( feature, value );
              toReturn = true;
          }
          catch( SAXNotRecognizedException e )
          {
              final String message = "Could not set feature '" + feature + "' because the parser doesn't recognize it";
              if( warn )
              {
                  getContext().warn( message );
              }
          }
          catch( SAXNotSupportedException e )
          {
              final String message = "Could not set feature '" + feature + "' because the parser doesn't support it";
              if( warn )
              {
                  getContext().warn( message );
              }
          }
          return toReturn;
      }
  
      /*
       * parse the file
       */
      private void doValidate( File afile )
          throws TaskException
      {
          try
          {
              getContext().debug( "Validating " + afile.getName() + "... " );
              m_errorHandler.reset();
              InputSource is = new InputSource( new FileReader( afile ) );
              String uri = "file:" + afile.getAbsolutePath().replace( '\\', '/' );
              for( int index = uri.indexOf( '#' ); index != -1;
                   index = uri.indexOf( '#' ) )
              {
                  uri = uri.substring( 0, index ) + "%23" + uri.substring( index + 1 );
              }
              is.setSystemId( uri );
              m_xmlReader.parse( is );
          }
          catch( SAXException ex )
          {
              final String message = "Could not validate document " + afile;
              throw new TaskException( message );
          }
          catch( IOException ex )
          {
              final String message = "Could not validate document " + afile;
              throw new TaskException( message, ex );
          }
  
          if( m_errorHandler.getFailure() )
          {
              final String message = afile + " is not a valid XML document.";
              throw new TaskException( message );
          }
      }
  
      /**
       * init the parser : load the parser class, and set features if necessary
       */
      private void initValidator()
          throws TaskException
      {
          try
          {
              // load the parser class
              // with JAXP, we would use a SAXParser factory
              final ClassLoader classLoader = FileListUtil.createClassLoader( m_classpath, getContext() );
              final Class readerClass = classLoader.loadClass( m_readerClassName );
  
              // then check it implements XMLReader
              if( XMLReader.class.isAssignableFrom( readerClass ) )
              {
  
                  m_xmlReader = (XMLReader)readerClass.newInstance();
                  getContext().debug( "Using SAX2 reader " + m_readerClassName );
              }
              else
              {
  
                  // see if it is a SAX1 Parser
                  if( Parser.class.isAssignableFrom( readerClass ) )
                  {
                      Parser parser = (Parser)readerClass.newInstance();
                      m_xmlReader = new ParserAdapter( parser );
                      getContext().debug( "Using SAX1 parser " + m_readerClassName );
                  }
                  else
                  {
                      throw new TaskException( INIT_FAILED_MSG
                                               + m_readerClassName
                                               + " implements nor SAX1 Parser nor SAX2 XMLReader." );
                  }
              }
          }
          catch( ClassNotFoundException e )
          {
              throw new TaskException( INIT_FAILED_MSG + m_readerClassName, e );
          }
          catch( InstantiationException e )
          {
              throw new TaskException( INIT_FAILED_MSG + m_readerClassName, e );
          }
          catch( IllegalAccessException e )
          {
              throw new TaskException( INIT_FAILED_MSG + m_readerClassName, e );
          }
  
          m_xmlReader.setEntityResolver( buildEntityResolver() );
  
          m_errorHandler = new ValidatorErrorHandler( m_warn, getContext() );
          m_xmlReader.setErrorHandler( m_errorHandler );
  
          if( !( m_xmlReader instanceof ParserAdapter ) )
          {
              // turn validation on
              if( !m_lenient )
              {
                  boolean ok = setFeature( "http://xml.org/sax/features/validation", true, true );
                  if( !ok )
                  {
                      throw new TaskException( INIT_FAILED_MSG
                                               + m_readerClassName
                                               + " doesn't provide validation" );
                  }
              }
              // set other features
              Enumeration enum = m_features.keys();
              while( enum.hasMoreElements() )
              {
                  String featureId = (String)enum.nextElement();
                  setFeature( featureId, ( (Boolean)m_features.get( featureId ) ).booleanValue(), true );
              }
          }
      }
  
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/XSLTParam.java
  
  Index: XSLTParam.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.antlib.xml;
  
  public final class XSLTParam
  {
      private String m_name;
      private String m_expression;
  
      public void setExpression( String expression )
      {
          m_expression = expression;
      }
  
      public void setName( String name )
      {
          m_name = name;
      }
  
      protected String getExpression()
      {
          return m_expression;
      }
  
      protected String getName()
      {
          return m_name;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/xml/XSLTProcess.java
  
  Index: XSLTProcess.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.antlib.xml;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Iterator;
  import javax.xml.transform.Templates;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.stream.StreamSource;
  import org.apache.avalon.excalibur.io.FileUtil;
  import org.apache.avalon.excalibur.io.IOUtil;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.AbstractMatchingTask;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.myrmidon.framework.file.Path;
  import org.apache.tools.todo.types.ScannerUtil;
  
  /**
   * A Task to process via XSLT a set of XML documents. This is useful for
   * building views of XML based documentation. arguments:
   * <ul>
   *   <li> basedir
   *   <li> destdir
   *   <li> style
   *   <li> includes
   *   <li> excludes
   * </ul>
   * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. <p>
   *
   * This task will recursively scan the sourcedir and destdir looking for XML
   * documents to process via XSLT. Any other files, such as images, or html files
   * in the source directory will be copied into the destination directory.
   *
   * @author <a href="mailto:kvisco@exoffice.com">Keith Visco</a>
   * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
   * @author <a href="mailto:russgold@acm.org">Russell Gold</a>
   * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
   */
  public class XSLTProcess
      extends AbstractMatchingTask
  {
      private File m_destdir;
      private File m_basedir;
      private String m_targetExtension = ".html";
      private ArrayList m_params = new ArrayList();
      private File m_in;
      private File m_out;
      private Path m_classpath;
      private boolean m_force;
      private File m_stylesheet;
  
      private boolean m_processorPrepared;
      private TransformerFactory m_transformerFactory;
      private Transformer m_transformer;
  
      /**
       * Set the base directory.
       */
      public void setBasedir( final File basedir )
      {
          m_basedir = basedir;
      }
  
      /**
       * Set the classpath to load the Processor through (attribute).
       */
      public void setClasspath( final Path classpath )
          throws TaskException
      {
          addClasspath( classpath );
      }
  
      /**
       * Set the destination directory into which the XSL result files should be
       * copied to
       */
      public void setDestdir( final File destdir )
      {
          m_destdir = destdir;
      }
  
      /**
       * Set the desired file extension to be used for the target
       */
      public void setExtension( final String targetExtension )
      {
          m_targetExtension = targetExtension;
      }
  
      /**
       * Set whether to check dependencies, or always generate.
       */
      public void setForce( final boolean force )
      {
          m_force = force;
      }
  
      /**
       * Sets an input xml file to be styled
       */
      public void setIn( final File in )
      {
          m_in = in;
      }
  
      /**
       * Sets an out file
       */
      public void setOut( final File out )
      {
          m_out = out;
      }
  
      /**
       * Sets the file to use for styling relative to the base directory of this
       * task.
       */
      public void setStyle( final File stylesheet )
      {
          m_stylesheet = stylesheet;
      }
  
      /**
       * Set the classpath to load the Processor through (nested element).
       */
      public void addClasspath( final Path path )
          throws TaskException
      {
          if( m_classpath == null )
          {
              m_classpath = new Path();
          }
          m_classpath.add( path );
      }
  
      public void addParam( final XSLTParam param )
      {
          m_params.add( param );
      }
  
      public void execute()
          throws TaskException
      {
          validate();
  
          final FileSet fileSet = getFileSet();
          fileSet.setDir( m_basedir );
          final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
  
          prepareProcessor();
  
          // if we have an in file and out then process them
          if( m_in != null && m_out != null )
          {
              processSingleFile( m_in, m_out );
              return;
          }
  
          final String message = "Transforming into " + m_destdir;
          getContext().info( message );
  
          // Process all the files marked for styling
          processFiles( scanner );
  
          // Process all the directoried marked for styling
          processDirs( scanner );
      }
  
      private void validate()
          throws TaskException
      {
          if( null == m_stylesheet )
          {
              final String message = "no stylesheet specified";
              throw new TaskException( message );
          }
  
          if( null == m_basedir )
          {
              m_basedir = getBaseDirectory();
          }
  
          //-- make sure Source directory exists...
          if( null == m_destdir )
          {
              final String message = "destdir attributes must be set!";
              throw new TaskException( message );
          }
      }
  
      private void processDirs( final DirectoryScanner scanner )
          throws TaskException
      {
          final String[] dirs = scanner.getIncludedDirectories();
          for( int i = 0; i < dirs.length; i++ )
          {
              final String[] list = new File( m_basedir, dirs[ i ] ).list();
              for( int j = 0; j < list.length; j++ )
              {
                  process( m_basedir, list[ j ], m_destdir );
              }
          }
      }
  
      private void processFiles( final DirectoryScanner scanner )
          throws TaskException
      {
          final String[] list = scanner.getIncludedFiles();
          for( int i = 0; i < list.length; ++i )
          {
              process( m_basedir, list[ i ], m_destdir );
          }
      }
  
      /**
       * Create transformer factory, loads the stylesheet and set xsl:param parameters.
       */
      protected void prepareProcessor()
          throws TaskException
      {
          if( m_processorPrepared )
          {
              return;
          }
          m_processorPrepared = true;
  
          //Note the next line should use the specified Classpath
          //and load the class dynaically
          m_transformerFactory = TransformerFactory.newInstance();
          m_transformerFactory.setErrorListener( new TraxErrorListener( true ) );
          //m_transformer.setOutputProperty( OutputKeys.METHOD, m_type );
  
          try
          {
              getContext().info( "Loading stylesheet " + m_stylesheet );
              specifyStylesheet();
              specifyParams();
          }
          catch( final Exception e )
          {
              final String message = "Failed to read stylesheet " + m_stylesheet;
              throw new TaskException( e.getMessage(), e );
          }
      }
  
      private void specifyStylesheet()
          throws Exception
      {
          final FileInputStream xslStream = new FileInputStream( m_stylesheet );
          try
          {
              final StreamSource source = new StreamSource( xslStream );
              source.setSystemId( getSystemId( m_stylesheet ) );
              final Templates template = m_transformerFactory.newTemplates( source );
              m_transformer = template.newTransformer();
              m_transformer.setErrorListener( new TraxErrorListener( true ) );
          }
          finally
          {
              IOUtil.shutdownStream( xslStream );
          }
      }
  
      private void specifyParams() throws TaskException
      {
          final Iterator params = m_params.iterator();
          while( params.hasNext() )
          {
              final XSLTParam param = (XSLTParam)params.next();
  
              final String expression = param.getExpression();
              if( expression == null )
              {
                  throw new TaskException( "Expression attribute is missing." );
              }
  
              final String name = param.getName();
              if( name == null )
              {
                  throw new TaskException( "Name attribute is missing." );
              }
  
              m_transformer.setParameter( name, expression );
          }
      }
  
      /**
       * Processes the given input XML file and stores the result in the given
       * resultFile.
       */
      private void process( final File baseDir, final String xmlFile, final File destDir )
          throws TaskException
      {
          final String filename = FileUtil.removeExtension( xmlFile );
  
          final File in = new File( baseDir, xmlFile );
          final File out = new File( destDir, filename + m_targetExtension );
  
          processFile( in, out );
      }
  
      private void processFile( final File in, final File out )
          throws TaskException
      {
          final long styleSheetLastModified = m_stylesheet.lastModified();
          try
          {
              if( m_force ||
                  in.lastModified() > out.lastModified() ||
                  styleSheetLastModified > out.lastModified() )
              {
                  ensureDirectoryFor( out );
  
                  final String notice = "Processing " + in + " to " + out;
                  getContext().info( notice );
                  transform( in, out );
              }
          }
          catch( final Exception e )
          {
              // If failed to process document, must delete target document,
              // or it will not attempt to process it the second time
              final String message = "Failed to process " + in;
              getContext().info( message );
              if( out != null )
              {
                  out.delete();
              }
  
              throw new TaskException( e.getMessage(), e );
          }
      }
  
      private void processSingleFile( final File in, final File out )
          throws TaskException
      {
          final long styleSheetLastModified = m_stylesheet.lastModified();
          getContext().debug( "In file " + in + " time: " + in.lastModified() );
          getContext().debug( "Out file " + out + " time: " + out.lastModified() );
          getContext().debug( "Style file " + m_stylesheet + " time: " + styleSheetLastModified );
  
          processFile( in, out );
      }
  
      private void transform( final File in, final File out )
          throws Exception
      {
          FileInputStream fis = null;
          FileOutputStream fos = null;
          try
          {
              fis = new FileInputStream( in );
              fos = new FileOutputStream( out );
              final StreamSource source = new StreamSource( fis, getSystemId( in ) );
              final StreamResult result = new StreamResult( fos );
  
              m_transformer.transform( source, result );
          }
          finally
          {
              IOUtil.shutdownStream( fis );
              IOUtil.shutdownStream( fos );
          }
      }
  
      private String getSystemId( final File file )
          throws IOException
      {
          return file.getCanonicalFile().toURL().toExternalForm();
      }
  
      private void ensureDirectoryFor( final File targetFile )
          throws TaskException
      {
          //In future replace me with
          //FileUtil.forceMkdir( targetFile.getParent() );
          File directory = new File( targetFile.getParent() );
          if( !directory.exists() )
          {
              if( !directory.mkdirs() )
              {
                  throw new TaskException( "Unable to create directory: " +
                                           directory.getAbsolutePath() );
              }
          }
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message