Recently a poster had a problem with <apply>, because the executable it
was calling didn't create the destination directories, and <apply> would
not do it either. The poster used a very clever solution by doing the
<apply> in place (no dest attribute), and then use <move> to move all
the files to the destination directory.

Well, this morning I had exactly the same issue, but after examining
ExecuteOn and seeing that its internals were open enough, I coded up the
following little wrapper which solved the same problem in code (albeit
outside Ant). I've tested it for the serial case only.

This might be useful to someone else, and could provide the basis for a
patch to ExecuteOn.java ;-) --DD

import java.io.File;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.ExecuteOn;

/**
 * Wrapper around Ant's &lt;apply&gt; that creates target directories.
*/
public class Apply
             extends ExecuteOn {

    /**
     * Construct the command line for serial execution,
     * creating any necessary output directories.
     *
     * @param srcFile The filename to add to the commandline
     * @param baseDir filename is relative to this dir
     * @return the serial command line
     *
     * @see #createDestinationDirectory
     */
    protected String[] getCommandline(String srcFile, File baseDir) {
        // Done in parallel's getCommandline, but done here too just in
case
        createDestinationDirectory(srcFile);
        return super.getCommandline(srcFile, baseDir);
    }

    /**
     * Construct the command line for parallel execution.
     *
     * @param srcFiles The filenames to add to the commandline
     * @param baseDirs filenames are relative to this dir
     * @return the parallel command line
     *
     * @see #createDestinationDirectory
     */
    protected String[] getCommandline(String[] srcFiles, File[]
baseDirs) {
        for (int i = 0; i < srcFiles.length; ++i) {
            createDestinationDirectory(srcFiles[i]);
        }
        return super.getCommandline(srcFiles, baseDirs);
    }

    /**
     * Creates the destination directories for a given source file.
     * <p>
     * If a [EMAIL PROTECTED] #setDest destination directory} and a
     * [EMAIL PROTECTED] #createMapper filename mapper} have been specified, the
     * target files' destination directories are created.
     *
     * @param  srcFile the source file's relative filename.
     * @throws BuildException if a destination directory could not be
created.
     */
    protected void createDestinationDirectory(String srcFile) {
        if (this.mapper == null || this.destDir == null) {
            return;
        }

        String[] targets = this.mapper.mapFileName(srcFile);
        if (targets == null || targets.length < 1) {
            return;
        }

        for (int i = 0; i < targets.length; ++i) {
            String target = targets[i];
            File targetFile = new File(this.destDir, target);
            File destination = targetFile.getParentFile();
            if (!destination.exists()) {
                log("Creating dest. dir: " + destination,
Project.MSG_DEBUG);
                if (!destination.mkdirs()) {
                    throw new BuildException("Cannot create dest. dir "
+
                      destination + " of source file " + srcFile);
                }
            }
        }
    }

}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to