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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">
* [EMAIL PROTECTED]</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>
* , [EMAIL PROTECTED] #setLenient(boolean)}, will be ignored. <p>
*
* if not set, the default [EMAIL PROTECTED]
#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 [EMAIL PROTECTED]
* #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:[EMAIL PROTECTED]">Keith Visco</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Sam Ruby</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Russell Gold</a>
* @author <a href="[EMAIL PROTECTED]">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:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>