You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Jon Stevens <la...@gmail.com> on 2010/06/04 20:52:12 UTC

Extending path

Hi all,

Been a long long time since I've been around these parts, so apologies
if this has been covered before.

What I'd like to do is be able to add a couple of attributes to the
<file> element that lives in a <filelist> and then get access to those
attributes in my Task. I've mucked around for the last couple hours on
seeing how I could extend the existing ant code to make this happen
and it really doesn't seem easily possible.

For example:

    <path id="filelist.classpath">
        <myfilelist dir="${lib.dir}">
            <file name="${ant.jar}" src="thesrc" scope="run" />
            <file name="svntask.jar" src="svntasksrc" scope="compile" />
        </myfilelist>
    </path>

<myTask>
    <classpath refid="foo" />
</myTask>

Thus, in MyTask.java, I have:

    private List<Path> classpaths = new ArrayList<Path>();

    public void addClasspath(Path classpath) {
        classpaths.add(classpath);
    }

This works fine.

However, since there is no way to access the Union within a Path, I'm
kind of stuck cause I can't access the actual myfilelist objects to
get out my additional attributes. I could implement my own Path
object, but that is kind of a pain as I've already had to copy/paste
the source code for FileList.

I guess, ideally, Ant would be a lot more extensible if all of the
private fields had getter/setters and internally those getter/setters
were used instead of direct access. This would allow me to more easily
extend the existing Ant objects.

What I'm trying to accomplish is the ability to define a <path> within
Ant and then be able to pass that to a Task that I wrote that can
generate the Eclipse .classpath and .launch files. The task will be
smart about looking at the scope (run/compile) as well as pointing to
the source for the jar file.

Thoughts?

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
Hi Matt,

Using Resources/ResourceCollections is definitely better than what I
had tried before. After a bit more wrangling today and I think I've
got what I wanted. Thanks for the feedback.

jon


On Mon, Jun 7, 2010 at 2:18 PM, Matt Benson <gu...@gmail.com> wrote:
> I'm not sure what filelist has that you need to begin with...
> sequence?  You might be better off creating a resource type that
> decorates another resource to add the attributes you need, i.e. adding
> 'scope' to some file-based resource.  Then you could create those
> directly, or implement a resource collection to transform the
> resources of some other resource collection to your new resource type.
>  This approach is probably your best best because then your resources
> should be usable by whatever other tasks know how to deal with
> filesystem-based resources.
>
> HTH,
> Matt
>
> On 6/7/10, Jon Stevens <la...@gmail.com> wrote:
>> Anyone? Stefan?
>>
>> On Fri, Jun 4, 2010 at 11:52 AM, Jon Stevens <la...@gmail.com> wrote:
>>> Hi all,
>>>
>>> Been a long long time since I've been around these parts, so apologies
>>> if this has been covered before.
>>>
>>> What I'd like to do is be able to add a couple of attributes to the
>>> <file> element that lives in a <filelist> and then get access to those
>>> attributes in my Task. I've mucked around for the last couple hours on
>>> seeing how I could extend the existing ant code to make this happen
>>> and it really doesn't seem easily possible.
>>>
>>> For example:
>>>
>>>    <path id="filelist.classpath">
>>>        <myfilelist dir="${lib.dir}">
>>>            <file name="${ant.jar}" src="thesrc" scope="run" />
>>>            <file name="svntask.jar" src="svntasksrc" scope="compile" />
>>>        </myfilelist>
>>>    </path>
>>>
>>> <myTask>
>>>    <classpath refid="foo" />
>>> </myTask>
>>>
>>> Thus, in MyTask.java, I have:
>>>
>>>    private List<Path> classpaths = new ArrayList<Path>();
>>>
>>>    public void addClasspath(Path classpath) {
>>>        classpaths.add(classpath);
>>>    }
>>>
>>> This works fine.
>>>
>>> However, since there is no way to access the Union within a Path, I'm
>>> kind of stuck cause I can't access the actual myfilelist objects to
>>> get out my additional attributes. I could implement my own Path
>>> object, but that is kind of a pain as I've already had to copy/paste
>>> the source code for FileList.
>>>
>>> I guess, ideally, Ant would be a lot more extensible if all of the
>>> private fields had getter/setters and internally those getter/setters
>>> were used instead of direct access. This would allow me to more easily
>>> extend the existing Ant objects.
>>>
>>> What I'm trying to accomplish is the ability to define a <path> within
>>> Ant and then be able to pass that to a Task that I wrote that can
>>> generate the Eclipse .classpath and .launch files. The task will be
>>> smart about looking at the scope (run/compile) as well as pointing to
>>> the source for the jar file.
>>>
>>> Thoughts?
>>>
>>> jon
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
>> For additional commands, e-mail: dev-help@ant.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Matt Benson <gu...@gmail.com>.
I'm not sure what filelist has that you need to begin with...
sequence?  You might be better off creating a resource type that
decorates another resource to add the attributes you need, i.e. adding
'scope' to some file-based resource.  Then you could create those
directly, or implement a resource collection to transform the
resources of some other resource collection to your new resource type.
 This approach is probably your best best because then your resources
should be usable by whatever other tasks know how to deal with
filesystem-based resources.

HTH,
Matt

On 6/7/10, Jon Stevens <la...@gmail.com> wrote:
> Anyone? Stefan?
>
> On Fri, Jun 4, 2010 at 11:52 AM, Jon Stevens <la...@gmail.com> wrote:
>> Hi all,
>>
>> Been a long long time since I've been around these parts, so apologies
>> if this has been covered before.
>>
>> What I'd like to do is be able to add a couple of attributes to the
>> <file> element that lives in a <filelist> and then get access to those
>> attributes in my Task. I've mucked around for the last couple hours on
>> seeing how I could extend the existing ant code to make this happen
>> and it really doesn't seem easily possible.
>>
>> For example:
>>
>>    <path id="filelist.classpath">
>>        <myfilelist dir="${lib.dir}">
>>            <file name="${ant.jar}" src="thesrc" scope="run" />
>>            <file name="svntask.jar" src="svntasksrc" scope="compile" />
>>        </myfilelist>
>>    </path>
>>
>> <myTask>
>>    <classpath refid="foo" />
>> </myTask>
>>
>> Thus, in MyTask.java, I have:
>>
>>    private List<Path> classpaths = new ArrayList<Path>();
>>
>>    public void addClasspath(Path classpath) {
>>        classpaths.add(classpath);
>>    }
>>
>> This works fine.
>>
>> However, since there is no way to access the Union within a Path, I'm
>> kind of stuck cause I can't access the actual myfilelist objects to
>> get out my additional attributes. I could implement my own Path
>> object, but that is kind of a pain as I've already had to copy/paste
>> the source code for FileList.
>>
>> I guess, ideally, Ant would be a lot more extensible if all of the
>> private fields had getter/setters and internally those getter/setters
>> were used instead of direct access. This would allow me to more easily
>> extend the existing Ant objects.
>>
>> What I'm trying to accomplish is the ability to define a <path> within
>> Ant and then be able to pass that to a Task that I wrote that can
>> generate the Eclipse .classpath and .launch files. The task will be
>> smart about looking at the scope (run/compile) as well as pointing to
>> the source for the jar file.
>>
>> Thoughts?
>>
>> jon
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
Anyone? Stefan?

On Fri, Jun 4, 2010 at 11:52 AM, Jon Stevens <la...@gmail.com> wrote:
> Hi all,
>
> Been a long long time since I've been around these parts, so apologies
> if this has been covered before.
>
> What I'd like to do is be able to add a couple of attributes to the
> <file> element that lives in a <filelist> and then get access to those
> attributes in my Task. I've mucked around for the last couple hours on
> seeing how I could extend the existing ant code to make this happen
> and it really doesn't seem easily possible.
>
> For example:
>
>    <path id="filelist.classpath">
>        <myfilelist dir="${lib.dir}">
>            <file name="${ant.jar}" src="thesrc" scope="run" />
>            <file name="svntask.jar" src="svntasksrc" scope="compile" />
>        </myfilelist>
>    </path>
>
> <myTask>
>    <classpath refid="foo" />
> </myTask>
>
> Thus, in MyTask.java, I have:
>
>    private List<Path> classpaths = new ArrayList<Path>();
>
>    public void addClasspath(Path classpath) {
>        classpaths.add(classpath);
>    }
>
> This works fine.
>
> However, since there is no way to access the Union within a Path, I'm
> kind of stuck cause I can't access the actual myfilelist objects to
> get out my additional attributes. I could implement my own Path
> object, but that is kind of a pain as I've already had to copy/paste
> the source code for FileList.
>
> I guess, ideally, Ant would be a lot more extensible if all of the
> private fields had getter/setters and internally those getter/setters
> were used instead of direct access. This would allow me to more easily
> extend the existing Ant objects.
>
> What I'm trying to accomplish is the ability to define a <path> within
> Ant and then be able to pass that to a Task that I wrote that can
> generate the Eclipse .classpath and .launch files. The task will be
> smart about looking at the scope (run/compile) as well as pointing to
> the source for the jar file.
>
> Thoughts?
>
> jon
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
> Sorry to step late into the thread but you know you can change the ant used in Eclipse ?
> In the preferences look into Ant / Runtime and change the "Ant Home".
>
> Nicolas

Sure, but getting a company full of java developers to all do that is
pretty much impossible. =) I have a hard enough time getting people
off of Eclipse 3.3. =)

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 9 juin 2010 à 08:11, Jon Stevens a écrit :

> http://code.google.com/p/sweetened/source/browse/#svn/trunk/src/com/googlecode/sweetened/typedef
> 
> http://code.google.com/p/sweetened/source/browse/trunk/example.xml
> 
> 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. Especially in the
> way that the <sfile> element is initialized (see the need to call
> this.setFile() in SweetenedFileResource.setName()).
> 
> 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>.
> 
> 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. 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. At this point, my head is spinning from all the layers of
> abstraction in ant.

Sorry to step late into the thread but you know you can change the ant used in Eclipse ?
In the preferences look into Ant / Runtime and change the "Ant Home".


Nicolas


> 
> All in all, I think I'm onto some new ant functionality here that is
> really useful. If you are like me and you don't like Maven, Ivy just
> doesn't work right (has anyone actually tried the examples in the
> documentation?) and Gradle is just too slow, this is a good
> alternative to being able to specify your dependencies in your ant
> build file and then use those to produce your Eclipse .classpath and
> launch config files. All I want is something simple and fast and just
> works. =)
> 
> thanks,
> 
> jon
> 
> 
> On Tue, Jun 8, 2010 at 7:14 AM, Stefan Bodewig <bo...@apache.org> wrote:
>> On 2010-06-04, Jon Stevens wrote:
>> 
>>> What I'd like to do is be able to add a couple of attributes to the
>>> <file> element that lives in a <filelist> and then get access to those
>>> attributes in my Task.
>> 
>> I've seen you've already taken on Matt's Resource advice.  You may want
>> to look into org.apache.tools.ant.types.resources.ResourceDecorator
>> which wraps itself around a different Resource (specified as a nested
>> element inside a build file) and forwards all "normal" methods to the
>> wrapped Resource.
>> 
>> You'd only need to implement setters for your additional attributes and
>> should be done.
>> 
>> Stefan
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
>> For additional commands, e-mail: dev-help@ant.apache.org
>> 
>> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-06-14, Jon Stevens wrote:

> On Mon, Jun 14, 2010 at 2:06 AM, Stefan Bodewig <bo...@apache.org> wrote:
>>  Since that method is final (at least in 1.8.0) you can't even
>> override it.

> Yea, can we talk about this? It seems like there is a lot of places
> where ant discourages people from being able to override stuff. Is
> there a good reason for that?

The more things are final the more freedom we have to change things
without breaking backwards compatibility.  For example I had to tunnel
new arguments in ThreadLocals inside the <zip> task because a different
task (jarjar) was overriding a protected method that I no longer
intended to invoke directly for 1.8.0.

I've been doing C# during ${dayjob} for most of the last five years and
there "final" is the default.  It forces you to think about what
extension points you are willing to support in the future.  Nowadays I
tend to make things final in Java as well and only open up access as
needed.

This is just my personal opinion and doesn't necessary reflect what
others around here think.  YMMV.

> http://code.google.com/p/sweetened/source/browse/trunk/example.xml

Looks a lot nicer than the initial version, congrats.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
On Mon, Jun 14, 2010 at 2:06 AM, Stefan Bodewig <bo...@apache.org> wrote:
>  Since that method is final (at
> least in 1.8.0) you can't even override it.

Yea, can we talk about this? It seems like there is a lot of places
where ant discourages people from being able to override stuff. Is
there a good reason for that?

> You don't really want to use refid because this is meant to say a given
> type is just a placeholder for something defined anywhere else.  In your
> case you just need to use a different name for the attribute (say
> reference instead of refid) and just use Ant's reference system for all
> the rest - don't make your baseclass think the instance was just a
> placeholder.

Yep, that is pretty much what I ended up doing. I had to write my own
recursive tree [1] which seems to be working well enough for a first
shot. I've actually got things working now with an ant syntax that I'm
happy with. I haven't had time to fully document things yet, but take
a look at the example.xml file...

http://code.google.com/p/sweetened/source/browse/trunk/example.xml

You can now define a path to the jar, its source code as well as a
scope in a single location in an ant build file. This is enough
information to generate the .classpath/.project file for Eclipse as
well as provide a single location to setup compile/javadoc/junit
classpaths. All without having to learn or use Ivy or Maven (both of
which fail the kiss test for me). I feel like this is functionality
that has been missing in ant forever now.

jon

[1] http://code.google.com/p/sweetened/source/browse/trunk/src/com/googlecode/sweetened/typedef/SweetenedPath.java#55

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-06-11, Jon Stevens wrote:

> Ok, new question. Say I have a build.xml that looks like this:

> <project>
>     <spath id="filelist.classpath" scope="unit">
>         <sfilelist dir="${lib.dir}">
>             <sfile name="${ant.jar}" scope="compile" />
>             <sfile name="${ant-googlecode.jar}" scope="runtime" />
>             <sfile name="svntask.jar" scope="runtime" />
>         </sfilelist>
>         <sfilelist dir="${target.dir}">
>             <sfile name="sweetened.jar" src="src" scope="runtime" />
>         </sfilelist>
>         <sfilelist dir="${alexandria.dir}">
>             <sfile name="${junit.jar}" scope="unit" />
>         </sfilelist>
>     </spath>

>     <spath id="javac.classpath" scope="compile" refid="filelist.classpath" />

>     <echo>
>         javac.classpath: ${toString:javac.classpath}
>     </echo>
> </project>

> spath extends Union.

> When the ${toString} is called, the spath.getCollection() method is
> called by ant. At that point, though, ant is calling the
> getCollection() method on the spath instance of filelist.classpath

I think it is this code in BaseResourceCollectionContainer that is
causing the problem for you

    public final synchronized Iterator iterator() {
        if (isReference()) {
            return ((BaseResourceCollectionContainer) getCheckedRef()).iterator();
        }

Since you spath is a reference (the refid syntax) the iterator() method
just delegates to the "real" instance.  Since that method is final (at
least in 1.8.0) you can't even override it.

> I guess one option would be to implement my own refid type system
> within my spath, but I was hoping that I could just use ant's.

You don't really want to use refid because this is meant to say a given
type is just a placeholder for something defined anywhere else.  In your
case you just need to use a different name for the attribute (say
reference instead of refid) and just use Ant's reference system for all
the rest - don't make your baseclass think the instance was just a
placeholder.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
Ok, new question. Say I have a build.xml that looks like this:

<project>
    <spath id="filelist.classpath" scope="unit">
        <sfilelist dir="${lib.dir}">
            <sfile name="${ant.jar}" scope="compile" />
            <sfile name="${ant-googlecode.jar}" scope="runtime" />
            <sfile name="svntask.jar" scope="runtime" />
        </sfilelist>
        <sfilelist dir="${target.dir}">
            <sfile name="sweetened.jar" src="src" scope="runtime" />
        </sfilelist>
        <sfilelist dir="${alexandria.dir}">
            <sfile name="${junit.jar}" scope="unit" />
        </sfilelist>
    </spath>

    <spath id="javac.classpath" scope="compile" refid="filelist.classpath" />

    <echo>
        javac.classpath: ${toString:javac.classpath}
    </echo>
</project>

spath extends Union.

When the ${toString} is called, the spath.getCollection() method is
called by ant. At that point, though, ant is calling the
getCollection() method on the spath instance of filelist.classpath and
not on the instance of javac.classpath. This is bad because the
'scope' of the javac.classpath should override the 'scope' of the
filelist.classpath.

I guess one option would be to implement my own refid type system
within my spath, but I was hoping that I could just use ant's.

thoughts?

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
On Thu, Jun 10, 2010 at 10:58 AM, Jon Stevens <la...@gmail.com> wrote:
> the getCollection() method on my spath element is called. However, the
> scope attribute on the spath is null. (ie: I've overrided
> getCollection() and this.scope is null). I'm not sure why this is
> getting nulled out.

Nevermind on the null issue! Found a bug... this is starting to work
out well I think... =)

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
> I think you've later seen that you don't since all the attributes of the
> <file> are available via <sfile> as well.  Using Ant 1.8.0 you can even
> do a sfile.as(FileProvider.class) to get access to the java.io.File
> instance itself.
>
> Yep, absolutely.  That's why I suggested tagging a whole resource
> collection later in my post.

This is the syntax that I'm looking to achieve:

    <spath id="filelist.classpath">
        <sfilelist dir="${lib.dir}">
            <sfile name="${ant.jar}" scope="compile" />
            <sfile name="svntask.jar" src="/path/to/svntask-src.jar"
scope="runtime" />
        </sfilelist>
        <sfilelist dir="${target.dir}">
            <sfile name="sweetened.jar"
src="/path/to/sweetened-src.jar" scope="runtime" />
        </sfilelist>
        <sfilelist dir="${alexandria.dir}">
            <sfile name="${junit.jar}" scope="compile" />
        </sfilelist>
    </spath>

    <spath id="javac.classpath" refid="filelist.classpath" scope="compile" />

Ideally, I could then do something like this:

<javac><classpath refid="javac.classpath" /></javac>

and only the jar files (defined via <sfile> instances) that are marked
with scope="compile" will get passed to the javac task.

I've changed <spath> to extend Union and that is working fine. The
problem I'm having now is that when I echo out the javac.classpath:

    <echo>
        ${toString:javac.classpath}
    </echo>

the getCollection() method on my spath element is called. However, the
scope attribute on the spath is null. (ie: I've overrided
getCollection() and this.scope is null). I'm not sure why this is
getting nulled out.

Also, I really can't use 1.8 features... as much as I'd like to, these
build files must be able to run from within eclipse.

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-06-09, Jon Stevens wrote:

> On Wed, Jun 9, 2010 at 3:06 AM, Stefan Bodewig <bo...@apache.org> wrote:
>> Whereever you do

>>            <sfile name="${ant.jar}" scope="compile" />

>> you'd instead use

>>            <sfile scope="compile">
>>              <file file="${ant.jar}"/>
>>            </sfile>

> I see where you are going, but this won't work. I need to be able to
> define the attributes on the <file> element itself.

I think you've later seen that you don't since all the attributes of the
<file> are available via <sfile> as well.  Using Ant 1.8.0 you can even
do a sfile.as(FileProvider.class) to get access to the java.io.File
instance itself.

> Wrapping every <file> in a <sfile> is too much boilerplate typing.

Yep, absolutely.  That's why I suggested tagging a whole resource
collection later in my post.

>> and don't extend MatchingTask, this is so Ant 1.1 ;-)

> If you recall, I was the first person to use 'ant' outside of Sun, so
> my knowledge will forever be stuck in the past. =) Also, the
> documentation on the website is so out of date that it is hard to tell
> what I should use.

Is it?  Likely we should re-write parts of the tutorials to focus more
on resources and resource collection than on filesets and paths.

> What do you suggest over MatchingTask?

You don't need to extend any class at all since Ant can and will use
reflection for the execute method as well if you don't.

If you extend ProjectComponent you get the additional benefit of a
project instance and logging convenience methods.  The most common base
class would be Task, though.

> Ok, I think that definitely points me in the right direction. Thanks
> so much for your help. It is very much appreciated.

You're welcome

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
On Wed, Jun 9, 2010 at 3:06 AM, Stefan Bodewig <bo...@apache.org> wrote:
> [I appologize for reshuffling your post but this way my response make
> mode sense, at least to me 8-)]

I sometimes ramble. Thanks! =)

> Letting the IDE force the Ant version upon you somewhat defeats the
> purpose of an IDE independent build process, doesn't it?

You mention Ant's backwards compatibility mantra and then you say that? =) =)

> 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 ;-)

The reason is esoteric based on the interaction of <filelist> and
<file> and the order of instantiation. Regardless, I'll try the RD
pattern and see if that helps.

> [BTW, I'd recommend using the <echoxml> task instead of <echo> and
> looking into oato.util.XmlFragment for your <sweetenedbits> nested
> element.]

Ok!

> Whereever you do
>
>            <sfile name="${ant.jar}" scope="compile" />
>
> you'd instead use
>
>            <sfile scope="compile">
>              <file file="${ant.jar}"/>
>            </sfile>

I see where you are going, but this won't work. I need to be able to
define the attributes on the <file> element itself. For example. I
want to be able to point to the source code for each file. Wrapping
every <file> in a <sfile> is too much boilerplate typing.

> I think you are doing way to much.  Embrace ResourceCollections - oh,
> and don't extend MatchingTask, this is so Ant 1.1 ;-)

If you recall, I was the first person to use 'ant' outside of Sun, so
my knowledge will forever be stuck in the past. =) Also, the
documentation on the website is so out of date that it is hard to tell
what I should use. What do you suggest over MatchingTask?

>        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.

Sweet!

> 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.

Good to know.

> Another idea would be to write a ResourceCollection implementation that
> tags the scope attribute to any Resource contained.  Something like

The tagging is a good idea, but I think a bit overkill. I'd like to
keep this as simple as possible because I think that since src is
pretty much a one-to-one mapping to a <file>, I'd end up with a huge
amount of xml wrapping for no real gain.

> 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.

Ok, I think that definitely points me in the right direction. Thanks
so much for your help. It is very much appreciated.

jon

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Stefan Bodewig <bo...@apache.org>.
[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-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Jon Stevens <la...@gmail.com>.
http://code.google.com/p/sweetened/source/browse/#svn/trunk/src/com/googlecode/sweetened/typedef

http://code.google.com/p/sweetened/source/browse/trunk/example.xml

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. Especially in the
way that the <sfile> element is initialized (see the need to call
this.setFile() in SweetenedFileResource.setName()).

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>.

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. 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. At this point, my head is spinning from all the layers of
abstraction in ant.

All in all, I think I'm onto some new ant functionality here that is
really useful. If you are like me and you don't like Maven, Ivy just
doesn't work right (has anyone actually tried the examples in the
documentation?) and Gradle is just too slow, this is a good
alternative to being able to specify your dependencies in your ant
build file and then use those to produce your Eclipse .classpath and
launch config files. All I want is something simple and fast and just
works. =)

thanks,

jon


On Tue, Jun 8, 2010 at 7:14 AM, Stefan Bodewig <bo...@apache.org> wrote:
> On 2010-06-04, Jon Stevens wrote:
>
>> What I'd like to do is be able to add a couple of attributes to the
>> <file> element that lives in a <filelist> and then get access to those
>> attributes in my Task.
>
> I've seen you've already taken on Matt's Resource advice.  You may want
> to look into org.apache.tools.ant.types.resources.ResourceDecorator
> which wraps itself around a different Resource (specified as a nested
> element inside a build file) and forwards all "normal" methods to the
> wrapped Resource.
>
> You'd only need to implement setters for your additional attributes and
> should be done.
>
> Stefan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Extending path

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-06-04, Jon Stevens wrote:

> What I'd like to do is be able to add a couple of attributes to the
> <file> element that lives in a <filelist> and then get access to those
> attributes in my Task.

I've seen you've already taken on Matt's Resource advice.  You may want
to look into org.apache.tools.ant.types.resources.ResourceDecorator
which wraps itself around a different Resource (specified as a nested
element inside a build file) and forwards all "normal" methods to the
wrapped Resource.

You'd only need to implement setters for your additional attributes and
should be done.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org