ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hi...@apache.org
Subject svn commit: r893502 [1/2] - in /ant/sandbox/groovyfront: ./ META-INF/ doc/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/ant/ src/main/java/org/apache/ant/groovyfront/ src/main/resources/ src/main/r...
Date Wed, 23 Dec 2009 13:05:33 GMT
Author: hibou
Date: Wed Dec 23 13:05:31 2009
New Revision: 893502

URL: http://svn.apache.org/viewvc?rev=893502&view=rev
Log:
Import of Groovy Front from bug #48347

Added:
    ant/sandbox/groovyfront/
    ant/sandbox/groovyfront/.classpath
    ant/sandbox/groovyfront/.project
    ant/sandbox/groovyfront/META-INF/
    ant/sandbox/groovyfront/META-INF/MANIFEST.MF
    ant/sandbox/groovyfront/build.xml
    ant/sandbox/groovyfront/doc/
    ant/sandbox/groovyfront/doc/doc.html
    ant/sandbox/groovyfront/ivy.xml
    ant/sandbox/groovyfront/src/
    ant/sandbox/groovyfront/src/main/
    ant/sandbox/groovyfront/src/main/java/
    ant/sandbox/groovyfront/src/main/java/org/
    ant/sandbox/groovyfront/src/main/java/org/apache/
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBinding.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBuilder.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontMetaClass.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontParsingContext.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProject.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProjectHelper.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontScriptMetaClass.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTarget.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTask.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyRunner.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SimpleNamespaceBuilder.java
    ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SubGroovyFrontTask.java
    ant/sandbox/groovyfront/src/main/resources/
    ant/sandbox/groovyfront/src/main/resources/META-INF/
    ant/sandbox/groovyfront/src/main/resources/META-INF/services/
    ant/sandbox/groovyfront/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper
    ant/sandbox/groovyfront/src/test/
    ant/sandbox/groovyfront/src/test/antunit/
    ant/sandbox/groovyfront/src/test/antunit/antlibTest.groovy
    ant/sandbox/groovyfront/src/test/antunit/varMappingTest.groovy
    ant/sandbox/groovyfront/src/test/java/
    ant/sandbox/groovyfront/src/test/java/org/
    ant/sandbox/groovyfront/src/test/java/org/apache/
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/groovyfront/
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/groovyfront/GroovyFrontAntlibTestSuite.java
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/groovyfront/GroovyFrontBuilderTest.java
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/groovyfront/GroovyFrontScriptTestSuite.java
    ant/sandbox/groovyfront/src/test/java/org/apache/ant/groovyfront/MyTestTask.java
    ant/sandbox/groovyfront/src/test/resources/
    ant/sandbox/groovyfront/src/test/resources/org/
    ant/sandbox/groovyfront/src/test/resources/org/apache/
    ant/sandbox/groovyfront/src/test/resources/org/apache/ant/
    ant/sandbox/groovyfront/src/test/resources/org/apache/ant/groovyfront/
    ant/sandbox/groovyfront/src/test/resources/org/apache/ant/groovyfront/antlib.xml

Added: ant/sandbox/groovyfront/.classpath
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/.classpath?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/.classpath (added)
+++ ant/sandbox/groovyfront/.classpath Wed Dec 23 13:05:31 2009
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+    -->
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/test/java"/>
+	<classpathentry kind="src" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?ivyXmlPath=ivy.xml&amp;confs=*&amp;acceptedTypes=jar%2Cbundle%2Cejb%2Cmaven-plugin&amp;sourceTypes=source&amp;javadocTypes=javadoc&amp;sourceSuffixes=-source%2C-sources%2C-src&amp;javadocSuffixes=-javadoc%2C-javadocs%2C-doc%2C-docs&amp;alphaOrder=true&amp;resolveInWorkspace=true"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="output" path="eclipse-classes"/>
+</classpath>

Added: ant/sandbox/groovyfront/.project
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/.project?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/.project (added)
+++ ant/sandbox/groovyfront/.project Wed Dec 23 13:05:31 2009
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+    -->
+<projectDescription>
+	<name>ant-groovyfront</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: ant/sandbox/groovyfront/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/META-INF/MANIFEST.MF?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/META-INF/MANIFEST.MF (added)
+++ ant/sandbox/groovyfront/META-INF/MANIFEST.MF Wed Dec 23 13:05:31 2009
@@ -0,0 +1,28 @@
+#        ***************************************************************
+#        * Licensed to the Apache Software Foundation (ASF) under one
+#        * or more contributor license agreements.  See the NOTICE file
+#        * distributed with this work for additional information
+#        * regarding copyright ownership.  The ASF licenses this file
+#        * to you under the Apache License, Version 2.0 (the
+#        * "License"); you may not use this file except in compliance
+#        * with the License.  You may obtain a copy of the License at
+#        *
+#        *   http://www.apache.org/licenses/LICENSE-2.0
+#        *
+#        * Unless required by applicable law or agreed to in writing,
+#        * software distributed under the License is distributed on an
+#        * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#        * KIND, either express or implied.  See the License for the
+#        * specific language governing permissions and limitations
+#        * under the License.
+#        ***************************************************************
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Ant GroovyFront
+Bundle-SymbolicName: org.apache.ant.groovyfront
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Require-Bundle: com.springsource.org.codehaus.groovy;bundle-version="1.6.5",
+ com.springsource.org.apache.tools.ant;bundle-version="1.8.0",
+ com.springsource.org.apache.tools.ant.launch;bundle-version="1.8.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5

Added: ant/sandbox/groovyfront/build.xml
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/build.xml?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/build.xml (added)
+++ ant/sandbox/groovyfront/build.xml Wed Dec 23 13:05:31 2009
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+    -->
+<!--
+	Bootstrap build
+-->
+<project name="ant-groovyfront" default="build" xmlns:ivy="ivy" xmlns:bushel="bushel" xmlns:au="antlib:org.apache.ant.antunit">
+
+    <property name="project.version" value="1.0.0" />
+
+    <path id="antlib.classpath">
+        <fileset dir="${basedir}/../common-build/lib">
+            <include name="*.jar" />
+        </fileset>
+    </path>
+
+    <target name="clean">
+        <delete dir="${basedir}/target" />
+    </target>
+
+    <target name="build">
+        <taskdef uri="ivy" resource="org/apache/ivy/ant/antlib.xml" classpathref="antlib.classpath" />
+        <taskdef uri="bushel" resource="com/googlecode/bushel/ant/antlib.xml" classpathref="antlib.classpath" />
+        <bushel:buildobr dir="${basedir}/../external-bundles" out="${basedir}/../common-build/repo-external.xml" indent="true" />
+        <ivy:configure file="${basedir}/../common-build/ivysettings.xml" />
+        <ivy:resolve file="ivy.xml" conf="*" />
+        <ivy:cachepath pathid="ivy.compile.classpath" conf="default" useOrigin="true" />
+        <mkdir dir="${basedir}/target/classes" />
+        <path id="compile.classpath">
+            <fileset dir="${basedir}/../common-build/apache-ant-1.7.1/lib" includes="*.jar" />
+            <path refid="ivy.compile.classpath" />
+        </path>
+        <javac srcdir="${basedir}/src/main/java" classpathref="compile.classpath" destdir="${basedir}/target/classes" debug="true">
+        </javac>
+        <copy todir="${basedir}/target/classes">
+            <fileset dir="${basedir}/src/main/resources" />
+        </copy>
+        <jar basedir="${basedir}/target/classes" destfile="${basedir}/target/${ant.project.name}_${project.version}.jar">
+        </jar>
+    </target>
+
+    <target name="deploy" depends="clean,build">
+        <copy file="${basedir}/target/${ant.project.name}_${project.version}.jar" todir="${basedir}/../common-build/apache-ant-1.7.1/lib/" />
+    </target>
+
+    <target name="test">
+        <taskdef uri="antlib:org.apache.ant.antunit" resource="org/apache/ant/antunit/antlib.xml" classpathref="antlib.classpath" />
+        <au:antunit>
+            <fileset dir="${basedir}/src/test/antunit" includes="**/*-test.xml" />
+            <au:plainlistener />
+        </au:antunit>
+    </target>
+</project>

Added: ant/sandbox/groovyfront/doc/doc.html
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/doc/doc.html?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/doc/doc.html (added)
+++ ant/sandbox/groovyfront/doc/doc.html Wed Dec 23 13:05:31 2009
@@ -0,0 +1,565 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+    -->
+<html>
+<body>
+
+<h1>Introduction</h1>
+
+<p>
+The groovy frontend is about bringing Groovy into Ant, so you can write your
+build file in Groovy rather than in XML. The language change so the build files are
+less overloaded of useless characters. The build file structure is kept very
+similar to the XML one. So the learning of that new language is pretty straight
+forward, the translation of an XML build file into a groovy one is quite simple.
+</p>
+
+<p>
+Actually, behind the hood you will write XML, but the 
+<a href="http://groovy.codehaus.org/Creating+XML+using+Groovy%27s+MarkupBuilder">Groovy way</a>.
+And we will get all the benefit of a scripting language as Groovy. Just to mention
+at least one feature: no more need of the ant contrib for the use of the if-then-else
+structure, you will just use the Groovy one just like you would do in Java.
+</p>
+
+<h1>Hello world</h1>
+
+<p>
+Let's see throw a very simple example how easy is to write a Groovy build script.
+So here is a simple hello world build file:
+<pre>
+project.name = 'hello-world-project'
+project.basedir = '.'
+project.defaultTarget = 'sayhello'
+
+target(name: 'sayhello', description: 'Say hello to the world') {
+  echo(message: 'Hello world !')
+}
+</pre>
+Here is what it would have been written in XML:
+<pre>
+&lt;project name="myproject" basedir="." default="sayhello"&gt;
+
+  &lt;target name="sayhello" description="Say hello to the world"&gt;
+    &lt;echo message="Hello world !" /&gt;
+  &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+</p>
+
+<p>
+As you can see a Groovy build script do not start with some root node. It is actually
+just a simple Groovy script which has some predefined function
+and variables and with which is associated an Ant project instance.
+</p>
+<p>
+So as attached variable there is the Ant project, on which we set its name,
+base directory and default target. And there is a special function (that doesn't
+appear to be so but it is) "target" which will actually define a target. The
+definition of the target take into parameter a name, it also accept a depends,
+just like in XML.
+</p>
+
+<p>
+In the target we are entering into the XML mode, where you write XML with the
+<a href="http://groovy.codehaus.org/Creating+XML+using+Groovy%27s+MarkupBuilder">
+Groovy MarkupBuilder</a>. In this mode a function call is interpreted as a XML
+tag, the parameters of the function call the attributes of the XML tag, and the
+closure (the brackets) the content (data and sub tags) of the XML tag.
+</p>
+
+<p>
+And to run that script, nothing different from the classical XML build file
+invokation. Just name your Groovy build file <tt>build.groovy</tt> file and launch
+ant in the folder you put your file in:
+<pre>
+$ ls
+build.groovy
+$ ant -p
+Buildfile: build.groovy
+
+Main targets:
+
+Other targets:
+
+ sayhello  Say hello to the world
+Default target: sayhello
+$ ant
+Buildfile: build.groovy
+
+sayhello:
+     [echo] Hello world !
+
+BUILD SUCCESSFUL
+Total time: 0 seconds
+</pre> 
+</p>
+
+<h1>Strings in Groovy</h1>
+
+<p>
+In Groovy there are two kinds of strings. Some are simple quoted which are just
+basic Strings. Some are double quoted where Groovy is parsing and replacing
+property values (usually called GString).
+</p>
+
+<p>
+The ones with are double quoted are interpreted so that we can put variable in
+place of tokens, like in XML build script. But the difference with XML is that
+while the XML script find the variables in the Ant properties and the Ant
+references, Groovy is searching in its own variable space. The Groovy frontend
+of Ant is making the Ant properties and the Ant references available to Groovy.
+So setting and getting variables in Groovy is settings and getting Ant property
+and Ant references. The Groovy strings can be used as in the XML scripts. See:
+<pre>
+  property(name: 'myprop', value: 'myvalue')
+  echo(message: "the value of myprop is: ${myprop}")
+</pre>
+But as the string is interpreted by Groovy, properties with dots cannot be
+accessed. For instance this following piece of script will fail.
+<pre>
+  property(name: 'myprop.value', value: 'myvalue')
+  echo(message: "the value of myprop is: ${myprop.value}") // myprop doesn't exist for Groovy
+</pre>
+In that case you should prefer using the Ant tokenizer by using simple string,
+simple quoted:
+<pre>
+  property(name: 'myprop.value', value: 'myvalue')
+  echo(message: 'the value of myprop is: ${myprop.value}')
+</pre>
+</p>
+
+<p>
+Escaping <code>$</code> is different in GString and in simple strings. In Ant (the
+simple string), you will use <code>$$</code>. Whereas in Groovy you should use
+<code>\$\$</code> (it is doubled because it will be also interpreted by Ant).
+</p>
+
+<p>
+So it is <b>recommended to only use simple string</b>. And if you do want
+to refer to local variables, then use GString or just use simple string
+concatenation:
+<pre>
+  def localVar = 'foo'
+  echo(message: "using GSTring to get localVar: ${localVar}")
+  echo(message: 'using simple string concatenation to get localVar: ' + localVar)
+</pre>
+</p>
+
+<h1>Groovy variables</h1>
+
+<p>
+As in every Groovy script, we can define local variables, variables local to the
+environment they are being used. For instance we can do:
+<pre>
+  def myvar = 'foo'
+  echo(message: "the value of myvar is: ${myvar}")
+</pre>
+</p>
+
+<p>
+There are also variables which are properties of the enclosing class. In the Groovy
+frontend they are managed in a custom way. It tries to map these properties to
+the Ant environment of properties and references. So when setting a Groovy you
+will actually set an Ant property (which are immutable):
+<pre>
+  myprop = 'foo'
+  myprop = 'bar'
+  echo(message: 'the value of myprop will be foo: ${myprop}') 
+</pre>
+</p>
+
+<p>
+When trying to read a variable, the Groovy frontend search for
+<ul>
+<li>a corresponding Ant property. If none found it then search for</li>
+<li>a corresponding Ant reference. If none found it then search for</li>
+<li>a real Groovy property, like the predefined ones 'project'</li>
+</ul>
+</p>
+
+<p>
+When trying to set a value on a variable, the Groovy frontend will check that:
+<ul>
+<li>it doesn't try to modify the 'project' property</li>
+</ul>
+</p>
+
+<h1>Invoke a task</h1>
+
+<p>
+Invoking a task is pretty straight forward as soon as you know how to write it
+in XML. Let's see some examples.
+</p>
+
+<table border="1">
+  <thead>
+    <tr>
+        <th></th>
+        <th>In XML</th>
+        <th>in Groovy</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>A simple task with a simple attribute</td>
+      <td><pre>
+  &lt;touch file="temp.txt" /&gt;
+</pre></td>
+      <td><pre>
+  touch(file: 'temp.txt')
+</pre></td>
+    </tr>
+    <tr>
+      <td>A task with some text as value</td>
+      <td><pre>
+  &lt;echo&gt;
+    echoing some text
+  &lt;/echo&gt;
+</pre></td>
+      <td><pre>
+  echo('echoing some text')
+</pre></td>
+    </tr>
+    <tr>
+      <td>A task with an attribute and some text as value</td>
+      <td><pre>
+  &lt;echo file="log.txt"&gt;
+    echoing some text
+  &lt;/echo&gt;
+</pre></td>
+      <td><pre>
+  echo(file: 'log.txt', 'echoing some text')
+</pre></td>
+    </tr>
+    <tr>
+      <td>A task with sub element</td>
+      <td><pre>
+  &lt;copy todir="${basedir}/target"&gt;
+    &lt;fileset dir="${basedir}/src"&gt;
+      &lt;exclude name="**/*.java" /&gt;
+    &lt;/filset&gt;
+  &lt;/copy&gt;
+</pre></td>
+      <td><pre>
+  copy(todir: '${basedir}/target') {
+    fileset(dir: '${basedir}/src') {
+      exclude(name: '**/*.java')
+    }
+  }
+</pre></td>
+    </tr>
+    <tr>
+      <td>A task mixing text value and sub element</td>
+      <td><pre>
+  &lt;fail&gt;
+    oups, it failed !
+    &lt;condition&gt;
+      &lt;not&gt;
+        &lt;isset property="thisdoesnotexist"/&gt;
+      &lt;/not&gt;
+    &lt;/condition&gt;
+  &lt;/fail&gt;
+</pre></td>
+      <td><pre>
+  fail('oups, it failed !') {
+    condition() {
+      not() {
+        isset(property: 'thisdoesnotexist')
+      }
+    }
+  }
+</pre></td>
+    </tr>
+  </tbody>
+</table>
+
+<h1>Task definition and namesapce</h1>
+
+<p>
+In Ant we can import new task and type definitions into a build script. These tasks
+and types can get into the default namespace, or in a custom one.
+</p>
+
+<p>
+When these types and tasks are defined in the default namespace, as in XML,
+nothing particular to do to call the imported tasks. For instance in XML we write:
+<pre>
+&lt;project&gt;
+
+  &lt;taskdef resource="org/apache/ivy/ant/antlib.xml" /&gt;
+
+  &lt;target name="buildlist"&gt;
+    &lt;buildlist reference="build-path" ivyfilepath="ivy/ivy.xml" reverse="true"&gt;
+      &lt;fileset dir="projects" includes="**/build.xml"/&gt;
+    &lt;/buildlist&gt;
+  &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+In Groovy it is as simple:
+<pre>
+taskdef(resource: 'org/apache/ivy/ant/antlib.xml')
+
+target(name: 'buildlist') {
+  buildlist(reference: 'build-path', ivyfilepath: 'ivy/ivy.xml', reverse: 'true') {
+    fileset(dir: 'projects', includes: '**/build.xml')
+  }
+}
+</pre>
+</p>
+
+<p>
+If the tasks or types are defined in a custom namespace, then in XML we need to
+define a XML namespace and the call of the imported tasks are in that XML namespace:
+<pre>
+&lt;project xmlns:ivy="org.apache.ivy.ant"&gt;
+
+  &lt;taskdef resource="org/apache/ivy/ant/antlib.xml" uri="org.apache.ivy.ant" /&gt;
+
+  &lt;target name="buildlist"&gt;
+    &lt;ivy:buildlist reference="build-path" ivyfilepath="ivy/ivy.xml" reverse="true"&gt;
+      &lt;fileset dir="projects" includes="**/build.xml"/&gt;
+    &lt;/ivy:buildlist&gt;
+  &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+In Groovy here is a pure Groovy way of playing with namespace:
+<pre>
+import groovy.xml.NamespaceBuilder
+
+taskdef(resource: 'org/apache/ivy/ant/antlib.xml', uri: 'org.apache.ivy.ant')
+def ns = NamespaceBuilder.newInstance([ 'ivy': 'org.apache.ivy.ant' ], project.references['groovyfront.builder'])
+
+target(name: 'buildlist') {
+  ns.'ivy:buildlist'(reference: 'build-path', ivyfilepath: 'ivy/ivy.xml', reverse: 'true') {
+    fileset(dir: 'projects', includes: '**/build.xml')
+  }
+}
+</pre>
+The Groovy frontend of Ant is providing easier way of playing with them:
+<pre>
+taskdef(resource: 'org/apache/ivy/ant/antlib.xml', uri: 'org.apache.ivy.ant')
+def ivy = groovyns(uri: 'org.apache.ivy.ant')
+
+target(name: 'buildlist') {
+  ivy.buildlist(reference: 'build-path', ivyfilepath: 'ivy/ivy.xml', reverse: 'true') {
+    fileset(dir: 'projects', includes: '**/build.xml')
+  }
+}
+</pre>
+You can also specify a prefix to the groovyns so that in the log you don't get
+the verbose uri log, just the prefix. Without the prefix you can get in the log
+something like this:
+<pre>
+  [org.apache.ivy.ant:buildlist] ...
+</pre>
+If you specify a prefix this way:
+<pre>
+def ivy = groovyns(prefix: 'ivy', uri: 'org.apache.ivy.ant')
+</pre>
+Then you get in the log:
+<pre>
+  [ivy:buildlist] ...
+</pre>
+</p>
+
+<h1>Import / Include</h1>
+
+<p>
+<code>import</code> being a keyword in Groovy, the <code>import</code> Ant task
+has been renamed in the Grovvy frontend <code>include</code>. So
+<code>include</code> is just a direct alias of <code>import</code>, the
+functionality is exactly the same.
+</p>
+
+<p>
+As this Groovy frontend is just a frontend above Ant, we can actually mix XML
+build files with Groovy ones. Only the language is different.
+</p>
+
+<table border="1">
+  <thead>
+    <tr>
+        <th></th>
+        <th>In XML</th>
+        <th>in Groovy</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>Import of a build.xml file</td>
+      <td><pre>
+  &lt;import file="common/build.xml" /&gt;
+</pre></td>
+      <td><pre>
+  include(file: 'common/build.xml')
+</pre></td>
+    </tr>
+    <tr>
+      <td>Import of a build.groovy file</td>
+      <td><pre>
+  &lt;import file="common/build.groovy" /&gt;
+</pre></td>
+      <td><pre>
+  include(file: 'common/build.groovy')
+</pre></td>
+    </tr>
+  </tbody>
+</table>
+
+<h1>Bringing Groovy into Ant</h1>
+
+<p>
+As the script is expressed in the Groovy language, we can use some of the Groovy
+language feature into our build script.
+</p>
+
+<h2>if-then-else</h2>
+
+<p>
+A very basic feature that doesn't exist in Ant is branching. Well, there
+are some on targets (if, unless), and there are some in
+<a href="http://ant-contrib.sourceforge.net/tasks/tasks/if.html">ant-contrib</a>,
+but there are quite difficult or painful to write.
+</p>
+
+<p>
+So here is the basic use case:
+<pre>
+target(name: 'default') {
+  condition(property: 'fileExist', value: 'true', else: 'false') {
+    available(file: 'file.txt')
+  }
+  if (fileExist) {
+    echo('file.txt exists')
+  } else {
+    echo('file.txt was not found')
+  }
+}
+</pre>
+Note that the property has to be set for alternative value otherwise Groovy will
+complain that is it looking up for a property that doesn't exist. If no
+alternative value is provided, then the script should look like:
+<pre>
+target(name: 'default') {
+  condition(property: 'fileExist') {
+    available(file: 'file.txt')
+  }
+  if (project.properties['fileExist'] != null && fileExist) {
+    echo('file.txt exists')
+  } else {
+    echo('file.txt was not found')
+  }
+}
+</pre>
+</p>
+
+<p>
+You can even put an if-then-else structure in a task definition:
+<pre>
+target(name: 'default') {
+  copy(todir: basedir) {
+    fileset(dir: '${basedir}/target') {
+      if (excludeJava) {
+        exlude(name: '**/*.java')
+      }
+    }
+  }
+}
+</pre>
+</p>
+<h2>Loops</h2>
+
+<p>
+<code>for</code>, <code>while</code>, <code>do-while</code>
+</p>
+
+<h2>try-catch</h2>
+
+<p>
+TODO: should we document that ?
+</p>
+
+<h2>functions</h2>
+
+<p>
+In Groovy you can define function (closure with arguments). So we can define
+function that call ant task, latter to be called in some target.
+<pre>
+def copyselected = { dir, todir, includes ->
+  copy(todir: todir) {
+    fileset(dir: dir) {
+      include(name: includes)
+    }
+  }
+}
+
+target(name: 'copy-java') {
+  copyselected('${basedir}/src', '${basedir}/target/sources', '**/*.java')  
+}
+
+target(name: 'copy-txt') {
+  copyselected('${basedir}/src', '${basedir}/target/jar', '**/*.txt')  
+}
+</pre>
+</p>
+
+<p>
+But use these with caution, as local variables override ant tasks. If you
+define a local variable that has the same name of an ant task, then you won't be
+able to call the tasks. For instance this will fail:
+<pre>
+def echo = 3
+echo(message: 'calling this task will fail')
+</pre>
+</p>
+
+<h1>Crappy code allowed by Groovy</h1>
+
+<p>
+Properties can be set everywhere Groovy allow variable setting. And properties
+are global to the entire script while standard Groovy property are only affected
+to the local closure. This can be confusing. This kind of code should be avoided:
+<pre>
+target(name: 'set-prop') {
+  copy(todir: basedir) {
+    fileset(dir: '${basedir}/target') {
+      excludePattern = '**/*.java'
+      exlude(name: '${excludePattern}')
+    }
+  }
+}
+</pre>
+And we should prefer the folowing code that does exactly the same as above:
+<pre>
+target(name: 'set-prop') {
+  excludePattern = '**/*.java'
+  copy(todir: basedir) {
+    fileset(dir: '${basedir}/target') {
+      exlude(name: '${excludePattern}')
+    }
+  }
+}
+</pre>
+</p>
+
+</body>
+</html>
\ No newline at end of file

Added: ant/sandbox/groovyfront/ivy.xml
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/ivy.xml?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/ivy.xml (added)
+++ ant/sandbox/groovyfront/ivy.xml Wed Dec 23 13:05:31 2009
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="http://www.jaya.free.fr/ivyrep/ivy-doc.xsl"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+    -->
+<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
+    <info organisation="org.apache.ant" module="groovyfront" />
+    <dependencies>
+        <dependency org="org.apache.ant" name="ant" rev="1.8.0" />
+        <dependency org="org.apache.ant" name="antunit" rev="1.2.0" />
+
+        <dependency org="org.codehaus.groovy" name="groovy" rev="1.6.5" transitive="false" />
+        <dependency org="asm" name="asm" rev="2.2.3" />
+        <dependency org="antlr" name="antlr" rev="2.7.7" />
+    </dependencies>
+</ivy-module>

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBinding.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBinding.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBinding.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBinding.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.Binding;
+import groovy.lang.MissingPropertyException;
+
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+
+public class GroovyFrontBinding extends Binding {
+
+    public static final String NULL_TOSTRING = "null";
+
+    private final GroovyFrontProject project;
+
+    private final GroovyFrontBuilder groovyFrontBuilder;
+
+    public GroovyFrontBinding(final GroovyFrontProject project, final GroovyFrontBuilder grovyFrontBuilder) {
+        this.project = project;
+        this.groovyFrontBuilder = grovyFrontBuilder;
+    }
+
+    @Override
+    public Object getVariable(final String name) {
+        Object returnValue = project.getProperty(name);
+        if (returnValue == null) {
+            returnValue = project.getReference(name);
+            if (returnValue == null) {
+                returnValue = groovyFrontBuilder.getProperty(name);
+                if (returnValue == null) {
+                    throw new MissingPropertyException(name + " is undefined");
+                }
+            }
+        }
+        return returnValue;
+    }
+
+    @Override
+    public void setVariable(final String name, final Object newValue) {
+        if ("project".equals(name)) {
+            throw new BuildException("The variable 'project' cannot be overriden");
+        }
+        project.setNewProperty(name, newValue == null ? NULL_TOSTRING : newValue.toString());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Map getVariables() {
+        return project.getProperties();
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBuilder.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBuilder.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBuilder.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontBuilder.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.Closure;
+import groovy.util.AntBuilder;
+import groovy.xml.QName;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.UnknownElement;
+
+public class GroovyFrontBuilder extends AntBuilder {
+
+    public GroovyFrontBuilder(GroovyFrontProject project) {
+        super(project);
+    }
+
+    @Override
+    protected void setClosureDelegate(Closure closure, Object node) {
+        super.setClosureDelegate(closure, node);
+        closure.setResolveStrategy(Closure.DELEGATE_FIRST);
+    }
+
+    boolean isTaskDefined(String taskName) {
+        Object name = getName(taskName);
+
+        String tagName = name.toString();
+        String ns = "";
+
+        if (name instanceof QName) {
+            QName q = (QName) name;
+            tagName = q.getLocalPart();
+            ns = q.getNamespaceURI();
+        }
+
+        UnknownElement task = new UnknownElement(tagName);
+        task.setProject(getProject());
+        task.setNamespace(ns);
+        task.setQName(tagName);
+        task.setTaskType(ProjectHelper.genComponentName(task.getNamespace(), tagName));
+        task.setTaskName(tagName);
+
+        new RuntimeConfigurable(task, task.getTaskName());
+
+        try {
+            task.maybeConfigure();
+        } catch (BuildException e) {
+            return false;
+        }
+        return true;
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontMetaClass.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontMetaClass.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontMetaClass.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontMetaClass.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.DelegatingMetaClass;
+import groovy.lang.MetaClass;
+import groovy.lang.MissingMethodException;
+import groovy.lang.Tuple;
+
+import org.codehaus.groovy.runtime.MetaClassHelper;
+
+public class GroovyFrontMetaClass extends DelegatingMetaClass {
+
+    protected final GroovyFrontBuilder groovyFrontBuilder;
+
+    public GroovyFrontMetaClass(final MetaClass metaClass, final GroovyFrontBuilder groovyFrontBuilder) {
+        super(metaClass);
+        this.groovyFrontBuilder = groovyFrontBuilder;
+    }
+
+    @Override
+    public Object invokeMethod(final Object object, final String methodName, final Object[] arguments) {
+        Object returnObject = null;
+        try {
+            returnObject = super.invokeMethod(object, methodName, arguments);
+        } catch (final MissingMethodException mme) {
+            if (groovyFrontBuilder.isTaskDefined(methodName)) {
+                returnObject = groovyFrontBuilder.invokeMethod(methodName, arguments);
+            } else {
+                throw mme;
+            }
+        }
+        return returnObject;
+    }
+
+    @Override
+    public Object invokeMethod(final Object object, final String methodName, final Object arguments) {
+        if (arguments == null) {
+            return invokeMethod(object, methodName, MetaClassHelper.EMPTY_ARRAY);
+        } else if (arguments instanceof Tuple) {
+            return invokeMethod(object, methodName, ((Tuple) arguments).toArray());
+        } else if (arguments instanceof Object[]) {
+            return invokeMethod(object, methodName, (Object[]) arguments);
+        } else {
+            return invokeMethod(object, methodName, new Object[] { arguments });
+        }
+    }
+
+    @Override
+    public Object invokeMethod(final String name, final Object args) {
+        return invokeMethod(this, name, args);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object invokeMethod(final Class sender, final Object receiver, final String methodName,
+            final Object[] arguments, final boolean isCallToSuper, final boolean fromInsideClass) {
+        return invokeMethod(receiver, methodName, arguments);
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontParsingContext.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontParsingContext.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontParsingContext.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontParsingContext.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tools.ant.Target;
+
+public class GroovyFrontParsingContext {
+
+    private Map<String, Target> currentTargets = new HashMap<String, Target>();
+
+    private String currentProjectName;
+
+    private boolean imported;
+
+    private File buildFile;
+
+    private File buildFileParent;
+
+    public Map<String, Target> getCurrentTargets() {
+        return currentTargets;
+    }
+
+    public void setCurrentTargets(Map<String, Target> currentTargets) {
+        this.currentTargets = currentTargets;
+    }
+
+    public String getCurrentProjectName() {
+        return currentProjectName;
+    }
+
+    public void setCurrentProjectName(String currentProjectName) {
+        this.currentProjectName = currentProjectName;
+    }
+
+    public boolean isImported() {
+        return imported;
+    }
+
+    public void setImported(boolean imported) {
+        this.imported = imported;
+    }
+
+    public void setBuildFile(File buildFile) {
+        this.buildFile = buildFile;
+        this.buildFileParent = new File(buildFile.getParent());
+    }
+
+    public File getBuildFile() {
+        return buildFile;
+    }
+
+    public File getBuildFileParent() {
+        return buildFileParent;
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProject.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProject.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProject.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProject.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,629 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+
+public class GroovyFrontProject extends Project {
+
+    private final Project delegate;
+
+    private final GroovyFrontParsingContext context;
+
+    private final String buildFileName;
+
+    public GroovyFrontProject(Project project, GroovyFrontParsingContext context, String buildFileName) {
+        this.delegate = project;
+        this.context = context;
+        this.buildFileName = buildFileName;
+    }
+
+    protected Project getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public void setName(String name) {
+        delegate.setName(name);
+        context.setCurrentProjectName(name);
+        String antFileProp = MagicNames.ANT_FILE + name;
+        String dup = delegate.getProperty(antFileProp);
+        if (dup != null) {
+            File dupFile = new File(dup);
+            if (context.isImported() && !dupFile.equals(context.getBuildFile())) {
+                delegate.log("Duplicated project name in import. Project " + name + " defined first in " + dup
+                        + " and again in " + context.getBuildFile(), Project.MSG_WARN);
+            }
+        }
+
+        if (context.getBuildFile() != null) {
+            delegate.setUserProperty(antFileProp, context.getBuildFile().toString());
+        }
+    }
+
+    @Override
+    public String getName() {
+        if (delegate.getName() != null) {
+            return delegate.getName();
+        }
+        return buildFileName;
+    }
+
+    @Override
+    public void setBaseDir(File baseDir) throws BuildException {
+        if (context.isImported()) {
+            return;
+        }
+        if (getDelegate().getUserProperty(MagicNames.PROJECT_BASEDIR) != null) {
+            // the user specified it explicitly (probably on the command line
+            // so we won't override anything
+            return;
+        }
+        // check whether the user has specified an absolute path
+        if (baseDir.isAbsolute()) {
+            getDelegate().setBaseDir(baseDir);
+        } else {
+            getDelegate().setBaseDir(
+                    FileUtils.getFileUtils().resolveFile(context.getBuildFileParent(), baseDir.getPath()));
+        }
+    }
+
+    @Override
+    public void setBasedir(String baseD) throws BuildException {
+        if (context.isImported()) {
+            return;
+        }
+        setBaseDir(new File(baseD));
+    }
+
+    @Override
+    public void setDefault(String defaultTarget) {
+        if (context.isImported()) {
+            return;
+        }
+        delegate.setDefault(defaultTarget);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void setDefaultTarget(String defaultTarget) {
+        if (context.isImported()) {
+            return;
+        }
+        delegate.setDefaultTarget(defaultTarget);
+    }
+
+    @Override
+    public void setDescription(String description) {
+        if (context.isImported()) {
+            return;
+        }
+        delegate.setDescription(description);
+    }
+
+    @Override
+    public void addBuildListener(BuildListener listener) {
+        delegate.addBuildListener(listener);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void addDataTypeDefinition(String typeName, Class typeClass) {
+        delegate.addDataTypeDefinition(typeName, typeClass);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void addFilter(String token, String value) {
+        delegate.addFilter(token, value);
+    }
+
+    @Override
+    public void addIdReference(String id, Object value) {
+        delegate.addIdReference(id, value);
+    }
+
+    @Override
+    public void addOrReplaceTarget(String targetName, Target target) {
+        delegate.addOrReplaceTarget(targetName, target);
+    }
+
+    @Override
+    public void addOrReplaceTarget(Target target) {
+        delegate.addOrReplaceTarget(target);
+    }
+
+    @Override
+    public void addReference(String referenceName, Object value) {
+        delegate.addReference(referenceName, value);
+    }
+
+    @Override
+    public void addTarget(String targetName, Target target) throws BuildException {
+        delegate.addTarget(targetName, target);
+    }
+
+    @Override
+    public void addTarget(Target target) throws BuildException {
+        delegate.addTarget(target);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void addTaskDefinition(String taskName, Class taskClass) throws BuildException {
+        delegate.addTaskDefinition(taskName, taskClass);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void checkTaskClass(Class taskClass) throws BuildException {
+        delegate.checkTaskClass(taskClass);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(File sourceFile, File destFile, boolean filtering, boolean overwrite,
+            boolean preserveLastModified) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering, overwrite, preserveLastModified);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(File sourceFile, File destFile, boolean filtering, boolean overwrite) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering, overwrite);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(File sourceFile, File destFile, boolean filtering) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(File sourceFile, File destFile) throws IOException {
+        delegate.copyFile(sourceFile, destFile);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(String sourceFile, String destFile, boolean filtering, boolean overwrite,
+            boolean preserveLastModified) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering, overwrite, preserveLastModified);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(String sourceFile, String destFile, boolean filtering, boolean overwrite) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering, overwrite);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(String sourceFile, String destFile, boolean filtering) throws IOException {
+        delegate.copyFile(sourceFile, destFile, filtering);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void copyFile(String sourceFile, String destFile) throws IOException {
+        delegate.copyFile(sourceFile, destFile);
+    }
+
+    @Override
+    public void copyInheritedProperties(Project other) {
+        delegate.copyInheritedProperties(other);
+    }
+
+    @Override
+    public void copyUserProperties(Project other) {
+        delegate.copyUserProperties(other);
+    }
+
+    @Override
+    public AntClassLoader createClassLoader(ClassLoader parent, Path path) {
+        return delegate.createClassLoader(parent, path);
+    }
+
+    @Override
+    public AntClassLoader createClassLoader(Path path) {
+        return delegate.createClassLoader(path);
+    }
+
+    @Override
+    public Object createDataType(String typeName) throws BuildException {
+        return delegate.createDataType(typeName);
+    }
+
+    @Override
+    public Project createSubProject() {
+        return delegate.createSubProject();
+    }
+
+    @Override
+    public Task createTask(String taskType) throws BuildException {
+        return delegate.createTask(taskType);
+    }
+
+    @Override
+    public int defaultInput(byte[] buffer, int offset, int length) throws IOException {
+        return delegate.defaultInput(buffer, offset, length);
+    }
+
+    @Override
+    public void demuxFlush(String output, boolean isError) {
+        delegate.demuxFlush(output, isError);
+    }
+
+    @Override
+    public int demuxInput(byte[] buffer, int offset, int length) throws IOException {
+        return delegate.demuxInput(buffer, offset, length);
+    }
+
+    @Override
+    public void demuxOutput(String output, boolean isWarning) {
+        delegate.demuxOutput(output, isWarning);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return delegate.equals(obj);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void executeSortedTargets(Vector sortedTargets) throws BuildException {
+        delegate.executeSortedTargets(sortedTargets);
+    }
+
+    @Override
+    public void executeTarget(String targetName) throws BuildException {
+        delegate.executeTarget(targetName);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void executeTargets(Vector names) throws BuildException {
+        delegate.executeTargets(names);
+    }
+
+    @Override
+    public void fireBuildFinished(Throwable exception) {
+        delegate.fireBuildFinished(exception);
+    }
+
+    @Override
+    public void fireBuildStarted() {
+        delegate.fireBuildStarted();
+    }
+
+    @Override
+    public void fireSubBuildFinished(Throwable exception) {
+        delegate.fireSubBuildFinished(exception);
+    }
+
+    @Override
+    public void fireSubBuildStarted() {
+        delegate.fireSubBuildStarted();
+    }
+
+    @Override
+    public File getBaseDir() {
+        return delegate.getBaseDir();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Vector getBuildListeners() {
+        return delegate.getBuildListeners();
+    }
+
+    @Override
+    public ClassLoader getCoreLoader() {
+        return delegate.getCoreLoader();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getDataTypeDefinitions() {
+        return delegate.getDataTypeDefinitions();
+    }
+
+    @Override
+    public InputStream getDefaultInputStream() {
+        return delegate.getDefaultInputStream();
+    }
+
+    @Override
+    public String getDefaultTarget() {
+        return delegate.getDefaultTarget();
+    }
+
+    @Override
+    public String getDescription() {
+        return delegate.getDescription();
+    }
+
+    @Override
+    public String getElementName(Object element) {
+        return delegate.getElementName(element);
+    }
+
+    @Override
+    public Executor getExecutor() {
+        return delegate.getExecutor();
+    }
+
+    @SuppressWarnings( { "unchecked", "deprecation" })
+    @Override
+    public Hashtable getFilters() {
+        return delegate.getFilters();
+    }
+
+    @Override
+    public FilterSet getGlobalFilterSet() {
+        return delegate.getGlobalFilterSet();
+    }
+
+    @Override
+    public InputHandler getInputHandler() {
+        return delegate.getInputHandler();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getProperties() {
+        return delegate.getProperties();
+    }
+
+    @Override
+    public String getProperty(String propertyName) {
+        return delegate.getProperty(propertyName);
+    }
+
+    @Override
+    public Object getReference(String key) {
+        return delegate.getReference(key);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getReferences() {
+        return delegate.getReferences();
+    }
+
+    @Override
+    public Resource getResource(String name) {
+        return delegate.getResource(name);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getTargets() {
+        return delegate.getTargets();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getTaskDefinitions() {
+        return delegate.getTaskDefinitions();
+    }
+
+    @Override
+    public Task getThreadTask(Thread thread) {
+        return delegate.getThreadTask(thread);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getUserProperties() {
+        return delegate.getUserProperties();
+    }
+
+    @Override
+    public String getUserProperty(String propertyName) {
+        return delegate.getUserProperty(propertyName);
+    }
+
+    @Override
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    @Override
+    public void inheritIDReferences(Project parent) {
+        delegate.inheritIDReferences(parent);
+    }
+
+    @Override
+    public void init() throws BuildException {
+        delegate.init();
+    }
+
+    @Override
+    public void initProperties() throws BuildException {
+        delegate.initProperties();
+    }
+
+    @Override
+    public void initSubProject(Project subProject) {
+        delegate.initSubProject(subProject);
+    }
+
+    @Override
+    public boolean isKeepGoingMode() {
+        return delegate.isKeepGoingMode();
+    }
+
+    @Override
+    public void log(String message, int msgLevel) {
+        delegate.log(message, msgLevel);
+    }
+
+    @Override
+    public void log(String message, Throwable throwable, int msgLevel) {
+        delegate.log(message, throwable, msgLevel);
+    }
+
+    @Override
+    public void log(String message) {
+        delegate.log(message);
+    }
+
+    @Override
+    public void log(Target target, String message, int msgLevel) {
+        delegate.log(target, message, msgLevel);
+    }
+
+    @Override
+    public void log(Target target, String message, Throwable throwable, int msgLevel) {
+        delegate.log(target, message, throwable, msgLevel);
+    }
+
+    @Override
+    public void log(Task task, String message, int msgLevel) {
+        delegate.log(task, message, msgLevel);
+    }
+
+    @Override
+    public void log(Task task, String message, Throwable throwable, int msgLevel) {
+        delegate.log(task, message, throwable, msgLevel);
+    }
+
+    @Override
+    public void registerThreadTask(Thread thread, Task task) {
+        delegate.registerThreadTask(thread, task);
+    }
+
+    @Override
+    public void removeBuildListener(BuildListener listener) {
+        delegate.removeBuildListener(listener);
+    }
+
+    @Override
+    public String replaceProperties(String value) throws BuildException {
+        return delegate.replaceProperties(value);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public File resolveFile(String fileName, File rootDir) {
+        return delegate.resolveFile(fileName, rootDir);
+    }
+
+    @Override
+    public File resolveFile(String fileName) {
+        return delegate.resolveFile(fileName);
+    }
+
+    @Override
+    public void setCoreLoader(ClassLoader coreLoader) {
+        delegate.setCoreLoader(coreLoader);
+    }
+
+    @Override
+    public void setDefaultInputStream(InputStream defaultInputStream) {
+        delegate.setDefaultInputStream(defaultInputStream);
+    }
+
+    @Override
+    public void setExecutor(Executor e) {
+        delegate.setExecutor(e);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void setFileLastModified(File file, long time) throws BuildException {
+        delegate.setFileLastModified(file, time);
+    }
+
+    @Override
+    public void setInheritedProperty(String name, String value) {
+        delegate.setInheritedProperty(name, value);
+    }
+
+    @Override
+    public void setInputHandler(InputHandler handler) {
+        delegate.setInputHandler(handler);
+    }
+
+    @Override
+    public void setJavaVersionProperty() throws BuildException {
+        delegate.setJavaVersionProperty();
+    }
+
+    @Override
+    public void setKeepGoingMode(boolean keepGoingMode) {
+        delegate.setKeepGoingMode(keepGoingMode);
+    }
+
+    @Override
+    public void setNewProperty(String name, String value) {
+        delegate.setNewProperty(name, value);
+    }
+
+    @Override
+    public void setProperty(String name, String value) {
+        delegate.setProperty(name, value);
+    }
+
+    @Override
+    public void setSystemProperties() {
+        delegate.setSystemProperties();
+    }
+
+    @Override
+    public void setUserProperty(String name, String value) {
+        delegate.setUserProperty(name, value);
+    }
+
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Hashtable getInheritedProperties() {
+        return delegate.getInheritedProperties();
+    }
+
+    @Override
+    public boolean hasReference(String key) {
+        return delegate.hasReference(key);
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProjectHelper.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProjectHelper.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProjectHelper.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontProjectHelper.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,171 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.Binding;
+import groovy.lang.GroovyShell;
+import groovy.lang.Script;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.util.FileUtils;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+public class GroovyFrontProjectHelper extends ProjectHelper {
+
+    private static final String REFID_CONTEXT = "groovyfront.parsingcontext";
+
+    private static final String REFID_BUILDER = "groovyfront.builder";
+
+    @Override
+    public String getDefaultBuildFile() {
+        return "build.groovy";
+    }
+
+    @Override
+    public boolean supportsBuildFile(File buildFile) {
+        return buildFile.getName().toLowerCase().endsWith(".groovy");
+    }
+
+    @Override
+    public void parse(Project project, Object source) throws BuildException {
+        @SuppressWarnings("unchecked")
+        Vector<Object> stack = getImportStack();
+        stack.addElement(source);
+        GroovyFrontParsingContext context = null;
+        context = (GroovyFrontParsingContext) project.getReference(REFID_CONTEXT);
+        if (context == null) {
+            context = new GroovyFrontParsingContext();
+            project.addReference(REFID_CONTEXT, context);
+        }
+
+        if (getImportStack().size() > 1) {
+            Map<String, Target> currentTargets = context.getCurrentTargets();
+            String currentProjectName = context.getCurrentProjectName();
+            boolean imported = context.isImported();
+            try {
+                context.setImported(true);
+                context.setCurrentTargets(new HashMap<String, Target>());
+                parse(project, source, context);
+            } finally {
+                context.setCurrentTargets(currentTargets);
+                context.setCurrentProjectName(currentProjectName);
+                context.setImported(imported);
+            }
+        } else {
+            // top level file
+            context.setCurrentTargets(new HashMap<String, Target>());
+            parse(project, source, context);
+        }
+    }
+
+    private void parse(Project project, Object source, GroovyFrontParsingContext context) throws BuildException {
+        InputStream in;
+        String buildFileName = null;
+
+        try {
+            if (source instanceof File) {
+                File buildFile = (File) source;
+                buildFileName = buildFile.toString();
+                buildFile = FileUtils.getFileUtils().normalize(buildFile.getAbsolutePath());
+                context.setBuildFile(buildFile);
+                in = new FileInputStream(buildFile);
+                // } else if (source instanceof InputStream ) {
+            } else if (source instanceof URL) {
+                URL url = (URL) source;
+                buildFileName = url.toString();
+                in = url.openStream();
+                // } else if (source instanceof InputSource ) {
+            } else {
+                throw new BuildException("Source " + source.getClass().getName() + " not supported by this plugin");
+            }
+        } catch (IOException e) {
+            throw new BuildException("Error reading groovy file " + buildFileName + ": " + e.getMessage(), e);
+        }
+
+        // set explicitly before starting ?
+        if (project.getProperty("basedir") != null) {
+            project.setBasedir(project.getProperty("basedir"));
+            // NB: this won't be overridden as it is a user property (see GroovyFrontProject class)
+        } else {
+            // set the property even if it may be overridden within the groovy file
+            project.setBasedir(context.getBuildFileParent().getAbsolutePath());
+        }
+
+        // wrap the project instance so we can be in control of the set on the properties on the project
+        GroovyFrontProject groovyFrontProject;
+        if (project instanceof GroovyFrontProject) {
+            groovyFrontProject = (GroovyFrontProject) project;
+        } else {
+            groovyFrontProject = new GroovyFrontProject(project, context, buildFileName);
+        }
+
+        defineDefaultTasks(groovyFrontProject);
+
+        GroovyFrontBuilder antBuilder = new GroovyFrontBuilder(groovyFrontProject);
+        groovyFrontProject.addReference(REFID_BUILDER, antBuilder);
+        Binding binding = new GroovyFrontBinding(groovyFrontProject, antBuilder);
+        GroovyShell groovyShell = new GroovyShell(getClass().getClassLoader(), binding);
+        final Script script;
+        try {
+            script = groovyShell.parse(in, buildFileName);
+        } catch (CompilationFailedException e) {
+            throw new BuildException("Error reading groovy file " + buildFileName + ": " + e.getMessage(), e);
+        }
+        script.setBinding(binding);
+        script.setMetaClass(new GroovyFrontScriptMetaClass(script.getMetaClass(), groovyFrontProject, antBuilder, context));
+        new GroovyRunner() {
+            @Override
+            protected void doRun() {
+                script.run();
+            }
+        }.run();
+    }
+
+    private void defineDefaultTasks(GroovyFrontProject groovyFrontProject) {
+        defineDefaultTask("groovyant", GroovyFrontTask.class, groovyFrontProject);
+        defineDefaultTask("subgroovyant", SubGroovyFrontTask.class, groovyFrontProject);
+    }
+
+    private void defineDefaultTask(String name, Class cl, GroovyFrontProject groovyProject) {
+        AntTypeDefinition def = new AntTypeDefinition();
+        def.setName(name);
+        def.setClassName(cl.getCanonicalName());
+        def.setClass(cl);
+        def.setAdapterClass(null);
+        def.setAdaptToClass(null);
+        def.setRestrict(false);
+        def.setClassLoader(this.getClass().getClassLoader());
+        def.checkClass(groovyProject);
+        ComponentHelper.getComponentHelper(groovyProject).addDataTypeDefinition(def);
+
+    }
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontScriptMetaClass.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontScriptMetaClass.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontScriptMetaClass.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontScriptMetaClass.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,135 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.Closure;
+import groovy.lang.MetaClass;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.taskdefs.AntlibDefinition;
+
+public class GroovyFrontScriptMetaClass extends GroovyFrontMetaClass {
+
+    private final GroovyFrontProject project;
+    private final GroovyFrontParsingContext context;
+
+    public GroovyFrontScriptMetaClass(MetaClass metaClass, GroovyFrontProject project, GroovyFrontBuilder groovyFrontBuilder,
+            GroovyFrontParsingContext context) {
+        super(metaClass, groovyFrontBuilder);
+        this.project = project;
+        this.context = context;
+    }
+
+    @Override
+    public Object invokeMethod(Object object, String methodName, Object[] arguments) {
+        if ("target".equals(methodName)) {
+            defineTarget(arguments);
+            return null;
+        }
+        if ("include".equals(methodName)) {
+            return importScript(arguments);
+        }
+        if ("groovyns".equals(methodName)) {
+            if (arguments.length != 1 && !(arguments[0] instanceof Map)) {
+                throw new BuildException("Invalid method signature for 'groovyns'");
+            }
+            String uri = (String) ((Map) arguments[0]).get("uri");
+            if (uri == null) {
+                throw new BuildException("Missing 'uri' argument on 'groovyns'");
+            }
+            String prefix = (String) ((Map) arguments[0]).get("prefix");
+            return new SimpleNamespaceBuilder(groovyFrontBuilder, prefix, uri);
+        }
+        Object returnObject = super.invokeMethod(object, methodName, arguments);
+        if (returnObject instanceof AntlibDefinition) {
+            AntlibDefinition antlibDefinition = (AntlibDefinition) returnObject;
+            returnObject = new SimpleNamespaceBuilder(groovyFrontBuilder, antlibDefinition.getURI(), antlibDefinition.getURI());
+        }
+        return returnObject;
+    }
+
+    private void defineTarget(Object[] args) {
+        if (args.length != 2 || !(args[0] instanceof Map) || !(args[1] instanceof Closure)) {
+            throw new BuildException("A target is ill formed. Expecting map, closure but was: " + Arrays.toString(args));
+        }
+        @SuppressWarnings("unchecked")
+        Map<String, String> map = (Map<String, String>) args[0];
+        Closure closure = (Closure) args[1];
+        closure.setMetaClass(new GroovyFrontMetaClass(closure.getMetaClass(), groovyFrontBuilder));
+        String name = map.get("name");
+        String description = map.get("description");
+        String depends = map.get("depends");
+
+        if (name == null) {
+            throw new BuildException("a target name must be set");
+        }
+        if (name.length() == 0) {
+            throw new BuildException("a target name must not be empty");
+        }
+        // Check if this target is in the current build file
+        if (context.getCurrentTargets().get(name) != null) {
+            throw new BuildException("Duplicate target '" + name + "'");
+        }
+
+        GroovyFrontTarget target = new GroovyFrontTarget(groovyFrontBuilder, closure);
+        target.setName(name);
+        target.setProject(project);
+        target.setLocation(new Location(groovyFrontBuilder.getAntXmlContext().getLocator()));
+
+        if (depends != null) {
+            target.setDepends(depends);
+        }
+        if (description != null) {
+            target.setDescription(description);
+        }
+
+        Hashtable<?, ?> projectTargets = project.getTargets();
+        // If the name has not already been defined, log an override
+        // NB: unlike ant xml project helper, the imported file are executed before the target definition of the main
+        // file
+        if (projectTargets.containsKey(name)) {
+            project.log("Overrided target " + name + ": it has already defined in a previous import",
+                    Project.MSG_VERBOSE);
+        }
+        context.getCurrentTargets().put(name, target);
+        project.addOrReplaceTarget(name, target);
+
+        if (context.isImported() && context.getCurrentProjectName() != null
+                && context.getCurrentProjectName().length() != 0) {
+            // In an imported file (and not completely ignoring the project tag)
+            String newName = context.getCurrentProjectName() + "." + name;
+            Target newTarget = new GroovyFrontTarget(target);
+            newTarget.setName(newName);
+            context.getCurrentTargets().put(newName, newTarget);
+            project.addOrReplaceTarget(newName, newTarget);
+        }
+
+    }
+
+    private Object importScript(Object[] arguments) {
+        return groovyFrontBuilder.invokeMethod("import", arguments);
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTarget.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTarget.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTarget.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTarget.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.Closure;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Target;
+
+public class GroovyFrontTarget extends Target {
+
+    private final Closure closure;
+    private final GroovyFrontBuilder groovyFrontBuilder;
+
+    public GroovyFrontTarget(GroovyFrontBuilder groovyFrontBuilder, Closure closure) {
+        this.groovyFrontBuilder = groovyFrontBuilder;
+        this.closure = closure;
+    }
+
+    public GroovyFrontTarget(GroovyFrontTarget other) {
+        super(other);
+        this.closure = other.closure;
+        this.groovyFrontBuilder = other.groovyFrontBuilder;
+    }
+
+    @Override
+    public void execute() throws BuildException {
+        groovyFrontBuilder.getAntXmlContext().setCurrentTarget(this);
+        final Closure c = closure;
+        // if (testIfCondition() && testUnlessCondition()) {
+        new GroovyRunner() {
+            @Override
+            protected void doRun() {
+                c.call();
+            }
+        }.run();
+        // } else if (!testIfCondition()) {
+        // project.log(this, "Skipped because property '" + project.replaceProperties(ifCondition) + "' not set.",
+        // Project.MSG_VERBOSE);
+        // } else {
+        // project.log(this, "Skipped because property '" + project.replaceProperties(unlessCondition) + "' set.",
+        // Project.MSG_VERBOSE);
+        // }
+    }
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTask.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTask.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTask.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyFrontTask.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import org.apache.tools.ant.taskdefs.Ant;
+
+public class GroovyFrontTask extends Ant {
+
+    @Override
+    protected String getDefaultBuildFile() {
+        return "build.groovy";
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyRunner.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyRunner.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyRunner.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/GroovyRunner.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.MissingMethodException;
+import groovy.lang.MissingPropertyException;
+
+import org.apache.tools.ant.BuildException;
+import org.codehaus.groovy.runtime.InvokerInvocationException;
+
+public abstract class GroovyRunner {
+
+    abstract protected void doRun();
+
+    public void run() {
+        try {
+            doRun();
+        } catch (MissingMethodException e) {
+            throw new BuildException(e.getMessage(), e);
+        } catch (MissingPropertyException e) {
+            throw new BuildException(e.getMessage(), e);
+        } catch (InvokerInvocationException e) {
+            throw new BuildException(e.getCause().getMessage(), e);
+        }
+
+    }
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SimpleNamespaceBuilder.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SimpleNamespaceBuilder.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SimpleNamespaceBuilder.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SimpleNamespaceBuilder.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import groovy.lang.GroovyObjectSupport;
+import groovy.xml.NamespaceBuilder;
+import groovy.xml.NamespaceBuilderSupport;
+
+import java.util.Collections;
+
+public class SimpleNamespaceBuilder extends GroovyObjectSupport {
+
+    private NamespaceBuilderSupport nsBuilder;
+
+    private final String prefix;
+
+    public SimpleNamespaceBuilder(GroovyFrontBuilder groovyFrontBuilder, String prefix, String uri) {
+        this.prefix = prefix == null ? uri.replaceAll(":", ".") : prefix;
+        nsBuilder = NamespaceBuilder.newInstance(Collections.singletonMap(this.prefix, uri), groovyFrontBuilder);
+    }
+
+    @Override
+    public Object invokeMethod(String name, Object args) {
+        return nsBuilder.invokeMethod(prefix + ":" + name, args);
+    }
+}

Added: ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SubGroovyFrontTask.java
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SubGroovyFrontTask.java?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SubGroovyFrontTask.java (added)
+++ ant/sandbox/groovyfront/src/main/java/org/apache/ant/groovyfront/SubGroovyFrontTask.java Wed Dec 23 13:05:31 2009
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.groovyfront;
+
+import org.apache.tools.ant.taskdefs.SubAnt;
+
+public class SubGroovyFrontTask extends SubAnt {
+
+    @Override
+    protected String getDefaultBuildFile() {
+        return "build.groovy";
+    }
+
+}

Added: ant/sandbox/groovyfront/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper
URL: http://svn.apache.org/viewvc/ant/sandbox/groovyfront/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper?rev=893502&view=auto
==============================================================================
--- ant/sandbox/groovyfront/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper (added)
+++ ant/sandbox/groovyfront/src/main/resources/META-INF/services/org.apache.tools.ant.ProjectHelper Wed Dec 23 13:05:31 2009
@@ -0,0 +1 @@
+org.apache.ant.groovyfront.GroovyFrontProjectHelper



Mime
View raw message