Class BusCollect<T>

java.lang.Object
org.oddjob.beanbus.AbstractFilter<T,T>
org.oddjob.beanbus.destinations.BusCollect<T>
Type Parameters:
T - The type of the beans to be collected.
All Implemented Interfaces:
Consumer<T>, BusFilter<T,T>, Outbound<T>, Service, Resettable, Stoppable

public class BusCollect<T> extends AbstractFilter<T,T> implements Resettable, Service
Author:
rob

Description

A component that collects what it consumes. By default, results are collected into a container that provides indexed access and conversions that allows it to be used as a list by other components. Alternatively a keyMapper or a valueMapper function may be provided that creates a container with map like access to the incoming data. These containers are available with the list and map properties respectively. If the output property is set the results of the captured objects are written to the provided output as text lines.

This component acn be the final destination of a BasicBusService or it may be used in the middle of other components so is can act as a Wire Tap.

Example

Collecting values into a list. The echo job shows how to access the list by element, display its size, and its contents. The script checks the result for us. The list property is converted into a Java List as it is bound to the script.
<oddjob>

    <job>

        <sequential>

            <jobs>

                <bus:bus xmlns:bus="oddjob:beanbus">

                    <of>

                        <bus:driver>

                            <values>

                                <list>

                                    <values>

                                        <value value="Apple"/>

                                        <value value="Orange"/>

                                        <value value="Pear"/>

                                    </values>

                                </list>

                            </values>

                        </bus:driver>

                        <bus:collect id="collect"/>

                    </of>

                </bus:bus>

                <echo>Index 2: ${collect.list.value[2]}

Size: ${collect.list.size}

As Text: ${collect.list}</echo>

                <script name="Check List" resultForState="true" resultVariable="retval">

                    <bind>

                        <value key="actual" value="${collect.list}"/>

                    </bind>var expected = Java.type("java.util.List").of("Apple", "Orange", "Pear");

var retval = 0;

if (!expected.equals(actual)){

 print("Excpeted: " + expected + ", but got: " + actual);

 retval = 1;

}

retval;</script>

            </jobs>

        </sequential>

    </job>

</oddjob>
Collecting values into a map using a Key Mapper. The mapping function uses a JavaScript expression to use the first letter of the data as the key. The echo job shows how to access the map by element, display its size, and its contents. The script checks the result for us. The map property is converted into a Java Map as it is bound to the script.
<oddjob>

    <job>

        <sequential>

            <jobs>

                <bus:bus xmlns:bus="oddjob:beanbus">

                    <of>

                        <bus:driver>

                            <values>

                                <list>

                                    <values>

                                        <value value="Apple"/>

                                        <value value="Orange"/>

                                        <value value="Pear"/>

                                    </values>

                                </list>

                            </values>

                        </bus:driver>

                        <bus:collect id="collect">

                            <keyMapper>

                                <value value="#{function(x) { return x.charAt(0) }}"/>

                            </keyMapper>

                        </bus:collect>

                    </of>

                </bus:bus>

                <echo>Element 'O': ${collect.map.value(O)}

Size: ${collect.map.size}

As Text: ${collect.map}</echo>

                <script name="Check List" resultForState="true" resultVariable="retval">

                    <bind>

                        <value key="actual" value="${collect.map}"/>

                    </bind>var expected = Java.type("java.util.Map").of("A", "Apple", "O", "Orange", "P", "Pear");

var retval = 0;

if (!expected.equals(actual)){

 print("Excpeted: " + expected + ", but got: " + actual);

 retval = 1;

}

retval;</script>

            </jobs>

        </sequential>

    </job>

</oddjob>
Collecting values into a map using a Value Mapper. The mapping function uses a JavaScript expression to calculate the square of the numbers passed by the Bus Driver. The echo job shows how we can't access the map by element because Oddjob expression treat a mapped property key as a string. We show a roundabout way that access can be done using a JavaScript expression. As above, the script checks the result for us.
<oddjob>

    <job>

        <sequential>

            <jobs>

                <bus:bus xmlns:bus="oddjob:beanbus">

                    <of>

                        <bus:driver>

                            <values>

                                <list>

                                    <values>

                                        <value value="#{1}"/>

                                        <value value="#{2}"/>

                                        <value value="#{3}"/>

                                    </values>

                                </list>

                            </values>

                        </bus:driver>

                        <bus:collect id="collect">

                            <valueMapper>

                                <value value="#{function(x) { return x * x }}"/>

                            </valueMapper>

                        </bus:collect>

                    </of>

                </bus:bus>

                <echo>Element '2': ${collect.map.value(2)}

Element 2: #{collect.get('map').getValue(2)}

Size: ${collect.map.size}

As Text: ${collect.map}</echo>

                <script name="Check List" resultForState="true" resultVariable="retval">

                    <bind>

                        <value key="actual" value="${collect.map}"/>

                    </bind>var expected = Java.type("java.util.Map").of(1, 1.0, 2, 4.0, 3, 9.0);

var retval = 0;

if (!expected.equals(actual)){

 print("Excpeted: " + expected + ", but got: " + actual);

 retval = 1;

}

retval;</script>

            </jobs>

        </sequential>

    </job>

</oddjob>
Collecting values into a map using a Key and Value Mapper. As above except that the key is the number as a String, so it is accessible as an Oddjob mapped property. As above, the script checks the result for us.
<oddjob>

    <job>

        <sequential>

            <jobs>

                <bus:bus xmlns:bus="oddjob:beanbus">

                    <of>

                        <bus:driver>

                            <values>

                                <list>

                                    <values>

                                        <value value="#{1}"/>

                                        <value value="#{2}"/>

                                        <value value="#{3}"/>

                                    </values>

                                </list>

                            </values>

                        </bus:driver>

                        <bus:collect id="collect">

                            <keyMapper>

                                <value value="#{function(x) { return x.toString() }}"/>

                            </keyMapper>

                            <valueMapper>

                                <value value="#{function(x) { return x * x }}"/>

                            </valueMapper>

                        </bus:collect>

                    </of>

                </bus:bus>

                <echo>Element '2': ${collect.map.value(2)}

Element 2: #{collect.get('map').getValue(2)}

Size: ${collect.map.size}

As Text: ${collect.map}</echo>

                <script name="Check List" resultForState="true" resultVariable="retval">

                    <bind>

                        <value key="actual" value="${collect.map}"/>

                    </bind>var expected = Java.type("java.util.Map").of("1", 1.0, "2", 4.0, "3", 9.0);

var retval = 0;

if (!expected.equals(actual)){

 print("Excpeted: " + expected + ", but got: " + actual);

 retval = 1;

}

retval;</script>

            </jobs>

        </sequential>

    </job>

</oddjob>
Collecting values into an Output Stream. Here we use a buffer. The buffer is declared as a variable to we can access its properties to display the text it contains and validate that text as lines using a script.
<oddjob>

    <job>

        <sequential>

            <jobs>

                <variables id="vars">

                    <text>

                        <buffer/>

                    </text>

                </variables>

                <bus:bus xmlns:bus="oddjob:beanbus">

                    <of>

                        <bus:driver>

                            <values>

                                <list>

                                    <values>

                                        <value value="Apple"/>

                                        <value value="Orange"/>

                                        <value value="Pear"/>

                                    </values>

                                </list>

                            </values>

                        </bus:driver>

                        <bus:collect id="collect">

                            <output>

                                <value value="${vars.text}"/>

                            </output>

                        </bus:collect>

                    </of>

                </bus:bus>

                <echo>${vars.text.text}</echo>

                <script name="Check Result" resultForState="true" resultVariable="retval">

                    <bind>

                        <value key="actual" value="${vars.text.lines}"/>

                    </bind>var expected = ["Apple", "Orange", "Pear"];

var actualJs = Java.from(actual)

var retval = 0;

for (i = 0; i &lt; expected.length; ++i) {

  if (expected[i] != actual[i]) {

    retval = 1;

  }

}

if (retval != 0){

  print("Excpeted: " + expected + ", but got: " + actualJs);

}

retval;</script>

            </jobs>

        </sequential>

    </job>

</oddjob>
There are many examples elsewhere.