ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Murdoch" <adammurdoch...@yahoo.com>
Subject RE: antlib descriptor
Date Wed, 20 Feb 2002 10:32:35 GMT


> -----Original Message-----
> From: Conor MacNeill [mailto:conor@cortexebusiness.com.au]
> Sent: Tuesday, 19 February 2002 11:33 PM
> To: Ant Developers List
> Subject: Re: antlib descriptor
>
>
> 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 :-)
>

At this stage, we can get away something very general:

A role is a way of grouping together objects that perform a similar
function, or are used in a similar way.  For example 'task' is the role that
all tasks fulfill.  We only have 2 roles at this stage: task and data-type.
We *may* add more in the future.  Maybe the new roles will be used to
implement type substitution, maybe not.  Doesn't matter for now.

So, an antlib is a collection of role implementations, and the antlib
descriptor simply contains the definitions of those implementations.  Each
top-level element in the descriptor forms the definition of a particular
implementation, and the name of the element indicates the role that the
implementation fulfills.

To be able to deal with the introduction of new roles, all we need to do at
this stage is deal with the fact that new top-level elements may appear in
future descriptor versions.


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

Yep - myrmidon looks for addBar()/setBar()/createBar() methods before trying
to create a 'bar' data-type instance.

I want to change this so that it checks both, and bails if the name is
ambiguous (and add some way for the user to unambiguously request one method
or the other).

...

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

Myrmidon has changed a little since then.  It's still in flux, of course.
Given:

<foo>
  <bar>

if there is a Foo.addBar(X x) or a Foo.add(X x), and X is an interface, the
configurer creates a 'bar' data-type instance.  Only the data-type role is
used (though this will probably change soon).

I want to change the Foo.addBar() case to work similar to the way Mutant
does, with a 'type' attribute.  The type attribute would be optional.


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

Given that myrmidon doesn't actually use roles during configuration, I don't
think that roles are necessarily the only solution to the type substitution
problem.

However, the concept of roles is a handy design pattern for extensibility.
Roles are used all through myrmidon, to great effect.  Each type of
pluggable element forms a role, and different implementations can be easily
swapped in.  Some examples:

* Roles for types that are assembled from build files, like 'task' and
'data-type'.

* Roles for types that are used internally, like 'converter' or
'project-listener' or 'project-builder'.

* Roles for each of the services that are made available to tasks, like
'exec-manager', 'file-system-manager', or 'task-executor'.

* Roles for each of the components that make up the engine, like
'configurer', 'type-manager' or 'deployer'.

So, roles and type substitution really are different issues.  If we are
going to standardise on anything (which would be a good thing), we should
decide how syntax is going to work, and then worry about whether roles
should be a visible part of the solution.


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