ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jose Alberto Fernandez" <>
Subject Re: antlib descriptor
Date Wed, 20 Feb 2002 01:26:00 GMT
From: "Conor MacNeill" <>

> Steve Loughran wrote:
> > Also, can you leave some space inside this DTD for adding in implementations
> > of abitrary roles, even if we dont actually support such roles in Ant1.5.
> > Example: conditions, ejbjar extensions, javac and jsp factories. That way we
> > can tack full support for them in in the post 1.5 timeframe inside libraries
> > that will also work (downgraded) on ant 1.5.
> > 
> Let's agree on the concept of roles firstly then :-)


> I have not implemented roles in mutant as I have always found the 
> descriptions relatively complex. What are the goals of defining and 
> using roles? As far as I can see this is to allow extensibility, 
> primarily the ability to define new nested elements for a task without 
> changing the task.  Mutant supports this capability in, IMHO, a simpler 
> way, although it is perhaps less appealing syntactically.

To jump ahead, I really dislike Mutant extensibility approach. I wouldn't
mind it as a way to resolve ambiguities, but to be the only notation 
for doing it, that I really dislike. We are talking not only about exotic things like
<ejbjar> but also basic things like <condition>, <mappers>, etc.
Needing to use Mutant's notation all over the place, defeates the hole

> To understand the propsals being put forth to support roles, I have 
> studied Jose Alberto's sandbox proposal. Jose Alberto, could I ask that 
> you do not use tabs. You may also consider using a tool like checkstyle 
> to verify your Javadoc. Anyway, this is my understanding of how roles work.

I will do that when things are a little more stable, with so many ideas comming from you
guys, I am still changing things around. 

Just as an initial note to my comments bellow, let me just remind people that
my proposal is constraint by having to maintain the semantic of the code
currently in ANT1, many of the ordering desicions have to do with the fact
that in ANT1 that is the order in which things are done. 

> Lets say we are presented with the following construction
> <foo>
>    <bar>
> where foo is an instance of Foo class and we are trying to create the 
> nested element bar. It appears that before the standard addBar, 
> createBar methods are checked, the code will attempt to use the role 
> framework to create the nested element. I think myrmidon does this in 
> the other order.

Yes, this is because in ANT1, for tasks (role TaskContainer) the method
"addTask" will not be taken into account as an introspector method.
In the generalization this means that roles take precedence over Introspected

> ProjectHelper calls IntrospectionHelper to create the nested element.
> IntrospectionHelper calls Project.createInRole.
> Project.createInRole calls SymbolTable.findRoles to find all Roles which 
> are implemented by Foo.class. This works by iterating through all the 
> roles in the system and checking if Foo implements the Role's 
> corresponding interface. findRoles returns a list of the satisfying Role 
> names.
> Let's say there are three roles - thing, widget, dunsel - returned.

Notice that in general, I think, the number of roles will be small, and that
in particular very few roles will apply at any given point.

> For each of these roles, Project calls createForRole, passing the name 
> of the role and the name of the nested element (bar in this case). For 
> each role, it attempts to find a factory calling SymbolTable.get (I 
> think this should be renamed getFactory). The factory object is used to 
> create the instance. If more than one factory is found, an error is 
> thrown. Lets say Foo implements Thingable. "bar" must have been 
> registered as supporting the Thingable role (not that it implements 
> Thingable)

Good point about the getFactory(). I would say that bar must define
a type appropriate for a Thingable container. I english here is not easy
since what in escense we need to say is that the type of <bar> as defined
on role Thingable, must be a type compatible argument for the method
of the thingable interface.

> The symbolTable object is consulted each time to get the interface 
> method corresponding to the role. If only one instance is created, the 
> interface method is invoked on foo with the instance.
> foo.addThing(bar);

This is a fair description. Notice that the reason it is the way it is, is to
make it compatible with ANT1 and in particular the way in which ANT1
defines containers of tasks (i.e., interface TaskContainer). This is why
the role is defined by the interface implemented by the role.

Additionally in myrmidom, if I remember correctly, there is a requirement that
the methods for roles, must have interfaces as the type of the arguments,
but since ANT1 uses classes instead of interfaces to define almost everything
this approach would have problems in ANT1.

> If I understand Peter's description of roles in myrmidon (from 7th Jan 
> email, I also had a quick look at the code but it wasn't clear to me), 
> it is pretty similar to the above, although the role is associated with 
> the interface implemented by the nested instance rather than by the 
> "container" class. IOW, rather than searching for every role interface 
> implemented by Foo.class, myrmidon searches for interfaces based on the 
> existence of add(X x) methods. It determines the roles by looking up the 
> role that corresponds to class X.
> If we boil down what roles do, I see it as
> 1. determines the type of the instance that should be created
> 2. determines the method which should be called to add that instance
> I took a slightly different approach to that problem in mutant. The 
> syntax I use is
> <foo>
>    <thing ant:type="bar">

As  said before, I really dislike the syntax in Mutant in particular because
with a syntax like that there is no need for the "ant:type" attribute,
one could get the same result with similar notation using the current ANT1.
Bt for some reason people dislike it (that is why we keep on having things
like <ejbjar>, <condition> etc.

If your syntax where instead of the form:

      <bar ant:role="thing" >

Then at least I could see this syntax as a way to disambiguate things. But I would
still like to make such attribute optional.

> So, the nested element name identifies the method to be called 
> (addThing()) and the data type is given by the ant:type attribute. The 
> name, "bar" is a standard Ant datatype registered with typedef, for 
> example. I am using the ant namespace for the necessary metadata. I also 
> use it to identify reference instances (ant:refid), I think myrmidon 
> adds "-ref" to the element name.
> To give an example using real Ant types.
> <foo>
>    <fileset ant:type="zipfileset">
> Mutant's approach is pretty simple and also quite explicit. The build 
> file writer asks explicitly for the type they want, rather than the 
> background plumbing figuring it out. The roles approach has always 
> seemed a little complicated to me. I guess the downside in my approach 
> is that the syntax is a little ugly.

Yes ugly, too ugly, uglier that a box of chocolates :-)

> Anyway, I'd appreciate your thoughts. If everybody thinks roles are the 
> way to go, I guess I'll have to handle the complexity. Also it would 
> probably be worth harmonizing on which interface we are going to 
> identify with the role.

Whatever we decide, we need to take into account the restriction of not breaking
ANT1 ad the way it does things. In perticular this means that mutant and myrmidom
aproaches will not work because the syntax is incompatible with the tasks 
already inexistance. That does not mean that my should be taken as is, I am open for comments.

Jose Alberto

To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message