[I appologize for reshuffling your post but this way my response make mode sense, at least to me 8-)]
On 2010-06-09, Jon Stevens wrote: > It looks like ResourceDecorator is 1.8 only and since this needs to > work in Eclipse, I'm stuck in 1.7.x land for now. IIUC what you do is a one-time action - or once whenever you change dependencies - so it should be possible to use Ant outside of Eclipse just for this. Letting the IDE force the Ant version upon you somewhat defeats the purpose of an IDE independent build process, doesn't it? Anyway, yes, ResourceDecorator has been added after the 1.7.1 release. > I guess I could add that class to my own code, but I'm not entirely > sure how it works from your description. If you could provide some > examples, that would be great. It's really just the Decorator pattern implemented for the Resource class. The implementation is trivial. > http://code.google.com/p/sweetened/source/browse/#svn/trunk/src/com/googlecode/sweetened/typedef OK. One approach would be something like public class SweetenedFileResource extends ResourceDecorator { private String src = null; private String scope = SweetenedScope.ALL.getScope(); public void setSrc(String src) { this.src = src; } public String getSrc() { return src; } public void setScope(String scope) { this.scope = scope; } public String getScope() { return scope; } } I'm not sure how/why you need nameInner in your code, I'm trying to get results quickly but guessing that you won't need it when using ResourceDecorator ;-) > http://code.google.com/p/sweetened/source/browse/trunk/example.xml [BTW, I'd recommend using the <echoxml> task instead of <echo> and looking into oato.util.XmlFragment for your <sweetenedbits> nested element.] Whereever you do <sfile name="${ant.jar}" scope="compile" /> you'd instead use <sfile scope="compile"> <file file="${ant.jar}"/> </sfile> This can be used wherever Ant accepts any kind of resource or resource collection (since resource is a resource collection). > The above is what I have so far, and it works pretty well, but isn't > beautiful. It was kind of ugly since I had to implement my own <path>, > <filelist> and <file> elements by extending the existing ones (as you > can see from the example.xml, I just prefixed them with a 's' (ie: > <spath>) and doing some hackery to make it all work. I think you are doing way to much. Embrace ResourceCollections - oh, and don't extend MatchingTask, this is so Ant 1.1 ;-) In you example if you'd use something like <union id="filelist.classpath"> <sfile scope="compile"> <file file="${lib.dir}/${ant.jar}"/> </sfile> <sfile scope="runtime"> <file file="${lib.dir}/svntask.jar"/> </sfile> ... all the other definitions ... </union> then theUnion.iterator() will return SweetendFileResource instances that you can cast to in order to access the scope attribute. Any other thing you may want to know about the file is directly available from the nested resource - and the getName|Size... methods forward to it. One improvement might be to extract the getters of SweetendFileResource into an interface you could as well use Resource.as(Class) instead of hard-coded casts - Ant 1.8.x only. Another idea would be to write a ResourceCollection implementation that tags the scope attribute to any Resource contained. Something like <union id="filelist.classpath"> <sweetened scope="compile"> <filelist dir="${lib.dir}"> <file name="${ant.jar}"/> </filelist> <filelist dir="${alexandria.dir}"> <file name="${junit.jar}"/> </filelist> </sweetened> <sweetened scope="runtime"> <filelist dir="${lib.dir}"> <file name="svntask.jar"/> </filelist> </sweetened> <sweetened scope="runtime" src="src"> <filelist dir="${target.dir}"> <file name="sweetened.jar"/> </filelist> </sweetened> </spath> Where the sweetened ResourceCollection iterator() would return SweetenedFileResources for all nested resources. Inside of your task you'd get something like protected List<SweetenedFileResource> getJars(SweetenedScope scope) { List<SweetenedFileResource> jars = new ArrayList<SweetenedFileResource>(); for (Resource r : getSweetenedBits()) { if (r instanceof SweetenedFileResource) { SweetenedFileResource sfr = (SweetenedFileResource) r; SweetenedScope sfrScope = SweetenedScope.safeValueOf(sfr.getScope()); if (sfrScope != null && (sfrScope == scope || sfrScope == SweetenedScope.ALL)) jars.add(sfr); } } return jars; } where I assume that getSweetenedBits returns a Union of all resource collections rather than a list of Paths. I'm not using the interface/as() combination in order to make it possible to stick to Ant 1.7.1 (if you add ResourceDecorator to your own code base). > Basically, all I want to do is be able to add a couple attributes to a > <file> element and then get access to those attributes in my Task. I > also want the container for those <file> elements to be able to be > passed as a refid into a <classpath>. What I described above should allow you to do just that. You can also look at MappedResource and MappedResourceCollection in Ant (1.8.x only) which adds a <mapper> to arbitrary resource(collection)s and maps the name of the resource without changing any other attributes as a similar example. > All in all, I think I'm onto some new ant functionality here that is > really useful. The building blocks are all there inside of Ant (the ResourceDecorator). > At this point, my head is spinning from all the layers of abstraction > in ant. It is a code base that has grown organically and that believes in backwards compatibility almost dogmatically. In your case things get worse since you come look into it with your knowledge of a pre-ResourceCollection-era of Ant. If you start out with the concepts of Resource and ResourceCollection and completely do away with Path and FileList things become more easy to follow. Stefan --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org For additional commands, e-mail: dev-h...@ant.apache.org