|
- <?xml version="1.0"?>
- <document>
-
- <properties>
- <title>On Task Configuring in Ant 2</title>
- <author email="peter@apache.org">Peter Donald</author>
- </properties>
-
- <body>
-
- <section name="Introduction">
- <p>This section will describe in detail the mechanism via which tasks are
- configured. Configuration is the name given to the stage in tasks
- lifecycle via which the XML representation is mapped onto the task
- object.</p>
- </section>
-
- <section name="Names">
-
- <p>When mapping the XML representation on to the task object you
- need to be able map the names as they appear in the XML to the
- names as they appear in the Java code. The process is for generating
- a java name from the xml name is as follows.</p>
- <ol>
- <li>Capitalize the first character of name.</li>
- <li>Find any '-' characters in XML name and remove character and
- capitalize the following letter. (And there must be a following
- letter)</li>
- </ol>
- <p>Some example mappings;</p>
- <source>
- my-name ===> MyName
- aString ===> AString
- Basedir ===> Basedir
- baseDir ===> BaseDir
- url ===> Url</source>
- <p>Note that the above transformation is lossy and as such the
- following XML names all map to the same Java name. The ant1.x mapping
- is similarly lossy and in practice this has not been an issue.</p>
- <source>
- base-dir ===> BaseDir
- Base-dir ===> BaseDir
- baseDir ===> BaseDir
- BaseDir ===> BaseDir</source>
- <p><i>NOTE: We should really resolve this and either disallow '-' characters
- or disallow uppercase or something. (PD)</i></p>
- </section>
-
- <section name="Resolving Values">
- <p>The first stage of mapping the XML representation to the task
- is resolving all text data. The text data that needs to be resolved
- include the values of attributes and the content.</p>
- <p>Resolution consists of expanding any property references in the text
- data. Property references are identified as starting with the token
- "${" and finishing with another "}" token. The text
- in between is the name of a property. The value of the property replaces
- the sequence of text starting with the "${" token and finishing
- with the "}" token.</p>
- <p>Note that the value of the property may not be a string. If the text data
- contains text (or other property references) to either side of the property
- reference then it must be <a href="converter.html">converted</a> to a
- String.</p>
- </section>
-
- <section name="Modeller">
- <p>Currently the representation of object are stored in a hierarchial
- tree of <code>org.apache.myrmidon.api.metadata.ModelElement</code>
- objects. Each ModelElement has a number of attributes and can have
- either content or sub-elements.</p>
- <p>In most cases it is the responsibility of the runtime to map
- the ModelElement onto an object. However in some cases it may be useful
- for the object to get access to it's own model and for it to explicitly
- manage it's own configuration. In this case the object should implement
- the <code>org.apache.myrmidon.api.metadata.Modeller</code> interface
- which will provide the mechanism for the object to receive its own
- representation and configure itself.</p>
- <p>Note that the Modeller mechanism should be avoided if possible
- as it adds considerable complexity to the implementing object.</p>
- </section>
-
- <section name="Attributes">
- <p>To map an XML attribute on to a Java object, the name of the
- attribute is mapped to a java name and prefixed with the string
- "set". The resulting string is then used to look up a
- method with a single parameter.</p>
- <p>For example, for the attribute "world" would result
- in a lookup of a method named "setWorld" with a single
- parameter.</p>
- <p>If multiple methods were matched during the lookup then an
- exception is thrown indicating ambiguity. Theres is an exception
- to this rule that allows 2 methods to be matched if one of the
- methods takes a <code>java.lang.String</code> parameter. The method
- that has the <code>java.lang.String</code> parameter is ignored and
- the other method would be chosen. This exception is allowed as it is
- common practice for a task to evolve from String parameters to more
- strongly typed parameters.</p>
- <p>The resolved text data of the attribute must be
- <a href="converter.html">converted</a> to the type of the matched
- methods parameter. For example, if the "setWorld" method
- took a parameter of type <code>java.io.File</code> then the resolved
- text data must be converted into a <code>java.io.File</code>. The
- conversion is done by the Converter architecture that is more fully
- described in the <a href="converter.html">Converter HOWTO</a>.</p>
- <p>After the value is converted to the correct type the method is
- invoked with the converted value.</p>
- </section>
-
- <section name="Content">
- <p>The XML representation of object can have either have nested
- elements or nested text (content) but not both. To add the content
- to an object a method named "content" with one parameter is looked
- up. The resolved text data for content is then
- <a href="converter.html">converted</a> to the type of the parameter
- and passed in via the method.</p>
- </section>
-
- <section name="Element">
- <p>Mapping an ModelElement onto a java object is a series of steps.
- If the ModelElement name ends with the string "-ref" then
- it is treated as a reference element - see the <em>Referrenced
- Elements</em> section. Otherwise, the element is first attempted to
- be mapped as a <em>Named Element</em> and if no match is found via
- that method it tries to treat the element as a <em>Typed Element</em>.</p>
- <subsection name="Named Elements">
- <p>To map a named ModelElement on to a Java object, the name of
- the element is mapped to a java name and prefixed with the string
- "add". The resulting string is then used to look up a
- method with a single parameter.</p>
-
- <p>For example, for the attribute "geometry" would result
- in a lookup of a method named "addGeometry" with a single
- parameter. If multiple methods were matched during the lookup then an
- exception is thrown indicating ambiguity. If no methods were found that
- match name then skip down to configuring "typed" elements.</p>
-
- <p>The type of the methods single parameter is then examined to determine
- what happens next. There are two valid situations, if neither of these are
- satisfied, then an exception is thrown.</p>
- <ul>
- <li>The parameters type is <code>org.apache.myrmidon.api.metadata.ModelElement</code></li>
- <li>The parameters type is a concrete class</li>
- </ul>
- <p>1. If the parameter has a type of <code>org.apache.myrmidon.api.metadata.ModelElement</code>
- then the un-modified model representation of element is passed to object by invoking
- the adder method.</p>
- <p>2. If the parameters type is concrete then an instance of the parameter is
- instantiated using the default constructor. This created object is then configured
- in the same manner as task using the elements representation as the model. After
- the object is configured it is passed into object by invoking the adder method.</p>
- </subsection>
- <subsection name="Referrenced Elements">
- <p>A referenced element is one that has a name ending in
- "-ref" and has a single attribute "name"
- and no content or child elements.</p>
-
- <p>The value of the "name" attribute is the name of a property.
- The value of this property is retrieved from the TaskContext.</p>
-
- <p>Like with <em>Named Elements</em> the name of the element (minus
- the "-ref" part) is mapped to a java name and prefixed with the string
- "add". The resulting string is then used to look up a
- method with a single parameter. If multiple methods were matched during the lookup then an
- exception is thrown indicating ambiguity.</p>
-
- <p>The value retrieved from the TaskContext is then converted to the type
- of the methods parameter and the add method is invoked with the converted value.</p>
-
- <p>An example usage is the following;</p>
- <source><![CDATA[
-
- <my-task ...>
- <classpath-ref name="project.class.path"/>
- </my-task>
-
- ]]></source>
- </subsection>
- <subsection name="Typed Elements">
- <p>"Typed" elements can also be added to an object. A typed element
- is one in which the name of the element actually refers to a type rather than the
- name of the adder to call.</p>
- <p>For example, you may wish to allow a task to add arbitrary instances of the
- Condition role to a task. So instead of adding methods such as
- <code>addAnd(AndCondition)</code>, <code>addOr(OrCondition)</code> and
- <code>addXor(XorCondition)</code> you can instead add a single method
- <code>add(Condition)</code>. This vastly simplifies the amount of work required
- to write tasks that take conditions. More importantly it allows end-users to
- extend the number of elements selected by task. For instance if the user wanted
- a "nand" condition they could write the Nand type use it in their build
- file. For a discussion on roles and types see the <a href="types.html">Types
- HOWTO</a>.</p>
- <p>To use a Typed adder there must be a single method named "add" that
- has a single parameter. The parameter <em>MUST</em> be an abstract interface and
- must be registered as a role. The name of the element is then used to lookup the
- a type in the TypeManager with a role matching the interface name.</p>
-
- <p>For example if an element named "nand" was added to an object that had
- an adder with the signature <code>void add( Condition condition )</code> then
- the type named "nand" in the role "Condition" would be looked up.
- An instance of the type would then be created using the default constructor and the
- created object would be configured and then adder to object using adder.</p>
-
- </subsection>
- </section>
- </body>
- </document>
|