There are two types of element tags: absolute, and relative. An absolute tag is the extension tag field, and should be unique. A relative tag is the name of the mutator method on the parent element (object class) which handles the child element in question.

For POEs with a POE or ITask parent, the element tag must correspond to its associated mutator method, i.e., it must be relative. For instance, a Trebuchet pattern such as:

<trebuchet-group target="someuri">
    <pattern base="somesourcefile"/>
</trebuchet-group>

implies that there is a setPattern( TrebuchetPattern ) or addPattern( TrebuchetPattern ) method on the trebuchet-group class. Note that when any reflection takes place, xml-style (hyphenated) tag names will be automatically converted to the Java-style name, e.g., <trebuchet-group> becomes TrebuchetGroup.

A special case is the tagged element whose type is a primitiveAssignable. For instance, the addInclude( String ) method on the TrebuchetPattern class. In this case, the tag carries its value as text:

<trebuchet-pattern base="someuri">
    <include>*fileA*.xml</include>
</trebuchet-pattern>

(More on element TEXT under 5. Interchanging Attributes and Tags.)

If a Collection or Map is handled by a POE, its tag follows the above-mentioned naming scheme:

<element-with-integer-list>
    <integers>
        <value type="int">4</value>
        <value type="int">7</value>
    </integers>
</element-with-integer-list>

implies there is a method on the parent element setIntegers( List ).

Notes

  1. For collections and maps, there are default implementations for the interface class parameters: java.util.List = java.util.ArrayList, java.util.Map = java.util.HashMap, java.util.Set = java.util.HashSet.
  2. The value element takes a single type attribute denoting a primitiveAssignable class; the default value is string. The actual value is given as the TEXT (but see further 5. Interchanging Attributes and Tags.)

Inside of ISelfConfiguring elements, collections or maps, all element tags must be absolute; this is because the type of the child elements of these objects is not determined by introspection on the parent. Hence:

<self-configuring-element>
    <map>
        <map-entry key="a">
            <list>
               <value type="int">4</value>
               <value type="int">7</value>
            </list>
        </map-entry>
    </map>
    <trebuchet-pattern base="someuri">
        <include>*fileA*.xml</include>
    </trebuchet-pattern>
</self-configuring-element>

<trebuchet-pattern> is the absolute tag for ncsa.tools.trebuchet.types.TrebuchetPattern.

Notes

  1. Inside of ISelfConfiguring elements, this constraint can be circumvented, provided the container knows how to map the alternative tags to the actual extension/type tag or to its fully-qualified Class name.
  2. All elements added to a <map> must be of type <map-entry>, which takes a key attribute and a single element, again expressed with its absolute tag.

The absolute tags corresponding to collections and maps are:

TAG

CLASS

<list>

java.util.ArrayList

<linked-list>

java.util.LinkedList

<vector>

java.util.Vector

<map>

java.util.HashMap

<hash-map>

java.util.HashMap

<tree-map>

java.util.TreeMap

<hash-set>

java.util.HashSet

<tree-set>

java.util.TreeSet

Reserved Tags

The following tags always denote the type java.lang.Object:

  • <ref>
  • <reference>
  • <object>

Overriding Relative Tags

In some cases, such as when a task or element needs to add or set an object which is subject to further customized extension or subclassing, it may not be possible to code the Ogrescript class to take all known concrete types as potential children. For this purpose, a special syntax exists which acts as a directive to the container to construct the specific type indicated.

For such elements, simply append the absolute tag to the relative tag, using ".":

<copy taskName="BULK_FILE_MOVE" target="file:${runtime.dir}">
  <configuration>
        <property name="transferMode" value="gridftp-stream"/>
       	<property name="target-active" value="true" type="boolean"/>
       	<property name="tcpBufferSize" value="2097152" type="int"/> 
  </configuration>
  <listener.transfer-completed-listener bulk="true"/>
  <source base="mssftp://mss.ncsa.uiuc.edu/u/ncsa/bjewett/RT/NAM/00">
       	<include>nam*</include>
  </source>
</copy>

The prefix.suffix syntax indicates that the method corresponding to the relative tag, addListener, has a general (assignable) type, and that this particular element is of the concrete type corresponding to the transfer-completed-listener tag registered as an extension. One can thus continue to create listeners to add to this task without modifying the task itself to take those concrete types.

(Of course, one could also use the less compact solution of constructing the listener and then referencing it:

<declare name="listener">
   <transfer-completed-listener bulk="true"/>
</declare>
<copy taskName="BULK_FILE_MOVE" target="file:${runtime.dir}">
  <configuration>
        <property name="transferMode" value="gridftp-stream"/>
       	<property name="target-active" value="true" type="boolean"/>
       	<property name="tcpBufferSize" value="2097152" type="int"/> 
  </configuration>
  <listener>${listener}</listener>
  <source base="mssftp://mss.ncsa.uiuc.edu/u/ncsa/bjewett/RT/NAM/00">
       	<include>nam*</include>
  </source>
</copy>
<remove name="listener"/>

The advantage of the first solution, aside from the syntactic sugar, is that it does not leave the listener in the Ogrescript environment after the task has completed; to make sure that object gets garbage-collected, one should explicitly remove it, as illustrated.)

NB: As a consequence, you should not create elements whose names contain '.', or they will not parse correctly.

  • No labels