<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="filter"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Filter</title>

  <section id="filter-introduction">
    <title>Introduction</title>
    <para>
      Message Filters are used to decide whether a Message should be passed along or dropped based on some criteria
      such as a Message Header value or Message content itself. Therefore, a Message Filter is similar
      to a router, except that for each Message received from the filter's input channel, that same Message may or may
      not be sent to the filter's output channel. Unlike the router, it makes no decision regarding
      <emphasis>which</emphasis> Message Channel to send the Message to but only decides <emphasis>whether</emphasis> to send.
      <note>
        As you will see momentarily, the Filter also supports a discard channel, so in certain cases it
        <emphasis>can</emphasis> play the role of a very simple router (or "switch") based on a boolean condition.
      </note>
    </para>
    <para>
      In Spring Integration, a Message Filter may be configured as a Message Endpoint that delegates to an
      implementation of the <interfacename>MessageSelector</interfacename> interface. That interface is itself quite
      simple: <programlisting language="java"><![CDATA[ public interface MessageSelector {

     boolean accept(Message<?> message);

 }]]></programlisting>
      The <classname>MessageFilter</classname> constructor accepts a selector instance:
      <programlisting language="java"><![CDATA[ MessageFilter filter = new MessageFilter(someSelector);]]></programlisting>
    </para>
      In combination with the namespace and SpEL, very powerful filters can be configured with very little java code.
  </section>

  <section id="filter-config">
    <title>Configuring Filter</title>
    <section id="filter-xml">
      <title>Configuring a Filter with XML</title>

    <para>
    The &lt;filter&gt; element is used to create a Message-selecting endpoint. In addition to "<code>input-channel</code>
      and <code>output-channel</code> attributes, it requires a <code>ref</code>. The <code>ref</code> may point to a 
      <interfacename>MessageSelector</interfacename> implementation:
      <programlisting language="xml"><![CDATA[ <int:filter input-channel="input" ref="selector" output-channel="output"/>

 <bean id="selector" class="example.MessageSelectorImpl"/>]]></programlisting>
    </para>
    <para>
      Alternatively, the <code>method</code> attribute can be added at which point the <code>ref</code> may refer to any object.
      The referenced method may expect either the <interfacename>Message</interfacename> type or the payload type of
      inbound Messages. The method must return a boolean value. If the method returns 'true',
      the Message <emphasis>will</emphasis> be sent to the output-channel.
      <programlisting language="xml"><![CDATA[ <int:filter input-channel="input" output-channel="output"
         ref="exampleObject" method="someBooleanReturningMethod"/>

 <bean id="exampleObject" class="example.SomeObject"/>]]></programlisting>
    </para>
    <para>
      If the selector or adapted POJO method returns <code>false</code>, there are a few settings that control the
      handling of the rejected Message. By default (if configured like the example above), rejected Messages will
      be silently dropped. If rejection should instead result in an error condition, then set the
      <code>throw-exception-on-rejection</code> attribute to <code>true</code>:
      <programlisting language="xml"><![CDATA[ <int:filter input-channel="input" ref="selector"
      output-channel="output" throw-exception-on-rejection="true"/> ]]></programlisting>
    </para>
    <para>  
    If you want rejected messages to be routed to a specific channel, provide that reference as the <code>discard-channel</code>:
      <programlisting language="xml"><![CDATA[ <int:filter input-channel="input" ref="selector"
      output-channel="output" discard-channel="rejectedMessages"/> ]]></programlisting>
    </para>
    <note>
      Message Filters are commonly used in conjunction with a Publish Subscribe Channel. Many filter endpoints may
      be subscribed to the same channel, and they decide whether or not to pass the Message to the next endpoint which
      could be any of the supported types (e.g. Service Activator). This provides a <emphasis>reactive</emphasis>
      alternative to the more <emphasis>proactive</emphasis> approach of using a Message Router with a single
      Point-to-Point input channel and multiple output channels.
    </note>
  <para>
      Using a <code>ref</code> attribute is generally recommended if the custom filter implementation is referenced in other
      <code>&lt;filter&gt;</code> definitions. However if the custom filter implementation is scoped to a
      single <code>&lt;filter&gt;</code> element, provide an inner bean definition:
<programlisting language="xml"><![CDATA[<int:filter method="someMethod" input-channel="inChannel" output-channel="outChannel">
  <beans:bean class="org.foo.MyCustomFilter"/>
</filter>]]></programlisting>
    </para>
    <note>
      <para>
        Using both the <code>ref</code> attribute and an inner handler definition in the same <code>&lt;filter&gt;</code> configuration
        is not allowed, as it creates an ambiguous condition, and an Exception will be thrown.
      </para>
    </note>
    <para>
      With the introduction of SpEL support, Spring Integration added the <code>expression</code> attribute to the filter
      element. It can be used to avoid Java entirely for simple filters.
      <programlisting language="xml"><![CDATA[<int:filter input-channel="input" expression="payload.equals('nonsense')"/>]]></programlisting>
      </para>
      <para>
      The string passed as the expression attribute will be evaluated as a SpEL expression with the Message available in
      the evaluation context.
      If it is necessary to include the result of an expression in the scope of the application context you can use the
      #{} notation as defined in the 
      <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#expressions-beandef">
        SpEL reference documentation
      </ulink>.
      <programlisting language="xml"><![CDATA[<int:filter input-channel="input" 
            expression="payload.matches(#{filterPatterns.nonsensePattern})"/>]]></programlisting>
      </para>
      <para>
      If the Expression itself needs to be dynamic, then an 'expression' sub-element may be used. That provides a level of
      indirection for resolving the Expression by its key from an ExpressionSource. That is a strategy interface that you
      can implement directly, or you can rely upon a version available in Spring Integration that loads Expressions from
      a "resource bundle" and can check for modifications after a given number of seconds. All of this is demonstrated in
      the following configuration sample where the Expression could be reloaded within one minute if the underlying file
      had been modified. If the ExpressionSource bean is named "expressionSource", then it is not necessary to provide the
      <code>source</code> attribute on the &lt;expression&gt; element, but in this case it's shown for completeness.
      <programlisting language="xml"><![CDATA[<int:filter input-channel="input" output-channel="output">
      <int:expression key="filterPatterns.example" source="myExpressions"/>
  </int:filter>

  <beans:bean id="myExpressions" id="myExpressions"
   class="org.springframework.integration.expression.ReloadableResourceBundleExpressionSource">
      <beans:property name="basename" value="config/integration/expressions"/>
      <beans:property name="cacheSeconds" value="60"/>
  </beans:bean>
]]></programlisting>
    </para>
    <para>
    Then, the 'config/integration/expressions.properties' file (or any more specific version with a locale extension
    to be resolved in the typical way that resource-bundles are loaded) would contain a key/value pair:
  <programlisting language="xml"><![CDATA[  filterPatterns.example=payload > 100]]></programlisting>

    <note>All of these examples that use <code>expression</code> as an attribute 
      or sub-element can also be applied within transformer, router, splitter, 
      service-activator, and header-enricher elements. Of course, the semantics/role
      of the given component type would affect the interpretation of the evaluation 
      result in the same way that the return value of a method-invocation would 
      be interpreted. For example, an expression can return Strings that are to 
      be treated as Message Channel names by a router component. However, the 
      underlying functionality of evaluating the expression against the Message 
      as the root object, and resolving bean names if prefixed with '@' is consistent
      across all of the core EIP components within Spring Integration.</note>
    </para>
    </section>
    <section id="filter-annotations">
        <title>Configuring a Filter with Annotations</title>
	    <para>A filter configured using annotations would look like this.</para>
	
	    <programlisting language="java"><![CDATA[public class PetFilter {
	  ... 
	
	  @Filter ]]><co id="filterann" /><![CDATA[ 
	  public boolean dogsOnly(String input) {
	    ...
	  }
		
	}]]></programlisting>
	
	    <calloutlist>
	      <callout arearefs="filterann">
	        <para>An annotation indicating that this method shall be used as a
	        filter. Must be specified if this class will be used as a filter.</para>
	      </callout>
	    </calloutlist>
	
	    <para>All of the configuration options provided by the xml element are
	    also available for the <interfacename>@Filter</interfacename> annotation.</para>
	
	    <para>The filter can be either referenced explicitly from XML or, if
	    the <interfacename>@MessageEndpoint</interfacename> annotation is defined 
	    on the class, detected automatically through classpath scanning.</para>
	  </section>
  </section>
</section>
