<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="cci"
    xmlns="http://docbook.org/ns/docbook" version="5.0"
    xmlns:xl="http://www.w3.org/1999/xlink"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
        http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
  <title>JCA CCI</title>

  <section xml:id="cci-introduction">
    <title>Introduction</title>

    <para>Java EE provides a specification to standardize access to enterprise
    information systems (EIS): the JCA (J2EE Connector Architecture). This
    specification is divided into several different parts:</para>

    <itemizedlist>
      <listitem>
        <para>SPI (Service provider interfaces) that the connector provider
        must implement. These interfaces constitute a resource adapter which
        can be deployed on a Java EE application server. In such a scenario, the
        server manages connection pooling, transaction and security (managed
        mode). The application server is also responsible for managing the
        configuration, which is held outside the client application. A
        connector can be used without an application server as well; in this
        case, the application must configure it directly (non-managed
        mode).</para>
      </listitem>

      <listitem>
        <para>CCI (Common Client Interface) that an application can use to
        interact with the connector and thus communicate with an EIS. An API
        for local transaction demarcation is provided as well.</para>
      </listitem>
    </itemizedlist>

    <para>The aim of the Spring CCI support is to provide classes to access a
    CCI connector in typical Spring style, leveraging the Spring Framework's
    general resource and transaction management facilities.</para>

    <note>
      <para>The client side of connectors doesn't alway use CCI. Some
      connectors expose their own APIs, only providing JCA resource adapter to
      use the system contracts of a Java EE container (connection pooling, global
      transactions, security). Spring does not offer special support for such
      connector-specific APIs.</para>
    </note>
  </section>

  <section xml:id="cci-config">
    <title>Configuring CCI</title>

    <section xml:id="cci-config-connector">
      <title>Connector configuration</title>

      <para>The base resource to use JCA CCI is the
      <interfacename>ConnectionFactory</interfacename> interface. The
      connector used must provide an implementation of this interface.</para>

      <para>To use your connector, you can deploy it on your application
      server and fetch the <interfacename>ConnectionFactory</interfacename>
      from the server's JNDI environment (managed mode). The connector must be
      packaged as a RAR file (resource adapter archive) and contain a
      <filename>ra.xml</filename> file to describe its deployment
      characteristics. The actual name of the resource is specified when you
      deploy it. To access it within Spring, simply use Spring's
      <classname>JndiObjectFactoryBean</classname> /
      <literal>&lt;jee:jndi-lookup&gt;</literal> fetch the factory by its JNDI
      name.</para>

      <para>Another way to use a connector is to embed it in your application
      (non-managed mode), not using an application server to deploy and
      configure it. Spring offers the possibility to configure a connector as
      a bean, through a provided <literal>FactoryBean</literal>
      (<classname>LocalConnectionFactoryBean</classname>). In this manner, you
      only need the connector library in the classpath (no RAR file and no
      <filename>ra.xml</filename> descriptor needed). The library must be
      extracted from the connector's RAR file, if necessary.</para>

      <para>Once you have got access to your
      <interfacename>ConnectionFactory</interfacename> instance, you can
      inject it into your components. These components can either be coded
      against the plain CCI API or leverage Spring's support classes for CCI
      access (e.g. <classname>CciTemplate</classname>).</para>

      <note>
        <para>When you use a connector in non-managed mode, you can't use
        global transactions because the resource is never enlisted / delisted
        in the current global transaction of the current thread. The resource
        is simply not aware of any global Java EE transactions that might be
        running.</para>
      </note>
    </section>

    <section xml:id="cci-config-connectionfactory">
      <title><interfacename>ConnectionFactory</interfacename> configuration in
      Spring</title>

      <para>In order to make connections to the EIS, you need to obtain a
      <interfacename>ConnectionFactory</interfacename> from the application
      server if you are in a managed mode, or directly from Spring if you are
      in a non-managed mode.</para>

      <para>In a managed mode, you access a
      <interfacename>ConnectionFactory</interfacename> from JNDI; its
      properties will be configured in the application server.</para>

      <programlisting language="xml">&lt;jee:jndi-lookup id="eciConnectionFactory" jndi-name="eis/cicseci"/&gt;</programlisting>

      <para>In non-managed mode, you must configure the
      <interfacename>ConnectionFactory</interfacename> you want to use in the
      configuration of Spring as a JavaBean. The
      <classname>LocalConnectionFactoryBean</classname> class offers this
      setup style, passing in the
      <classname>ManagedConnectionFactory</classname> implementation of your
      connector, exposing the application-level CCI
      <interfacename>ConnectionFactory</interfacename>.</para>

      <programlisting language="xml">&lt;bean id="eciManagedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory"&gt;
  &lt;property name="serverName" value="TXSERIES"/&gt;
  &lt;property name="connectionURL" value="tcp://localhost/"/&gt;
  &lt;property name="portNumber" value="2006"/&gt;
&lt;/bean&gt;

&lt;bean id="eciConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="eciManagedConnectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

      <note>
        <para>You can't directly instantiate a specific
        <interfacename>ConnectionFactory</interfacename>. You need to go
        through the corresponding implementation of the
        <classname>ManagedConnectionFactory</classname> interface for your
        connector. This interface is part of the JCA SPI specification.</para>
      </note>
    </section>

    <section xml:id="cci-config-cci-connections">
      <title>Configuring CCI connections</title>

      <para>JCA CCI allow the developer to configure the connections to the
      EIS using the <interfacename>ConnectionSpec</interfacename>
      implementation of your connector. In order to configure its properties,
      you need to wrap the target connection factory with a dedicated adapter,
      <classname>ConnectionSpecConnectionFactoryAdapter</classname>. So, the
      dedicated <interfacename>ConnectionSpec</interfacename> can be
      configured with the property <literal>connectionSpec</literal> (as an
      inner bean).</para>

      <para>This property is not mandatory because the CCI
      <interfacename>ConnectionFactory</interfacename> interface defines two
      different methods to obtain a CCI connection. Some of the
      <interfacename>ConnectionSpec</interfacename> properties can often be
      configured in the application server (in managed mode) or on the
      corresponding local <classname>ManagedConnectionFactory</classname>
      implementation.</para>

      <programlisting language="java">public interface ConnectionFactory implements Serializable, Referenceable {
  ...
  Connection getConnection() throws ResourceException;
  Connection getConnection(ConnectionSpec connectionSpec) throws ResourceException;
  ...
}</programlisting>

      <para>Spring provides a
      <classname>ConnectionSpecConnectionFactoryAdapter</classname> that
      allows for specifying a <interfacename>ConnectionSpec</interfacename>
      instance to use for all operations on a given factory. If the adapter's
      <literal>connectionSpec</literal> property is specified, the adapter
      uses the <literal>getConnection</literal> variant with the
      <interfacename>ConnectionSpec</interfacename> argument, otherwise
	  the variant without argument.</para>

      <programlisting language="xml">&lt;bean id="managedConnectionFactory"
    class="com.sun.connector.cciblackbox.CciLocalTxManagedConnectionFactory"&gt;
  &lt;property name="connectionURL" value="jdbc:hsqldb:hsql://localhost:9001"/&gt;
  &lt;property name="driverName" value="org.hsqldb.jdbcDriver"/&gt;
&lt;/bean&gt;

&lt;bean id="targetConnectionFactory"
    class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="managedConnectionFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="connectionFactory"
    class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter"&gt;
  &lt;property name="targetConnectionFactory" ref="targetConnectionFactory"/&gt;
  &lt;property name="connectionSpec"&gt;
    &lt;bean class="com.sun.connector.cciblackbox.CciConnectionSpec"&gt;
      &lt;property name="user" value="sa"/&gt;
      &lt;property name="password" value=""/&gt;
    &lt;/bean&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting>
    </section>

    <section xml:id="cci-config-single-connection">
      <title>Using a single CCI connection</title>

      <para>If you want to use a single CCI connection, Spring provides a
      further <interfacename>ConnectionFactory</interfacename> adapter to
      manage this. The <classname>SingleConnectionFactory</classname> adapter
      class will open a single connection lazily and close it when this bean
      is destroyed at application shutdown. This class will expose special
      <interfacename>Connection</interfacename> proxies that behave
      accordingly, all sharing the same underlying physical connection.</para>

      <programlisting language="xml">&lt;bean id="eciManagedConnectionFactory"
    class="com.ibm.connector2.cics.ECIManagedConnectionFactory"&gt;
  &lt;property name="serverName" value="TEST"/&gt;
  &lt;property name="connectionURL" value="tcp://localhost/"/&gt;
  &lt;property name="portNumber" value="2006"/&gt;
&lt;/bean&gt;

&lt;bean id="targetEciConnectionFactory"
    class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="eciManagedConnectionFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="eciConnectionFactory"
    class="org.springframework.jca.cci.connection.SingleConnectionFactory"&gt;
  &lt;property name="targetConnectionFactory" ref="targetEciConnectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

      <note>
        <para>This <interfacename>ConnectionFactory</interfacename> adapter
        cannot directly be configured with a
        <interfacename>ConnectionSpec</interfacename>. Use an intermediary
        <classname>ConnectionSpecConnectionFactoryAdapter</classname> that the
        <classname>SingleConnectionFactory</classname> talks to if you require
        a single connection for a specific
        <interfacename>ConnectionSpec</interfacename>.</para>
      </note>
    </section>
  </section>

  <section xml:id="cci-using">
    <title>Using Spring's CCI access support</title>

    <section xml:id="cci-record-creator">
      <title>Record conversion</title>

      <para>One of the aims of the JCA CCI support is to provide convenient
      facilities for manipulating CCI records. The developer can specify the
      strategy to create records and extract datas from records, for use with
      Spring's <classname>CciTemplate</classname>. The following interfaces
      will configure the strategy to use input and output records if you don't
      want to work with records directly in your application.</para>

      <para>In order to create an input <interfacename>Record</interfacename>,
      the developer can use a dedicated implementation of the
      <interfacename>RecordCreator</interfacename> interface.</para>

      <programlisting language="java">public interface RecordCreator {

  Record createRecord(RecordFactory recordFactory) throws ResourceException, DataAccessException;
}</programlisting>

      <para>As you can see, the <literal>createRecord(..)</literal> method
      receives a <interfacename>RecordFactory</interfacename> instance as
      parameter, which corresponds to the
      <interfacename>RecordFactory</interfacename> of the
      <interfacename>ConnectionFactory</interfacename> used. This reference
      can be used to create <interfacename>IndexedRecord</interfacename> or
      <interfacename>MappedRecord</interfacename> instances. The following
      sample shows how to use the <interfacename>RecordCreator</interfacename>
      interface and indexed/mapped records.</para>

      <programlisting language="java">public class MyRecordCreator implements RecordCreator {

  public Record createRecord(RecordFactory recordFactory) throws ResourceException {
    IndexedRecord input = recordFactory.createIndexedRecord("input");
    input.add(new Integer(id));
    return input;
  }
}</programlisting>

      <para>An output <interfacename>Record</interfacename> can be used to
      receive data back from the EIS. Hence, a specific implementation of the
      <interfacename>RecordExtractor</interfacename> interface can be passed
      to Spring's <classname>CciTemplate</classname> for extracting data from
      the output <interfacename>Record</interfacename>.</para>

      <programlisting language="java">public interface RecordExtractor {

  Object extractData(Record record) throws ResourceException, SQLException, DataAccessException;
}</programlisting>

      <para>The following sample shows how to use the
      <interfacename>RecordExtractor</interfacename> interface.</para>

      <programlisting language="java">public class MyRecordExtractor implements RecordExtractor {

  public Object extractData(Record record) throws ResourceException {
    CommAreaRecord commAreaRecord = (CommAreaRecord) record;
    String str = new String(commAreaRecord.toByteArray());
    String field1 = string.substring(0,6);
    String field2 = string.substring(6,1);
    return new OutputObject(Long.parseLong(field1), field2);
  }
}</programlisting>
    </section>

    <section xml:id="cci-using-template">
      <title>The <classname>CciTemplate</classname></title>

      <para>The <classname>CciTemplate</classname> is the central class of the
      core CCI support package
      (<literal>org.springframework.jca.cci.core</literal>). It simplifies the
      use of CCI since it handles the creation and release of resources. This
      helps to avoid common errors like forgetting to always close the
      connection. It cares for the lifecycle of connection and interaction
      objects, letting application code focus on generating input records from
      application data and extracting application data from output
      records.</para>

      <para>The JCA CCI specification defines two distinct methods to call
      operations on an EIS. The CCI <interfacename>Interaction</interfacename>
      interface provides two execute method signatures:</para>

      <programlisting language="java">public interface javax.resource.cci.Interaction {
  ...
  boolean execute(InteractionSpec spec, Record input, Record output) throws ResourceException;

  Record execute(InteractionSpec spec, Record input) throws ResourceException;
  ...
}</programlisting>

      <para>Depending on the template method called,
      <classname>CciTemplate</classname> will know which
      <literal>execute</literal> method to call on the interaction. In any
      case, a correctly initialized
      <interfacename>InteractionSpec</interfacename> instance is
      mandatory.</para>

      <para><literal>CciTemplate.execute(..)</literal> can be used in two
      ways:</para>

      <itemizedlist>
        <listitem>
          <para>With direct <interfacename>Record</interfacename> arguments.
          In this case, you simply need to pass the CCI input record in, and
          the returned object be the corresponding CCI output record.</para>
        </listitem>

        <listitem>
          <para>With application objects, using record mapping. In this case,
          you need to provide corresponding
          <interfacename>RecordCreator</interfacename> and
          <interfacename>RecordExtractor</interfacename> instances.</para>
        </listitem>
      </itemizedlist>

      <para>With the first approach, the following methods of the template
      will be used. These methods directly correspond to those on the
      <interfacename>Interaction</interfacename> interface.</para>

      <programlisting language="java">public class CciTemplate implements CciOperations {

  public Record execute(InteractionSpec spec, Record inputRecord)
      throws DataAccessException { ... }

  public void execute(InteractionSpec spec, Record inputRecord, Record outputRecord)
      throws DataAccessException { ... }

}</programlisting>

      <para>With the second approach, we need to specify the record creation
      and record extraction strategies as arguments. The interfaces used are
      those describe in the previous section on record conversion. The
      corresponding <classname>CciTemplate</classname> methods are the
      following:</para>

      <programlisting language="java">public class CciTemplate implements CciOperations {

  public Record execute(InteractionSpec spec, RecordCreator inputCreator)
      throws DataAccessException { ... }

  public Object execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor)
      throws DataAccessException { ... }

  public Object execute(InteractionSpec spec, RecordCreator creator, RecordExtractor extractor)
      throws DataAccessException { ... }

}</programlisting>

      <para>Unless the <literal>outputRecordCreator</literal> property is set
      on the template (see the following section), every method will call the
      corresponding <literal>execute</literal> method of the CCI
      <interfacename>Interaction</interfacename> with two parameters:
      <interfacename>InteractionSpec</interfacename> and input
      <interfacename>Record</interfacename>, receiving an output
      <interfacename>Record</interfacename> as return value.</para>

      <para><classname>CciTemplate</classname> also provides methods to create
      <literal>IndexRecord</literal> and <literal>MappedRecord</literal>
      outside a <interfacename>RecordCreator</interfacename> implementation,
      through its <literal>createIndexRecord(..)</literal> and
      <literal>createMappedRecord(..)</literal> methods. This can be used
      within DAO implementations to create
      <interfacename>Record</interfacename> instances to pass into
      corresponding <literal>CciTemplate.execute(..)</literal> methods.</para>

      <programlisting language="java">public class CciTemplate implements CciOperations {

  public IndexedRecord createIndexedRecord(String name) throws DataAccessException { ... }

  public MappedRecord createMappedRecord(String name) throws DataAccessException { ... }

}</programlisting>
    </section>

    <section xml:id="cci-using-dao">
      <title>DAO support</title>

      <para>Spring's CCI support provides a abstract class for DAOs,
      supporting injection of a
      <interfacename>ConnectionFactory</interfacename> or a
      <classname>CciTemplate</classname> instances. The name of the class is
      <classname>CciDaoSupport</classname>: It provides simple
      <literal>setConnectionFactory</literal> and
      <literal>setCciTemplate</literal> methods. Internally, this class will
      create a <classname>CciTemplate</classname> instance for a passed-in
      <interfacename>ConnectionFactory</interfacename>, exposing it to
      concrete data access implementations in subclasses.</para>

      <programlisting language="java">public abstract class CciDaoSupport {

  public void setConnectionFactory(ConnectionFactory connectionFactory) { ... }
  public ConnectionFactory getConnectionFactory() { ... }

  public void setCciTemplate(CciTemplate cciTemplate) { ... }
  public CciTemplate getCciTemplate() { ... }

}</programlisting>
    </section>

    <section xml:id="automatic-output-generation">
      <title>Automatic output record generation</title>

      <para>If the connector used only supports the
      <methodname>Interaction.execute(..)</methodname> method with input and
      output records as parameters (that is, it requires the desired output
      record to be passed in instead of returning an appropriate output
      record), you can set the <literal>outputRecordCreator</literal> property
      of the <classname>CciTemplate</classname> to automatically generate an
      output record to be filled by the JCA connector when the response is
      received. This record will be then returned to the caller of the
      template.</para>

      <para>This property simply holds an implementation of the
      <interfacename>RecordCreator</interfacename> interface, used for that
      purpose. The <interfacename>RecordCreator</interfacename> interface has
      already been discussed in <xref linkend="cci-record-creator" />. The
      <literal>outputRecordCreator</literal> property must be directly
      specified on the <classname>CciTemplate</classname>. This could be done
      in the application code like so:</para>

      <programlisting language="java">cciTemplate.setOutputRecordCreator(new EciOutputRecordCreator());</programlisting>

      <para>Or (recommended) in the Spring configuration, if the
      <classname>CciTemplate</classname> is configured as a dedicated bean
      instance:</para>

      <programlisting language="xml">&lt;bean id="eciOutputRecordCreator" class="eci.EciOutputRecordCreator"/&gt;

&lt;bean id="cciTemplate" class="org.springframework.jca.cci.core.CciTemplate"&gt;
  &lt;property name="connectionFactory" ref="eciConnectionFactory"/&gt;
  &lt;property name="outputRecordCreator" ref="eciOutputRecordCreator"/&gt;
&lt;/bean&gt;</programlisting>

      <note>
        <para>As the <classname>CciTemplate</classname> class is thread-safe,
        it will usually be configured as a shared instance.</para>
      </note>
    </section>

    <section xml:id="template-summary">
      <title>Summary</title>

      <para>The following table summarizes the mechanisms of the
      <classname>CciTemplate</classname> class and the corresponding methods
      called on the CCI <interfacename>Interaction</interfacename>
      interface:<table frame="all" xml:id="cci-interaction-execute-methods">
          <title>Usage of <interfacename>Interaction</interfacename> execute
          methods</title>

          <tgroup cols="3">
            <thead>
              <row>
                <entry align="center">CciTemplate method signature</entry>

                <entry align="center">CciTemplate outputRecordCreator
                property</entry>

                <entry align="center">execute method called on the CCI
                Interaction</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>

                <entry align="center">not set</entry>

                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>

                <entry align="center">set</entry>

                <entry align="center">boolean execute(InteractionSpec, Record,
                Record)</entry>
              </row>

              <row>
                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>

                <entry align="center">not set</entry>

                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>
              </row>

              <row>
                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>

                <entry align="center">set</entry>

                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec,
                RecordCreator)</entry>

                <entry align="center">not set</entry>

                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec,
                RecordCreator)</entry>

                <entry align="center">set</entry>

                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec, Record,
                RecordExtractor)</entry>

                <entry align="center">not set</entry>

                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec, Record,
                RecordExtractor)</entry>

                <entry align="center">set</entry>

                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec,
                RecordCreator, RecordExtractor)</entry>

                <entry align="center">not set</entry>

                <entry align="center">Record execute(InteractionSpec,
                Record)</entry>
              </row>

              <row>
                <entry align="center">Record execute(InteractionSpec,
                RecordCreator, RecordExtractor)</entry>

                <entry align="center">set</entry>

                <entry align="center">void execute(InteractionSpec, Record,
                Record)</entry>
              </row>
            </tbody>
          </tgroup>
        </table></para>
    </section>

    <section xml:id="cci-straight">
      <title>Using a CCI <interfacename>Connection</interfacename> and
      <interfacename>Interaction</interfacename> directly</title>

      <para><classname>CciTemplate</classname> also offers the possibility to
      work directly with CCI connections and interactions, in the same manner
      as <classname>JdbcTemplate</classname> and
      <classname>JmsTemplate</classname>. This is useful when you want to
      perform multiple operations on a CCI connection or interaction, for
      example.</para>

      <para>The interface <interfacename>ConnectionCallback</interfacename>
      provides a CCI <interfacename>Connection</interfacename> as argument, in
      order to perform custom operations on it, plus the CCI
      <interfacename>ConnectionFactory</interfacename> which the
      <interfacename>Connection</interfacename> was created with. The latter
      can be useful for example to get an associated
      <interfacename>RecordFactory</interfacename> instance and create
      indexed/mapped records, for example.</para>

      <programlisting language="java">public interface ConnectionCallback {

  Object doInConnection(Connection connection, ConnectionFactory connectionFactory)
      throws ResourceException, SQLException, DataAccessException;
}</programlisting>

      <para>The interface <interfacename>InteractionCallback</interfacename>
      provides the CCI <interfacename>Interaction</interfacename>, in order to
      perform custom operations on it, plus the corresponding CCI
      <interfacename>ConnectionFactory</interfacename>.</para>

      <programlisting language="java">public interface InteractionCallback {

  Object doInInteraction(Interaction interaction, ConnectionFactory connectionFactory)
      throws ResourceException, SQLException, DataAccessException;
}</programlisting>

      <note>
        <para><interfacename>InteractionSpec</interfacename> objects can
        either be shared across multiple template calls or newly created
        inside every callback method. This is completely up to the DAO
        implementation.</para>
      </note>
    </section>

    <section xml:id="cci-template-example">
      <title>Example for <classname>CciTemplate</classname> usage</title>

      <para>In this section, the usage of the
      <classname>CciTemplate</classname> will be shown to acces to a CICS with
      ECI mode, with the IBM CICS ECI connector.</para>

      <para>Firstly, some initializations on the CCI
      <interfacename>InteractionSpec</interfacename> must be done to specify
      which CICS program to access and how to interact with it.</para>

      <programlisting language="java">ECIInteractionSpec interactionSpec = new ECIInteractionSpec();
interactionSpec.setFunctionName("MYPROG");
interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);</programlisting>

      <para>Then the program can use CCI via Spring's template and specify
      mappings between custom objects and CCI
      <literal>Records</literal>.</para>

      <programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {

  public OutputObject getData(InputObject input) {
    ECIInteractionSpec interactionSpec = ...;

    OutputObject output = (ObjectOutput) getCciTemplate().execute(interactionSpec,
        new RecordCreator() {
          public Record createRecord(RecordFactory recordFactory) throws ResourceException {
            return new CommAreaRecord(input.toString().getBytes());
          }
        },
        new RecordExtractor() {
          public Object extractData(Record record) throws ResourceException {
            CommAreaRecord commAreaRecord = (CommAreaRecord)record;
            String str = new String(commAreaRecord.toByteArray());
            String field1 = string.substring(0,6);
            String field2 = string.substring(6,1);
            return new OutputObject(Long.parseLong(field1), field2);
          }
        });

    return output;
  }
}</programlisting>

      <para>As discussed previously, callbacks can be used to work directly on
      CCI connections or interactions.</para>

      <programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {

  public OutputObject getData(InputObject input) {
    ObjectOutput output = (ObjectOutput) getCciTemplate().execute(
        new ConnectionCallback() {
          public Object doInConnection(Connection connection, ConnectionFactory factory)
              throws ResourceException {

            <lineannotation>// do something...</lineannotation>
          }
        });
    }
    return output;
  }
}</programlisting>

      <note>
        <para>With a <interfacename>ConnectionCallback</interfacename>, the
        <interfacename>Connection</interfacename> used will be managed and
        closed by the <classname>CciTemplate</classname>, but any interactions
        created on the connection must be managed by the callback
        implementation.</para>
      </note>

      <para>For a more specific callback, you can implement an
      <interfacename>InteractionCallback</interfacename>. The passed-in
      <interfacename>Interaction</interfacename> will be managed and closed by
      the <classname>CciTemplate</classname> in this case.</para>

      <programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {

  public String getData(String input) {
    ECIInteractionSpec interactionSpec = ...;

    String output = (String) getCciTemplate().execute(interactionSpec,
        new InteractionCallback() {
          public Object doInInteraction(Interaction interaction, ConnectionFactory factory)
              throws ResourceException {
            Record input = new CommAreaRecord(inputString.getBytes());
            Record output = new CommAreaRecord();
            interaction.execute(holder.getInteractionSpec(), input, output);
            return new String(output.toByteArray());
          }
        });

    return output;
  }
}</programlisting>

      <para>For the examples above, the corresponding configuration of the
      involved Spring beans could look like this in non-managed mode:</para>

      <programlisting language="xml">&lt;bean id="managedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory"&gt;
  &lt;property name="serverName" value="TXSERIES"/&gt;
  &lt;property name="connectionURL" value="local:"/&gt;
  &lt;property name="userName" value="CICSUSER"/&gt;
  &lt;property name="password" value="CICS"/&gt;
&lt;/bean&gt;

&lt;bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="managedConnectionFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="component" class="mypackage.MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

      <para>In managed mode (that is, in a Java EE environment), the
      configuration could look as follows:</para>

      <programlisting language="xml">&lt;jee:jndi-lookup id="connectionFactory" jndi-name="eis/cicseci"/&gt;

&lt;bean id="component" class="MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>
    </section>
  </section>

  <section xml:id="cci-object">
    <title>Modeling CCI access as operation objects</title>

    <para>The <literal>org.springframework.jca.cci.object</literal> package
    contains support classes that allow you to access the EIS in a different
    style: through reusable operation objects, analogous to Spring's JDBC
    operation objects (see JDBC chapter). This will usually encapsulate the
    CCI API: an application-level input object will be passed to the operation
    object, so it can construct the input record and then convert the received
    record data to an application-level output object and return it.</para>

    <para><emphasis>Note</emphasis>: This approach is internally based on the
    <classname>CciTemplate</classname> class and the
    <interfacename>RecordCreator</interfacename> /
    <interfacename>RecordExtractor</interfacename> interfaces, reusing the
    machinery of Spring's core CCI support.</para>

    <section xml:id="cci-object-mapping-record">
      <title><classname>MappingRecordOperation</classname></title>

      <para><classname>MappingRecordOperation</classname> essentially performs
      the same work as <classname>CciTemplate</classname>, but represents a
      specific, pre-configured operation as an object. It provides two
      template methods to specify how to convert an input object to a input
      record, and how to convert an output record to an output object (record
      mapping):</para>

      <itemizedlist>
        <listitem>
          <para><literal>createInputRecord(..)</literal> to specify how to
          convert an input object to an input
          <interfacename>Record</interfacename></para>
        </listitem>

        <listitem>
          <para><literal>extractOutputData(..)</literal> to specify how to
          extract an output object from an output
          <interfacename>Record</interfacename></para>
        </listitem>
      </itemizedlist>

      <para>Here are the signatures of these methods:</para>

      <programlisting language="java">public abstract class MappingRecordOperation extends EisOperation {
  ...
  protected abstract Record createInputRecord(RecordFactory recordFactory, Object inputObject)
      throws ResourceException, DataAccessException { ... }

  protected abstract Object extractOutputData(Record outputRecord)
      throws ResourceException, SQLException, DataAccessException { ... }
  ...
}</programlisting>

      <para>Thereafter, in order to execute an EIS operation, you need to use
      a single execute method, passing in an application-level input object
      and receiving an application-level output object as result:</para>

      <programlisting language="java">public abstract class MappingRecordOperation extends EisOperation {
  ...
  public Object execute(Object inputObject) throws DataAccessException {
  ...
}</programlisting>

      <para>As you can see, contrary to the <classname>CciTemplate</classname>
      class, this <methodname>execute(..)</methodname> method does not have an
      <interfacename>InteractionSpec</interfacename> as argument. Instead, the
      <interfacename>InteractionSpec</interfacename> is global to the
      operation. The following constructor must be used to instantiate an
      operation object with a specific
      <interfacename>InteractionSpec</interfacename>:</para>

      <programlisting language="java">InteractionSpec spec = ...;
MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnectionFactory(), spec);
...</programlisting>
    </section>

    <section xml:id="cci-object-mapping-comm-area">
      <title><classname>MappingCommAreaOperation</classname></title>

      <para>Some connectors use records based on a COMMAREA which represents
      an array of bytes containing parameters to send to the EIS and data
      returned by it. Spring provides a special operation class for working
      directly on COMMAREA rather than on records. The
      <classname>MappingCommAreaOperation</classname> class extends the
      <classname>MappingRecordOperation</classname> class to provide such
      special COMMAREA support. It implicitly uses the
      <classname>CommAreaRecord</classname> class as input and output record
      type, and provides two new methods to convert an input object into an
      input COMMAREA and the output COMMAREA into an output object.</para>

      <programlisting language="java">public abstract class MappingCommAreaOperation extends MappingRecordOperation {
  ...
  protected abstract byte[] objectToBytes(Object inObject)
      throws IOException, DataAccessException;

  protected abstract Object bytesToObject(byte[] bytes)
      throws IOException, DataAccessException;
  ...
}</programlisting>
    </section>

    <section xml:id="cci-automatic-record-gen">
      <title>Automatic output record generation</title>

      <para>As every <classname>MappingRecordOperation</classname> subclass is
      based on CciTemplate internally, the same way to automatically generate
      output records as with <classname>CciTemplate</classname> is available.
      Every operation object provides a corresponding
      <literal>setOutputRecordCreator(..)</literal> method. For further
      information, see <xref linkend="automatic-output-generation" />.</para>
    </section>

    <section xml:id="cci-object-summary">
      <title>Summary</title>

      <para>The operation object approach uses records in the same manner as
      the <classname>CciTemplate</classname> class.</para>

      <table frame="all" xml:id="cci-interaction-methods">
        <title>Usage of Interaction execute methods</title>

        <tgroup cols="3">
          <thead>
            <row>
              <entry
              align="center"><classname>MappingRecordOperation</classname>
              method signature</entry>

              <entry
              align="center"><classname>MappingRecordOperation</classname>
              <literal>outputRecordCreator</literal> property</entry>

              <entry align="center">execute method called on the CCI
              <interfacename>Interaction</interfacename></entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry align="center">Object execute(Object)</entry>

              <entry align="center">not set</entry>

              <entry align="center">Record execute(InteractionSpec,
              Record)</entry>
            </row>

            <row>
              <entry align="center">Object execute(Object)</entry>

              <entry align="center">set</entry>

              <entry align="center">boolean execute(InteractionSpec, Record,
              Record)</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>

    <section xml:id="cci-objects-mappring-record-example">
      <title>Example for <classname>MappingRecordOperation</classname>
      usage</title>

      <para>In this section, the usage of the
      <classname>MappingRecordOperation</classname> will be shown to access a
      database with the Blackbox CCI connector.</para>

      <note>
        <para>The original version of this connector is provided by the Java EE
        SDK (version 1.3), available from Sun.</para>
      </note>

      <para>Firstly, some initializations on the CCI
      <interfacename>InteractionSpec</interfacename> must be done to specify
      which SQL request to execute. In this sample, we directly define the way
      to convert the parameters of the request to a CCI record and the way to
      convert the CCI result record to an instance of the
      <classname>Person</classname> class.</para>

      <programlisting language="java">public class PersonMappingOperation extends MappingRecordOperation {

  public PersonMappingOperation(ConnectionFactory connectionFactory) {
    setConnectionFactory(connectionFactory);
    CciInteractionSpec interactionSpec = new CciConnectionSpec();
    interactionSpec.setSql("select * from person where person_id=?");
    setInteractionSpec(interactionSpec);
  }

  protected Record createInputRecord(RecordFactory recordFactory, Object inputObject)
      throws ResourceException {
    Integer id = (Integer) inputObject;
    IndexedRecord input = recordFactory.createIndexedRecord("input");
    input.add(new Integer(id));
    return input;
  }

  protected Object extractOutputData(Record outputRecord)
      throws ResourceException, SQLException {
    ResultSet rs = (ResultSet) outputRecord;
    Person person = null;
    if (rs.next()) {
      Person person = new Person();
      person.setId(rs.getInt("person_id"));
      person.setLastName(rs.getString("person_last_name"));
      person.setFirstName(rs.getString("person_first_name"));
    }
    return person;
  }
}</programlisting>

      <para>Then the application can execute the operation object, with the
      person identifier as argument. Note that operation object could be set
      up as shared instance, as it is thread-safe.</para>

      <programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {

  public Person getPerson(int id) {
    PersonMappingOperation query = new PersonMappingOperation(getConnectionFactory());
    Person person = (Person) query.execute(new Integer(id));
    return person;
  }
}</programlisting>

      <para>The corresponding configuration of Spring beans could look as
      follows in non-managed mode:</para>

      <programlisting language="xml">&lt;bean id="managedConnectionFactory"
    class="com.sun.connector.cciblackbox.CciLocalTxManagedConnectionFactory"&gt;
  &lt;property name="connectionURL" value="jdbc:hsqldb:hsql://localhost:9001"/&gt;
  &lt;property name="driverName" value="org.hsqldb.jdbcDriver"/&gt;
&lt;/bean&gt;

&lt;bean id="targetConnectionFactory"
    class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="managedConnectionFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="connectionFactory"
    class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter"&gt;
  &lt;property name="targetConnectionFactory" ref="targetConnectionFactory"/&gt;
  &lt;property name="connectionSpec"&gt;
    &lt;bean class="com.sun.connector.cciblackbox.CciConnectionSpec"&gt;
      &lt;property name="user" value="sa"/&gt;
      &lt;property name="password" value=""/&gt;
    &lt;/bean&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="component" class="MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

      <para>In managed mode (that is, in a Java EE environment), the
      configuration could look as follows:</para>

      <programlisting language="xml">&lt;jee:jndi-lookup id="targetConnectionFactory" jndi-name="eis/blackbox"/&gt;

&lt;bean id="connectionFactory"
    class="org.springframework.jca.cci.connection.ConnectionSpecConnectionFactoryAdapter"&gt;
  &lt;property name="targetConnectionFactory" ref="targetConnectionFactory"/&gt;
  &lt;property name="connectionSpec"&gt;
    &lt;bean class="com.sun.connector.cciblackbox.CciConnectionSpec"&gt;
      &lt;property name="user" value="sa"/&gt;
      &lt;property name="password" value=""/&gt;
    &lt;/bean&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="component" class="MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>
    </section>

    <section xml:id="cci-objects-mapping-comm-area-example">
      <title>Example for <classname>MappingCommAreaOperation</classname>
      usage</title>

      <para>In this section, the usage of the
      <classname>MappingCommAreaOperation</classname> will be shown: accessing
      a CICS with ECI mode with the IBM CICS ECI connector.</para>

      <para>Firstly, the CCI <interfacename>InteractionSpec</interfacename>
      needs to be initialized to specify which CICS program to access and how
      to interact with it.</para>

      <programlisting language="java">public abstract class EciMappingOperation extends MappingCommAreaOperation {

  public EciMappingOperation(ConnectionFactory connectionFactory, String programName) {
    setConnectionFactory(connectionFactory);
    ECIInteractionSpec interactionSpec = new ECIInteractionSpec(),
    interactionSpec.setFunctionName(programName);
    interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
    interactionSpec.setCommareaLength(30);
    setInteractionSpec(interactionSpec);
    setOutputRecordCreator(new EciOutputRecordCreator());
  }

  private static class EciOutputRecordCreator implements RecordCreator {
    public Record createRecord(RecordFactory recordFactory) throws ResourceException {
      return new CommAreaRecord();
    }
  }
}</programlisting>

      <para>The abstract <classname>EciMappingOperation</classname> class can
      then be subclassed to specify mappings between custom objects and
      <literal>Records</literal>.</para>

      <programlisting language="java">public class MyDaoImpl extends CciDaoSupport implements MyDao {

  public OutputObject getData(Integer id) {
    EciMappingOperation query = new EciMappingOperation(getConnectionFactory(), "MYPROG") {
      protected abstract byte[] objectToBytes(Object inObject) throws IOException {
        Integer id = (Integer) inObject;
        return String.valueOf(id);
      }
      protected abstract Object bytesToObject(byte[] bytes) throws IOException;
        String str = new String(bytes);
        String field1 = str.substring(0,6);
        String field2 = str.substring(6,1);
        String field3 = str.substring(7,1);
        return new OutputObject(field1, field2, field3);
      }
    });

    return (OutputObject) query.execute(new Integer(id));
  }
}</programlisting>

      <para>The corresponding configuration of Spring beans could look as
      follows in non-managed mode:</para>

      <programlisting language="xml">&lt;bean id="managedConnectionFactory" class="com.ibm.connector2.cics.ECIManagedConnectionFactory"&gt;
  &lt;property name="serverName" value="TXSERIES"/&gt;
  &lt;property name="connectionURL" value="local:"/&gt;
  &lt;property name="userName" value="CICSUSER"/&gt;
  &lt;property name="password" value="CICS"/&gt;
&lt;/bean&gt;

&lt;bean id="connectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean"&gt;
  &lt;property name="managedConnectionFactory" ref="managedConnectionFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="component" class="MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

      <para>In managed mode (that is, in a Java EE environment), the
      configuration could look as follows:</para>

      <programlisting language="xml">&lt;jee:jndi-lookup id="connectionFactory" jndi-name="eis/cicseci"/&gt;

&lt;bean id="component" class="MyDaoImpl"&gt;
  &lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;/bean&gt;</programlisting>
    </section>
  </section>

  <section xml:id="cci-tx">
    <title>Transactions</title>

    <para>JCA specifies several levels of transaction support for resource
    adapters. The kind of transactions that your resource adapter supports is
    specified in its <filename>ra.xml</filename> file. There are essentially
    three options: none (for example with CICS EPI connector), local
    transactions (for example with a CICS ECI connector), global transactions
    (for example with an IMS connector).</para>

    <programlisting language="xml">&lt;connector&gt;

  &lt;resourceadapter&gt;

    <lineannotation>&lt;!-- &lt;transaction-support&gt;NoTransaction&lt;/transaction-support&gt; --&gt;</lineannotation>
    <lineannotation>&lt;!-- &lt;transaction-support&gt;LocalTransaction&lt;/transaction-support&gt; --&gt;</lineannotation>
    &lt;transaction-support&gt;XATransaction&lt;/transaction-support&gt;

  &lt;resourceadapter&gt;

&lt;connector&gt;</programlisting>

    <para>For global transactions, you can use Spring's generic transaction
    infrastructure to demarcate transactions, with
    <classname>JtaTransactionManager</classname> as backend (delegating to the
    Java EE server's distributed transaction coordinator underneath).</para>

    <para>For local transactions on a single CCI
    <interfacename>ConnectionFactory</interfacename>, Spring provides a
    specific transaction management strategy for CCI, analogous to the
    <classname>DataSourceTransactionManager</classname> for JDBC. The CCI API
    defines a local transaction object and corresponding local transaction
    demarcation methods. Spring's
    <classname>CciLocalTransactionManager</classname> executes such local CCI
    transactions, fully compliant with Spring's generic
    <interfacename>PlatformTransactionManager</interfacename>
    abstraction.</para>

    <programlisting language="xml">&lt;jee:jndi-lookup id="eciConnectionFactory" jndi-name="eis/cicseci"/&gt;

&lt;bean id="eciTransactionManager"
    class="org.springframework.jca.cci.connection.CciLocalTransactionManager"&gt;
  &lt;property name="connectionFactory" ref="eciConnectionFactory"/&gt;
&lt;/bean&gt;</programlisting>

    <para>Both transaction strategies can be used with any of Spring's
    transaction demarcation facilities, be it declarative or programmatic.
    This is a consequence of Spring's generic
    <interfacename>PlatformTransactionManager</interfacename> abstraction,
    which decouples transaction demarcation from the actual execution
    strategy. Simply switch between
    <classname>JtaTransactionManager</classname> and
    <classname>CciLocalTransactionManager</classname> as needed, keeping your
    transaction demarcation as-is.</para>

    <para>For more information on Spring's transaction facilities, see the
    chapter entitled <xref linkend="transaction" />.</para>
  </section>
</chapter>
