> -----Original Message----- > From: Erik Hatcher [mailto:[EMAIL PROTECTED] > Sent: Saturday, 2 March 2002 1:21 PM > To: Ant Developers List > Subject: Re: TaskAdapter and execute() > > > From: "Peter Donald" <[EMAIL PROTECTED]> > > > 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:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
