This should help. -----Original Message----- From: Chris Winters [mailto:[EMAIL PROTECTED]] Sent: Friday, May 11, 2001 7:03 AM To: [EMAIL PROTECTED] Subject: Re: How to concatenate files in ant * [EMAIL PROTECTED] ([EMAIL PROTECTED]) [010510 19:36]: > I solved my immediate problem by exec, but if you want to email me the task > code I'll be happy to use it. Maybe it should make it's way into Ant proper > as well :) Attached! Hope you find it useful. Chris
package com.optiron.ant; // $Id: ConcatenateFiles.java,v 1.3 2001/05/07 18:02:17 cwinters Exp $ /** * com.optiron.ant.ConcatenateFiles * Copyright (c) 2001 Optiron, Inc. All Rights Reserved. * * This software is licenced under the Apache Software License. See: * * http://www.apache.org/LICENSE.txt * * for the license contents. */ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.tools.ant.*; import org.apache.tools.ant.types.*; /** * This class implements a new task for Ant: ConcatenateFiles. As the name * states, the purpose of this task is to concatenate two or more files into a * single file with a new name. You can also subsitute a message for one or * both of the 'begin' and 'end' files. * * Note that this will automatically overwrite the destFile until we create * some forceOverride methods. * * <p>Arguments for this task:</p> * <ul> * <li>file: new filename * <li>fileset: set of files that are concatenated for the new file * </ul> * * <p>The next two arguments are mutually exclusive:</p> * <ul> * <li>beginfile: file that begins the new file * <li>beginmessage: message that begins the new file * </ul> * * <p>The next two arguments are mutually exclusive:</p> * <ul> * <li>endfile: file that ends the new file * <li>endmessage: message that ends the new file * </ul> * * <p>Usage:</p> * <p>First define the taskdef:</p> * <pre> * <taskdef name="concatenate" * classname="com.optiron.ant.ConcatenateFiles"/> * </pre> * <p>Now define some actions:</p> * * <p>Concatenate all the files beginning with 'Plumbing' in the base * directory to a file called <tt>concat.txt</tt>:</p> * <code> * <concatenate file="concat.txt"> * <fileset dir="${basedir}" includes="Plumbing*.*"/> * </concatenate> * </code> * <p>Concatenate all XML files in the <code>deployment</code> subdirectory into * a file called <code>main.xml</code>: * <code> * <concatenate file="main.xml"> * <fileset dir="${basedir}/deployment" includes="**\/xml"/> * </concatenate> * </code> * * <p>More about Ant: * <a href="http://jakarta.apache.org/ant/">http://jakarta.apache.org/ant/</a></p> * * @author Chris Winters <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> * @version $Revision: 1.3 $ */ public class ConcatenateFiles extends Task { protected File file = null; protected File destFile = null; protected File beginFile = null; protected File endFile = null; protected String beginMessage = null; protected String endMessage = null; protected List filesets = new ArrayList(); protected int verbosity = Project.MSG_VERBOSE; public void setFile( File _set ) { file = _set; } public void setBeginfile( File _set ) { beginFile = _set; } public void setEndfile( File _set ) { endFile = _set; } public void setBeginmessage( String _set ) { beginMessage = _set; } public void setEndmessage( String _set ) { endMessage = _set; } public void addFileset( FileSet set ) { filesets.add( set ); } public void setVerbose( boolean _set ) { if ( _set ) { verbosity = Project.MSG_INFO; } else { verbosity = Project.MSG_VERBOSE; } } /** * Perform the actual action. First validate the parameters passed * to the task to ensure everything is sane, then open up the * output file. Next do the beginning file/message, process the * fileset and then do the ending file/message. * * @exception BuildException for any IO problems (can't read file, * can't open file, can't write to file, etc.) */ public void execute() throws BuildException { // Ensure everything is set correctly validateAttributes(); FileWriter out = null; try { // Open up the new file and a writer to it. destFile = new File( file.getAbsolutePath() ); if ( destFile.exists() ) { log( "File " + destFile.getAbsolutePath() + " exists; removing.", verbosity ); destFile.delete(); destFile.createNewFile(); } out = new FileWriter( destFile.getAbsolutePath() ); // If the beginFile is defined, contatenate it if ( beginFile != null ) { concatenate( out, beginFile ); log( "Beginning file " + beginFile.getAbsolutePath() + " ok", verbosity ); } if ( beginMessage != null ) { concatenate( out, beginMessage ); log( "Beginning message ok", verbosity ); } // Now do the filesets specified Iterator fsi = filesets.iterator(); while ( fsi.hasNext() ) { FileSet fs = (FileSet)fsi.next(); DirectoryScanner ds = fs.getDirectoryScanner( project ); String[] srcFiles = ds.getIncludedFiles(); File baseDir = ds.getBasedir().getAbsoluteFile(); for ( int i = 0; i < srcFiles.length; i++ ) { File readFile = new File( baseDir, srcFiles[i] ); concatenate( out, readFile ); log( "Fileset file " + readFile.getAbsolutePath() + " ok", verbosity ); } } // And if the endFile is defined, do it if ( endFile != null ) { concatenate( out, endFile ); log( "Ending file " + endFile.getAbsolutePath() + " ok", verbosity ); } if ( endMessage != null ) { concatenate( out, endMessage ); log( "Ending message ok", verbosity ); } log( "Created new file (" + destFile.getAbsolutePath() + ") successfully" ); out.close(); } catch ( IOException ioe ) { throw new BuildException( "Error with the filesystem: " + ioe.getMessage() ); } finally { try { if ( out != null ) { out.close(); } } catch ( IOException ioe ) { throw new BuildException( "Cannot close output buffer! Error: " + ioe.getMessage() ); } } } /** * Ensure we have the right attributes. Failure conditions are: * * <ul> * <li>destination file is not specified</li> * <li>both 'beginmessage' and 'beginfile' are specified</li> * <li>both 'endmessage' and 'endfile' are specified</li> * <li>no messages or files are specified at all</li> * </ul> * * @throws BuildException if one of the specifications is not met. */ protected void validateAttributes() throws BuildException { if ( file == null ) { throw new BuildException("You must specify a destfile." ); } if ( beginMessage != null && beginFile != null ) { throw new BuildException( "You cannot specify both 'beginmessage' and 'beginfile'" ); } if ( endMessage != null && endFile != null ) { throw new BuildException( "You cannot specify both 'endmessage' and 'endfile'" ); } boolean hasMessage = ( beginMessage != null || endMessage != null ); boolean hasFile = ( beginFile != null || endFile != null || filesets.size() > 0 ); if ( ! hasMessage && ! hasFile ) { throw new BuildException( "You must specify one or more messages or files." ); } } /** * Concatenate two text files * * @param to file object appending to * @param from file whose contents we're appending * @throws IOException if we can't read the file or if the actual * write fails */ private static void concatenate( FileWriter to, File from ) throws IOException { BufferedReader in = new BufferedReader( new FileReader( from ) ); String inBuf = new String(); StringBuffer contents = new StringBuffer(); while ( ( inBuf = in.readLine() ) != null ) { contents.append( inBuf + "\r\n" ); } in.close(); concatenate( to, contents.toString() ); } /** * Concatenate a string to a text file * * @param to file object appending to * @param from string we're appending * @throws IOException if the write fails */ private static void concatenate( FileWriter to, String from ) throws IOException { to.write( from ); } }
