The documentation for org.apache.tools.ant.util.FileNameMapper states "Used to find the name of the target file(s) corresponding to a source file." Note the use of the word "file(s)." Further the API: java.lang.String[] mapFileName(java.lang.String sourceFileName) shows that you can map a single file name to many. However, the copy task ignores all but the first mapped file name. See line 489 of 1.5.3-1 source for org.apache.tools.ant.taskdefs.Copy: 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()); } Copy and potentially other tasks that know about mappers should be fixed to fulfill the expectations set by the FileNameMapper javadoc and API declaration.
I could try to fix this problem, but I would be glad to see what other committers think about that first.
I'm going to patch the Copy task against 1.5.3-1 for use at my site since we need this capability anyhow. Once I test it, I can submit a patch (against head for 1.6). I don't know if the problem affects other classes, but I might beable to fix those too. Let me know by Sunday if you'd rather I not do it...I've not followed the dev list and am unaware of attitudes of the ant team.
It is a good idea that you prepare patches against HEAD. Since these patches will induce a change of behavior of the tasks, it might be good to add a new flag to the copy task called for instance ignoredoublemappings and set it to true by default. This way in the "normal" case only the first mapping will be used, leaving the behavior of the task intact. If you do <copy ignoredoublemappings="false"/> then <copy/> will use all mappings.
Any change will likely need to propagate to Move.java as well (which is a subclass of Copy). And to Sync (new in Ant 1.6), which uses a subclass of Copy internally. We'd also need to make some strong notes in the javadocs as well as in WHATSNEW.
Does a move of a single file to multiple files even make sense? Options for applying this fix to : (a) implement a move of a single file to N mapped files as N-1 copies and 1 move ? (b) warn that only first mapping is used if ignoremultiplemappings="false" and the mapper returns >1 mapped path? (c) error if same conditions as (b) (d) error if Copy's ignoremultiplemappings is used on Move (i.e. break LSP) (e) nothing - silently ignore multiple mapped files What do others think should be done for Move?
better keep dev@ant in CC or nobody is going to notice when you make progress or ask questions ;-) To your question - if copy to multiple files makes sense, so does move, IMHO. I'd lean to your option (a).
One thing to be aware of is that the dependency code in copy is strongly bound to a single source file -> target file mapping.
Created attachment 7164 [details] Patch to Copy and Move to accomodate multiple mappings.
Submitted Patch - Please review and commit if acceptable. I changed the behavior of Move slightly to check for self-move of empty directories. As of Move's 1.35 version, this check was not done and a self- move would delete the directory. I did not touch Sync$MyCopy as it currently asserts the use of an Identity mapper. Certainly rules for doing mapping in a Sync task could be devised, but they'd be pretty hairy since syncing is two way and I'm not sure how you'd deal with N-to-1 syncs in the reversal of a mapping. I'll let the core team decide to do something about this if they feel it's necessary...I don't consider Sync broken in terms of mapping.
I was just curious if I submitted my proposed patch correctly (per directions at http://www.apache.org/dev/contributors.html) and wanted to make sure it didn't fall through the cracks. Not urgent...just checking.
The patch is fine. It would be nice to have some unit tests.
Created attachment 7302 [details] Ant build script to run some unit tests
Commited the patch with some slight modifications (change name of attribute from igore to enable, and some check style changes). Thanks.