peterreilly 2003/07/24 06:14:21 Modified: docs/manual/CoreTasks copy.html move.html src/main/org/apache/tools/ant/taskdefs Copy.java Move.java Added: src/etc/testcases/taskdefs multimap.xml src/testcases/org/apache/tools/ant/taskdefs MultiMapTest.java Log: Add multimapping to the copy and move task Some slight changes from the orignal patch - rename of ignoremultiplemapping to enablemultiplemapping and some checkstyle changes PR: 21320 Obtained from: Evan Easton Revision Changes Path 1.19 +17 -0 ant/docs/manual/CoreTasks/copy.html Index: copy.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/copy.html,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- copy.html 19 May 2003 15:37:31 -0000 1.18 +++ copy.html 24 Jul 2003 13:14:20 -0000 1.19 @@ -118,6 +118,23 @@ <td align="center">No - defaults to the value of the encoding attribute if given or the default JVM encoding otherwise.</td> </tr> + <tr> + <td valign="top">outputencoding</td> + <td valign="top">The encoding to use when writing the files. + <em>since Ant 1.6</em>.</td> + <td align="center">No - defaults to the value of the encoding + attribute if given or the default JVM encoding otherwise.</td> + </tr> + <tr> + <td valign="top">enablemultiplemapping</td> + <td valign="top"> + If true the task will process to all the mappings for a + given source path. If false the task will only process + the first file or directory. This attribute is only relevant + if there is a mapper subelement. + <em>since Ant 1.6</em>.</td> + <td align="center">No - defaults to false.</td> + </tr> </table> <h3>Parameters specified as nested elements</h3> 1.14 +10 -0 ant/docs/manual/CoreTasks/move.html Index: move.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/move.html,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- move.html 19 May 2003 15:37:31 -0000 1.13 +++ move.html 24 Jul 2003 13:14:20 -0000 1.14 @@ -103,6 +103,16 @@ <td align="center">No - defaults to the value of the encoding attribute if given or the default JVM encoding otherwise.</td> </tr> + <tr> + <td valign="top">enablemultiplemapping</td> + <td valign="top"> + If true the task will process to all the mappings for a + given source path. If false the task will only process + the first file or directory. This attribute is only relevant + if there is a mapper subelement. + <em>since Ant 1.6</em>.</td> + <td align="center">No - defaults to false.</td> + </tr> </table> <h3>Parameters specified as nested elements</h3> <h4>mapper</h4> 1.1 ant/src/etc/testcases/taskdefs/multimap.xml Index: multimap.xml =================================================================== <?xml version="1.0"?> <project name="test" basedir="."> <path id="testclasses"> <pathelement location="../../../../build/testcases" /> <pathelement path="${java.class.path}" /> </path> <mapper id="testmapper" classname="org.apache.tools.ant.taskdefs.MultiMapTest$TestMapper" classpathref="testclasses"/> <property name="map.ext" value=".copy2"/> <property name="rootScratchDir" value="test_multi_mapper_scratch_area"/> <property name="baseScratchSrc" value="${rootScratchDir}/src"/> <target name="setup"> <delete dir="${baseScratchSrc}"/> <mkdir dir="${baseScratchSrc}"/> <delete dir="${baseScratchDest}"/> <mkdir dir="${baseScratchDest}"/> <touch file="${baseScratchSrc}/somefile.txt"/> </target> <!-- test simple single file to multiple file move --> <target name="multicopy" depends="setup"> <copy todir="${baseScratchDest}" enablemultiplemappings="true"> <fileset dir="${baseScratchSrc}" includes="somefile.txt"/> <mapper refid="testmapper"/> </copy> <condition property="multicopy.outcome"> <and> <available file="${baseScratchDest}/somefile.txt"/> <available file="${baseScratchDest}/somefile.txt${map.ext}"/> </and> </condition> <fail unless="multicopy.outcome">multicopy failed</fail> </target> <target name="multimove" depends="setup"> <move todir="${baseScratchDest}" enablemultiplemappings="true"> <fileset dir="${baseScratchSrc}" includes="somefile.txt"/> <mapper refid="testmapper"/> </move> <condition property="test2.outcome"> <and> <available file="${baseScratchDest}/somefile.txt"/> <available file="${baseScratchDest}/somefile.txt${map.ext}"/> <not> <available file="${baseScratchSrc}/somefile.txt"/> </not> <not> <available file="${baseScratchSrc}/somefile.txt${map.ext}"/> </not> </and> </condition> <fail unless="test2.outcome">mulitmove failed</fail> </target> <!-- test traditional single file to single file copy explicitly telling task to ignore multiple mappings --> <target name="singlecopy" depends="setup"> <copy todir="${baseScratchDest}" enablemultiplemappings="false"> <fileset dir="${baseScratchSrc}" includes="somefile.txt"/> <mapper refid="testmapper"/> </copy> <condition property="singlecopy.outcome"> <and> <available file="${baseScratchDest}/somefile.txt"/> <not> <available file="${baseScratchDest}/somefile.txt${map.ext}"/> </not> <available file="${baseScratchSrc}/somefile.txt"/> </and> </condition> <fail unless="singlecopy.outcome">singlecopy failed</fail> </target> <target name="singlemove" depends="setup"> <move todir="${baseScratchDest}" enablemultiplemappings="false"> <fileset dir="${baseScratchSrc}" includes="somefile.txt"/> <mapper refid="testmapper"/> </move> <condition property="singlemove.outcome"> <and> <available file="${baseScratchDest}/somefile.txt"/> <not> <available file="${baseScratchDest}/somefile.txt${map.ext}"/> </not> <not> <available file="${baseScratchSrc}/somefile.txt"/> </not> </and> </condition> <fail unless="singlemove.outcome">singlemove failed</fail> </target> <!-- test dir w/ file + empty dir multimap copy --> <target name="copywithempty"> <delete dir="${baseScratchSrc}"/> <mkdir dir="${baseScratchSrc}/dirwithfile"/> <mkdir dir="${baseScratchSrc}/emptydir"/> <touch file="${baseScratchSrc}/dirwithfile/somefile.txt"/> <delete dir="${baseScratchDest}"/> <mkdir dir="${baseScratchDest}"/> <copy todir="${baseScratchDest}" enablemultiplemappings="true"> <fileset dir="${baseScratchSrc}" includes="**/*"/> <mapper refid="testmapper"/> </copy> <condition property="copywithempty.outcome"> <and> <available file="${baseScratchDest}/dirwithfile"/> <available file="${baseScratchDest}/dirwithfile${map.ext}"/> <available file="${baseScratchDest}/dirwithfile/somefile.txt"/> <available file="${baseScratchDest}/dirwithfile/somefile.txt${map.ext}"/> <not> <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt"/> </not> <not> <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt${map.ext}"/> </not> <available file="${baseScratchDest}/emptydir"/> <available file="${baseScratchDest}/emptydir${map.ext}"/> </and> </condition> <fail unless="copywithempty.outcome">copywithempty failed</fail> </target> <!-- test dir w/ file + empty dir multimap move --> <target name="movewithempty"> <delete dir="${baseScratchSrc}"/> <mkdir dir="${baseScratchSrc}/dirwithfile"/> <mkdir dir="${baseScratchSrc}/emptydir"/> <touch file="${baseScratchSrc}/dirwithfile/somefile.txt"/> <delete dir="${baseScratchDest}"/> <mkdir dir="${baseScratchDest}"/> <move todir="${baseScratchDest}" enablemultiplemappings="true"> <fileset dir="${baseScratchSrc}" includes="**/*"/> <mapper refid="testmapper"/> </move> <condition property="movewithempty.outcome"> <and> <available file="${baseScratchDest}/dirwithfile"/> <available file="${baseScratchDest}/dirwithfile${map.ext}"/> <available file="${baseScratchDest}/dirwithfile/somefile.txt"/> <available file="${baseScratchDest}/dirwithfile/somefile.txt${map.ext}"/> <not> <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt"/> </not> <not> <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt${map.ext}"/> </not> <available file="${baseScratchDest}/emptydir"/> <available file="${baseScratchDest}/emptydir${map.ext}"/> <not> <available file="${baseScratchSrc}/dirwithfile"/> </not> <not> <available file="${baseScratchSrc}/emptydir"/> </not> </and> </condition> <fail unless="movewithempty.outcome">movewithempty failed</fail> </target> <target name="cleanup"> <delete dir="${rootScratchDir}"/> </target> </project> 1.63 +92 -47 ant/src/main/org/apache/tools/ant/taskdefs/Copy.java Index: Copy.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Copy.java,v retrieving revision 1.62 retrieving revision 1.63 diff -u -r1.62 -r1.63 --- Copy.java 19 Jul 2003 11:20:12 -0000 1.62 +++ Copy.java 24 Jul 2003 13:14:20 -0000 1.63 @@ -102,6 +102,7 @@ protected File destDir = null; // the destination directory protected Vector filesets = new Vector(); + private boolean enableMultipleMappings = false; protected boolean filtering = false; protected boolean preserveLastModified = false; protected boolean forceOverwrite = false; @@ -260,6 +261,28 @@ } /** + * Attribute to handle mappers that return multiple + * mappings for a given source path. + * @param enableMultipleMappings If true the task will + * copy to all the mappings for a given source path, if + * false, only the first file or directory is + * processed. + * By default, this setting is false to provide backward + * compatibility with earlier releases. + * @since 1.6 + */ + public void setEnableMultipleMappings(boolean enableMultipleMappings) { + this.enableMultipleMappings = enableMultipleMappings; + } + + /** + * @return the value of the enableMultipleMapping attribute + */ + public boolean isEnableMultipleMapping() { + return enableMultipleMappings; + } + + /** * If false, note errors to the output but keep going. * @param failonerror true or false */ @@ -354,7 +377,7 @@ if (forceOverwrite || !destFile.exists() || (file.lastModified() > destFile.lastModified())) { fileCopyMap.put(file.getAbsolutePath(), - destFile.getAbsolutePath()); + new String[] {destFile.getAbsolutePath()}); } else { log(file + " omitted as " + destFile + " is up to date.", Project.MSG_VERBOSE); @@ -528,8 +551,20 @@ for (int i = 0; i < toCopy.length; i++) { File src = new File(fromDir, toCopy[i]); - File dest = new File(toDir, mapper.mapFileName(toCopy[i])[0]); - map.put(src.getAbsolutePath(), dest.getAbsolutePath()); + + String[] mappedFiles = mapper.mapFileName(toCopy[i]); + + if (!enableMultipleMappings) { + map.put(src.getAbsolutePath(), + new String[] {new File(toDir, mappedFiles[0]).getAbsolutePath()}); + } else { + // reuse the array created by the mapper + for (int k = 0; k < mappedFiles.length; k++) { + mappedFiles[k] = new File(toDir, mappedFiles[k]).getAbsolutePath(); + } + + map.put(src.getAbsolutePath(), mappedFiles); + } } } @@ -546,64 +581,74 @@ Enumeration e = fileCopyMap.keys(); while (e.hasMoreElements()) { String fromFile = (String) e.nextElement(); - String toFile = (String) fileCopyMap.get(fromFile); - - if (fromFile.equals(toFile)) { - log("Skipping self-copy of " + fromFile, verbosity); - continue; - } + String[] toFiles = (String[]) fileCopyMap.get(fromFile); - try { - log("Copying " + fromFile + " to " + toFile, verbosity); + for (int i = 0; i < toFiles.length; i++) { + String toFile = toFiles[i]; - FilterSetCollection executionFilters = - new FilterSetCollection(); - if (filtering) { - executionFilters - .addFilterSet(getProject().getGlobalFilterSet()); - } - for (Enumeration filterEnum = filterSets.elements(); - filterEnum.hasMoreElements();) { - executionFilters - .addFilterSet((FilterSet) filterEnum.nextElement()); + if (fromFile.equals(toFile)) { + log("Skipping self-copy of " + fromFile, verbosity); + continue; } - fileUtils.copyFile(fromFile, toFile, executionFilters, - filterChains, forceOverwrite, - preserveLastModified, inputEncoding, - outputEncoding, getProject()); - } catch (IOException ioe) { - String msg = "Failed to copy " + fromFile + " to " + toFile - + " due to " + ioe.getMessage(); - File targetFile = new File(toFile); - if (targetFile.exists() && !targetFile.delete()) { - msg += " and I couldn't delete the corrupt " + toFile; + + try { + log("Copying " + fromFile + " to " + toFile, verbosity); + + FilterSetCollection executionFilters = + new FilterSetCollection(); + if (filtering) { + executionFilters + .addFilterSet(getProject().getGlobalFilterSet()); + } + for (Enumeration filterEnum = filterSets.elements(); + filterEnum.hasMoreElements();) { + executionFilters + .addFilterSet((FilterSet) filterEnum.nextElement()); + } + fileUtils.copyFile(fromFile, toFile, executionFilters, + filterChains, forceOverwrite, + preserveLastModified, inputEncoding, + outputEncoding, getProject()); + } catch (IOException ioe) { + String msg = "Failed to copy " + fromFile + " to " + toFile + + " due to " + ioe.getMessage(); + File targetFile = new File(toFile); + if (targetFile.exists() && !targetFile.delete()) { + msg += " and I couldn't delete the corrupt " + toFile; + } + throw new BuildException(msg, ioe, getLocation()); } - throw new BuildException(msg, ioe, getLocation()); } } } if (includeEmpty) { Enumeration e = dirCopyMap.elements(); - int count = 0; + int createCount = 0; while (e.hasMoreElements()) { - File d = new File((String) e.nextElement()); - if (!d.exists()) { - if (!d.mkdirs()) { - log("Unable to create directory " - + d.getAbsolutePath(), Project.MSG_ERR); - } else { - count++; + String[] dirs = (String[]) e.nextElement(); + for (int i = 0; i < dirs.length; i++) { + File d = new File(dirs[i]); + if (!d.exists()) { + if (!d.mkdirs()) { + log("Unable to create directory " + + d.getAbsolutePath(), Project.MSG_ERR); + } else { + createCount++; + } } } } - - if (count > 0) { - log("Copied " + count + " empty director" - + (count == 1 ? "y" : "ies") - + " to " + destDir.getAbsolutePath()); + if (createCount > 0) { + log("Copied " + dirCopyMap.size() + + " empty director" + + (dirCopyMap.size() == 1 ? "y" : "ies") + + " to " + createCount + + " empty director" + + (createCount == 1 ? "y" : "ies") + " under " + + destDir.getAbsolutePath()); } } } - } + 1.39 +123 -72 ant/src/main/org/apache/tools/ant/taskdefs/Move.java Index: Move.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Move.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- Move.java 19 Jul 2003 11:20:12 -0000 1.38 +++ Move.java 24 Jul 2003 13:14:20 -0000 1.39 @@ -125,67 +125,29 @@ Enumeration e = fileCopyMap.keys(); while (e.hasMoreElements()) { String fromFile = (String) e.nextElement(); - String toFile = (String) fileCopyMap.get(fromFile); - if (fromFile.equals(toFile)) { - log("Skipping self-move of " + fromFile, verbosity); - continue; - } - - boolean moved = false; File f = new File(fromFile); - + boolean selfMove = false; if (f.exists()) { //Is this file still available to be moved? - File d = new File(toFile); - - try { - log("Attempting to rename: " + fromFile - + " to " + toFile, verbosity); - moved = renameFile(f, d, filtering, forceOverwrite); - } catch (IOException ioe) { - String msg = "Failed to rename " + fromFile - + " to " + toFile - + " due to " + ioe.getMessage(); - throw new BuildException(msg, ioe, getLocation()); - } - - if (!moved) { - try { - log("Moving " + fromFile + " to " + toFile, - verbosity); - - FilterSetCollection executionFilters = - new FilterSetCollection(); - if (filtering) { - executionFilters - .addFilterSet(getProject().getGlobalFilterSet()); - } - for (Enumeration filterEnum = - getFilterSets().elements(); - filterEnum.hasMoreElements();) { - executionFilters - .addFilterSet((FilterSet) filterEnum - .nextElement()); - } - getFileUtils().copyFile(f, d, executionFilters, - getFilterChains(), - forceOverwrite, - getPreserveLastModified(), - getEncoding(), - getOutputEncoding(), - getProject()); - - f = new File(fromFile); - if (!f.delete()) { - throw new BuildException("Unable to delete " - + "file " - + f.getAbsolutePath()); - } - } catch (IOException ioe) { - String msg = "Failed to copy " + fromFile + " to " - + toFile - + " due to " + ioe.getMessage(); - throw new BuildException(msg, ioe, getLocation()); + String[] toFiles = (String[]) fileCopyMap.get(fromFile); + for (int i = 0; i < toFiles.length; i++) { + String toFile = (String) toFiles[i]; + + if (fromFile.equals(toFile)) { + log("Skipping self-move of " + fromFile, verbosity); + selfMove = true; + + // if this is the last time through the loop then + // move will not occur, but that's what we want + continue; + } + File d = new File(toFile); + if ((i + 1) == toFiles.length && !selfMove) { + // Only try to move if this is the last mapped file + // and one of the mappings isn't to itself + moveFile(f, d, filtering, forceOverwrite); + } else { + copyFile(f, d, filtering, forceOverwrite); } } } @@ -194,31 +156,120 @@ if (includeEmpty) { Enumeration e = dirCopyMap.keys(); - int count = 0; + int createCount = 0; while (e.hasMoreElements()) { String fromDirName = (String) e.nextElement(); - String toDirName = (String) dirCopyMap.get(fromDirName); - File fromDir = new File(fromDirName); - File toDir = new File(toDirName); - if (!toDir.exists()) { - if (!toDir.mkdirs()) { - log("Unable to create directory " - + toDirName, Project.MSG_ERR); - } else { - count++; + String[] toDirNames = (String[]) dirCopyMap.get(fromDirName); + boolean selfMove = false; + for (int i = 0; i < toDirNames.length; i++) { + + if (fromDirName.equals(toDirNames[i])) { + log("Skipping self-move of " + fromDirName, verbosity); + selfMove = true; + continue; + } + + File d = new File(toDirNames[i]); + if (!d.exists()) { + if (!d.mkdirs()) { + log("Unable to create directory " + + d.getAbsolutePath(), Project.MSG_ERR); + } else { + createCount++; + } } } - if (okToDelete(fromDir)) { + + File fromDir = new File(fromDirName); + if (!selfMove && okToDelete(fromDir)) { deleteDir(fromDir); } + } - if (count > 0) { - log("Moved " + count + " empty directories to " + if (createCount > 0) { + log("Moved " + dirCopyMap.size() + + " empty director" + + (dirCopyMap.size()== 1 ? "y" : "ies") + + " to " + createCount + + " empty director" + + (createCount == 1 ? "y" : "ies") + " under " + destDir.getAbsolutePath()); } } } + + /** + * Try to move the file via a rename, but if this fails or filtering + * is enabled, copy the file then delete the sourceFile. + */ + private void moveFile(File fromFile, File toFile, + boolean filtering, boolean overwrite) { + boolean moved = false; + try { + log("Attempting to rename: " + fromFile + + " to " + toFile, verbosity); + moved = renameFile(fromFile, toFile, filtering, forceOverwrite); + } catch (IOException ioe) { + String msg = "Failed to rename " + fromFile + + " to " + toFile + + " due to " + ioe.getMessage(); + throw new BuildException(msg, ioe, getLocation()); + } + + if (!moved) { + copyFile(fromFile, toFile, filtering, overwrite); + if (!fromFile.delete()) { + throw new BuildException("Unable to delete " + + "file " + + fromFile.getAbsolutePath()); + } + } + } + + /** + * Copy fromFile to toFile. + * @param fromFile + * @param toFile + * @param filtering + * @param overwrite + */ + private void copyFile(File fromFile, File toFile, + boolean filtering, boolean overwrite) { + try { + log("Copying " + fromFile + " to " + toFile, + verbosity); + + FilterSetCollection executionFilters = + new FilterSetCollection(); + if (filtering) { + executionFilters + .addFilterSet(getProject().getGlobalFilterSet()); + } + for (Enumeration filterEnum = + getFilterSets().elements(); + filterEnum.hasMoreElements();) { + executionFilters + .addFilterSet((FilterSet) filterEnum + .nextElement()); + } + + getFileUtils().copyFile(fromFile, toFile, executionFilters, + getFilterChains(), + forceOverwrite, + getPreserveLastModified(), + getEncoding(), + getOutputEncoding(), + getProject()); + + } catch (IOException ioe) { + String msg = "Failed to copy " + fromFile + + " to " + toFile + + " due to " + ioe.getMessage(); + throw new BuildException(msg, ioe, getLocation()); + } + } + /** * Its only ok to delete a directory tree if there are 1.1 ant/src/testcases/org/apache/tools/ant/taskdefs/MultiMapTest.java Index: MultiMapTest.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "Ant" and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.tools.ant.taskdefs; import java.lang.reflect.Method; import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.util.FileNameMapper; /** * @author Peter Reilly */ public class MultiMapTest extends BuildFileTest { public MultiMapTest(String name) { super(name); } public void setUp() { configureProject("src/etc/testcases/taskdefs/multimap.xml"); } public void tearDown() { executeTarget("cleanup"); } public void testMultiCopy() { executeTarget("multicopy"); } public void testMultiMove() { executeTarget("multimove"); } public void testSingleCopy() { executeTarget("singlecopy"); } public void testSingleMove() { executeTarget("singlemove"); } public void testCopyWithEmpty() { executeTarget("copywithempty"); } public void testMoveWithEmpty() { executeTarget("movewithempty"); } public static class TestMapper implements FileNameMapper { public TestMapper() {} public void setFrom(String from) {} public void setTo(String to) {} public String[] mapFileName(final String source_file_name) { return new String[] { source_file_name, source_file_name+".copy2" }; } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]