ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Donald <pe...@apache.org>
Subject Re: IntrospectionHelper request
Date Mon, 07 Jan 2002 04:32:44 GMT
On Mon, 7 Jan 2002 11:33, Jose Alberto Fernandez wrote:
> From: "Peter Donald" <peter@apache.org>
>
> > So far I haven't actually seen a good use for it. Can you give me a good
> > use case ? The only one provided is directly due to limitations in Ant1.x
> > model. When these limitations are removed there would be no need for
> > DynaTask. So besides the specified case have you got another example ?
>
> The examples I have are things like <ejb-jar> which need to support new
> elements as new EJBcontainers are supported, and tasks like <condition>
> that is suppose to allow more conditions being defined over time. The
> curent requirement of modifying core tasks everytime a new thing is added
> is totally unacceptable.

agreed. Theres a whole bunch of other types aswell (ie mappers) that have 
similar limitations.

> A simmilar problem we are having with <javac>
> everytime we add support for a new compiler.

javac/jsp/etc is a similar problem however not exactly the same and not 
something I will address in myrmidon (at least not in the near future). There 
will still be some ugly hardcoding in here but recently Adam suggested using 
XML format to configure the underlying services such as

<javac ...>
  <jikes warnings="full" .../>
</javac>

However this is more radical than what I have been thinking about but it is 
one possible solution. I have not really played with it to see whether it 
works or not.

> I have not seen a good solution for this issues. Upto now we are stuck on
> requiring changing the core tasks in order for the introspector to work.
> That should not be needed.

It was explained the same time I explained the notion of types/roles which 
you missed also ;) Basically it goes something like the following.

Myrmidon defines roles in a roles.xml file. Each role represents a grouping 
of types for a similar purpose. Roles are implemented using java interfaces. 
So lets say we have the role "Condition" defined by the following interface

package org.apache.myrmidon.framework.condition;

public interface Condition
{
  boolean test( TaskContext context );
}

You would then add a roles file like 

<roles>
  <role name="condition" 
class="org.apache.myrmidon.framework.condition.Condition"/>
</roles>

You would also need to add some implementations of the Condition 
interface/role and add them to a type library. Via adding them to types.xml 
file like

<types>
  <!-- some task also stored in type library -->
  <task name="a-task" class="..."/>

  <!-- note that name of element matches name of role as defined in 
roles.xml--> 
  <condition name="and" class="org.apache.myrmidon.framework.condition.And"/>
  <condition name="or" class="org.apache.myrmidon.framework.condition.Or"/>
  <condition name="not" class="org.apache.myrmidon.framework.condition.Not"/>
</types> 

Then during the configuration process you cam across element "and". You would 
first look it up using the standard mechanisms (add/create/set/whatever) and 
if that failed you would look for a single method like

void add( X x );

If X represents an interface - lets say Condition in this case - then it will 
look up the role registry to find the shorthand role name for that particular 
class. So in this case it will lookup org.apache.myrmidon.framework.Condition 
and retrieve the "condition" shorthand name.

Then it will look up the "condition" TypeFactory (where all the "condition" 
types are registered to via the types.xml). Then it will call createType() 
(or whatever the method is called) on the factory, passing in the name of the 
element (in our case "and"). The TypeFactory will then lookup its registry 
and create appropriate type (org.apache.myrmidon.framework.And in our case).

And this And instance will be configured and passed into the task via the 
add() method.

I think thats basically how it went though I have not reimplemented this in 
the latest proposal and haven't looked at it for about a year but last time I 
did it I liked it and found it satisfied almost all of my needs without being 
too complex.

> Another example is the fact that it is not possible to write a task using
> the scripting facilities that are curent in ANT. What I would like is
> scripted tasks that are at the same standing as compiled tasks. In
> particular in ANT2 I would like for scripts to have less access to the
> internal machinery of ANT but more ability to define tasks in the same
> standing as compiled tasks. The curent balance is completely wrong.

ants scripting capability needs a complete overhaul and could be good if done 
right - however thta is a massive task and not something I am game to take on 
just yet. A lot of this requires us refactoring common code into a framework 
and then creating a nice facade + documenting a particular variety 
(javascript being my preference atm).

> > > Will Ant2 allow dynamically defined attributes/elements?  If so, by
> > > what mechanism?
> >
> > Probably - the mechanism has not really been decided upon I don't think
> > but my preference was to pass the task model/task
> > configuration/hierarchial hashmap/whatever to the task and allow it to
> > configure itself (with help from the container if needed).
>
> Can you be more specific? This says very little. Some days ago someone
> talked about letting tasks provide their own introspection (the task itself
> decides what it wants to expose) is that what you are taling about? Is it
> something else?

Well how to best explain this. Hmmm .. the idea is related to the TaskModel / 
TaskProxy / TaskConfiguration concept. Where in ant1.x you build a tree of 
task objects as you parse the project in ant2 you will create a tree of task 
models or whatever that are basically representations of the XML describing 
the task. 

So when Ant2 goes to execute a task it will 
1. create a task with same name as top level element of task (by looking in 
type registry)
2. pass all the required services to task (TaskContext and friends)
3. configure task
4. maybe validate task
5. call execute()

So with stage 3 sometime you want/need to do tricky things - in particular 
when you are writing container tasks like <if/> and friends. Theres a few 
ways to do this. One is to make a number of magic tasks and establish a whole 
other set of patterns for the container tasks to implement and hope this 
works out properly. However this leads to far too much complexity IMHO and is 
not flexible for people who want to do really wierd stuff.

So the other possibility is that you pass the task it's own task model. It 
can thus read the taskmodel/XML and then interpret it as appropriate. However 
that can be hard to hack so we will provide some abstract class that makes it 
simple to configure attributes/elements using the containers services. 
Something like

setAttribute( anObject, "key", "myvalue" );
addElement( anObject, myElement );
execTask( myElement );

or whatever. These will be tuned to make things easy to write these sort of 
tasks. 

Now you could abuse this functionality and dynamically set proeprties and 
throw all sorts of type safety to the wind but it is not going to be 
something I think we should encourage.

-- 
Cheers,

Pete

*-------------------------------------*
| Does the name `Pavlov' ring a bell? |
*-------------------------------------*

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