== GroupSelector

Having a configuration like this: 
[source,xml]
------
  <txnmgr ...>
   <participant A />
   <participant B />
   <participant C />
   <participant D />
   ...
  </txnmgr>
------

may be good for some small applications, but you risk ending up having to
configure multiple transaction managers for different classes of transactions
(e.g., network management, authorization, draft capture, etc.) or add
complexity to participants in order to operate or do nothing depending
on the transation type.

In order to simplify the TransactionManager configuration, we've added a very
simple interface called +GroupSelector+: 

[source,java]
-------------

    public interface GroupSelector extends TransactionParticipant {
        public String select (long id, Serializable context);
    }
 
-------------

A participant implementing the +GroupSelector+ interface can modify the flow of
a transaction by returning a space-separated list of group names (or can
specify 'null' to signify no action). 

Our Q2-based TransactionManager reference implementation supports this
interface and lets you design your own configuration file with a structure
like this: 

[source,xml]
------------

  <txnmgr ...>
   <participant A />
   <participant B />
   ...
   ...
   <group name="GroupA">
    <participant A />
    <participant B />
    <participant C />
   </group>
   <group name="GroupB">
    <participant J />
    <participant K />
    <participant L />
   </group>
   <group name="GroupC">
    <participant X />
    <participant Y />
    <participant Z />
   </group>
   ...
   ...
  </txnmgr>
------------

.Sample GroupSelector implementation
====
[source,java]
----

    public class Switch implements GroupSelector {
        public int  prepare (long id, Serializable context) {
            return PREPARED | READONLY | NO_JOIN;
        }
        public void commit   (long id, Serializable context) { }
        public void abort    (long id, Serializable context) { }
        public String select (long id, Serializable context) {
            try {
                ISOMsg m = (ISOMsg) ((Context)context).get (ISOMSG);
                String groups = cfg.get (m.getMTI(), null);
                return groups;
            } catch (Exception e) {
                warn (e);
                return null;
            }
        }
    }
  
----
====

By using the +Switch+ presented in the previous example, you can write a
TransactionManager configuration file like this: 

[source,xml]
----
   ...
   ...
   <participant class="org.jpos.my.Switch" logger="Q2">
    <property name="0100" value="Authorization Response Log" />
    <property name="0200" value="Financial Response Log" />
    <property name="0220" value="Notification Response Log" />
    <property name="0221" value="Notification Response Log" />
    <property name="0420" value="Reversal Response Log" />
    <property name="0421" value="Reversal Response Log" />
    <property name="0500" value="BatchManagement Response Log" />
    <property name="0421" value="Reversal Response Log" />
    <property name="0800" value="NetworkManagement Response Log" />
   </participant>
   ...
   ...
   <group name="Financial">
    <participant class="com.my.company.CheckRequiredFields">
     <property name="fields" value="0,3,4,17,49,32,41,43,37,PAN,AMOUNT" />
    </participant>
    <participant class="com.my.company.CheckCurrency" />
    ...
    ...
   </group>

   <group name="Reversal">
    ...
    ...
   </group>
   ...
   ...
  
----

Using the previous approach, the application can be designed using small
reusable participants. Moreover, using XML entity expansion, the resulting
configuration file can be very readable.

We have found it very useful to have very small participants to perform tasks
like: Debug the context; introduce Delays (during testing); Open  and Close 
O/R mapping sessions, etc. 

