Coverage Report - ca.uhn.hl7v2.protocol.impl.InitiatorImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
InitiatorImpl
81%
48/59
88%
16/18
1.6
 
 1  
 /*
 2  
  * Created on 3-May-2004
 3  
  */
 4  
 package ca.uhn.hl7v2.protocol.impl;
 5  
 
 6  
 import java.util.ArrayList;
 7  
 import java.util.HashMap;
 8  
 import java.util.List;
 9  
 import java.util.Map;
 10  
 
 11  
 import ca.uhn.hl7v2.HL7Exception;
 12  
 import ca.uhn.hl7v2.model.Message;
 13  
 import ca.uhn.hl7v2.parser.GenericParser;
 14  
 import ca.uhn.hl7v2.parser.Parser;
 15  
 import ca.uhn.hl7v2.protocol.Initiator;
 16  
 import ca.uhn.hl7v2.protocol.Processor;
 17  
 import ca.uhn.hl7v2.protocol.Transportable;
 18  
 import ca.uhn.hl7v2.util.Terser;
 19  
 
 20  
 /**
 21  
  * Default implementation of <code>Initiator</code>. 
 22  
  * 
 23  
  * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
 24  
  * @version $Revision: 1.1 $ updated on $Date: 2007-02-19 02:24:26 $ by $Author: jamesagnew $
 25  
  */
 26  
 public class InitiatorImpl implements Initiator {
 27  
 
 28  
     private final List<String> myMetadataFields;
 29  
     private final Parser myParser;
 30  
     private final Processor myProcessor;
 31  
     private int myMaxRetries;
 32  
     private long myRetryInterval;
 33  
     private long myReceiveTimeout;
 34  
     
 35  
     /**
 36  
      * Creates an instance that uses a <code>GenericParser</code>
 37  
      * @param theProcessor the <code>Processor</code> used to communicate 
 38  
      *  with the remote system
 39  
      */
 40  30
     public InitiatorImpl(Processor theProcessor) {
 41  30
         myMetadataFields = new ArrayList<String>(20);
 42  30
         myMetadataFields.add("MSH-18"); //add character set by default
 43  30
         myParser = new GenericParser();
 44  30
         myProcessor = theProcessor;
 45  30
         init();
 46  30
     }
 47  
     
 48  
     /**
 49  
      * Creates an instance that uses the given <code>Parser</code>
 50  
      * @param theParser parser to use for parsing and encoding messages
 51  
      * @param theProcessor the <code>Processor</code> used to communicate 
 52  
      *  with the remote system
 53  
      */
 54  0
     public InitiatorImpl(Parser theParser, Processor theProcessor) {
 55  0
         myMetadataFields = new ArrayList<String>(20);
 56  0
         myParser = theParser;
 57  0
         myProcessor = theProcessor;
 58  0
         init();
 59  0
     }
 60  
     
 61  
     private void init() {
 62  30
         myMaxRetries = 3;
 63  30
         myRetryInterval = 3000;
 64  30
         myReceiveTimeout = 10000;
 65  30
     }
 66  
     
 67  
     
 68  
     /**
 69  
      * @param theMaxRetries max number of retries for initial message delivery 
 70  
      */
 71  
     public void setMaxRetries(int theMaxRetries) {
 72  0
         myMaxRetries = theMaxRetries;
 73  0
     }
 74  
     
 75  
     public int getMaxRetries() {
 76  25
         return myMaxRetries;
 77  
     }
 78  
     
 79  
     /**
 80  
      * @param theRetryIntervalMillis milliseconds between retries of message delivery 
 81  
      */
 82  
     public void setRetryInterval(long theRetryIntervalMillis) {
 83  0
         myRetryInterval = theRetryIntervalMillis;
 84  0
     }
 85  
     
 86  
     public long getRetryInterval() {
 87  25
         return myRetryInterval;
 88  
     }
 89  
     
 90  
     /**
 91  
      * @param theReceiveTimeout the length of time we wait for responses (defaults 
 92  
      *      to 10 seconds)
 93  
      */
 94  
     public void setReceiveTimeout(long theReceiveTimeout) {
 95  20
         myReceiveTimeout = theReceiveTimeout;
 96  20
     }
 97  
     
 98  
     public long getReceiveTimeout() {
 99  40
         return myReceiveTimeout;
 100  
     }
 101  
     
 102  
     /**
 103  
      * @see ca.uhn.hl7v2.protocol.Initiator#sendAndReceive(ca.uhn.hl7v2.model.Message)
 104  
      */
 105  
     public Message sendAndReceive(Message theMessage) throws HL7Exception {
 106  25
         Terser t = new Terser(theMessage);
 107  25
         String appAckNeeded = t.get("/MSH-16");
 108  25
         String msgId = t.get("/MSH-10");
 109  
         
 110  25
         String messageText = getParser().encode(theMessage);
 111  25
         Map<String, Object> metadata = getMetadata(theMessage);
 112  25
         Transportable out = new TransportableImpl(messageText, metadata);
 113  
         
 114  25
         if (needAck(appAckNeeded)) {
 115  20
             myProcessor.reserve(msgId, getReceiveTimeout());
 116  
         }
 117  
         
 118  25
         myProcessor.send(out, getMaxRetries(), getRetryInterval());
 119  
         
 120  25
         Message in = null;
 121  25
         if (needAck(appAckNeeded)) { 
 122  20
             Transportable received = myProcessor.receive(msgId, getReceiveTimeout());
 123  20
             if (received != null && received.getMessage() != null) {
 124  10
                 in = getParser().parse(received.getMessage());
 125  
             }
 126  
         }
 127  
         
 128  25
         return in;
 129  
     }
 130  
     
 131  
     /**
 132  
      * @param theAckCode from MSH-16
 133  
      * @return true if the code indicates that we should wait for an ACK and try 
 134  
      *      to return it to the caller 
 135  
      */
 136  
     private boolean needAck(String theAckCode) {
 137  50
         boolean need = false;
 138  50
         if (theAckCode == null 
 139  40
             || theAckCode.equals("") 
 140  40
             || theAckCode.equals(Processor.AL) 
 141  20
             || theAckCode.equals(Processor.ER)) 
 142  
         {
 143  40
             need = true; 
 144  
         }        
 145  50
         return need;
 146  
     }
 147  
     
 148  
     private Map<String, Object> getMetadata(Message theMessage) throws HL7Exception {
 149  25
         Map<String, Object> md = new HashMap<String, Object>();
 150  25
         Terser t = new Terser(theMessage);
 151  
 
 152  
         //snapshot so concurrent changes won't break our iteration
 153  25
         String[] fields = getMetadataFields().toArray(new String[0]);
 154  
         
 155  50
         for (int i = 0; i < fields.length; i++) {
 156  25
             String field = fields[i].toString();
 157  25
             String val = t.get(field); 
 158  25
             md.put(field, val);
 159  
         }
 160  
         
 161  25
         return md;
 162  
     }
 163  
 
 164  
     /** 
 165  
      * @see ca.uhn.hl7v2.protocol.Initiator#getParser()
 166  
      */
 167  
     public Parser getParser() {
 168  35
         return myParser;
 169  
     }
 170  
 
 171  
     /** 
 172  
      * @see ca.uhn.hl7v2.protocol.Initiator#getUnderlyingProcessor()
 173  
      */
 174  
     public Processor getUnderlyingProcessor() {
 175  0
         return myProcessor;
 176  
     }
 177  
 
 178  
     /**
 179  
      * @see ca.uhn.hl7v2.protocol.Initiator#getMetadataFields()
 180  
      */
 181  
     public List<String> getMetadataFields() {
 182  25
         return myMetadataFields;
 183  
     }
 184  
 
 185  
 
 186  
 }