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>
 *   &lt;taskdef name="concatenate"
 *            classname="com.optiron.ant.ConcatenateFiles"/&gt;
 *   </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 );
    }
}

Reply via email to