ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Antoine Levy-Lambert" <levylamb...@tiscali-dsl.de>
Subject Re: antlib
Date Wed, 21 May 2003 14:24:18 GMT

----- Original Message -----
From: "Conor MacNeill" <conor@cortexebusiness.com.au>
To: "Ant Developers List" <dev@ant.apache.org>
Sent: Wednesday, May 21, 2003 1:54 PM
Subject: Re: antlib


> On Wed, 21 May 2003 08:31 pm, Jose Alberto Fernandez wrote:
> >
> > Well I have to say you are mistaken, in my proposal the task (container)
> > implemented the addConfigured(InterfaceRole) method. The interface was
> > for the thing being passed (the child element, after possibly some
> > adaptor).
> >
>
> Well I am glad to hear I am wrong. Until 7 days ago, the code in your
proposal
> was this (Project.java)
>
>     public Object createInRole(Object container, String type) {
>         Class clz = container.getClass();
>         String roles[] = symbols.findRoles(clz);
>         Object theOne = null;
>         Method add = null;
>
> It certainly implies the roles are associated with the Container class,
not
> the nested "type" name. findRoles is checking if
> Role.isImplementedBy(container class).
>
> Right now that method has been removed from Project.java and nothing I see
> calls findRoles. Actually I don't really understand how the proposal
> currently hangs together.
>
Conor, it is well possible that the proposal currently has some errors in
the code. I have had to do a lot of surgery on the proposal to make it
compile, without understanding fully a number of classes such as
ComponentHelper, IntrospectionHelper. Originally, these classes were in the
proposal; I had problems with them due to the evolution of Project.java in
the main branch, and I simply removed them - probably wrongly - from the
proposal.
> >
> > The reason had to do with been able to deal with object (classes) that
may
> > implement multiple interfaces. The code should not pick just
> > any arbitrary interface for which it happens to be an
> > addConfigured(Interface) in the container and just use it. If the object
> > implements 5 interfaces for which we have addConfigured(InterfaceN)
which
> > one should we used? Definetly it should not be taken by chance. Part of
the
> > reason
> > for the infrastructure is to try to minimize this cases and allow users
to
> > resolve when this issues arise.
> >
>
> Won't this be relatively rare (i.e. a class implementing multiple
interfaces
> being passed to a task accepting more than one of those interfaces)? If
the
> nested element is implementing multiple interfaces won't it also support
> multiple roles? Or do I need to typedef the same class into two different
> typenames, one for each role. So, if my circle also implements a
> org.apache.demo.BlockInterface interface, will it support the "block"
role.
> Is it (extending Antoine's example)
>
> <roledef name="block" class="org.apache.demo.BlockInterface"/>
> <typedef name="circle" class="org.apache.demo.Circle" role="shape,
block"/>
>
> or
>
> <roledef name="block" class="org.apache.demo.BlockInterface"/>
> <typedef name="circle" class="org.apache.demo.Circle" role="shape"/>
> <typedef name="circleblock" class="org.apache.demo.Circle" role="block"/>
>
> The first option would mean roles are no better at selecting a method than
a
> search based on the implemented interfaces. The second would be OK, but I
> think we are getting pretty messy. An instance supporting multiple
interfaces
> can't be passed to different tasks using different interfaces. A
circleblock
> instance could not be passed to a task taking a ShapeInterface, because it
is
> not in that Role. A class supporting multiple interfaces is probably
intended
> to be used as both types of objects at different times.
>
> How does the multiple role situation "allow users to resolve when this
issues
> arise"? What am I missing?
>
> Overall, I still see it as a lot of complexity for the exceptional case.
>
> Conor
>
>
I would go for the second solution, that is define circle and circleblock as
two different xml tags.
It is one way to make sure that the right add method is called.

I would see another argument for roles. A Java class can implement a number
of interfaces, some of which are currently not relevant to ant for the
purpose of choosing an addConfiguredXYZ method. For instance, a datatype
could implement Cloneable, Serializable, etc and these interfaces are not
relevant for ant.

I do not see a lot of complexity in this role business. I don't think that
adding a role attribute in the typedef task will make things much heavier
for users. Probably ant users are never going to have a look at all these
typedef, taskdef, roledef and just use whatever is in their antlib
descriptor or in a resource file supplied with third party ant tasks and
datatypes.

The advantages of roles would be to allow a very deterministic style of
programming.

There would be however a half lazy solution :

- implement a <roledef/> task such as
<roledef name="shape" class="org.apache.demo.ShapeInterface"/>
<roledef name="block" class="org.apache.demo.BlockInterface"/>

- and just rely on introspection to map typedefs to roles (that is to look
which interfaces the class of a typedef implements)

In this case, all components containing an
addConfiguredXYZ(org.apache.demo.ShapeInterface) will be automatically
fitted by IntrospectionHelper the capacity to add classes derived from
ShapeInterface. So if there is a <typedef name="circle"
class="org.apache.demo.Circle"/>, and that Circle implements ShapeInterface,
then IntrospectionHelper will behave as if the ComputeAreaTask and
ComputePerimeterTask were containing an addConfiguredCircle method.

In ambiguous cases, if Circle implements two or more interfaces which have
been marked as roles, then you will need to throw an exception in the build.
Or in the ComputePerimeterTask, you could have
<computeperimeter>
      <circle radius="5" centerx="12" centery="-1.5" ant-role="shape"/>
      <!-- triggers the invocation of an
addConfiguredShape(org.apache.demo.ShapeInterface) method -->
      <circle radius="5" centerx="12" centery="-1.5" ant-role="block"/>
      <!-- triggers the invocation of an
addConfiguredBlock(org.apache.demo.BlockInterface) method -->
</computeperimeter>

- maybe also accept a role attribute in typedefs without making it
compulsory, for developers of third party ant add ons who want to be 100%
sure how their tags are going to be used.

Cheers

Antoine


Mime
View raw message