You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Steve Amerige <St...@sas.com> on 2012/01/25 12:51:47 UTC

Filtering Macrodef Elements

Hi all,

I'm looking to filter a macrodef element before it gets interpreted so as to change it's behavior.  Here's an example of what I'm 
talking about:

<target name="myentrypoint">
...
<mymacro>
<%{mytask} %{myattribute}="%{myvalue}"/>
     %{myblockofcode}
</mymacro>
...
</target>

In other words, I want the definition of mymacro to do *token substitution *on the (implicit) element body and then have that 
changed body executed.  (The token substitution algorithm, in my case, is not a simple replacement procedure but requires some more 
complex processing, in case that matters to this question.)

Here are my limitations:

1.  My target is being called by some other Ant code.  I do not have any control of what happens before I'm called, nor can I change 
how Ant was invoked or do any compilation.

2. Once in my target, I can use Groovy scriptdefs, Ant-Contrib, and anything that comes with Ant 1.7.

Can anyone suggest how this might be done?  I did read "Developing with Apache Ant, Writing Your Own Task 
<http://ant.apache.org/manual/develop.html>," but I'm not sure if this helps considering what I have available to me.  I'm hoping 
that since I have Groovy (essentially, Java), that something might still be possible.

Any ideas?

Many thanks,
Steve Amerige
SAS Institute, Deployment Software Development

Re: Filtering Macrodef Elements

Posted by Steve Amerige <St...@sas.com>.
Hi all,

I've done a bit of work on this and have modified the doit.groovy to:

import org.apache.tools.ant.Task

import java.lang.Class.*
import java.lang.reflect.*

def groovydoit()
{
     Task body = (Task) elements.get("sequential").get(0)
     println body.dump()

     Class c = Class.forName("org.apache.tools.ant.taskdefs.Sequential")
     def m = c.getDeclaredMethods()
     m.each() {
        println it
     }
     Field f = c.getDeclaredField("nestedTasks")
     f.setAccessible(true)
     Vector nestedTasks = (Vector)f.get(body)
     for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();)
     {
        Task nestedTask = (Task)e.nextElement();
        nestedTask.perform()
     }
}

You'll notice that I'm using reflection to get the private field *nestedTasks *in *org.apache.tools.ant.taskdefs.Sequential*.  After 
that, I can do what execute() would do and I'm iterating over the element body.

I'm thinking that if I can do:

  * Serialize each nested task to a string representation
  * Make my tokenization substitutions
  * Take the resultant string and form a Task from it

then, this would solve the tokenization challenge.  Can anyone suggest how I can do the above?

Thanks,
Steve Amerige
SAS Institute, Deployment Software Development


On 1/25/2012 1:12 PM, Scot P. Floess wrote:
> Steve,
>
> Definitely gonna need to think about this ;)  At this point, "I got
> nothin'"   ;)
>
> On Wed, 25 Jan 2012, Steve Amerige wrote:
>
>> Hi Flossy,
>>
>> On 1/25/2012 10:00 AM, Scot P. Floess wrote:
>>> Just at a first glance - one consideration I'd mention is that what you
>>> list is not syntactically correct XML...  So, I think if you wanted
>>> something like that you will need to preprocess and convert to an XML that
>>> can be processed.  Unless that is what you are saying and I've
>>> misunderstood ;)
>> Thanks for the reply.  You're right in that the syntax wasn't correct.  Here
>> is the revision:
>>
>> <target name="myentrypoint">
>> <!-- ... -->
>>
>>    <mytokenizer>
>>       %{mytask} %{myattribute}="%{myvalue}" %{/mytask}
>>       %{myblockofcode}
>>    </mytokenizer>
>>
>> <!-- ... -->
>> </target>
>>
>> The *mytokenizer *task would do substitutions for the %{*/token/*} entries.
>>
>> The requirement is that the tokenization happen not as a pre-process step,
>> but during the execution of the *myentrypoint *target.  Compiling code is not
>> available to me.  Changing the requirements I need to live with is not
>> possible.  I will define the *mytokenizer *macrodef or scriptdef in the same
>> file as the *myentrypoint *and I can use Ant 1.7, Ant-Contrib, and Groovy
>> code.
>>
>> I'm trying to figure out how to define *mytokenizer *to solve this problem.
>>
>> Thanks,
>> Steve Amerige
>> SAS Institute, Deployment Software Development
>>
>>
> Scot P. Floess             RHCT  (Certificate Number 605010084735240)
> Chief Architect FlossWare  http://sourceforge.net/projects/flossware
>                              http://flossware.sourceforge.net
>                              https://github.com/organizations/FlossWare
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
>
>
>


Re: Filtering Macrodef Elements

Posted by "Scot P. Floess" <sf...@nc.rr.com>.
Steve,

Definitely gonna need to think about this ;)  At this point, "I got 
nothin'"   ;)

On Wed, 25 Jan 2012, Steve Amerige wrote:

> Hi Flossy,
>
> On 1/25/2012 10:00 AM, Scot P. Floess wrote:
>> Just at a first glance - one consideration I'd mention is that what you
>> list is not syntactically correct XML...  So, I think if you wanted
>> something like that you will need to preprocess and convert to an XML that
>> can be processed.  Unless that is what you are saying and I've
>> misunderstood ;)
>
> Thanks for the reply.  You're right in that the syntax wasn't correct.  Here 
> is the revision:
>
> <target name="myentrypoint">
> <!-- ... -->
>
>   <mytokenizer>
>      %{mytask} %{myattribute}="%{myvalue}" %{/mytask}
>      %{myblockofcode}
>   </mytokenizer>
>
> <!-- ... -->
> </target>
>
> The *mytokenizer *task would do substitutions for the %{*/token/*} entries.
>
> The requirement is that the tokenization happen not as a pre-process step, 
> but during the execution of the *myentrypoint *target.  Compiling code is not 
> available to me.  Changing the requirements I need to live with is not 
> possible.  I will define the *mytokenizer *macrodef or scriptdef in the same 
> file as the *myentrypoint *and I can use Ant 1.7, Ant-Contrib, and Groovy 
> code.
>
> I'm trying to figure out how to define *mytokenizer *to solve this problem.
>
> Thanks,
> Steve Amerige
> SAS Institute, Deployment Software Development
>
>

Scot P. Floess             RHCT  (Certificate Number 605010084735240)
Chief Architect FlossWare  http://sourceforge.net/projects/flossware
                            http://flossware.sourceforge.net
                            https://github.com/organizations/FlossWare

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: Filtering Macrodef Elements

Posted by Steve Amerige <St...@sas.com>.
Hi Flossy,

On 1/25/2012 10:00 AM, Scot P. Floess wrote:
> Just at a first glance - one consideration I'd mention is that what you
> list is not syntactically correct XML...  So, I think if you wanted
> something like that you will need to preprocess and convert to an XML that
> can be processed.  Unless that is what you are saying and I've
> misunderstood ;)

Thanks for the reply.  You're right in that the syntax wasn't correct.  Here is the revision:

<target name="myentrypoint">
<!-- ... -->

    <mytokenizer>
       %{mytask} %{myattribute}="%{myvalue}" %{/mytask}
       %{myblockofcode}
    </mytokenizer>

  <!-- ... -->
</target>

The *mytokenizer *task would do substitutions for the %{*/token/*} entries.

The requirement is that the tokenization happen not as a pre-process step, but during the execution of the *myentrypoint *target.  
Compiling code is not available to me.  Changing the requirements I need to live with is not possible.  I will define the 
*mytokenizer *macrodef or scriptdef in the same file as the *myentrypoint *and I can use Ant 1.7, Ant-Contrib, and Groovy code.

I'm trying to figure out how to define *mytokenizer *to solve this problem.

Thanks,
Steve Amerige
SAS Institute, Deployment Software Development


Re: Filtering Macrodef Elements

Posted by "Scot P. Floess" <sf...@nc.rr.com>.
Steve,

Just at a first glance - one consideration I'd mention is that what you 
list is not syntactically correct XML...  So, I think if you wanted 
something like that you will need to preprocess and convert to an XML that 
can be processed.  Unless that is what you are saying and I've 
misunderstood ;)

Flossy


On Wed, 25 Jan 2012, Steve Amerige wrote:

> Hi all,
>
> I'm looking to filter a macrodef element before it gets interpreted so as to 
> change it's behavior.  Here's an example of what I'm talking about:
>
> <target name="myentrypoint">
> ...
> <mymacro>
> <%{mytask} %{myattribute}="%{myvalue}"/>
>    %{myblockofcode}
> </mymacro>
> ...
> </target>
>
> In other words, I want the definition of mymacro to do *token substitution 
> *on the (implicit) element body and then have that changed body executed. 
> (The token substitution algorithm, in my case, is not a simple replacement 
> procedure but requires some more complex processing, in case that matters to 
> this question.)
>
> Here are my limitations:
>
> 1.  My target is being called by some other Ant code.  I do not have any 
> control of what happens before I'm called, nor can I change how Ant was 
> invoked or do any compilation.
>
> 2. Once in my target, I can use Groovy scriptdefs, Ant-Contrib, and anything 
> that comes with Ant 1.7.
>
> Can anyone suggest how this might be done?  I did read "Developing with 
> Apache Ant, Writing Your Own Task 
> <http://ant.apache.org/manual/develop.html>," but I'm not sure if this helps 
> considering what I have available to me.  I'm hoping that since I have Groovy 
> (essentially, Java), that something might still be possible.
>
> Any ideas?
>
> Many thanks,
> Steve Amerige
> SAS Institute, Deployment Software Development
>

Scot P. Floess             RHCT  (Certificate Number 605010084735240)
Chief Architect FlossWare  http://sourceforge.net/projects/flossware
                            http://flossware.sourceforge.net
                            https://github.com/organizations/FlossWare

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org