Package org.apache.commons.workflow.core

Implementations of Steps in the core library.

See:
          Description

Class Summary
AndStep Evaluate properties specified by the associated Descriptors, and transfer control to the specified step if ALL of them are true (if boolean) or not null (if Object).
BreakStep Locate the closest surrounding Iterator, set the nesting control to false, and transfer control to the Iterator.
CallStep Pop the top value from the evaluation stack, which must be an Activity, and initiate a "subroutine call" to execute this Activity before resuming the current one.
ConstructStep Create a new object of the specified class, using the constructor that accepts the arguments specified by the associated Descriptor objects.
ContinueStep Locate the closest surrounding Iterator, set the nesting control to true, and transfer control to the Iterator.
CoreRuleSet RuleSet for the Step definitions supported by the core library.
DuplicateStep Push a new copy of the top item on the evaluation stack onto the stack.
ExitStep Signal our Context that we have completed the current Activity.
GetStep For each associated Descriptor, make a copy of the specified Java object and push it on to the evaluation stack, in the order that descriptors are listed.
GotoStep Unconditionally transfer control to the specified step.
IfAnyStep Evaluate properties specified by the associated Descriptors, and execute the nested Steps if and only if ANY of them evaluate to a positive result.
IfNotAnyStep Evaluate properties specified by the associated Descriptors, and execute the nested Steps if and only if ALL of them evaluate to a negative result.
IfNotStep Evaluate properties specified by the associated Descriptors, and execute the nested Steps if and only if ANY of them evaluate to a negative result.
IfStep Evaluate properties specified by the associated Descriptors, and execute the nested Steps if and only if they ALL evaluate to a positive result.
InvokeStep Call the specified method of the specified bean in the specified scope, passing arguments as specified by associated Descriptor objects.
LoadStep Load a class with the specified name from the specified class loader, and push the corresponding java.lang.Class object onto the evaluation stack.
NotAndStep Evaluate properties specified by the associated Descriptors, and transfer control to the specified step if ALL of them are false (if boolean) or null (if Object).
NotOrStep Evaluate properties specified by the associated Descriptors, and transfer control to the specified step if ANY of them are false (if boolean) or null (if Object).
OrStep Evaluate properties specified by the associated Descriptors, and transfer control to the specified step if ANY of them are true (if boolean) or not null (if Object).
PopStep Pop the top value from the evaluation stack and throw it away.
PutStep For each associated Descriptor, pop the top value from the evaluation stack, and store it as specified by that Descriptor, in the order that descriptors are listed.
RemoveStep For each associated Descriptor, remove the corresponding Java object from our Context, in the order that descriptors are listed.
StringStep Push the specified String value onto the top of the evaluation stack.
SuspendStep Signal our Context to suspend execution until control is returned.
SwapStep Swap the positions of the top two values on the evaluation stack.
WhileAnyStep Repeatedly evaluate the properties specified by the associated Descriptors, and execute the nested Steps if and only if ANY of them evaluate to a positive result.
WhileNotAnyStep Repeatedly evaluate the properties specified by the associated Descriptors, and execute the nested Steps if and only if ALL of them evaluate to a negative result.
WhileNotStep Repeatedly evaluate the properties specified by the associated Descriptors, and execute the nested Steps if and only if ANY of them evaluate to a negative result.
WhileStep Repeatedly evaluate the properties specified by the associated Descriptors, and execute the nested Steps if and only if ALL of them evaluate to a positive result.
 

Package org.apache.commons.workflow.core Description

Implementations of Steps in the core library.

Core Step Library - Overview

This package contains org.apache.commons.workflow.Step implementations for the core library. This library includes Steps for fundamental object stack manipulation, as well as conditional branching. Such Steps are commonly required in defining Activities, no matter what domain you are using the Workflow system in.

The sections below define each of the Step definitions included in this library, utilizing the XML syntax that is recognized by the Digester used to process your Activity definition files. Although you can use any namespace prefix, the convention is to declare core as the namespace prefix, as in the following example:

  <base:activity id="Demonstration Activity"
    xmlns:base="http://commons.apache.org/workflow/base"
    xmlns:core="http://commons.apache.org/workflow/core"
  >

    <core:string value="This is a string value"/>

  </base:activity>

NOTE - It is not required that you use the XML syntax, processed with a Digester, to initialize the Steps associated with each Activity. However, this usage is very convenient, and is likely to be the most common case, so the Steps are documented from that perspective. To use the underlying implementation classes directly, see the Javadocs for each Step implementation class, just as you would for any other Java class.

[core:and] [core:call] [core:construct] [core:duplicate] [core:exit] [core:get] [core:goto] [core:if] [core:ifAny] [core:ifNot] [core:ifNotAny] [core:invoke] [core:load] [core:notAnd] [core:notOr] [core:or] [core:pop] [core:put] [core:remove] [core:string] [core:suspend] [core:swap]

Core Step Library - Step Definitions

core:and

The core:and Step evaluates the properties specified by all nested <core:descriptor> elements, and transfers control to the specified step if ALL of them are true (if boolean) or not null (if Object). To avoid non-deterministic evaluation stack behavior, all of the nested <core:descriptor> elements are always evaluated.

The core:and element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:and element. All of them will be evaluated in order to determine whether or not a branch to the Step specified by the step attribute should occur or not.

In the following example, control will branch to the Step labelled ok if all of the specified properties of the address bean return non-null String values. Otherwise, control will be transferred (via the core:goto Step) to the Step labelled notOk.

  <core:and step="ok">
    <core:descriptor xpath="address/street1"/>
    <core:descriptor xpath="address/city"/>
    <core:descriptor xpath="address/state"/>
    <core:descriptor xpath="address/zipCode"/>
  </core:and>
  <core:goto step="notOk"/>

core:break

The core:break Step can be used inside an iteration loop (such as core:while, core:whileAny, core:whileNot, and core:whileNotAny) to prematurely exit from the current iteration, and force the termination of the loop. Thus, it has semantics similar to the "break" statement in programming languages like Java and C/C++.

The core:break element recognizes the following attributes:

In the example below, the loop will repeated as long as the loopNow attribute returns a positive result. However, the last iteration will also be prematurely broken if the breakNow attribute returns a positive loop:

  <core:while>
    <core:descriptor xpath="loopNow"/>
    ... Steps executed if "loopNow" is positive ...
    <core:if>
      <core:descriptor xpath="breakNow"/>
      <core:break/>
    </core:if>
    ... Steps executed if "loopNow" is positive and ...
    ... "breakNow" is negative ...
  </core:while>

core:call

The core:call Step pops the top value from the evaluation stack, which must be an Activity, and initiates a "subroutine call" to execute this Activity before resuming the current one. Control will be returned to the step following this one, once the called Activity executes an core:exit Step, or the last defined Step in the Activity has been executed.

The core:call element recognizes the following attributes:

In the example below, the activity property of the process bean is assumed to return an instance of Activity that is to be executed to accomplish a portion of a business process. This allows components to manage the overall control flow dynamically.

  <core:get>
    <core:descriptor xpath="process/activity"/>
  </core:get>
  <core:call/>

core:construct

The core:construct Step creates a new object of the specified class, and pushes it onto the stack. The specified class, and the optional argument(s) to the constructor, are defined by the nested core:descriptor elements.

The core:construct element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. They are interpreted as follows:

FIXME - Currently, this Step does not correctly recognize constructors that accept primitive argument types.

FIXME - We need a better way to deal with exceptions (either checked or unchecked) thrown by calling the constructor.

In the example below, it is assumed that the top item on the evaluation stack is an instance of java.lang.Class, produced by some unspecified previous processing. This class has a constructor that takes two arguments - a java.util.Map and a java.lang.String - that are returned by appropriate bean properties.

  <core:construct>
    <core:class/>   <-- Top item is a Class -->
    <core:descriptor xpath="foo/map" type="java.util.Map"/>
    <core:descriptor xpath="bar/string"/>
  </core:construct>

core:continue

The core:continue Step can be used inside an iteration loop (such as core:while, core:whileAny, core:whileNot, and core:whileNotAny) to prematurely return to the conditional test at the top of the loop, to determine whether it should be repeated again. Thus, it has semantics similar to the "continue" statement in programming languages like Java and C/C++.

The core:continue element recognizes the following attributes:

In the example below, the loop will repeated as long as the loopNow attribute returns a positive result. If the continueNow attribute is also positive, that iteration will be prematurely stopped, and loopNow will be tested again for the next iteration:

  <core:while>
    <core:descriptor xpath="loopNow"/>
    ... Steps executed if "loopNow" is positive ...
    <core:if>
      <core:descriptor xpath="continueNow"/>
      <core:continue/>
    </core:if>
    ... Steps executed if "loopNow" is positive ...
    ... and "continueNow" is negative ...
  </core:while>

core:duplicate

The core:duplicate Step peeks at the top value on the evaluation stack and pushes another copy of it onto the stack. This is useful in scenarios where you execute Steps that consume items from the stack, but you wish to maintain a reference to the top object.

The core:duplicate element recognizes the following attributes:

In the example below, the script wants to display the top item on the stack (for debugging purposes) without consuming it.

  <core:duplicate/>
  <io:display>
    <io:descriptor/>   <-- Consumes top stack item -->
  </io:display>

core:exit

The core:exit Step causes execution of the current Activity to be completed, just as if the last Step in the Activity had been executed. If this Activity was executed as the result of a core:call invocation, control will resume with the next Step in the calling Activity. Otherwise, the Context.execute() call from the application will return control to the calling application.

The core:exit element recognizes the following attributes:

core:get

The core:get Step makes a copy of the properties specified by all nested <core:descriptor> elements, and pushes them on to the evaluation stack, in the order that the descriptors are listed.

The core:get element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:get element. All of them will be evaluated in the order listed, and the corresponding property values will be pushed on to the evaluation stack.

In the following example, the four specified properties of the address bean will be extracted and pushed on to the evaluation stack.

  <core:get>
    <core:descriptor xpath="address/street1"/>
    <core:descriptor xpath="address/city"/>
    <core:descriptor xpath="address/state"/>
    <core:descriptor xpath="address/zipCode"/>
  </core:get>

core:goto

The core:goto Step unconditionally transfers control to the Step specified by the step attribute. This value must match the id attribute of some other Step in the current Activity, which can occur either before or after the current Step.

The core:goto element recognizes the following attributes:

core:if

The core:if Step conditionally executes the immediately nested steps one time, if and only if ALL of the nested Descriptors evaluate to a positive result (i.e. boolean true, non-null String with length greater than zero, numeric value other than zero, or non-null for an Object). To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:if element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

In the example below, the nested block is executed because both Descriptors evaluate to positive results:

  <core:string value="Non-Null String 1"/>
  <core:string value="Non-Null String 2"/>
  <core:if>
    <core:descriptor/>    <-- Pop top stack item -->
    <core:descriptor/>    <-- Pop next stack item -->
    ... Steps placed here WILL be executed ...
  </core:if>

core:ifAny

The core:ifAny Step conditionally executes the immediately nested steps one time, if and only if ANY of the nested Descriptors evaluate to a positive result (i.e. boolean true, non-null String with length greater than zero, numeric value other than zero, or non-null for an Object). To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:ifAny element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

In the example below, the nested block is executed because the second Descriptor evaluates to a positive result:

  <core:string value=""/>
  <core:string value="Non-Null String"/>
  <core:ifAny>
    <core:descriptor/>    <-- Pop top stack item -->
    <core:descriptor/>    <-- Pop next stack item -->
    ... Steps placed here WILL be executed ...
  </core:ifAny>

core:ifNot

The core:ifNot Step conditionally executes the immediately nested steps one time, if and only if ANY of the nested Descriptors evaluate to a negative result (i.e. boolean false, null or zero-length String, numeric value equal zero, or null for an Object). To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:ifNot element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

In the example below, the nested block is executed because the first Descriptor evaluates to a negative result:

  <core:string value=""/>
  <core:string value="Non-Null String"/>
  <core:ifNot>
    <core:descriptor/>    <-- Pop top stack item -->
    <core:descriptor/>    <-- Pop next stack item -->
    ... Steps placed here WILL be executed ...
  </core:ifNot>

core:ifNotAny

The core:ifNotAny Step conditionally executes the immediately nested steps one time, if and only if ALL of the nested Descriptors evaluate to a negative result (i.e. boolean false, null or zero-length String, numeric value equal zero, or null for an Object). To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:ifNotAny element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

In the example below, the nested block is executed because both Descriptors evaluate to a negative result:

  <core:string value=""/>
  <core:string value=""/>
  <core:ifNotAny>
    <core:descriptor/>    <-- Pop top stack item -->
    <core:descriptor/>    <-- Pop next stack item -->
    ... Steps placed here WILL be executed ...
  </core:ifNotAny>

core:invoke

The core:invoke Step calls a specified method on a specified bean instance, passing the specified values, and pushes the return value (if any) on to the evaluation tack. The specified bean instance, and the arguments to be passed, are defined by the nested core:descriptor elements.

The core:invoke element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. They are interpreted as follows:

FIXME - Currently, this Step does not correctly recognize constructors that accept primitive argument types.

FIXME - We need a better way to deal with exceptions (either checked or unchecked) thrown by calling the method.

In the example below, it is assumed that the Customer bean specified by the first descriptor includes a public addAddress method that takes a String argument (the address type), and an address object (ours is in the "address" bean).

  <core:string value="Home"/>
  <core:invoke method="addAddress">
    <core:bean xpath="customer"/>
    <core:descriptor/>    <-- The String we just pushed -->
    <core:descriptor xpath="address"/>
  </core:invoke>

In this case, the addAddress() method is of type void, so it returns no value. If a value had been returned, it would have been pushed on to the evaluation stack.

core:load

The core:load Step causes the specified java.lang.Class to be loaded, and the corresponding Class object pushed onto the top of the execution stack. The name of the class to be loaded can be specified either statically or dynamically.

The core:load element recognizes the following attributes:

In the example below, the java.util.Date class is loaded, and a new Date instance is constructed using the zero-arguments constructor and pushed on to the evaluation stack.

  <core:load name="java.util.Date"/>
  <core:construct>
    <core:descriptor/>   <-- Consumes top item from the stack -->
  </core:construct>

core:notAnd

The core:notAnd Step evaluates the properties specified by all nested <core:descriptor> elements, and transfers control to the specified step if ALL of them are false (if boolean) or null (if Object). To avoid non-deterministic evaluation stack behavior, all of the nested <core:descriptor> elements are always evaluated.

NOTE: - This is the exact opposite of and.

The core:notAnd element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:notAnd element. All of them will be evaluated in order to determine whether or not a branch to the Step specified by the step attribute should occur or not.

In the following example, control will branch to the Step labelled empty if all of the specified properties of the address bean return null String values. Otherwise, control will be transferred (via the core:goto Step) to the Step labelled notEmpty.

  <core:notAnd step="empty">
    <core:descriptor xpath="address/street1"/>
    <core:descriptor xpath="address/city"/>
    <core:descriptor xpath="address/state"/>
    <core:descriptor xpath="address/zipCode"/>
  </core:notAnd>
  <core:goto step="notEmpty"/>

core:notOr

The core:notOr Step evaluates the properties specified by all nested <core:descriptor> elements, and transfers control to the specified step if ANY of them are false (if boolean) or null (if Object). To avoid non-deterministic evaluation stack behavior, all of the nested <core:descriptor> elements are always evaluated.

NOTE: - This is the exact opposite of or.

The core:notOr element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:or element. All of them will be evaluated in order to determine whether or not a branch to the Step specified by the step attribute should occur or not.

In the following example, control will branch to the Step labelled notOk if any of the specified properties of the address bean return null String values. Otherwise, control will be transferred (via the core:goto Step) to the Step labelled ok.

  <core:notOr step="notOk">
    <core:descriptor xpath="address/street1"/>
    <core:descriptor xpath="address/city"/>
    <core:descriptor xpath="address/state"/>
    <core:descriptor xpath="address/zipCode"/>
  </core:notOr>
  <core:goto step="ok"/>

core:or

The core:or Step evaluates the properties specified by all nested <core:descriptor> elements, and transfers control to the specified step if ANY of them are true (if boolean) or not null (if Object). To avoid non-deterministic evaluation stack behavior, all of the nested <core:descriptor> elements are always evaluated.

The core:or element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:or element. All of them will be evaluated in order to determine whether or not a branch to the Step specified by the step attribute should occur or not.

In the following example, control will branch to the Step labelled selected if at least one of the specified properties of the options object (presumably recording a set of boolean options, perhaps initialized from a series of checkboxes on an HTML form) is selected. Otherwise, control will be transferred (via the core:goto Step) to the Step labelled notSelected.

  <core:or step="selected">
    <core:descriptor xpath="options/red"/>
    <core:descriptor xpath="options/blue"/>
    <core:descriptor xpath="options/green"/>
    <core:descriptor xpath="options/white"/>
  </core:or>
  <core:goto step="notSelected"/>

core:pop

The core:pop Step unconditionally pops the top object off of the evaluation stack, and throws it away.

The core:pop element recognizes the following attributes:

core:put

The core:put Step pops a value off of the evaluation stack for each nested <core:descriptor> element, and sets the property specified by the descriptor, in the order that the descriptors are listed.

The core:put element recognizes the following attributes:

You may nest any number of core:descriptor elements within a core:put element. All of them will be evaluated in the order listed, and the corresponding property values will be set from values popped from the evaluation stack.

In the following example, the four specified properties of the address bean will be set from values popped off of the evaluation stack (presumably put there by processing like that of the core:get example).

  <core:put>
    <core:descriptor xpath="address/zipCode"/>
    <core:descriptor xpath="address/state"/>
    <core:descriptor xpath="address/city"/>
    <core:descriptor xpath="address/street1"/>
  </core:put>

core:remove

The core:remove Step evaluates the nested descriptors, and removes the corresponding objects from the appropriate Scope in our Context, in the order that the nested descriptors are specified. After objects are removed, they are no longer accessible via Steps like core:get.

The core:remove element recognizes the following attributes:

In the example below, the "address" and "customer" beans are removed from our local Context, presumably because they are no longer needed:

  <core:remove>
    <core:descriptor xpath="address"/>
    <core:descriptor xpath="customer"/>
  </core:remove>

core:string

The core:string Step pushes the specified literal String value onto the top of the evaluation stack.

The core:string element recognizes the following attributes:

core:suspend

The core:suspend Step signals our Context to suspend the execution of the Activity being processed. The most recent Context.execute() call will return immediately. On the next call to Context.execute(), processing will continue with the Step after this one.

This Step is designed for scenarios where you wish to allow the application that is managing your workflows to interact with the user before proceeding. It is especially useful in a web environment, where Activity execution must be suspended in order to complete the current HttpServletResponse, and await the next HttpServletRequest.

Note - It does not matter how deeply nested you might be in core:call calls to subordinate Activity executions. The state of the entire computation is immediately suspended, and will resume on the next call to Context.execute(), without the calling application needing to be aware of the nesting.

The core:suspend element recognizes the following attributes:

In the following example, it is assumed that you are using the Workflow system in an MVC-style framework, which uses RequestDispatcher.forward() to pass control to the resource responsible for creating a particular response. Control will be suspended until the next request comes in, at which point execution will be resumed. Thus, a simple multi-page interaction could be scripted like this (in a real scenario, you would want to deal with "next page" and "previous page" navigation links as well).

  <web:forward page="/page-1.jsp"/>
  <core:suspend/>
  ... process first input request ...
  <web:forward page="/page=2.jsp"/>
  <core:suspend/>
  ... process second input request ...

core:swap

The core:swap Step swaps the top two items on the evaluation stack. This can be useful when previous processing has generated items on the stack that are not in the desired order for future processing.

The core:swap element recognizes the following attributes:

core:while

The core:while Step executes the immediately nested steps zero or more times, if and only if ALL of the nested Descriptors evaluate to a positive result (i.e. boolean true, non-null String with length greater than zero, numeric value other than zero, or non-null for an Object) at the beginning of the loop. To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:while element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

You can nest a core:continue inside this block to cause control to be transferred back to the top of the loop for the next test, or a core:break to uncoditionally terminate execution of this iteration and skip any further iterations.

In the example below, the nested block is executed repeatedly, as long as the value of both the doit and again attributes are positive:

  <core:while>
    <core:descriptor xpath="doit"/>
    <core:descriptor xpath="again"/>
    ... Steps placed here may be repeatedly executed ...
  </core:while>

core:whileAny

The core:whileAny Step executes the immediately nested steps zero or more times, if and only if ANY of the nested Descriptors evaluate to a positive result (i.e. boolean true, non-null String with length greater than zero, numeric value other than zero, or non-null for an Object) at the beginning of the loop. To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:whileAny element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

You can nest a core:continue inside this block to cause control to be transferred back to the top of the loop for the next test, or a core:break to uncoditionally terminate execution of this iteration and skip any further iterations.

In the example below, the nested block is executed repeatedly, as long as the value of either the doit or again attributes are positive:

  <core:whileAny>
    <core:descriptor xpath="doit"/>
    <core:descriptor xpath="again"/>
    ... Steps placed here may be repeatedly executed ...
  </core:whileAny>

core:whileNot

The core:whileNot Step executes the immediately nested steps zero or more times, if and only if ALL of the nested Descriptors evaluate to a negative result (i.e. boolean false, null or zero-length String, numeric value equal to zero, or null for an Object) at the beginning of the loop. To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:whileNot element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

You can nest a core:continue inside this block to cause control to be transferred back to the top of the loop for the next test, or a core:break to uncoditionally terminate execution of this iteration and skip any further iterations.

In the example below, the nested block is executed repeatedly, as long as the value of both the doit and again attributes are negative:

  <core:whileNot>
    <core:descriptor xpath="doit"/>
    <core:descriptor xpath="again"/>
    ... Steps placed here may be repeatedly executed ...
  </core:whileNot>

core:whileNotAny

The core:whileNotAny Step executes the immediately nested steps zero or more times, if and only if ANY of the nested Descriptors evaluate to a negative result (i.e. boolean false, null or zero-length String, numeric value equal to zero, or null for an Object) at the beginning of the loop. To avoid non-deterministic evaluation stack behavior, all of the specified Descriptors are always evaluated exactly once.

The core:whileNotAny element recognizes the following attributes:

At least one nested core:descriptor element is required, although more than one are allowed. Each of them is evaluated to determine whether it returns a positive or negative result, then all of the results are combined as described above to determine whether the nested Steps are executed.

You can nest a core:continue inside this block to cause control to be transferred back to the top of the loop for the next test, or a core:break to uncoditionally terminate execution of this iteration and skip any further iterations.

In the example below, the nested block is executed repeatedly, as long as the value of eiether the doit or again attributes is negative:

  <core:whileNotAny>
    <core:descriptor xpath="doit"/>
    <core:descriptor xpath="again"/>
    ... Steps placed here may be repeatedly executed ...
  </core:whileNotAny>

Core Step Library - Nested Elements

core:descriptor

A core:descriptor element is a description of the mechanism by which an arbitrary Java object (typically a JavaBean) in some Scope, is referenced. This element recognizes the following attributes:

The syntax for XPath expressions is a sequence of one or more identifier strings, separated by forward slash ("/") characters. The expression is evaluated as follows:

When deciding what bean a particular descriptor applies to, the following rules are applied, in this priority order:

FIXME - Support the property attribute for access to bean properties via the Commons Beanutils package.



Copyright © 2001-2010 The Apache Software Foundation. All Rights Reserved.