CompositionComposition
Composing Applications
Home > Books > Tutorials and Training Guides > XRL By Example > Composition

Rate this page:
Really useful
Satisfactory
Not helpful
Confusing
Incorrect
Unsure
Extra comments:


Composing Applications

In this tutorial you have seen how to use XRL to map address spaces, create simple template defined resource widgets, and compose resource widgets to build new resources. In this section we will examine resource widget composition in more detail and show how NetKernel supports a clean and clear separation of layers, widgets, resources, and services that enables developers to quickly compose application solutions.

XRL Resource Widgets, continued...

Dynamic Template Pull

In the previous examples, we saw how template content could be located dynamically at runtime. In this example we will see how to specify the template at runtime. In the following XRL resource widget template, the content is static and the framing template, service-box-table, is located dynamically at runtime. The content is a static XML documentation fragment that describes three sets of three coloured boxes.

<div xmlns:xrl="http://1060.org/xrl" style="background-color: silver; padding:10px;">
  <div>Part 6 Content</div>
  <xrl:include href="xrl:service-box-table">
    <data>
      <set>
        <box>red</box>
        <box>green</box>
        <box>blue</box>
      </set>
      <set>
        <box>blue</box>
        <box>red</box>
        <box>green</box>
      </set>
      <set>
        <box>green</box>
        <box>blue</box>
        <box>red</box>
      </set>
    </data>
  </xrl:include>
</div>

At this level of abstraction details of the service-box-table implementation are hidden in a lower level. However, at this level we are concerned with delegation to the framing template, so let's examine how an xrl:include tag can provide a parameter argument in a service call.

In the links document that maps the XRL name service-box-table to an internal active URI, note that there is a args tag with the value param. The result of this entry is that the DPML runtime executes a DPML script to dynamically generate a HTML table with box entries...

<links>
  <link>
    <name>service-box-table</name>
    <int>active:dpml+operand@ffcpl:/xrldemo/services/box-table.idoc</int>
    <args>param</args>
  </link>
</links>

When the xrl runtime resolves the xrl:include tag, it locates the internal URI specified by the link name. It also passes the static XML inline document fragment as the 'param' argument to the DPML program because the service link has an <args> tag. This indicates to the XRL runtime that if an argument named 'param' is available then it should be passed as an argument on the internal service request. First try the example...

http://localhost:8080/workbench/xrldemo/part6/index.

You will note that the static XML content defining various coloured boxes has been translated into a visual representation. If you examine services/box-table.idoc you will see that the implementation calls a XSL stylesheet that translates the inline data.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xrl="http://1060.org/xrl" version="1.0">
  <xsl:output method="xml" />
  <xsl:template match="/data">
    <table>
      <xsl:apply-templates />
    </table>
  </xsl:template>
  <xsl:template match="set">
    <tr>
      <xsl:apply-templates />
    </tr>
  </xsl:template>
  <xsl:template match="box">
    <td>
      <xrl:include href="xrl:{.}-box" />
    </td>
  </xsl:template>
</xsl:stylesheet>

If you inspect the XSL code carefully, you will notice that the resulting table contains another set of dynamically generated xrl:includes tags, each of which references a coloured box resource. The resulting HTML table is as follows:

<table xmlns:xrl="http://1060.org/xrl">
  <tr>
    <td>
      <xrl:include href="xrl:red-box" />
    </td>
    <td>
      <xrl:include href="xrl:green-box" />
    </td>
    <td>
      <xrl:include href="xrl:blue-box" />
    </td>
  </tr>
  <tr>
    <td>
      <xrl:include href="xrl:blue-box" />
    </td>
    <td>
      <xrl:include href="xrl:red-box" />
    </td>
    <td>
      <xrl:include href="xrl:green-box" />
    </td>
  </tr>
  <tr>
    <td>
      <xrl:include href="xrl:green-box" />
    </td>
    <td>
      <xrl:include href="xrl:blue-box" />
    </td>
    <td>
      <xrl:include href="xrl:red-box" />
    </td>
  </tr>
</table>

The dynamically generated XRL references in this HTML fragment are also recursively resolved by the XRL runtime.

Dynamic Template and Dynamic Content

In this section we will extend the previous example to include dynamic content. The user will be presented a form that accepts a number specifying how many coloured boxes to generate. When executed, the program will generate an N by N grid of boxes and randomly select the colour for each box.

http://localhost:8080/workbench/xrldemo/part7/index.

We'll let you dissect the source in detail. What you'll discover is a set of linearly independent services which are marshalled and coordinated by the XRL recursion.

The important point with this application is that the form data is being passed down from the browser submission all the way through to the implementing services. Note that the input form itself is actually dynamically generated so that is displays the current grid size. This is the named link "part7-form" and is implemented by a DPML script with an active:dpml request...

<links>
  <link>
    <name>index7</name>
    <ext>/part7/index</ext>
    <int>active:xrl-html+template@xrl:part7-template+content@xrl:part7-content</int>
    <args>param,links</args>
  </link>
  <link>
    <name>part7-template</name>
    <int>ffcpl:/xrldemo/part7/template.xml</int>
  </link>
  <link>
    <name>part7-content</name>
    <int>ffcpl:/xrldemo/part7/content.xml</int>
  </link>
  <link>
    <name>part7-form</name>
    <int>active:dpml+operand@ffcpl:/xrldemo/part7/form.idoc</int>
    <args>param</args>
  </link>
</links>

So, how did this form-script get its parameter?

Parameter Relaying

When your web-browser submits the form, the form post data is received by NetKernel's HTTP transport. The HTTP transport initiates an internal request for the resource, this request is mapped by the front-end fulcrum to the the http-bridge accessor. This accessor extracts the posted form data and initiates an active URI request for ffcpl:/workbench/xrldemo/part7/index and passes the form-post data as the 'param' argument on this active URI request.

As we have seen previously, requests for ffcpl:/workbench/xrldemo enter the workbench module and are directed to the mapper accessor, however this mapping also captures and relays to the mapper all of the active URI arguments on the external request, including the 'param' argument containing the post data.

In general we don't think about these external stages - they are performed transparently by the infrastructure above us. The important thing, and the thing to focus on, is that we have initiated a request on the mapper and the externally generated post data has arrived as an argument named 'param'...

As in earlier examples, the mapper resolves the operand argument to the part7-index link. If we examine this link closely we see that it has a tag <args>. The args tag indicates to the mapper and the xrl runtimes the names of the arguments which should be relayed on with the internal active URI request which is specified in the int tag - in this case 'param'. So the 'param' argument which the mapper received, is relayed on as an argument to the active:xrl call.

During the xrl recursion the xrl runtime resolves an include request for "xrl:part7-form". It locates the appropriate link in the links document, which, as we discussed above, is a request to the DPML scripting runtime. However this link also has an <args> tag containing 'param'. The xrl runtime is therefore instructed to relay on the 'param' argument which it received on the active URI request to the DPML engine.

Finally the DPML script executes and uses the param to dynamically generate the form widget. In a very similar way the main grid of coloured boxes is generated. Examine the source code and look at how the 'param' argument is passed to another, independent DPML script to generate the table.

Other Points of Interest

The source for the example has a few other points of interest...

The random-box service is implemented as a simple wrapper over a secondary call to the mapper and links...


import java.util.*;

main()
{   r=new Random();
    c=r.nextInt(3);
    color=null;
    switch(c)
    {   case 0:
            color="red";
        break;
        case 1:
            color="green";
        break;
        case 2:
            color="blue";
        break;
    }

    //ReUse the mapper to source the box widgets
    req=context.createSubRequest();
    req.setURI("active:mapper");
    req.addArgument("operator", "ffcpl:/xrldemo/links.xml");
    req.addArgument("operand", "ffcpl:/workbench/xrldemo/widgets/"+color+"-box");
    result=context.issueSubRequest(req);
    
    context.createResponseFrom(result);

}

        

A DPML script to filter the default-parameter is used by two services (part7-form and dynamic-box-table). If no external parameter is provided, which is the case when the page is first requested, then a default size of 3 will be used...

<idoc>
  <seq>
    <instr>
      <type>copy</type>
      <operand>this:param:param</operand>
      <target>this:response</target>
    </instr>
    <exception>
      <comment>If there is no parameter then default to 3x3</comment>
      <instr>
        <type>copy</type>
        <operand>
          <nvp>
            <size>3</size>
          </nvp>
        </operand>
        <target>this:response</target>
      </instr>
    </exception>
  </seq>
</idoc>
© 2003-2007, 1060 Research Limited. 1060 registered trademark, NetKernel trademark of 1060 Research Limited.