I've written the attached native2ascii task, which I'd like to submit
for inclusion with ant.  It essentially serves as a wrapper for the
jdk native2ascii, with some additional smarts to act as a MatchingTask
and do dependency checking.  A draft usage is below.  Thanks to
Hiroaki Nakamura <[EMAIL PROTECTED]>, for useful comments on
how the task ought work (and prodding me to make it a bit more useful
than I'd originally planed).

Native2Ascii

Description:

Converts files from native encodings to ascii with escaped Unicode.
A common usage is to convert source files maintained in a native
operating system encoding, to ascii prior to compilation.

All matching files in the source directory are converted from a
native encoding to ascii.  If no encoding is specified, the default
encoding for the JVM is used.  If ext is specified, then output
files are renamed to use it as a new extension.  If dest and
src point to the same directory, ext is required.

This is a directory based task, and supports includes, includesfile,
excludes, excludesfile, and defaultexcludes along with its specific
attributes.

Attribute Description                              Required
-----------------------------------------------------------
reverse   Reverse the sense of the conversion,     No
          i.e. convert from ascii to native 

encoding  The native encoding the files are in     No

src       The directory to find files in           No

dest      The directory to output file to          Yes

ext       File extension to use in renaming        No
          output files 


Examples

<native2ascii encoding="EUCJIS" src="srcdir" dest="srcdir"
   includes="**/*.eucjis" ext=".java" />

Converts all files in the directory srcdir ending in eucjis
from the EUCJIS encoding to ascii and renames the to end in
.java.

<native2ascii encoding='EUCJIS" src="native/japanese" dest="src"
   includes="**/*.java />

Converts all the files ending in .java in the directory native/japanese
to ascii, placing the results in the directory src.  The names of
the files remain the same.



package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Commandline.Argument;

import java.io.File;

/**
 * Convert files from native encodings to ascii.
 *
 * @author Drew Sudell <[EMAIL PROTECTED]>
 */
public class Native2Ascii extends MatchingTask {

    private boolean reverse = false;  // convert from ascii back to native
    private String encoding = null;   // encoding to convert to/from
    private File srcDir = null;       // Where to find input files
    private File destDir = null;      // Where to put output files
    private String extension = null;  // Extension of output files if different


    /**
     * Flag the conversion to run in the reverse sense,
     * that is Ascii to Native encoding.
     * 
     * @param reverse True if the conversion is to be reversed,
     *                otherwise false;
     */
    public void setReverse(boolean reverse){
        this.reverse = reverse;
    }

    /**
     * Set the encoding to translate to/from.
     * If unset, the default encoding for the JVM is used.
     *
     * @param encoding String containing the name of the Native 
     *                 encoding to convert from or to.
     */
    public void setEncoding(String encoding){
        this.encoding = encoding;
    }

    /**
     * Set the source directory in which to find files to convert.
     *
     * @param srcDir Direcrory to find input file in.
     */
    public void setSrc(File srcDir){
        this.srcDir = srcDir;
    }


    /**
     * Set the destination dirctory to place converted files into.
     *
     * @param destDir directory to place output file into.
     */
    public void setDest(File destDir){
        this.destDir = destDir;
    }

    /**
     * Set the extension which converted files should have.
     * If unset, files will not be renamed.
     *
     * @param ext File extension to use for converted files.
     */
    public void setExt(String ext){
        this.extension = ext;
    }

    public void execute() throws BuildException {

        Commandline baseCmd = null;      // the common portion of our cmd line
        DirectoryScanner scanner = null; // Scanner to find our inputs
        String[] files;                  // list of files to process

        // default srcDir to basedir
        if (srcDir == null){
            srcDir = project.resolveFile(".");
        }

        // Require destDir
        if (destDir == null){
            throw new BuildException("The dest attribute must be set.");
        }

        // if src and dest dirs are the same, require the extension
        // to be set, so we don't stomp every file.  One could still
        // include a file with the same extension, but ....
        if (srcDir.equals(destDir) && (extension == null)){
            throw new BuildException("The ext attribut must be set if"
                                     + " src and dest dirs are the same.");
        }

        scanner = getDirectoryScanner(srcDir);
        log("Converting files from " + srcDir + " to " + destDir);
        files = scanner.getIncludedFiles();
        for (int i = 0; i < files.length; i++){
            convert(files[i]);
        }
    }

    /**
     * Convert a single file.
     *
     * @param fileName Name of the file to convert (relative to srcDir).
     */
    private void convert(String fileName) throws BuildException {

        Commandline cmd = new Commandline();  // Command line to run
        File srcFile;                         // File to convert
        File destFile;                        // where to put the results

        // Set up the basic args (this could be done once, but
        // it's cleaner here)
        if (reverse){
            cmd.createArgument().setValue("-reverse");
        }

        if (encoding != null){
            cmd.createArgument().setValue("-encoding");
            cmd.createArgument().setValue(encoding);
        }

        // Build the full file names, substuting the extension on the
        // destination file if needed.
        srcFile = new File(srcDir, fileName);

        if (extension != null){
            destFile
                = new File(destDir,
                           fileName.substring(0, fileName.lastIndexOf('.'))
                           + extension);
        }else{
            destFile = new File(destDir, fileName);
        }
        
        cmd.createArgument().setFile(srcFile);
        cmd.createArgument().setFile(destFile);

        // Only process if dest not newer than src
        if (! destFile.exists()
            || (destFile.lastModified() < srcFile.lastModified())){

            // Make sure we're not about to clobber something
            if (srcFile.equals(destFile)){
                throw new BuildException("file " + srcFile 
                                         + " would overwrite its self");
            }

            // Make intermediate directories if needed
            // XXX JDK 1.1 dosen't have File.getParentFile,
            String parentName = destFile.getParent();
            if (parentName != null){
                File parentFile = new File(parentName);
             
                if ((! parentFile.exists()) && ( ! parentFile.mkdirs())){
                    throw new BuildException("cannot create parent directory "
                                             + parentName);
                }
            }
                        
            log("converting " + fileName);
            sun.tools.native2ascii.Main n2a
                = new sun.tools.native2ascii.Main();
            if(! n2a.convert(cmd.getArguments())){
                throw new BuildException("conversion failed");
            }
        }
    }
}


-- 
        Drew Sudell     [EMAIL PROTECTED]      http://www.op.net/~asudell

Reply via email to