From: "Tim Dawson" <[EMAIL PROTECTED]>
> Sorry I wasn't as clear as I could have been.
>
> Imagine the following antlib deployment descriptor:
>
> <antlib>
> <typedef element="and"
> class="org.apache.ant.types.And"
> property="condition"/>
> <typedef element="or"
> class="org.apache.ant.types.Or"
> property="condition"/>
> <taskdef element="echo"
> class="org.apache.ant.tasks.Echo"/>
> </antlib>
>
As Peter just said, this is very close to <role/>s in his proposal.
The one thing I do not like about your design, is that it seems that you
are prescribing in the definition of the type, how tasks must name their
things. It looks funny to me.
By calling them <role/>s Peter seem to "decouple" it from the syntax. It means
that the groupping has a purpose beyond telling what name should be used
in tasks. On the other hand, I kind of like that your discovery is a little
stronger
than just by type matching.
> if a build file was encountered that had
>
> <target name="foo">
> <condition property="isMacOsButNotMacOsX">
> <and>
> <os family="mac" />
> <not>
> <os family="unix" />
> </not>
> </and>
> </condition>
> </target>
>
> The implementation of the Condition task and the Condition types (And, Os,
> Not, etc) would have been much simpler. Instead of all the addAnd() addOs()
> addNot() etc. methods, there would have been one addCondition() method in
> the ConditionTask class and one addCondition() method in the ConditionType
> abstract superclass (which would no longer need to inherit through the task
> hierarchy).
>
> This result is the same as what Conor proposed, the difference in what I'm
> proposing is how you determine what add() method to call -- something more
> well-defined, like the suggested deployment descriptor, or guessing based on
> introspecting superclasses (& eventually implemented interfaces), which is
> more flexible but less deterministic?
>
I guess the key difference here, is that for matching, the task writer needs to
specify the
<role> name it is expecting to have. This I like. I would also like for the
tasks to be more explicit
in indicating that they are expecting a role and not an attribute.
For example, if the method name where of the form:
public void addroleRolename(RoleType);
as you can see from the capitalization, this will not conflict with any
existing methods of the interface,
so in that regard is better than addConfiguredXXX() which could produce a clash.
On the other hand, addRolename() is compatible with the current pattern task
container, hence
we could eliminate the check for TaskContainer, and let introspection do the
job.
NOW FOR A DIFFERENT PROPOSAL:
One of the problems I have with these proposals is that they may be guessing
too much.
Introspection cannot differentiate if the presence of addCondition() means that
the task
wants to accept any type in a role called "condition" OR it is expecting an
element named
<condition/>. Peter, I think, tries to solve this by saying the parameter type
in the
case of a role need to be an interface, but that is just limitting (at least in
the case of ANT1.x
where many things are quite concreate e.g., Task).
My suggestion is for the <role> declaration to define an interface that the
Container needs to
implement. So for example any task that wants to allow for condifions must
implement
the interface ConditionContainer defined as:
interface ConditionContainer {
public addCondition(Condition c);
}
In the role definition in the descriptor you specify this as part of the role
description:
<role name="condition" typeclass="org.apache.ant.ConditionBase"
containerclass="org.apache.ant.ContainerCondition" />
and then the types are defined as ussual (by Peter):
<condition name="and" classname="org.apache.ant.types.And" />
This should be completely compatible with the current TaskContainer interface
used
in ANT1.x. And provides a stronger contract and less guessing by the
introspector.
Jose Alberto
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>