This project has retired. For details please refer to its Attic page.
Apache ODE – copy with insert attribute

copy with insert attribute

with insert attribute

This is a proposal for a BPEL extension (non-standard); This proposal is not yet implemented in ODE. See http://issues.apache.org/jira/browse/ODE-145 for current status information.

Consider a simple use case. A BPEL process collects quotes from a number of suppliers, to determine which one provides the best price, before submitting an order to that supplier. Typically this will be done using the activity, collecting information from each quote into a variable, and later on extracting a specific node from that variable, e.g. using XPath predicate to select the supplier with the lowest price.

BPEL does not support array variables, but we can use XML structures as collections. However, updating a collection to add a new element requires either using a different assignment mechanism ( e.g. XUpdate, not on the roadmap), or performing a copy-append-replace transformation, using XPath 2.0 or XSLT. But the later approach is complicated, obfuscated and fragile.

Instead, we're opting for a simpler mechanism that allows BPEL assignments to both replace and insert content. We introduce an insert attribute on the element. If the attribute is absent, the assignment performs a replacement, as per the BPEL 2.0 specification.

Syntax:

<bpel:assign>
    <bpel:copy insert="..."?>
        <bpel:from> ... </bpel:from>
        <bpel:to> ... </bpel:to>
    </bpel:copy>
</bpel:assign>

The insert attribute can take one of four values:

  • first -- The copy/to must select an EII. The value selected by the copy/from is then inserted as the first node inside that EII.
  • last -- The copy/to must select an EII. The value selected by the copy/from is then inserted as the last node inside that EII.
  • before -- The copy/to must select an EII or TII. The value selected by the copy/from is then inserted as a node preceding that EII/TII.
  • after -- The copy/to must select an EII or TII. The value selected by the copy/from is then inserted as a node proceeding that EII/TII.

For first and last, must return an EII or throw a selectionFailure. For before and after, must return an EII or TII or throw a selectionFailure. In all four cases, must select some value or a node, or throw a selectionFailure.

Example: Last

Let $foo be a complex element with value

<foo>
    <bar1/>
    <bar2/>
</foo>

Performing this assignment,

<bpel:copy insert="last">
    <bpel:from>
        <bpel:literal>
            <bar3/>
        </bpel:literal>
    </bpel:from>
    <bpel:to> $foo </bpel:to>
</bpel:copy>

results in $foo

<foo>
    <bar1/>
    <bar2/>
    <bar3/>   <!-- INSERTED -->
</foo>

Example: First

Continuing with the previous value of $foo,

<bpel:copy insert="first">
    <bpel:from>
        <bpel:literal>
            <bar0/>
        </bpel:literal>
    </bpel:from>
    <bpel:to> $foo </bpel:to>
</bpel:copy>

results in $foo

<foo>
    <bar0/>   <!-- INSERTED -->
    <bar1/>
    <bar2/>
    <bar3/>
</foo>

Example: Before

Continuing with the previous value of $foo,

<bpel:copy insert="before">
    <bpel:from>
        <bpel:literal>
            <baz/>
        </bpel:literal>
    </bpel:from>
    <bpel:to> $foo/bar1 </bpel:to>    <!-- Insert before "bar1" -->
</bpel:copy>

results in $foo

<foo>
    <bar0/>
    <baz/>   <!-- INSERTED -->
    <bar1/>
    <bar2/>
    <bar3/>
</foo>

Example: After

Continuing with the previous value of $foo,

<bpel:copy insert="before">
    <bpel:from>
        <bpel:literal>
            <bam/>
        </bpel:literal>
    </bpel:from>
    <bpel:to> $foo/bar2 </bpel:to>    <!-- Insert after "bar2" -->
</bpel:copy>

results in $foo

<foo>
    <bar0/>
    <baz/>
    <bar1/>
    <bar2/>
    <bam/>   <!-- INSERTED -->
    <bar3/>
</foo>