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

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.

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.

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)

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

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


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.

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.

Cheers
Conor



--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>



Reply via email to