import org.mule.api.annotations.Configurable;
import org.mule.api.annotations.Module;
import org.mule.api.annotations.Processor;
import org.mule.api.annotations.param.Optional;
import java.util.List;
import java.util.Map;
@Module(name = "collection")
public class CollectionModule {
@Configurable
@Optional
private List<String> strings;
@Configurable
@Optional
private Map<String, String> mapStrings;
Handling Collections
The DevKit provides a very simple way to handle java.util.Collection
and java.util.Map
types, whether they appear in @Configurable
fields or as parameters of @Processor
or @Source
methods. In addition, the DevKit allows more complex scenarios where theses types are nested such as Map<String, List<String>>
or List<Map<String, Object>>
.
There are two ways to handle these types from Mule: one is to declare the elements explicitly and the other option is to pass a reference to them.
Note: all the examples and explanations on this page are valid both for @Module
and @Connector
classes.
Examples
Let’s consider the following custom Mule Module:
And these Spring beans:
<spring:bean id="objectA" class="java.lang.String">
<spring:constructor-arg value="ObjectA"/>
</spring:bean>
<spring:bean id="objectB" class="java.lang.String">
<spring:constructor-arg value="ObjectB"/>
</spring:bean>
<spring:bean id="list" class="org.springframework.beans.factory.config.ListFactoryBean">
<spring:property name="sourceList">
<spring:list>
<spring:ref bean="objectA"/>
<spring:ref bean="objectB"/>
</spring:list>
</spring:property>
</spring:bean>
Then the Module can be configured in any of the following ways:
-
The elements of the list are declared explicitly:
<collection:config>
<collection:strings>
<collection:string>MuleSoft</collection:string>
<collection:string>FTW</collection:string>
</collection:strings>
</collection:config>
-
The elements of the map are declared explicitly:
<collection:config>
<collection:map-strings>
<collection:map-string key="a">MuleSoft</collection:map-string>
<collection:map-string key="b">FTW</collection:map-string>
</collection:map-strings>
</collection:config>
-
Equivalent to the previous map: the tag names (
a
andb
) are used as keys of the maps:
<collection:count-map-of-strings config-ref="configC">
<collection:map-strings>
<collection:a>mulesoft</collection:a>
<collection:b>ftw</collection:b>
</collection:map-strings>
</collection:count-map-of-strings>
-
One element declared explicitly and for the other one a reference is used:
<collection:config>
<collection:strings>
<collection:string>MuleSoft</collection:string>
<collection:string value-ref="objectA"/>
</collection:strings>
</collection:config>
-
Instead of declaring the elements of the list, a reference to a bean of the same type is passed:
<collection:config name="configA">
<collection:strings ref="list" />
</collection:config>
Nested Collections
Let’s consider the following @Processor
method:
@Processor
public void mapOfLists(Map<String, List<String>> map) {
The generated message processor can be invoked as follows:
<collection:map-of-lists>
<collection:map>
<collection:map key="key1" value-ref="list" />
<collection:map key="key2" value-ref="#[map-payload:anotherList]" />
</collection:map>
</collection:map-of-lists>
Or instead of passing the values of the map by reference, the map itself can be a reference:
<collection:map-of-lists>
<collection:map ref="#[map-payload:myMap]" />
</collection:map-of-lists>