need to look at refactoring Ant1 to allow extension without cut&paste). * Updated todo and regenerated docs. * Javadoc git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272106 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -77,22 +77,22 @@ | |||
| </td></tr> | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>In many ways Ant2 needs to follow rules similar to a number of | |||
| different application servers with respect to ClassLoader management. | |||
| Ant2 will create a number of different ClassLoaders that have access | |||
| to different sets of resources (and thus Classes). The main reason | |||
| for this arrangment is to partition different sections of the | |||
| application such as the Container, the Task API, task/type libraries | |||
| and support libraries.</p> | |||
| <p>In many ways Ant2 needs to follow rules similar to a number of | |||
| different application servers with respect to ClassLoader management. | |||
| Ant2 will create a number of different ClassLoaders that have access | |||
| to different sets of resources (and thus Classes). The main reason | |||
| for this arrangment is to partition different sections of the | |||
| application such as the Container, the Task API, task/type libraries | |||
| and support libraries.</p> | |||
| <p>The recomended structure for ClassLoader relationships is a hierarchy. | |||
| When a ClassLoader is asked for a resource (or a class) it first delegates | |||
| to it's parent to ask for the resource. If the resource is not present in | |||
| its parent ClassLoader then the ClassLoader attempts to locate the resource | |||
| in it's own store. In practice this means that all the classes (and static | |||
| variables defined by said classes) in a parent ClassLoader are shared with | |||
| the child ClassLoaders.</p> | |||
| <p>Using kooky ascii art, the specific ClassLoader structure for Ant2 is as | |||
| follows:</p> | |||
| When a ClassLoader is asked for a resource (or a class) it first delegates | |||
| to it's parent to ask for the resource. If the resource is not present in | |||
| its parent ClassLoader then the ClassLoader attempts to locate the resource | |||
| in it's own store. In practice this means that all the classes (and static | |||
| variables defined by said classes) in a parent ClassLoader are shared with | |||
| the child ClassLoaders.</p> | |||
| <p>Using kooky ascii art, the specific ClassLoader structure for Ant2 is as | |||
| follows:</p> | |||
| <div align="left"> | |||
| <table cellspacing="4" cellpadding="0" border="0"> | |||
| <tr> | |||
| @@ -103,16 +103,16 @@ follows:</p> | |||
| <tr> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| <td bgcolor="#ffffff"><pre> | |||
| Bootstrap | |||
| | | |||
| System | |||
| | | |||
| Common | |||
| / \ | |||
| Container Shared | |||
| / \ | |||
| Antlib1 Antlib2 ... | |||
| </pre></td> | |||
| Bootstrap | |||
| | | |||
| System | |||
| | | |||
| Common | |||
| / \ | |||
| Container Shared | |||
| / \ | |||
| Antlib1 Antlib2 ... | |||
| </pre></td> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| </tr> | |||
| <tr> | |||
| @@ -123,70 +123,93 @@ follows:</p> | |||
| </table> | |||
| </div> | |||
| <ul> | |||
| <li> | |||
| The <strong>Bootstrap</strong> ClassLoader contains the classes and resources | |||
| provided by the Java runtime. | |||
| </li> | |||
| <li> | |||
| The <strong>System</strong> ClassLoader contains the classes that were made accessible | |||
| via the CLASSPATH environment variable. If the standard ant script was used then this | |||
| should only contain the classes that are used to bootstrap the ant runtime. ie | |||
| <code>$ANT_HOME/bin/ant-launcher.jar</code> | |||
| </li> | |||
| <li> | |||
| The <strong>Common</strong> ClassLoader contains the classes and resources | |||
| that are made visible to both the Container and to all the ant type librarys. This | |||
| contains all the classes that the Container uses to communicate with tasks and other | |||
| supporting infrastructure. In particular it contains the following APIs; | |||
| <ul> | |||
| <li> | |||
| <em>Task API</em> - Contains the classes that are part of the API used | |||
| to define tasks. | |||
| </li> | |||
| <li> | |||
| <em>ProjectListener API</em> - Contains the classes necessary to define new | |||
| ProjectListeners. | |||
| </li> | |||
| <li> | |||
| <em>Aspect API</em> - Contains the classes that are used to define Aspects | |||
| of the container. | |||
| </li> | |||
| <li> | |||
| <em>Container API</em> - Contains the interfaces that are required to communicate | |||
| with the objects deep within the container. <strong>NOTE</strong>: These interfaces | |||
| are not to be used by user tasks but are made available so that certain tasks (such | |||
| as <antcall/>) can be implemented. However they are subject to change without | |||
| notice between between different ant2 versions. | |||
| </li> | |||
| </ul> | |||
| <p> | |||
| These classes are loaded from all the jars present in the <code>$ANT_HOME/lib</code> | |||
| directory. | |||
| </p> | |||
| </li> | |||
| <li> | |||
| The <strong>Container</strong> ClassLoader contains all the classes and resources | |||
| that are part of the actual implementation of the Container. These classes are not | |||
| directly accessible to any Ant library or task. Some of the classes are indirectly | |||
| accessible to tasks and other elements defined in the ant librarys as they implement | |||
| interfaces defined in the <strong>Common</strong> ClassLoader. The classes that are | |||
| stored in jars in the <code>$ANT_HOME/bin/lib/</code> directory. | |||
| </li> | |||
| <li> | |||
| The <strong>Shared</strong> ClassLoader contains all the classes and resources | |||
| that are shared across all of the ant librarys (unless they are als needed by the | |||
| container in which case they should be placed int the <strong>Container</strong> | |||
| ClassLoader). This ClassLoader is populated by all the jars that are contained in | |||
| the <code>$ANT_HOME/shared/</code> directory. | |||
| </li> | |||
| <li> | |||
| The <strong>AntLib</strong> ClassLoaders each contain the classes and resources | |||
| that required by that particular library. Note that in some cases a single Ant | |||
| Library will manifest as a single ClassLoader containing a single jar. However | |||
| in some cases it is possible for one Ant Library to have multiple jars in its | |||
| ClassLoader or even have multiple ClassLoaders. See XXXX for further details. | |||
| </li> | |||
| </ul> | |||
| <li> | |||
| The | |||
| <strong>Bootstrap</strong> ClassLoader contains the classes and resources | |||
| provided by the Java runtime. | |||
| </li> | |||
| <li> | |||
| The | |||
| <strong>System</strong> ClassLoader contains the classes that were made accessible | |||
| via the CLASSPATH environment variable. If the standard ant script was used then this | |||
| should only contain the classes that are used to bootstrap the ant runtime. ie | |||
| <code>$ANT_HOME/bin/ant-launcher.jar</code> | |||
| </li> | |||
| <li> | |||
| The | |||
| <strong>Common</strong> ClassLoader contains the classes and resources | |||
| that are made visible to both the Container and to all the ant type librarys. This | |||
| contains all the classes that the Container uses to communicate with tasks and other | |||
| supporting infrastructure. In particular it contains the following APIs; | |||
| <ul> | |||
| <li> | |||
| <em>Task API</em> - Contains the classes that are part of the API used | |||
| to define tasks. | |||
| </li> | |||
| <li> | |||
| <em>ProjectListener API</em> - Contains the classes necessary to define new | |||
| ProjectListeners. | |||
| </li> | |||
| <li> | |||
| <em>Aspect API</em> - Contains the classes that are used to define Aspects | |||
| of the container. | |||
| </li> | |||
| <li> | |||
| <em>Container API</em> - Contains the interfaces that are required to communicate | |||
| with the objects deep within the container. | |||
| <strong>NOTE</strong>: These interfaces | |||
| are not to be used by user tasks but are made available so that certain tasks (such | |||
| as <antcall/>) can be implemented. However they are subject to change without | |||
| notice between between different ant2 versions. | |||
| </li> | |||
| </ul> | |||
| <p> | |||
| These classes are loaded from all the jars present in the | |||
| <code>$ANT_HOME/lib</code> | |||
| directory. | |||
| </p> | |||
| </li> | |||
| <li> | |||
| The | |||
| <strong>Container</strong> ClassLoader contains all the classes and resources | |||
| that are part of the actual implementation of the Container. These classes are not | |||
| directly accessible to any Ant library or task. Some of the classes are indirectly | |||
| accessible to tasks and other elements defined in the ant librarys as they implement | |||
| interfaces defined in the | |||
| <strong>Common</strong> ClassLoader. The classes that are | |||
| stored in jars in the | |||
| <code>$ANT_HOME/bin/lib/</code> directory. | |||
| </li> | |||
| <li> | |||
| The | |||
| <strong>Shared</strong> ClassLoader contains all the classes and resources | |||
| that are shared across all of the ant librarys (unless they are als needed by the | |||
| container in which case they should be placed int the | |||
| <strong>Container</strong> | |||
| ClassLoader). This ClassLoader is populated by all the jars that are contained in | |||
| the | |||
| <code>$ANT_HOME/shared/</code> directory. | |||
| </li> | |||
| <li> | |||
| The | |||
| <strong>AntLib</strong> ClassLoaders each contain the classes and resources | |||
| that required by that particular library. Note that in some cases a single Ant | |||
| Library will manifest as a single ClassLoader containing a single jar. However | |||
| in some cases it is possible for one Ant Library to have multiple jars in its | |||
| ClassLoader or even have multiple ClassLoaders. See XXXX for further details. | |||
| </li> | |||
| </ul> | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| @@ -78,35 +78,42 @@ | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>Long ago there was identified the need for librarys that contain | |||
| tasks and other elements present in the build file. This document | |||
| attempts to describe the mechanism via which these libraries will be | |||
| defined and used in Ant2. The librarys (also referred to as | |||
| deployments) will be termed antlibs.</p> | |||
| tasks and other elements present in the build file. This document | |||
| attempts to describe the mechanism via which these libraries will be | |||
| defined and used in Ant2. The librarys (also referred to as | |||
| deployments) will be termed antlibs.</p> | |||
| <p>Ant librarys can be packaged and signed into a ANt Type Library | |||
| format (.atl) using the standard Java Archive tools. (For details on | |||
| the .jar file format see the | |||
| <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/index.html"> | |||
| Jar Specification</a>.</p> | |||
| format (.atl) using the standard Java Archive tools. (For details on | |||
| the .jar file format see the | |||
| <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/index.html"> | |||
| Jar Specification</a>. | |||
| </p> | |||
| <p>When packaged into such a form the META-INF/ directory contains | |||
| ant specific descriptors in addition to the standard Jar manifest | |||
| and other descriptor files. The archive will also contain the | |||
| <code>.class</code> files for all the tasks and other types the | |||
| library defines. It may also contain additional resources that can | |||
| be referenced in the build file (an example being DTDs).</p> | |||
| ant specific descriptors in addition to the standard Jar manifest | |||
| and other descriptor files. The archive will also contain the | |||
| <code>.class</code> files for all the tasks and other types the | |||
| library defines. It may also contain additional resources that can | |||
| be referenced in the build file (an example being DTDs). | |||
| </p> | |||
| <p>The library may also need access to other librarys or resources | |||
| to perform its job. For instance, if the task loaded an XML document | |||
| and then processed said document using the <em>Trax API</em> then | |||
| the Ant library needs to have access to the <em>Trax API</em> and an | |||
| implementation of the API. The Antlib mechanism thus uses the standard | |||
| "Optional Package" Specification to declare dependencies on other | |||
| libraries.</p> | |||
| to perform its job. For instance, if the task loaded an XML document | |||
| and then processed said document using the | |||
| <em>Trax API</em> then | |||
| the Ant library needs to have access to the | |||
| <em>Trax API</em> and an | |||
| implementation of the API. The Antlib mechanism thus uses the standard | |||
| "Optional Package" Specification to declare dependencies on other | |||
| libraries. | |||
| </p> | |||
| <p>The libraries will usually be installed in standard locations that | |||
| make it possible for the Ant container to automatically locate and scan | |||
| the libraries. It will also be possible for the users to specify | |||
| additional search locations or even the specific location of ant | |||
| libraries.</p> | |||
| make it possible for the Ant container to automatically locate and scan | |||
| the libraries. It will also be possible for the users to specify | |||
| additional search locations or even the specific location of ant | |||
| libraries.</p> | |||
| <p>The following sections will describe each of these different facets | |||
| in greater detail.</p> | |||
| in greater detail.</p> | |||
| <table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||
| <tr><td bgcolor="#828DA6"> | |||
| <font color="#ffffff" face="arial,helvetica,sanserif"> | |||
| @@ -128,9 +135,13 @@ in greater detail.</p> | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>The class and resources files should be stored as in standard jars. The | |||
| root directory being the base via which code and resources are loaded. So | |||
| the <code>.class</code> file for the Java class <code>com.biz.tasks.Mytask</code> | |||
| would be stored in <code>/com/biz/tasks/Mytask.class</code></p> | |||
| root directory being the base via which code and resources are loaded. So | |||
| the | |||
| <code>.class</code> file for the Java class | |||
| <code>com.biz.tasks.Mytask</code> | |||
| would be stored in | |||
| <code>/com/biz/tasks/Mytask.class</code> | |||
| </p> | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| @@ -143,24 +154,30 @@ would be stored in <code>/com/biz/tasks/Mytask.class</code></p> | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>It is often the case that a library will need external resources. The | |||
| example given above described dependence on an external XML library. The | |||
| ant library thus needs a mechanism via which to declare dependencies on | |||
| external libraries.</p> | |||
| example given above described dependence on an external XML library. The | |||
| ant library thus needs a mechanism via which to declare dependencies on | |||
| external libraries.</p> | |||
| <p>Ant2 uses the "Optional Package" mechanism. Prior to JDK1.3, an "Optional | |||
| Package" was known as an <em>Extension</em>. The specification for this | |||
| mechanism is available in the JDK1.3 documentation in the directory | |||
| <code>$JDK_HOME/docs/guide/extensions/versioning.html</code>. Alternatively | |||
| it is available online at | |||
| <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html"> | |||
| http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p> | |||
| Package" was known as an | |||
| <em>Extension</em>. The specification for this | |||
| mechanism is available in the JDK1.3 documentation in the directory | |||
| <code>$JDK_HOME/docs/guide/extensions/versioning.html</code>. Alternatively | |||
| it is available online at | |||
| <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html"> | |||
| http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>. | |||
| </p> | |||
| <p>This mechanism was adopted as it is an established standard. The standard | |||
| is also begining to be adopted by other specifications such as the <em>Servlet | |||
| 2.3 API</em>. Thus we are likely to see an increase of jars using this mechanism | |||
| to specify dependencies.</p> | |||
| is also begining to be adopted by other specifications such as the | |||
| <em>Servlet | |||
| 2.3 API</em>. Thus we are likely to see an increase of jars using this mechanism | |||
| to specify dependencies. | |||
| </p> | |||
| <p>The "Optional Package" mechanism allows jars to specify dependencies on other | |||
| jars that implement a particular specification at particular version levels. For | |||
| example you could specify a dependency on the Trax 1.1 API by adding the following | |||
| to the manifest of your jar.</p> | |||
| jars that implement a particular specification at particular version levels. For | |||
| example you could specify a dependency on the Trax 1.1 API by adding the following | |||
| to the manifest of your jar.</p> | |||
| <div align="left"> | |||
| <table cellspacing="4" cellpadding="0" border="0"> | |||
| <tr> | |||
| @@ -171,10 +188,10 @@ to the manifest of your jar.</p> | |||
| <tr> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| <td bgcolor="#ffffff"><pre> | |||
| Extension-List: trax | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| </pre></td> | |||
| Extension-List: trax | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| </pre></td> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| </tr> | |||
| <tr> | |||
| @@ -185,8 +202,8 @@ trax-Specification-Version: 1.1 | |||
| </table> | |||
| </div> | |||
| <p>In some cases you may also wish to specify a dependency on a specific vendors | |||
| implementation. For instance you may need to use xalan due to it implementing a | |||
| particular extension you need. In that case you manifest may contain;</p> | |||
| implementation. For instance you may need to use xalan due to it implementing a | |||
| particular extension you need. In that case you manifest may contain;</p> | |||
| <div align="left"> | |||
| <table cellspacing="4" cellpadding="0" border="0"> | |||
| <tr> | |||
| @@ -197,13 +214,13 @@ particular extension you need. In that case you manifest may contain;</p> | |||
| <tr> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| <td bgcolor="#ffffff"><pre> | |||
| Extension-List: trax | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| trax-Implementation-Title: org.apache.xalan.xslt | |||
| trax-Implementation-Version: 2.1.0 | |||
| trax-Implementation-Vendor: Apache Software Foundation | |||
| </pre></td> | |||
| Extension-List: trax | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| trax-Implementation-Title: org.apache.xalan.xslt | |||
| trax-Implementation-Version: 2.1.0 | |||
| trax-Implementation-Vendor: Apache Software Foundation | |||
| </pre></td> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| </tr> | |||
| <tr> | |||
| @@ -214,10 +231,10 @@ trax-Implementation-Vendor: Apache Software Foundation | |||
| </table> | |||
| </div> | |||
| <p>In many cases there will be no distinction between the specification and | |||
| the implementation of a library. For instance the Velocity project only has | |||
| one implementation and one specification. In which case it is sufficient to | |||
| just declare a dependency on the Velocity "Specification". A library that uses | |||
| both the Trax API and the Velocity project may look like;</p> | |||
| the implementation of a library. For instance the Velocity project only has | |||
| one implementation and one specification. In which case it is sufficient to | |||
| just declare a dependency on the Velocity "Specification". A library that uses | |||
| both the Trax API and the Velocity project may look like;</p> | |||
| <div align="left"> | |||
| <table cellspacing="4" cellpadding="0" border="0"> | |||
| <tr> | |||
| @@ -228,15 +245,15 @@ both the Trax API and the Velocity project may look like;</p> | |||
| <tr> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| <td bgcolor="#ffffff"><pre> | |||
| Extension-List: trax velocity | |||
| velocity-Extension-Name: org.apache.velocity | |||
| velocity-Specification-Version: 1.0 | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| trax-Implementation-Title: org.apache.xalan.xslt | |||
| trax-Implementation-Version: 2.1.0 | |||
| trax-Implementation-Vendor: Apache Software Foundation | |||
| </pre></td> | |||
| Extension-List: trax velocity | |||
| velocity-Extension-Name: org.apache.velocity | |||
| velocity-Specification-Version: 1.0 | |||
| trax-Extension-Name: Java API for XML Parsing | |||
| trax-Specification-Version: 1.1 | |||
| trax-Implementation-Title: org.apache.xalan.xslt | |||
| trax-Implementation-Version: 2.1.0 | |||
| trax-Implementation-Vendor: Apache Software Foundation | |||
| </pre></td> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| </tr> | |||
| <tr> | |||
| @@ -247,8 +264,8 @@ trax-Implementation-Vendor: Apache Software Foundation | |||
| </table> | |||
| </div> | |||
| <p>To make other jars available to Ant librarys as "Optional Packages" | |||
| or Extensions then you need to add a few lines to the manifest of the | |||
| other jar. The minimal manifest is the following;</p> | |||
| or Extensions then you need to add a few lines to the manifest of the | |||
| other jar. The minimal manifest is the following;</p> | |||
| <div align="left"> | |||
| <table cellspacing="4" cellpadding="0" border="0"> | |||
| <tr> | |||
| @@ -259,10 +276,10 @@ other jar. The minimal manifest is the following;</p> | |||
| <tr> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| <td bgcolor="#ffffff"><pre> | |||
| Extension-Name: org.realityforge.dve | |||
| Specification-Vendor: Peter Donald | |||
| Specification-Version: 1.0 | |||
| </pre></td> | |||
| Extension-Name: org.realityforge.dve | |||
| Specification-Vendor: Peter Donald | |||
| Specification-Version: 1.0 | |||
| </pre></td> | |||
| <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||
| </tr> | |||
| <tr> | |||
| @@ -273,8 +290,8 @@ Specification-Version: 1.0 | |||
| </table> | |||
| </div> | |||
| <p>It is important to note that looking for dependencies is recursive. For example, | |||
| if the ant library depends upon jar A and and A depends on B then both A and B will | |||
| need to be loaded by the container.</p> | |||
| if the ant library depends upon jar A and and A depends on B then both A and B will | |||
| need to be loaded by the container.</p> | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| @@ -287,22 +304,24 @@ need to be loaded by the container.</p> | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>So far there has been no mention of implementation strategies for | |||
| managing ClassLoaders and other details about where the "Optional Packages" | |||
| are stored. This section will outline such details but they could change | |||
| in the future. The above specification will still be accurate but the approach | |||
| to implementing specification will be different.</p> | |||
| managing ClassLoaders and other details about where the "Optional Packages" | |||
| are stored. This section will outline such details but they could change | |||
| in the future. The above specification will still be accurate but the approach | |||
| to implementing specification will be different.</p> | |||
| <p>In the current architecture all of the "Optional Packages" are assumed to | |||
| be stored in the <code>$ANT_HOME/ext</code> directory. The runtime will scan | |||
| this directory for jars and add all the "optional Packages" found into a | |||
| registry. This registry will be used by the library loading mechanism to locate | |||
| all the "Optional Packages". The user is able to specify an alternative directory | |||
| or add a new directory to search on the commandline.</p> | |||
| be stored in the | |||
| <code>$ANT_HOME/ext</code> directory. The runtime will scan | |||
| this directory for jars and add all the "optional Packages" found into a | |||
| registry. This registry will be used by the library loading mechanism to locate | |||
| all the "Optional Packages". The user is able to specify an alternative directory | |||
| or add a new directory to search on the commandline. | |||
| </p> | |||
| <p>When the container attempts to load an ant library it will also try to load | |||
| any needed dependencies. First it will check the parent ClassLoaders to see if any | |||
| of them contain the required dependencies. If not then it will search the | |||
| "Optional Packages" registry. If the dependency is not found then a error will be | |||
| signaled. If the dependency is found in the "Optional Packages" registry then it is | |||
| loaded by the same ClassLoader that is used to load the Ant library.</p> | |||
| any needed dependencies. First it will check the parent ClassLoaders to see if any | |||
| of them contain the required dependencies. If not then it will search the | |||
| "Optional Packages" registry. If the dependency is not found then a error will be | |||
| signaled. If the dependency is found in the "Optional Packages" registry then it is | |||
| loaded by the same ClassLoader that is used to load the Ant library.</p> | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| @@ -201,28 +201,23 @@ public class MyrmidonSecurityManager | |||
| <p>The Ant1 Compatibility layer is still in early stages of development. | |||
| </p> | |||
| <ul> | |||
| <li>Get a version of <code><ant></code> and | |||
| <code><antcall></code> working.</li> | |||
| <li>Get a version of <code><antcall></code> working.</li> | |||
| <li> | |||
| Provide hooks between Ant1 references and Myrmidon properties. | |||
| May use converters for adapting Ant2 objects (like Ant2 | |||
| <code><path></code> or <code><fileset></code>) | |||
| as Ant1 types. | |||
| </li> | |||
| <li>Handle differences between Ant1 if/unless on targets, | |||
| and Myrmidon <if> task.</li> | |||
| <li> | |||
| Write tests for the various bits that rely on Myrmidon | |||
| functionality: | |||
| Missing tests: | |||
| <ul> | |||
| <li>Simple sanity test</li> | |||
| <li>if/unless on targets: check that behaviour complies with Ant1</li> | |||
| <li>Make sure properties are shared between Ant1 and Myrmidon tasks.</li> | |||
| <li>Make sure that <ant1.property> behaves as per Ant1</li> | |||
| </ul> | |||
| </li> | |||
| <li>Get GUMP runs going using Myrmidon.</li> | |||
| <li>i18n messages</li> | |||
| <li>Add protected accessors for get/set/list properties in | |||
| Ant1 Project, to minimise the amount of code duplication in | |||
| Ant1CompatProject.</li> | |||
| </ul> | |||
| </blockquote> | |||
| </td></tr> | |||
| @@ -18,6 +18,7 @@ import java.util.Iterator; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.Set; | |||
| import java.security.CodeSource; | |||
| import org.apache.aut.converter.Converter; | |||
| import org.apache.aut.converter.ConverterException; | |||
| import org.apache.myrmidon.api.TaskContext; | |||
| @@ -38,16 +39,21 @@ import org.apache.myrmidon.interfaces.type.TypeManager; | |||
| public class Ant1CompatProject extends Project | |||
| { | |||
| public static final String ANT1_TASK_PREFIX = "ant1."; | |||
| public static final String MYRMIDON_PROJECT_PROP = | |||
| org.apache.myrmidon.interfaces.model.Project.PROJECT; | |||
| private static String javaclasspath; | |||
| static | |||
| { | |||
| URL ant1jar = | |||
| Ant1CompatProject.class.getProtectionDomain().getCodeSource().getLocation(); | |||
| String ant1classpath = ant1jar.getFile().toString(); | |||
| // Find the path to the Ant1 antlib file. | |||
| CodeSource ant1codesource = | |||
| Ant1CompatProject.class.getProtectionDomain().getCodeSource(); | |||
| String ant1jar = ant1codesource.getLocation().getFile().toString(); | |||
| // Append this to the java.class.path system property. | |||
| javaclasspath = System.getProperty( "java.class.path" ); | |||
| javaclasspath = javaclasspath + File.pathSeparator + ant1classpath; | |||
| javaclasspath = javaclasspath + File.pathSeparator + ant1jar; | |||
| } | |||
| private final Converter m_converter; | |||
| @@ -67,8 +73,8 @@ public class Ant1CompatProject extends Project | |||
| recontextulize( context ); | |||
| setBaseDir( m_context.getBaseDirectory() ); | |||
| String projectName = (String) | |||
| m_context.getProperty( org.apache.myrmidon.interfaces.model.Project.PROJECT ); | |||
| String projectName = | |||
| (String) m_context.getProperty( MYRMIDON_PROJECT_PROP ); | |||
| if( projectName != null ) | |||
| { | |||
| setName( projectName ); | |||
| @@ -9,6 +9,8 @@ package org.apache.tools.ant; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| /** | |||
| * An adapter for running (in Myrmidon) Ant1 tasks which do not extend Task | |||
| @@ -19,7 +21,18 @@ import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| public class Ant1CompatTaskAdapter | |||
| extends TaskAdapter | |||
| { | |||
| public void configure( Configuration configuration ) throws ConfigurationException | |||
| private static final Resources REZ = | |||
| ResourceManager.getPackageResources( Ant1CompatTaskAdapter.class ); | |||
| /** | |||
| * Gets the adapted task name from the configuration, and looks up the | |||
| * Class for the adapted task. The adapted task is then instantiated and | |||
| * configured. | |||
| * @param configuration The Task Model | |||
| * @throws ConfigurationException If the configuration is invalid. | |||
| */ | |||
| public void configure( Configuration configuration ) | |||
| throws ConfigurationException | |||
| { | |||
| // Create a new instance of the proxy object, | |||
| // and configure it. | |||
| @@ -29,7 +42,9 @@ public class Ant1CompatTaskAdapter | |||
| if( taskClass == null ) | |||
| { | |||
| throw new ConfigurationException( "Invalid task name for TaskAdapter: " + taskName ); | |||
| String message = | |||
| REZ.getString( "taskadapter.invalid-task-name.error", taskName ); | |||
| throw new ConfigurationException( message ); | |||
| } | |||
| Object adaptedTask = null; | |||
| @@ -39,7 +54,9 @@ public class Ant1CompatTaskAdapter | |||
| } | |||
| catch( Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Could not instantiate adapted task: " + taskClass.getName() ); | |||
| String message = | |||
| REZ.getString( "taskadapter.no-create.error", taskClass.getName() ); | |||
| throw new ConfigurationException( message ); | |||
| } | |||
| configure( adaptedTask, configuration ); | |||
| @@ -9,6 +9,8 @@ package org.apache.tools.ant; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| /** | |||
| * A task for instantiating Ant1 datatypes. | |||
| @@ -19,11 +21,14 @@ import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| public class Ant1CompatTypeInstanceTask | |||
| extends Task | |||
| { | |||
| private static final Resources REZ = | |||
| ResourceManager.getPackageResources( Ant1CompatTypeInstanceTask.class ); | |||
| public void configure( Configuration configuration ) throws ConfigurationException | |||
| { | |||
| if( configuration.getAttribute( "id", null ) == null ) | |||
| { | |||
| final String message = "id is required."; | |||
| final String message = REZ.getString( "type.no-id.error" ); | |||
| throw new ConfigurationException( message ); | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| type.no-id.error=Id must be specified. | |||
| taskadapter.invalid-task-name.error=Invalid task name for TaskAdapter: {0}. | |||
| taskadapter.no-create.error=Could not instantiate adapted task: {0}. | |||
| @@ -27,6 +27,7 @@ import org.apache.myrmidon.api.TaskException; | |||
| public class Task extends OriginalAnt1Task | |||
| implements org.apache.myrmidon.api.Task, Configurable | |||
| { | |||
| private static final String ANT1_PROJECT_PROP = "ant1.project"; | |||
| protected TaskContext m_context; | |||
| /** | |||
| @@ -44,11 +45,11 @@ public class Task extends OriginalAnt1Task | |||
| // Create/recontextualise the Ant1 Project. | |||
| Ant1CompatProject project = | |||
| (Ant1CompatProject)context.getProperty( "ant1.project" ); | |||
| (Ant1CompatProject)context.getProperty( ANT1_PROJECT_PROP ); | |||
| if( project == null ) | |||
| { | |||
| project = createProject(); | |||
| m_context.setProperty( "ant1.project", project ); | |||
| m_context.setProperty( ANT1_PROJECT_PROP, project ); | |||
| } | |||
| else | |||
| { | |||
| @@ -84,28 +84,23 @@ public class MyrmidonSecurityManager | |||
| <p>The Ant1 Compatibility layer is still in early stages of development. | |||
| </p> | |||
| <ul> | |||
| <li>Get a version of <code><ant></code> and | |||
| <code><antcall></code> working.</li> | |||
| <li>Get a version of <code><antcall></code> working.</li> | |||
| <li> | |||
| Provide hooks between Ant1 references and Myrmidon properties. | |||
| May use converters for adapting Ant2 objects (like Ant2 | |||
| <code><path></code> or <code><fileset></code>) | |||
| as Ant1 types. | |||
| </li> | |||
| <li>Handle differences between Ant1 if/unless on targets, | |||
| and Myrmidon <if> task.</li> | |||
| <li> | |||
| Write tests for the various bits that rely on Myrmidon | |||
| functionality: | |||
| Missing tests: | |||
| <ul> | |||
| <li>Simple sanity test</li> | |||
| <li>if/unless on targets: check that behaviour complies with Ant1</li> | |||
| <li>Make sure properties are shared between Ant1 and Myrmidon tasks.</li> | |||
| <li>Make sure that <ant1.property> behaves as per Ant1</li> | |||
| </ul> | |||
| </li> | |||
| <li>Get GUMP runs going using Myrmidon.</li> | |||
| <li>i18n messages</li> | |||
| <li>Add protected accessors for get/set/list properties in | |||
| Ant1 Project, to minimise the amount of code duplication in | |||
| Ant1CompatProject.</li> | |||
| </ul> | |||
| </subsection> | |||