10. Chaining processors

Up to now our process definitions was made up of a single step. We have seen that a single step can perform fairly complex actions. We will now introduce the ability to connect multiple steps.

Let’s expand the example by adding a second step:

<?xml version="1.0" encoding="UTF-8" ?>
<process first-step="formatDate"> 1
   <description>
      <output>
         <state>ok</state>
         <result name="welcomePage" 
                 description="composedPage" 
                 content-type="text/html" 
                 presentable="true" />
      </output>
   </description>

   <step id="formatDate" processor="dateFormatter">
      <load parameter="date">
         <value processor="system" result="currentDate"/>
      </load>
      <load parameter="timeFormat">
         <string>medium</string>
      </load>
      <save result="output" key="currentDate"/> 2
         <route state="ok" step="compose" /> 3
      </step>

   <step id="compose" processor="hello">
      <load parameter="currentDate">
         <value key="currentDate"/> 4
      </load>
      <load parameter="style">
         <string>color:red;font:italic;</string>
      </load>
      <save result="output" store="output" 
            key="welcomePage" presentable="true"/>
      <route state="ok" return="ok" />
   </step>
</process>
1

Optional attribute to set the starting step

2

If you don’t specify the store, the scope of the saved value is the current running process. Saved values with no store specified can be loaded by any other step in this process definition that is called in the same request. This is the easiest way to transfer data from one step to the following steps

3

The result state ok of the called processor is routed to the step with the id compose

4

If you don’t specify a store when loading a dynamic value, the scope is set to the current running process. This is the way to load values that have been stored by previous steps with no store specified.

We have extended our example by introducing a second step that will be performed before the step that we already know is executed. When a process gets launched, the first step that is defined in the process definition gets launched. If you want the process to start with a different step, you can explicitly specify the first step to start with. In the example you can this attribute has been used to show the syntax even if the desired first step is the first in our definition and would because of that fact have been the first one anyway.

The first step is associated with the DateFormatter that has been introduced in the previous examples. As we are no more using this processor implicitly by assigning the result directly to a dynamic value as we did in the previous example, we can now adjust the output format that will be generated by loading all parameters that we want to use. In this example we set the time format to medium. This has the effect, that in opposite to the default short time format the seconds of the current time are also displayed.

The result of the DateFormatter gets save to the temporary process store that is available to pass parameters from one step to the following ones.

As we define a routing for the only result state that the DateFormatter provides, the process will continue with the compose step. This step is nearly identically with the previous example, but we replaced the username parameter with a parameter called currentTime as this more reflects the content of the variable. This parameter gets loaded with the value that was stored by the first step. Change our template so that it matches the newly defined parameter name:

<html>
   <body>
      <h1 <?style style="<%style%>"?>>Current date: <%currentDate;required;text/plain%></h1>
   </body>
</html>

If we now reload the web page, we will see a more attractive page than ever:

You can see that the time now includes the seconds in contrast to the previous example screenshot. It’s now very easy for us to change the date or time format as we can load each parameter of the DateFormatter. In our previous version we could only specify the date parameter as it is only allowed to use processors with exactly one or zero required parameters to be loaded into dynamic values directly.