ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Murdoch" <adammurdoch...@yahoo.com>
Subject RE: TaskAdapter and execute()
Date Sat, 02 Mar 2002 05:11:34 GMT


> -----Original Message-----
> From: Erik Hatcher [mailto:jakarta-ant@ehatchersolutions.com]
> Sent: Saturday, 2 March 2002 1:21 PM
> To: Ant Developers List
> Subject: Re: TaskAdapter and execute()
> 
> 
> From: "Peter Donald" <peter@apache.org>
> > > On Fri, 1 Mar 2002 23:21, Adam Murdoch wrote:
> > > > The other bit would be to nick the XDocs stuff and get task/type
> > > > documentation going.
> >
> > I went to do this and came across issues regarding set/add confusion. I
> was
> > thinking that it may be to go back to the idea that set is just for
> > attributes and add is for nested elements. If you need to have both an
> > attribute and element with same name/type then the task developer can
> simply
> > write something like
> 
> [ I haven't been closely following myrmidon's code so forgive a "newbie"
> question ]
> 
> I thought the idea was to get away from a task knowing anything about its
> XML structure.  Why should a task care whether things are attributes or
> elements?  Aren't they essentially the same to the actual task?
> 

Yep, that is the idea.


> Could you explain this to me from the perspective of the actual 
> task itself?
> 

Here's how myrmidon currently configures objects:

Configuration in myrmidon is a touch more bean-like than Ant 1.  A class declares a bunch
of properties (a name, and an expected type, and a max multiplicity).  It does not (can not)
distinguish between properties that are set using an attribute, and those set using a nested
element (or a mix), or those set using a reference, or those set using a sub-type of the expected
type.

A class declares its properties using adder and setter methods.  Each setFoo() or addFoo()
method of a class defines a property 'foo'.  Using a setFoo() method indicates that the property
is single valued, and can be called at most once.  Using an addFoo() method, indicates that
the property is multi-valued, and can be called zero or more times.  It is an error to have
more than one adder/setter method on a class (except those that take String, they have a lower
precedence and are ignored if there is a non-String method).

For each attribute 'foo' of the element:

* The configurer looks for a property called 'foo' - that is, it looks for an addFoo() or
a setFoo() method.

* The configurer attempts to convert from the String attribute value to the type expected
by the adder/setter method.  Converters are pluggable, so task writers can add their own converters
to do specialised conversion.  There are also a bunch of 'built-in' converters (more or less
the same ones that come with Ant 1).  If no appropriate converter is available, an error is
thrown.

* The configurer calls the adder/setter method to set the property.  For single valued properties,
the configurer keeps track of the fact that it has set the property.

Net result is that a property can be set using an attribute, only if there is a converter
available to convert from String to the expected type.

For each nested element 'foo':

* The configurer looks for a property called 'foo'.

* If the property is single valued, and the property has already been set, an error is thrown.
 This can happen if either the property was already set using an attribute, or an earlier
nested element.

* The configurer creates an instance of the expected type.  If there is a createFoo() method,
then that is called to create the instance.  Otherwise the no-args constructor is called to
create the instance.

* The configurer recursively configures the instance using the nested element.

* The configurer calls the adder/setter method to set the property.  Again, it keeps track
of the fact that the property has been set, for single valued properties.

Net result is that a property can be set using a nested element, only if there is a creator
method, or if the expected type has a no-args constructor.

I've left out how references and polymorphism work, 'cause they still needs some work, and
are just noise at this stage.  Regardless, having the configurer handle references, and polymorphism,
is definitely the way of the future.

So, the class doesn't know or care whether the values of its properties come from.  The mapping
from XML attribute or nested element is solely the responsbility of the configurer.  For the
default configurer (we have 2 impls ATM, and you can always swap in your own), the mapping
depends on whether or not an instance of the expected type can be assembled from the attribute
or element in question.

Does that help explain things, or just muddy the water more?


Adam


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


Mime
View raw message