<?xml version="1.0" encoding="UTF-8"?>
<section version="5.0" xml:id="groovy" xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:ns5="http://www.w3.org/1999/xhtml"
         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
         xmlns:ns3="http://www.w3.org/2000/svg"
         xmlns:ns="http://docbook.org/ns/docbook">
  <title>Groovy support</title>

  <para>In Spring Integration 2.0 we added Groovy support allowing you to
  use the Groovy scripting language to provide the logic for
  various integration components similar to the way the Spring Expression Language
  (SpEL) is supported for routing, transformation and other integration
  concerns. For more information about Groovy please refer to the Groovy
  documentation which you can find
  on the <ulink url="http://groovy.codehaus.org">project website</ulink></para>

  <section id="groovy-config">
    <title>Groovy configuration</title>
    <para>  
    With Spring Integration 2.1, Groovy Support's configuration namespace
    is an extension of Spring Integration's Scripting Support and shares the core configuration 
    and behavior described in detail in the 
    <xref linkend="scripting">Scripting Support</xref> section. Even though Groovy scripts are
    well supported by generic Scripting Support, Groovy Support provides the 
    <emphasis>Groovy</emphasis> configuration namespace which is backed by the Spring Framework's 
    <classname>org.springframework.scripting.groovy.GroovyScriptFactory</classname> and related components, 
    offering extended capabilities for using Groovy. Below are a couple of sample configurations:</para>
    <para><emphasis>Filter</emphasis> <programlisting language="xml">&lt;int:filter input-channel="referencedScriptInput"&gt;
   &lt;int-groovy:script location="some/path/to/groovy/file/GroovyFilterTests.groovy"/&gt;
&lt;/int:filter&gt;

&lt;int:filter input-channel="inlineScriptInput"&gt;
     &lt;int-groovy:script&gt;&lt;![CDATA[
     return payload == 'good'
   ]]&gt;&lt;/int-groovy:script&gt;
&lt;/int:filter&gt;</programlisting>
	As the above examples show, the configuration looks identical to the general Scripting Support configuration. The only 
	difference is the use of the Groovy namespace as indicated in the examples by the <emphasis>int-groovy</emphasis> namespace prefix. 
	Also note that the <code>lang</code> attribute on the <code>&lt;script&gt;</code> tag is not valid in this namespace. 
  </para>

   
    <para><emphasis>Groovy object customization</emphasis> </para>
    
   <para>
	  If you need to customize the Groovy object itself, beyond setting variables, you can reference
	  a bean that implements <classname>org.springframework.scripting.groovy.GroovyObjectCustomizer</classname> via the
	  <code>customizer</code> attribute. For example, this might be useful if you want to implement a domain-specific
	  language (DSL) by modifying the MetaClass and registering functions to be available within the script:
	  
	   <programlisting language="xml"><![CDATA[<int:service-activator input-channel="groovyChannel">
    <int-groovy:script location="foo/SomeScript.groovy" customizer="groovyCustomizer"/>
</int:service-activator>

<beans:bean id="groovyCustomizer" class="org.foo.MyGroovyObjectCustomizer"/>]]></programlisting>

	  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.
    </para>
  </section>

  <section id="groovy-control-bus">
    <title>Control Bus</title>

    <para>As described in (<ulink
    url="http://www.eaipatterns.com/ControlBus.html">EIP</ulink>), the idea
    behind the Control Bus is that the same messaging system can be used for
    monitoring and managing the components within the framework as is used for
    "application-level" messaging. In Spring Integration we build upon the
    adapters described above so that it's possible to send Messages as a means
    of invoking exposed operations. One option for those operations is Groovy scripts.
    <programlisting language="xml"> &lt;int-groovy:control-bus input-channel="operationChannel"/&gt;</programlisting></para>

    <para>The Control Bus has an input channel that can be accessed for
    invoking operations on the beans in the application context.</para>

    <para>The Groovy Control Bus executes messages on the input channel as
    Groovy scripts. It takes a message, compiles the body to a Script,
    customizes it with a <classname>GroovyObjectCustomizer</classname>, and then executes it. The
    Control Bus' customizer exposes all the beans in the application context
    that are annotated with <code>@ManagedResource</code>, implement Spring's
    <classname>Lifecycle</classname> interface or extend Spring's <classname>CustomizableThreadCreator</classname> base class
    (e.g. several of the <classname>TaskExecutor</classname> and <classname>TaskScheduler</classname> implementations).</para>
    <para>
       <important>
        Be careful about using managed beans with custom scopes (e.g. 'request') in the Control Bus' command scripts, especially
        inside an <emphasis>async</emphasis> message flow. If <emphasis>The Control Bus' customizer</emphasis> can't expose a bean
        from the application context, it skips that bean. For example, if a custom scope's context is not established, the attempt
        to get a bean within that scope will trigger a <classname>BeanCreationException</classname>. In that case, such a bean
        will be ignored, and the customizer will continue with other beans.
       </important>
    </para>
    <para>
     If you need to further customize the Groovy objects, you can also provide a reference to a bean
     that implements <classname>org.springframework.scripting.groovy.GroovyObjectCustomizer</classname> via
     the <code>customizer</code> attribute.
	  
	   <programlisting language="xml"><![CDATA[<int-groovy:control-bus input-channel="input"
        output-channel="output"
        customizer="groovyCustomizer"/>
				   
<beans:bean id="groovyCustomizer" class="org.foo.MyGroovyObjectCustomizer"/>]]></programlisting>
    </para>
  </section>
</section>
