Merge remote-tracking branch 'upstream/master' into 4.0.0-WIP

Conflicts:
	spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java
	spring-integration-core/src/main/java/org/springframework/integration/support/channel/BeanFactoryChannelResolver.java
	spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java
	spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorParserTests.java
	spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java
	spring-integration-core/src/test/java/org/springframework/integration/config/xml/ControlBusTests.java
	spring-integration-file/src/main/java/org/springframework/integration/file/DefaultFileNameGenerator.java
	spring-integration-file/src/main/java/org/springframework/integration/file/remote/handler/FileTransferringMessageHandler.java
	spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java
	spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java
	spring-integration-ftp/src/test/java/org/springframework/integration/ftp/inbound/FtpInboundRemoteFileSystemSynchronizerTests.java
	spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpServerOutboundTests.java
	spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java
	spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java
	spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java
	spring-integration-jpa/src/test/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayIntegrationTests.java
	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/MongoDbMessageGroupStoreTests.java
	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/MongoDbMessageStoreTests.java
	spring-integration-redis/src/test/java/org/springframework/integration/redis/config/RedisOutboundChannelAdapterParserTests.java
	spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java
	spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java
	spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java

Resolved.
This commit is contained in:
Gary Russell
2013-11-25 17:59:51 -05:00
191 changed files with 8774 additions and 2707 deletions

View File

@@ -73,10 +73,10 @@
using generic <emphasis>&lt;header&gt;</emphasis> sub-elements where
you would have to provide both header 'name' and 'value', you can use
convenient sub-elements to set those values directly.
</para>
</para>
<para>
<emphasis>POJO Support</emphasis>
<emphasis role="bold">POJO Support</emphasis>
</para>
<para>
@@ -121,7 +121,7 @@
</int:header-enricher>]]></programlisting>
<para>
<emphasis>SpEL Support</emphasis>
<emphasis role="bold">SpEL Support</emphasis>
</para>
<para>
In Spring Integration 2.0 we have introduced the convenience of the
@@ -147,6 +147,51 @@
are bound to the SpEL Evaluation Context, giving you full access to
the incoming Message.
</para>
<para><emphasis role="bold">Header Channel Registry</emphasis></para>
<para>
Starting with <emphasis>Spring Integration 3.0</emphasis>, a new sub-element
<code>&lt;int:header-channels-to-string/&gt;</code> is available; it has no attributes.
This converts existing <code>replyChannel</code> and <code>errorChannel</code>
headers (when they are a
<classname>MessageChannel</classname>) to a String and stores the channel(s) in
a registry for later resolution when it is time to send a reply, or handle an error.
This is useful
for cases where the headers might be lost; for example when
serializing a message into a message store or when transporting the message
over JMS. If the header does not already exist, or it
is not a <classname>MessageChannel</classname>, no changes are made.
</para>
<para>
Use of this functionality requires the presence of a <classname>HeaderChannelRegistry</classname>
bean. By default, the framework creates a <classname>DefaultHeaderChannelRegistry</classname>
with the default expiry (60 seconds). Channels
are removed from the registry after this time. To change this, simply define a bean
with id <code>integrationHeaderChannelRegistry</code> and configure the required delay using
a constructor argument (milliseconds).
</para>
<para>
The <classname>HeaderChannelRegistry</classname> has a <code>size()</code> method to
determine the current size of the registry. The <code>runReaper()</code> method
cancels the current scheduled task and runs the reaper immediately; the task is
then scheduled to run again based on the current delay. These methods can be invoked
directly by getting a reference to the registry, or you can send a message with, for example,
the following content to a control bus:
</para>
<programlisting><![CDATA["@integrationHeaderChannelRegistry.runReaper()"]]></programlisting>
<para>
This sub-element is a convenience only, and is the equivalent of specifying:
</para>
<programlisting language="xml"><![CDATA[<int:reply-channel
expression="@integrationHeaderChannelRegistry.channelToChannelName(headers.replyChannel)"/>
<int:error-channel
expression="@integrationHeaderChannelRegistry.channelToChannelName(headers.errorChannel)"/>]]></programlisting>
<tip>
For more examples for configuring header enrichers, see
<ulink url="https://github.com/SpringSource/spring-integration/wiki/Header-Enricher-Advanced-Configuration">

View File

@@ -667,4 +667,17 @@ any transaction configuration essentially allowing you to enhance the behavior o
for more detail on the subject.
</para>
</section>
<section id="endpoint-inner">
<title>Endpoint Inner Beans</title>
<para>
Many endpoints are composite beans; this includes all consumers and all polled inbound channel adapters. Consumers (polled or event-
driven) delegate to a <interfacename>MessageHandler</interfacename>; polled adapters obtain messages by delegating to a
<interfacename>MessageSource</interfacename>. Often, it is useful to obtain a reference to the delegate bean, perhaps to
change configuration at runtime, or for testing. These beans can be obtained from the
<interfacename>ApplicationContext</interfacename> with well-known names. <interfacename>MessageHandler</interfacename>s
are registered with the application context with a bean id <code>someConsumer.handler</code> (where 'consumer' is the endpoint's
<code>id</code> attribute). <interfacename>MessageSource</interfacename>s are registered with a bean id
<code>somePolledAdapter.source</code>, again where 'somePolledAdapter' is the id of the adapter.
</para>
</section>
</section>

View File

@@ -35,6 +35,14 @@
<interfacename>FileListFilter</interfacename>. By default, an
<classname>AcceptOnceFileListFilter</classname> is used. This filter
ensures files are picked up only once from the directory.
<note>
The <classname>AcceptOnceFileListFilter</classname> stores its state in memory. If you wish the
state to survive a system restart, consider using the
<classname>FileSystemPersistentAcceptOnceFileListFilter</classname> instead. This filter stores
the accepted file names in a <interfacename>MetadataStore</interfacename>. The framework supplies
several store implementations (such as Redis), or you can provide your own. This filter matches on
the filename and modified time.
</note>
<programlisting language="xml"><![CDATA[<bean id="pollableFileSource"
class="org.springframework.integration.file.FileReadingMessageSource"
p:inputDirectory="${input.directory}"

View File

@@ -184,14 +184,37 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
(e.g. <code>filename-regex=".*\.test$"</code>). And of course if you need complete control you can use <code>filter</code>
attribute and provide a reference to any custom implementation of the
<classname>org.springframework.integration.file.filters.FileListFilter</classname>, a strategy interface for filtering a
list of files. This filter determines which remote files are retrieved.
list of files. This filter determines which remote files are retrieved. You can also combine a pattern based filter
with other filters, such as an <classname>AcceptOnceFileListFilter</classname> to avoid synchronizing files that
have previously been fetched, by using a <classname>CompositeFileListFilter</classname>.
</para>
<para>
The <classname>AcceptOnceFileListFilter</classname> stores its state in memory. If you wish the
state to survive a system restart, consider using the
<classname>FtpPersistentAcceptOnceFileListFilter</classname> instead. This filter stores
the accepted file names in a <interfacename>MetadataStore</interfacename>. The framework supplies
several store implementations (such as Redis), or you can provide your own. This filter matches on
the filename and the remote modified time.
</para>
<note>
Beginning with 3.0, you can also specify a filter used to filter the files locally, once they have
been retrieved. The default filter is an <classname>AcceptOnceFileListFilter</classname> which prevents processing
files with the same name multiple times in the same JVM execution; this can now be overridden
(for example with an <classname>AcceptAllFileListFilter</classname>), using the <code>local-filter</code> attribute.
Previously, the default <classname>AcceptOnceFileListFilter</classname> could not be overridden.
<para>
Beginning with <emphasis>version 3.0</emphasis>, you can also specify a filter used to filter the files locally, once they have
been retrieved. The default filter is an <classname>AcceptOnceFileListFilter</classname> which prevents processing
files with the same name multiple times in the same JVM execution; this can now be overridden
(for example with an <classname>AcceptAllFileListFilter</classname>), using the <code>local-filter</code> attribute.
Previously, the default <classname>AcceptOnceFileListFilter</classname> could not be overridden.
</para>
<para>
The <classname>AcceptOnceFileListFilter</classname> stores its state in memory. If you wish the
state to survive a system restart, consider using the
<classname>FileSystemPersistentAcceptOnceFileListFilter</classname> as a local filter instead. This filter stores
the accepted file names in a <interfacename>MetadataStore</interfacename>. The framework supplies
several store implementations (such as Redis), or you can provide your own.
<important>
This filter compares the filename and modified timestamp. If you wish to use this technique to avoid a
re-synchronized file from being processed, you should use the <code>preserve-timestamp</code> attribute discussed above.
</important>
</para>
</note>
<para>
The 'remote-file-separator' attribute allows you to configure a
@@ -345,6 +368,8 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
<listitem>mget (retrieve file(s))</listitem>
<listitem>rm (remove file(s))</listitem>
<listitem>mv (move/rename file)</listitem>
<listitem>put (send file)</listitem>
<listitem>mput (send multiple files)</listitem>
</itemizedlist>
</para>
<para><emphasis role="bold">ls</emphasis></para>
@@ -399,6 +424,7 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
<para>
<emphasis>mget</emphasis> retrieves multiple remote files based on a pattern and supports the following option:
<itemizedlist>
<listitem>-P - preserve the timestamps of the remote files</listitem>
<listitem>-x - Throw an exception if no files match the pattern (otherwise an empty
list is returned)</listitem>
</itemizedlist>
@@ -434,6 +460,40 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
so that the remote directory structure is retained locally.
</para>
</note>
<para><emphasis role="bold">put</emphasis></para>
<para>
<emphasis>put</emphasis> sends a file to the remote server; the payload of the message can be a
<classname>java.io.File</classname>, a <classname>byte[]</classname> or a <classname>String</classname>.
A <code>remote-filename-generator</code> (or expression) is used to name the remote file. Other available attributes include
<code>remote-directory</code>, <code>temporary-remote-directory</code> (and their <code>*-expression</code>)
equivalents, <code>use-temporary-file-name</code>, and <code>auto-create-directory</code>. Refer to the
schema documentation for more information.
</para>
<para>
The message payload resulting from a <emphasis>put</emphasis> operation is a
<classname>String</classname> representing the full path of the file on the server after transfer.
</para>
<para><emphasis role="bold">mput</emphasis></para>
<para>
<emphasis>mput</emphasis> sends multiple files to the server and supports the following option:
<itemizedlist>
<listitem>-R - Recursive - send all files (possibly filtered) in the directory and subdirectories</listitem>
</itemizedlist>
</para>
<para>
The message payload must be a <classname>java.io.File</classname> representing a local directory.
</para>
<para>
The same attributes as the <code>put</code> command are supported. In addition, files in the local
directory can be filtered with one of <code>mput-pattern</code>, <code>mput-regex</code> or
<code>mput-filter</code>. The filter works with recursion, as long as the subdirectories themselves
pass the filter. Subdirectories that do not pass the filter are not recursed.
</para>
<para>
The message payload resulting from an <emphasis>mget</emphasis> operation is a
<classname>List&lt;String&gt;</classname> object - a List of remote file paths resulting from
the transfer.
</para>
<para><emphasis role="bold">rm</emphasis></para>
<para>
The <emphasis>rm</emphasis> command has no options.
@@ -543,4 +603,15 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
sessions are closed when they are returned to the cache. New requests for sessions will establish new sessions as necessary.
</para>
</section>
<section id="ftp-rft">
<title>RemoteFileTemplate</title>
<para>
Starting with <emphasis>Spring Integration version 3.0</emphasis> a new abstraction is provided over the
<classname>FtpSession</classname> object. The template provides methods to send, retrieve (as an
<classname>InputStream</classname>), remove, and rename files. In addition an <code>execute</code>
method is provided allowing the caller to execute multiple operations on the session. In all cases,
the template takes care of reliably closing the session.
For more information, refer to the javadocs for <classname>RemoteFileTemplate</classname>.
</para>
</section>
</chapter>

View File

@@ -57,9 +57,26 @@
Setting a custom GroovyObjectCustomizer is not mutually exclusive with <code>&lt;variable&gt;</code> sub-elements or
the <code>script-variable-generator</code> attribute. It can also be provided when defining an inline script.
For more information regarding <code>&lt;variable&gt;</code> and <code>script-variable-generator</code>, see the
paragraph '<emphasis>Script variable bindings</emphasis>' of <xref linkend="scripting-config"/>.
</para>
</para>
<para>
With <emphasis>Spring Integration 3.0</emphasis>, in addition to the <code>variable</code> sub-element,
the <code>variables</code> attribute has been introduced. Also, groovy scripts have the ability to resolve a
variable to a bean in the
<interfacename>BeanFactory</interfacename>, if a binding variable was not provided with
the name:
<programlisting language="xml">&lt;int-groovy:script&gt;
&lt;![CDATA[
entityManager.persist(payload)
payload
]]&gt;
&lt;/int-groovy:script&gt;</programlisting>
where variable <code>entityManager</code> is an appropriate bean in the application context.
</para>
<para>
For more information regarding <code>&lt;variable&gt;</code>, <code>variables</code>,
and <code>script-variable-generator</code>, see the
paragraph '<emphasis>Script variable bindings</emphasis>' of <xref linkend="scripting-config"/>.
</para>
</section>
<section id="groovy-control-bus">

View File

@@ -520,6 +520,43 @@ By default the HTTP request will be generated using an instance of <classname>Si
method will be invoked on the payload object of the Message and the result
of that method will be used as the value for the URI variable named 'zipCode'.
</para>
<para>
Since <emphasis>Spring Integration 3.0</emphasis>, HTTP Outbound Endpoints support the
<code>uri-variables-expression</code> attribute to specify an <interfacename>Expression</interfacename>
which should be evaluated, resulting in a
<interfacename>Map</interfacename> for all URI variable placeholders within the URL template. It provides
a mechanism whereby different variable expressions can be used, based on the outbound message.
This attribute is mutually exclusive with the <code>&lt;uri-variable/&gt;</code> sub-element:
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway
url="http://foo.host/{foo}/bars/{bar}"
request-channel="trafficChannel"
http-method="GET"
uri-variables-expression="@uriVariablesBean.populate(payload)"
expected-response-type="java.lang.String"/>]]></programlisting>
where <code>uriVariablesBean</code> might be:
<programlisting language="java"><![CDATA[public class UriVariablesBean {
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
public Map<String, ?> populate(Object payload) {
Map<String, Object> variables = new HashMap<String, Object>();
if (payload instanceOf String.class)) {
variables.put("foo", "foo"));
}
else {
variables.put("foo", EXPRESSION_PARSER.parseExpression("headers.bar"));
}
return variables;
}
}]]></programlisting>
</para>
<note>
The <code>uri-variables-expression</code> must evaluate to a <interfacename>Map</interfacename>.
The values of the Map must be instances of
<interfacename>String</interfacename> or <interfacename>Expression</interfacename>.
This Map is provided to an <classname>ExpressionEvalMap</classname> for further resolution of URI variable placeholders
using those expressions in the context of the outbound <interfacename>Message</interfacename>.
</note>
<para>
<emphasis>Controlling URI Encoding</emphasis>
</para>

View File

@@ -489,11 +489,15 @@
or <classname>TcpConnectionExceptionEvent</classname>).
</para>
<para>
<classname>TcpConnectionEvents</classname> contain:
<classname>TcpConnectionEvents</classname> have the following properties:
<itemizedlist>
<listitem>Connection Id (which can be used in a message header to send data to the connection)</listitem>
<listitem>Connection Factory Name (the bean name of the connection factory the connection belongs to)</listitem>
<listitem>The <classname>Throwable</classname> (for <classname>TcpConnectionExceptionEvent</classname> events only)</listitem>
<listitem><code>connectionId</code> - the connection identifier which can be used in a message header
to send data to the connection</listitem>
<listitem><code>connectionFactoryName</code> - the bean name of the connection factory the connection belongs to</listitem>
<listitem><code>throwable</code> - the <classname>Throwable</classname> (for <classname>TcpConnectionExceptionEvent</classname> events only)</listitem>
<listitem><code>source</code> - the <interfacename>TcpConnection</interfacename>; this can be
used, for example, to determine the remote IP Address with <code>getHostAddress()</code> (cast required)
</listitem>
</itemizedlist>
</para>
</section>
@@ -626,7 +630,7 @@
<note>
<para>
For the inbound gateway, care must be taken to retain, or populate, the
<emphasis>ip_connnection_id</emphasis> header because it is used to
<emphasis>ip_connectionId</emphasis> header because it is used to
correlate the message to a connection. Messages that originate at the
gateway will automatically have the header set. If the reply is
constructed as a new message, you will need to set the header. The
@@ -760,7 +764,7 @@
<note>
<para>
On the server side, care must be taken to populate the
<emphasis>ip_connnection_id</emphasis> header because it is used to
<emphasis>ip_connectionId</emphasis> header because it is used to
correlate the message to a connection. Messages that originate at the
inbound adapter will automatically have the header set. If you wish to
construct other messages to send, you will need to set the header. The
@@ -1853,4 +1857,85 @@
</table>
</para>
</section>
<section id="ip-msg-headers">
<title>IP Message Headers</title>
<para>
The following <code>MessageHeader</code>s are used by this module:
</para>
<table id="ip-msg-headers-tbl">
<tgroup cols="3">
<colspec align="left" />
<colspec colnum="1" colname="col1" colwidth="1*"/>
<colspec colnum="2" colname="col2" colwidth="1*"/>
<colspec colnum="3" colname="col3"/>
<thead>
<row>
<entry align="center">Header Name</entry>
<entry align="center">IpHeaders Constant</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>ip_hostname</entry>
<entry>HOSTNAME</entry>
<entry>
The host name from which a TCP message or UDP packet was received. If
<code>lookupHost</code> is <code>false</code>, this will contain the ip address.
</entry>
</row>
<row>
<entry>ip_address</entry>
<entry>IP_ADDRESS</entry>
<entry>The ip address from which a TCP message or UDP packet was received.</entry>
</row>
<row>
<entry>ip_port</entry>
<entry>PORT</entry>
<entry>The remote port for a UDP packet.</entry>
</row>
<row>
<entry>ip_ackTo</entry>
<entry>ACKADDRESS</entry>
<entry>
The remote ip address to which UDP application-level acks will be sent. The
framework includes acknowledgment information in the data packet.
</entry>
</row>
<row>
<entry>ip_ackId</entry>
<entry>ACK_ID</entry>
<entry>
A correlation id for UDP application-level acks. The
framework includes acknowledgment information in the data packet.
</entry>
</row>
<row>
<entry>ip_tcp_remotePort</entry>
<entry>REMOTE_PORT</entry>
<entry>The remote port for a UDP packet.</entry>
</row>
<row>
<entry>ip_connectionId</entry>
<entry>CONNECTION_ID</entry>
<entry>
A unique identifier for a TCP connection; set by the framework for
inbound messages; when sending to a server-side inbound
channel adapter, or replying to an inbound gateway, this header is
required so the endpoint can determine which connection to send
the message to.
</entry>
</row>
<row>
<entry>ip_actualConnectionId</entry>
<entry>ACTUAL_CONNECTION_ID</entry>
<entry>
For information only - when using a cached or failover client connection
factory, contains the actual underlying connection id.
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</chapter>

View File

@@ -409,8 +409,10 @@
query="select s from Student s" ]]><co id="inboundAdapterQuery"/><![CDATA[
expect-single-result="true" ]]><co id="inboundAdapterExpectResult"/><![CDATA[
max-number-of-results="" ]]><co id="inboundAdapterMaxResults"/><![CDATA[
max-results="" ]]><co id="inboundAdapterMaxResults2"/><![CDATA[
max-results-expression="" ]]><co id="inboundAdapterMaxResultsExpression"/><![CDATA[
delete-after-poll="true"> ]]><co id="inboundAdapterDeleteAfterPoll"/><![CDATA[
delete-after-poll="true" ]]><co id="inboundAdapterDeleteAfterPoll"/><![CDATA[
flush-after-delete="true"> ]]><co id="inboundAdapterFlushAfterDelete"/><![CDATA[
<int:poller fixed-rate="2000" >
<int:transactional propagation="REQUIRED" transaction-manager="transactionManager"/>
</int:poller>
@@ -452,16 +454,22 @@
</para>
</callout>
<callout arearefs="inboundAdapterMaxResults">
<para>
<emphasis>Deprecated</emphasis>. Use <code>max-results</code> instead.
<emphasis>Optional</emphasis>.
</para>
</callout>
<callout arearefs="inboundAdapterMaxResults2">
<para>
This non zero, non negative integer value tells the adapter not to select more than given number
of rows on execution of the select operation. By default, if this attribute is not set,
all the possible records are selected by given query. This attribute is mutually exclusive to
all the possible records are selected by given query. This attribute is mutually exclusive with
<code>max-results-expression</code>. <emphasis>Optional</emphasis>.
</para>
</callout>
<callout arearefs="inboundAdapterMaxResultsExpression">
<para>
An expression mutually exclusive to <code>max-number-of-results</code> that can
An expression, mutually exclusive with <code>max-results</code>, that can
be used to provide an expression that will be evaluated to find the maximum number of results
in a result set. <emphasis>Optional</emphasis>.
</para>
@@ -477,6 +485,14 @@
<emphasis>java.lang.IllegalArgumentException: Removing
a detached instance ...</emphasis>
</para>
</callout>
<callout arearefs="inboundAdapterFlushAfterDelete">
<para>
Set this value to <code>true</code> if you want
to the persistence context immediately after deleting received entities
and if you don't want rely on the<interfacename>EntityManager</interfacename>'s flushMode.
The default value is set to <code>false</code>.
</para>
</callout>
</calloutlist>
<section id="jpaInboundChannelAdapterParameters">
@@ -845,6 +861,9 @@ public class Student {
order="" ]]><co id="outAdaptOrder"/><![CDATA[
parameter-source-factory="" ]]><co id="outAdaptParamSourceFact"/><![CDATA[
persist-mode="MERGE" ]]><co id="outAdaptPersistMode"/><![CDATA[
flush="true" ]]><co id="outAdaptFlush"/><![CDATA[
flush-size="10" ]]><co id="outAdaptFlushSize"/><![CDATA[
clear-on-flush="true" ]]><co id="outAdaptclearOnFlash"/><![CDATA[
use-payload-as-parameter-source="true" ]]><co id="outAdaptUserPayloadAsParamSrc"/><![CDATA[
<int:poller/>
<int-jpa:transactional/> ]]><co id="outAdaptTransactional"/><![CDATA[
@@ -941,6 +960,38 @@ public class Student {
<emphasis>NULL</emphasis> values returned by the iterator are ignored.
</para>
</callout>
<callout arearefs="outAdaptFlush">
<para>
Set this value to <code>true</code> if you want
to flush the persistence context immediately after persist, merge or delete operations
and don't want to rely on the <interfacename>EntityManager</interfacename>'s flushMode.
The default value is set to <code>false</code>. Applies only if the <code>flush-size</code>
attribute isn't specified. If this attribute is set to <code>true</code>,
then <code>flush-size</code> will be implicitly set to <code>1</code>, if it wasn't configured to any other value.
</para>
</callout>
<callout arearefs="outAdaptFlushSize">
<para>
Set this attribute to a value greater than '0' if you want
to flush the persistence context immediately after persist, merge or delete operations
and don't want to rely on the <interfacename>EntityManager</interfacename>'s flushMode.
The default value is set to <code>0</code> which means 'no flush'.
This attribute is geared towards messages with <interfacename>Iterable</interfacename> payloads.
For instance, if <code>flush-size</code> is set to <code>3</code>,
then <code>entityManager.flush()</code> is called after every third entity.
Furthermore, <code>entityManager.flush()</code> will be called once more after the entire loop.
There is no reason to configure the <code>flush</code>
attribute, if the 'flush-size' attribute is specified with a value greater than '0'.
</para>
</callout>
<callout arearefs="outAdaptclearOnFlash">
<para>
Set this value to 'true' if you want
to clear persistence context immediately after each flush operation.
The attribute's value is applied only if the <code>flush</code> attribute is set to
<code>true</code> or if the <code>flush-size</code> attribute is set to a value greater than <code>0</code>.
</para>
</callout>
<callout arearefs="outAdaptUserPayloadAsParamSrc">
<para>
If set to true, the payload of the Message will be used as a source for providing parameters.
@@ -1155,6 +1206,7 @@ public class Student {
jpa-operations=""
jpa-query=""
max-number-of-results="" ]]><co id="outGateMaxNumOfResults"/><![CDATA[
max-results="" ]]><co id="outGateMaxNumOfResults2"/><![CDATA[
max-results-expression="" ]]><co id="outGateMaxNumOfResultsExpression"/><![CDATA[
first-result="" ]]><co id="outGateFirstResult"/><![CDATA[
first-result-expression="" ]]><co id="outGateFirstResultExpression"/><![CDATA[
@@ -1182,16 +1234,22 @@ public class Student {
</para>
</callout>
<callout arearefs="outGateMaxNumOfResults">
<para>
<emphasis>Deprecated</emphasis>. Use <code>max-results</code> instead.
<emphasis>Optional</emphasis>.
</para>
</callout>
<callout arearefs="outGateMaxNumOfResults2">
<para>
This non zero, non negative integer value tells the adapter not to select more than given number
of rows on execution of the select operation. By default, if this attribute is not set,
all the possible records are selected by given query. This attribute is mutually exclusive to
all the possible records are selected by given query. This attribute is mutually exclusive with
<code>max-results-expression</code>. <emphasis>Optional</emphasis>.
</para>
</callout>
<callout arearefs="outGateMaxNumOfResultsExpression">
<para>
An expression mutually exclusive to <code>max-number-of-results</code> that can
An expression, mutually exclusive with <code>max-results</code>, that can
be used to provide an expression that will be evaluated to find the maximum number of results
in a result set. <emphasis>Optional</emphasis>.
</para>

View File

@@ -75,21 +75,21 @@
For example, if one of the headers contains an instance of some <emphasis>Spring Bean</emphasis>, upon deserialization you may end
up with a different instance of that bean,
which directly affects some of the implicit headers created by the framework (e.g., REPLY_CHANNEL or ERROR_CHANNEL).
Currently they are not serializable, but even if they were the deserialized channel would not represent the expected instance.
As a workaround we suggest to remove bean-ref headers via a <literal>&lt;header-filter/&gt;</literal>
before sending a message to an endpoint backed by a persistent <classname>MessageStore</classname>.
Also, we recommend using channel names instead of channel instances when setting those types of headers,
thus allowing it to be resolved in real time by the <classname>ChannelResolver</classname>.
Currently they are not serializable, but even if they were, the deserialized channel would not represent the expected instance.
</para>
<para>
Also avoid configuration of a message-flow like this:
Beginning with <emphasis>Spring Integration version 3.0</emphasis>, this issue can be resolved with a header enricher,
configured to replace these headers with a name after registering the channel with the <classname>HeaderChannelRegistry</classname>.
</para>
<para>
Also when configuring a message-flow like this:
<emphasis>gateway -&gt; queue-channel (backed by a persistent Message Store) -&gt; service-activator</emphasis>
That gateway creates a <emphasis>Temporary Reply Channel</emphasis> in the background, and it will be lost by the time the
service-activator's poller reads from the queue, because it has been deserialized by another thread on the sending side.
That gateway creates a <emphasis>Temporary Reply Channel</emphasis>, and it will be lost by the time the
service-activator's poller reads from the queue. Again, you can use the header enricher to replace the headers with a
String representation.
</para>
<para>
Nevertheless we are constantly thinking about potential improvements to the framework, such as a way to provide some
robust default serialization strategy for messages in these cases.
For more information, refer to the <xref linkend="header-enricher"/>.
</para>
</important>
</para>

View File

@@ -111,6 +111,35 @@
and an <emphasis>Aggregator</emphasis>. As you can see it is a simple bean configuration, and it expects a
<classname>MongoDbFactory</classname> as a constructor argument.
</para>
<important>
<para>
The <classname>MongoDbMessageStore</classname> uses a custom <classname>MappingMongoConverter</classname> implementation
to store <interfacename>Message</interfacename>s as MongoDB documents and there are some limitations
for the properties (<code>payload</code> and <code>header</code> values) of the <interfacename>Message</interfacename>.
For example an <classname>ErrorMessage</classname> can't be converted to the MongoDB document, because it has an
<classname>Exception</classname> property, where the cause property is infintely recursed. Also, there is no ability to
configure
custom converters for complex domain <code>payload</code>s or <code>header</code> values.
To achieve these capabilities, an alternative MongoDB <interfacename>MessageStore</interfacename> implementation has been
introduced; see next paragraph.
</para>
</important>
<para>
<emphasis>Spring Integration 3.0</emphasis> introduced the <classname>ConfigurableMongoDbMessageStore</classname> -
<interfacename>MessageStore</interfacename> and <interfacename>MessageGroupStore</interfacename> implementation.
This class can receive, as a constructor argument, a <classname>MongoTemplate</classname>, with which you can
configure with a
custom <classname>WriteConcern</classname>, for example. Another constructor requires a
<classname>MappingMongoConverter</classname>, and a <interfacename>MongoDbFactory</interfacename>,
which allows you to provide some custom conversions for <interfacename>Message</interfacename>s and their properties.
Note, by default, the <classname>ConfigurableMongoDbMessageStore</classname> uses standard Java serialization
to write/read <interfacename>Message</interfacename>s to/from MongoDB and relies on default values for other
properties from <classname>MongoTemplate</classname>, which is built from the provided
<interfacename>MongoDbFactory</interfacename> and <classname>MappingMongoConverter</classname>.
The default name for the collection stored by the <classname>ConfigurableMongoDbMessageStore</classname> is
<code>configurableStoreMessages</code>. It is recommended to use this implementation for robust and flexible solutions.
The <classname>MongoDbMessageStore</classname> remains for backward compatibility and may be removed in future releases.
</para>
</section>
<section id="mongodb-inbound-channel-adapter">
@@ -275,4 +304,4 @@
</para>
</section>
</chapter>
</chapter>

View File

@@ -98,7 +98,32 @@
</script:script>]]></programlisting>
As shown in the above example, you can bind a script variable either to a scalar value or a Spring bean reference. Note that
<code>payload</code> and <code>headers</code> will still be included as binding variables.
</para>
<para>
With <emphasis>Spring Integration 3.0</emphasis>, in addition to the <code>variable</code> sub-element,
the <code>variables</code> attribute has been introduced. This attribute and <code>variable</code> sub-elements
aren't mutually exclusive and you can combine them within one <code>script</code> component. However variables must
be unique, regardless of where they are defined. Also, since <emphasis>Spring Integration 3.0</emphasis>,
variable bindings are allowed for inline scripts too:
<programlisting language="xml">&lt;service-activator input-channel="input"&gt;
&lt;script:script lang="ruby" variables="foo=FOO, date-ref=dateBean"&gt;
&lt;script:variable name="bar" ref="barBean"/&gt;
&lt;script:variable name="baz" value="bar"/&gt;
&lt;![CDATA[
payload.foo = foo
payload.date = date
payload.bar = bar
payload.baz = baz
payload
]]&gt;
&lt;/script:script&gt;
&lt;/service-activator&gt;</programlisting>
The example above shows a combination of an inline script, a <code>variable</code> sub-element and a <code>variables</code> attribute.
The <code>variables</code> attribute is a comma-separated value, where each segment contains an '=' separated pair
of the variable and its value. The variable name can be suffixed with <code>-ref</code>, as in the
<code>date-ref</code> variable above. That means that the binding variable
will have the name <code>date</code>, but the value will be a reference to the <code>dateBean</code> bean from the application context.
This may be useful when using <emphasis>Property Placeholder Configuration</emphasis> or command line arguments.
</para>
<para>
If you need more control over how variables are generated, you can implement your own Java class
@@ -115,7 +140,7 @@
provide an implementation of <classname>ScriptVariableGenerator</classname> and reference it with the <code>script-variable-generator</code>
attribute:
<programlisting language="xml"><![CDATA[<int-script:script location="foo/bar/MyScript.groovy"
script-variable-generator="variableGenerator"/>
script-variable-generator="variableGenerator"/>
<bean id="variableGenerator" class="foo.bar.MyScriptVariableGenerator"/>]]></programlisting>
If a <code>script-variable-generator</code> is not provided, script components use
@@ -124,7 +149,7 @@
variables from the <code>Message</code> in its <code>generateScriptVariables(Message)</code> method.
<important>
You cannot provide both the <code>script-variable-generator</code> attribute and <code>&lt;variable&gt;</code> sub-element(s)
as they are mutually exclusive. Also, custom variable bindings cannot be used with an inline script.
as they are mutually exclusive.
</important>
</para>
</section>

View File

@@ -252,6 +252,18 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
</para>
</section>
<section id="sftp-rft">
<title>RemoteFileTemplate</title>
<para>
Starting with <emphasis>Spring Integration version 3.0</emphasis> a new abstraction is provided over the
<classname>SftpSession</classname> object. The template provides methods to send, retrieve (as an
<classname>InputStream</classname>), remove, and rename files. In addition an <code>execute</code>
method is provided allowing the caller to execute multiple operations on the session. In all cases,
the template takes care of reliably closing the session.
For more information, refer to the javadocs for <classname>RemoteFileTemplate</classname>.
</para>
</section>
<section id="sftp-inbound">
<title>SFTP Inbound Channel Adapter</title>
<para>
@@ -297,14 +309,37 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
(e.g. <code>filename-regex=".*\.test$"</code>). And of course if you need complete control you can use the <code>filter</code>
attribute to provide a reference to a custom implementation of the
<classname>org.springframework.integration.file.filters.FileListFilter</classname> - a strategy interface for filtering a
list of files. This filter determines which remote files are retrieved.
list of files. This filter determines which remote files are retrieved. You can also combine a pattern based filter
with other filters, such as an <classname>AcceptOnceFileListFilter</classname> to avoid synchronizing files that
have previously been fetched, by using a <classname>CompositeFileListFilter</classname>.
</para>
<para>
The <classname>AcceptOnceFileListFilter</classname> stores its state in memory. If you wish the
state to survive a system restart, consider using the
<classname>SftpPersistentAcceptOnceFileListFilter</classname> instead. This filter stores
the accepted file names in a <interfacename>MetadataStore</interfacename>. The framework supplies
several store implementations (such as Redis), or you can provide your own. This filter matches on
the filename and the remote modified time.
</para>
<note>
Beginning with 3.0, you can also specify a filter used to filter the files locally, once they have
been retrieved. The default filter is an <classname>AcceptOnceFileListFilter</classname> which prevents processing
files with the same name multiple times in the same JVM execution; this can now be overridden
(for example with an <classname>AcceptAllFileListFilter</classname>), using the <code>local-filter</code> attribute.
Previously, the default <classname>AcceptOnceFileListFilter</classname> could not be overridden.
<para>
Beginning with <emphasis>version 3.0</emphasis>, you can also specify a filter used to filter the files locally, once they have
been retrieved. The default filter is an <classname>AcceptOnceFileListFilter</classname> which prevents processing
files with the same name multiple times in the same JVM execution; this can now be overridden
(for example with an <classname>AcceptAllFileListFilter</classname>), using the <code>local-filter</code> attribute.
Previously, the default <classname>AcceptOnceFileListFilter</classname> could not be overridden.
</para>
<para>
The <classname>AcceptOnceFileListFilter</classname> stores its state in memory. If you wish the
state to survive a system restart, consider using the
<classname>FileSystemPersistentAcceptOnceFileListFilter</classname> as a local filter instead. This filter stores
the accepted file names in a <interfacename>MetadataStore</interfacename>. The framework supplies
several store implementations (such as Redis), or you can provide your own.
<important>
This filter compares the filename and modified timestamp. If you wish to use this technique to avoid a
re-synchronized file from being processed, you should use the <code>preserve-timestamp</code> attribute discussed above.
</important>
</para>
</note>
<para>
Please refer to the schema for more detail on these attributes.
@@ -414,6 +449,8 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
<listitem>mget (retrieve file(s))</listitem>
<listitem>rm (remove file(s))</listitem>
<listitem>mv (move/rename file)</listitem>
<listitem>put (send file)</listitem>
<listitem>mput (send multiple files)</listitem>
</itemizedlist>
</para>
<para><emphasis role="bold">ls</emphasis></para>
@@ -468,6 +505,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
<para>
<emphasis>mget</emphasis> retrieves multiple remote files based on a pattern and supports the following option:
<itemizedlist>
<listitem>-P - preserve the timestamps of the remote files</listitem>
<listitem>-x - Throw an exception if no files match the pattern (otherwise an empty
list is returned)</listitem>
</itemizedlist>
@@ -503,6 +541,40 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
so that the remote directory structure is retained locally.
</para>
</note>
<para><emphasis role="bold">put</emphasis></para>
<para>
<emphasis>put</emphasis> sends a file to the remote server; the payload of the message can be a
<classname>java.io.File</classname>, a <classname>byte[]</classname> or a <classname>String</classname>.
A <code>remote-filename-generator</code> (or expression) is used to name the remote file. Other available attributes include
<code>remote-directory</code>, <code>temporary-remote-directory</code> (and their <code>*-expression</code>)
equivalents, <code>use-temporary-file-name</code>, and <code>auto-create-directory</code>. Refer to the
schema documentation for more information.
</para>
<para>
The message payload resulting from a <emphasis>put</emphasis> operation is a
<classname>String</classname> representing the full path of the file on the server after transfer.
</para>
<para><emphasis role="bold">mput</emphasis></para>
<para>
<emphasis>mput</emphasis> sends multiple files to the server and supports the following option:
<itemizedlist>
<listitem>-R - Recursive - send all files (possibly filtered) in the directory and subdirectories</listitem>
</itemizedlist>
</para>
<para>
The message payload must be a <classname>java.io.File</classname> representing a local directory.
</para>
<para>
The same attributes as the <code>put</code> command are supported. In addition, files in the local
directory can be filtered with one of <code>mput-pattern</code>, <code>mput-regex</code> or
<code>mput-filter</code>. The filter works with recursion, as long as the subdirectories themselves
pass the filter. Subdirectories that do not pass the filter are not recursed.
</para>
<para>
The message payload resulting from an <emphasis>mget</emphasis> operation is a
<classname>List&lt;String&gt;</classname> object - a List of remote file paths resulting from
the transfer.
</para>
<para><emphasis role="bold">rm</emphasis></para>
<para>
The <emphasis>rm</emphasis> command has no options.

View File

@@ -176,13 +176,11 @@
</note>
For more information regarding JSON see 'JSON Transformers' in <xref linkend="transformer"/>.
</listitem>
<listitem>
<emphasis role="bold">#xpath</emphasis> - to evaluate an 'xpath' on some provided object.
For more information regarding xml and xpath see <xref linkend="xml"/>.
</listitem>
<!--<listitem>
<emphasis>#xpath</emphasis> - TBD
</listitem>
<listitem>
<emphasis>#request</emphasis> - TBD
</listitem>
<listitem>
<emphasis>#auth</emphasis> - TBD
</listitem>-->
</itemizedlist>

View File

@@ -361,6 +361,13 @@ public class Foo {
In addition to JSON Transformers, Spring Integration provides a built-in <emphasis>#jsonPath</emphasis>
SpEL function for use in expressions. For more information see <xref linkend="spel"/>.
</para>
<para>
<emphasis role="bold">#xpath SpEL Function</emphasis>
</para>
<para>
Since version <emphasis>3.0</emphasis>, Spring Integration also provides a built-in <emphasis>#xpath</emphasis>
SpEL function for use in expressions. For more information see <xref linkend="xpath-spel-function"/>.
</para>
</section>
<section id="transformer-annotation">

View File

@@ -117,8 +117,9 @@
<title>SpEL Functions Support</title>
<para>
To customize the SpEL <interfacename>EvaluationContext</interfacename> with static
<classname>Method</classname> functions the new <code>&lt;spel-function/&gt;</code>
component is introduced. For more information see <xref linkend="spel-functions" />.
<classname>Method</classname> functions, the new <code>&lt;spel-function/&gt;</code>
component is introduced. Two built-in functions are also provided (<code>#jsonPath</code>
and <code>#xpath</code>). For more information see <xref linkend="spel-functions" />.
</para>
</section>
<section id="3.0-spel-property-accessors">
@@ -166,6 +167,29 @@
For more information see <xref linkend="redis" />.
</para>
</section>
<section id="3.0-hcr">
<title>Header Channel Registry</title>
<para>
It is now possible to instruct the framework to store reply and error channels
in a registry for later resolution. This is useful for cases where
the <code>replyChannel</code> or <code>errorChannel</code> might be lost; for example
when serializing
a message. See <xref linkend="header-enricher"/> for more information.
</para>
</section>
<section id="3.0-configurable-mongo-MS">
<title>MongoDB support: New ConfigurableMongoDbMessageStore</title>
<para>
In addition to the existing <classname>eMongoDbMessageStore</classname>, a new
<classname>ConfigurableMongoDbMessageStore</classname> has been introduced.
This provides a more robust and flexible implementation of <interfacename>MessageStore</interfacename>
for MongoDB.
It does not have backward compatibility, with the existing store,
but it is recommended to use it for new applications. Existing applications can use it, but messages
in the old store will not be available.
See <xref linkend="mongodb"/> for more information.
</para>
</section>
</section>
<section id="3.0-general">
@@ -288,21 +312,27 @@
<para>
<itemizedlist>
<listitem>
The gateways now support the <code>mv</code> command, enabling the renaming of remote
files.
The gateways now support the <emphasis role="bold">mv</emphasis> command, enabling
the renaming of remote files.
</listitem>
<listitem>
The gateways now support recursive <code>ls</code> and <code>mget</code> commands, enabling
The gateways now support recursive <emphasis role="bold">ls</emphasis> and
<emphasis role="bold">mget</emphasis> commands, enabling
the retrieval of a remote file tree.
</listitem>
<listitem>
The gateways now support <emphasis role="bold">put</emphasis> and
<emphasis role="bold">mput</emphasis> commands, enabling
sending file(s) to the remote server.
</listitem>
<listitem>
The <code>local-filename-generator-expression</code> attribute is now supported,
enabling the naming of local files during transfer. By default, the same
enabling the naming of local files during retrieval. By default, the same
name as the remote file is used.
</listitem>
<listitem>
The <code>local-directory-expression</code> attribute is now supported,
enabling the naming of local directories during transfer based on the remote directory.
enabling the naming of local directories during retrieval based on the remote directory.
</listitem>
</itemizedlist>
</para>
@@ -310,6 +340,20 @@
For more information, see <xref linkend="ftp-outbound-gateway"/> and <xref linkend="sftp-outbound-gateway"/>.
</para>
</section>
<section id="3.0-remote-file-template">
<title>Remote File Template</title>
<para>
A new higher-level abstraction (<classname>RemoteFileTemplate</classname>) is provided over the
<interfacename>Session</interfacename> implementations used by the FTP and SFTP modules. While it is
used internally by endpoints, this abstraction can also be used programmatically and, like all
Spring <code>*Template</code> implemenations, reliably closes the underlying session while allowing
low level access to the session when needed.
</para>
<para>
For more information, see
<xref linkend="ftp-rft"/> and <xref linkend="sftp-rft"/>.
</para>
</section>
<section id="3.0-jdbc-mysql-v5_6_4">
<title>JDBC Message Store Improvements</title>
<para>
@@ -322,7 +366,7 @@
</para>
</section>
<section id="3.0-jpa-persist-merge-collections">
<title>JPA Support Improvements</title>
<title>JPA Support: Improvements</title>
<para>
Payloads to <emphasis>persist</emphasis> or
<emphasis>merge</emphasis> can now be of type
@@ -336,6 +380,11 @@
<interfacename>EntityManager</interfacename>.
<emphasis>NULL</emphasis> values returned by the iterator are ignored.
</para>
<para>
The JPA adapters now have additional attributes to optionally 'flush' and 'clear'
entities from the associated persistence context after performing persistence operations.
</para>
<para>For more information see <xref linkend="jpa"/>.</para>
</section>
<section id="3.0-json-transformers">
<title>Jackson Support (JSON)</title>
@@ -387,6 +436,13 @@
<emphasis>#requestHeaders</emphasis> and <emphasis>#cookies</emphasis>. These variables are available in
both payload and header expressions.
</listitem>
<listitem>
<emphasis role="bold">Outbound Endpoint 'uri-variables-expression'</emphasis> - HTTP Outbound Endpoints
now support the <code>uri-variables-expression</code> attribute to specify
an <interfacename>Expression</interfacename> to evaluate a <interfacename>Map</interfacename>
for all URI variable placeholders within URL template. This allows selection of a different
map of expressions based on the outgoing message.
</listitem>
</itemizedlist>
</para>
<para>
@@ -573,13 +629,17 @@
</para>
</section>
<section id="3.0-jpa-max-results">
<title>JPA Adapters: max-results-expression attribute</title>
<title>JPA Adapters: max-results and max-results-expression Attributes</title>
<para>
Retrieving gateways and inbound adapters now has a flexibility to specify the maximum
number of results in a result set as an expression. We now have <code>max-number-of-results</code>
and <code>max-results-expression</code> attributes which are used to provide the
maximum number of results and the expression to compute the maximum number of results in the
result set respectively. For more information see <xref linkend="jpa"/>.
The JPA retrieving gateway and inbound adapter now have an attribute to specify the maximum
number of results in a result set as an expression. In addition, the
<code>max-results</code> attribute has been introduced to replace
<code>max-number-of-results</code>, which has been deprecated.
<code>max-results</code> and <code>max-results-expression</code>
are used to provide the maximum number of results,
or an expression to compute the maximum number of results, respectively, in the
result set.
For more information see <xref linkend="jpa"/>.
</para>
</section>
<section id="3.0-redis">
@@ -604,5 +664,21 @@
For more information, see <xref linkend="redis"/>.
</para>
</section>
<section id="3.0-filelistfilter">
<title>Persistend File List Filters (file, (S)FTP)</title>
<para>
New <classname>FileListFilter</classname>s that use a persistent <classname>MetadataStore</classname> are
now available. These can be used to prevent duplicate files after a system restart. See
<xref linkend="file-reading"/>, <xref linkend="ftp-inbound"/>, and <xref linkend="sftp-inbound"/> for more information.
</para>
</section>
<section id="3.0-scripting-variables">
<title>Scripting Support: Variables Changes</title>
<para>
A new <code>variables</code> attribute has been introduced for scripting components.
In addition, variable bindings are now allowed for inline scripts.
See <xref linkend="groovy"/> and <xref linkend="scripting"/> for more information.
</para>
</section>
</section>
</chapter>

View File

@@ -34,6 +34,9 @@
<listitem>
<para><emphasis><link linkend='xml-xpath-filter'>XPath Filter</link></emphasis></para>
</listitem>
<listitem>
<para><emphasis><link linkend='xpath-spel-function'>#xpath SpEL Function</link></emphasis></para>
</listitem>
<listitem>
<para><emphasis><link linkend='xml-validating-filter'>Validating Filter</link></emphasis></para>
</listitem>
@@ -1253,6 +1256,39 @@
</calloutlist></para>
</section>
<section id="xpath-spel-function">
<title>#xpath SpEL Function</title>
<para>
Spring Integration, since version <emphasis>3.0</emphasis>, provides the <code>#xpath</code>
built-in SpEL function, which invokes the static method <code>XPathUtils.evaluate(...)</code>.
This method delegates to an <interfacename>org.springframework.xml.xpath.XPathExpression</interfacename>.
The following shows some usage examples:
<programlisting language="xml"><![CDATA[<transformer expression="#xpath(payload, '/name')"/>
<filter expression="#xpath(payload, headers.xpath, 'boolean')"/>
<splitter expression="#xpath(payload, '//book', 'document_list')"/>
<router expression="#xpath(payload, '/person/@age', 'number')">
<mapping channel="output1" value="16"/>
<mapping channel="output2" value="45"/>
</router>]]></programlisting>
<code>#xpath</code> also supports a third optional parameter for converting the result of the xpath evaluation.
It can be
one of the String constants <code>'string'</code>, <code>'boolean'</code>, <code>'number'</code>,
<code>'node'</code>, <code>'node_list'</code> and <code>'document_list'</code> or an
<interfacename>org.springframework.xml.xpath.NodeMapper</interfacename> instance.
By default the <code>#xpath</code> SpEL function returns a String representation of the xpath evaluation.
</para>
<note>
To enable the <code>#xpath</code> SpEL function, simply add the <code>spring-integration-xml.jar</code>
to the CLASSPATH; there is no need to declare any component(s) from the Spring Integration Xml Namespace.
</note>
<para>
For more information see <xref linkend="spel"/>.
</para>
</section>
<section id="xml-validating-filter">
<title>XML Validating Filter</title>
<para>