001package ca.uhn.hl7v2.hoh.encoder;
002
003import java.util.HashMap;
004import java.util.Map;
005import java.util.StringTokenizer;
006import java.util.regex.Matcher;
007import java.util.regex.Pattern;
008
009import ca.uhn.hl7v2.AcknowledgmentCode;
010
011import static ca.uhn.hl7v2.AcknowledgmentCode.*;
012
013public enum ResponseCode {
014
015        HTTP_200_OK(200, "OK"),
016
017        HTTP_400_BAD_REQUEST(400, "Bad Request"),
018
019        HTTP_500_INTERNAL_SERVER_ERROR(500, "Internal Server Error"), ;
020
021        private int myCode;
022        private String myMessage;
023        private static final Map<AcknowledgmentCode, ResponseCode> ourAckCodesToResponseCodes = new HashMap<AcknowledgmentCode, ResponseCode>();
024        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseCode.class);
025
026        static {
027                /*
028                 * As of a decision by the HL7 ITS working group, all HL7
029                 * response codes now map to HTTP 200.
030                 */
031                ourAckCodesToResponseCodes.put(AA, HTTP_200_OK);
032                ourAckCodesToResponseCodes.put(CA, HTTP_200_OK);
033                ourAckCodesToResponseCodes.put(AR, HTTP_200_OK);
034                ourAckCodesToResponseCodes.put(CR, HTTP_200_OK);
035                ourAckCodesToResponseCodes.put(AE, HTTP_200_OK);
036                ourAckCodesToResponseCodes.put(CE, HTTP_200_OK);
037        }
038
039        ResponseCode(int theCode, String theMessage) {
040                myCode = theCode;
041                myMessage = theMessage;
042        }
043
044        /**
045         * Returns the appropriate response code for a given ACK code. If none can
046         * be detected, returns {@link #HTTP_500_INTERNAL_SERVER_ERROR}
047         * 
048         * @param theAcknowledgementCode
049         *            The acknowledgement code, e.g. "AA", or "CE"
050         * @return The appropriate code
051         */
052        public static ResponseCode forAcknowledgementCode(String theAcknowledgementCode) {
053                ResponseCode retVal = null;
054                if (theAcknowledgementCode != null) {
055                        retVal = ourAckCodesToResponseCodes.get(AcknowledgmentCode.valueOf(theAcknowledgementCode));
056                } else {
057                        ourLog.warn("No HTTP response code defined for acknowledgement code: " + theAcknowledgementCode);
058                        retVal = ResponseCode.HTTP_500_INTERNAL_SERVER_ERROR;
059                }
060                if (retVal == null) {
061                        ourLog.warn("No HTTP response code defined for acknowledgement code: " + theAcknowledgementCode);
062                        retVal = HTTP_500_INTERNAL_SERVER_ERROR;
063                }
064                return retVal;
065        }
066
067        /**
068         * Detects the appropriate HTTP response code for a given message
069         * 
070         */
071        public static ResponseCode detect(String theRawMessage) {
072                switch (EncodingStyle.detect(theRawMessage)) {
073                case ER7:
074                default:
075                        StringTokenizer tok = new StringTokenizer(theRawMessage, "\r");
076                        while (tok.hasMoreTokens()) {
077                                String nextSegment = tok.nextToken();
078                                if (nextSegment.startsWith("MSA")) {
079                                        if (nextSegment.length() >= 6) {
080                                                String code = nextSegment.substring(4, 6);
081                                                return forAcknowledgementCode(code);
082                                        }
083                                }
084                        }
085                        ourLog.warn("Could not detect MSA.1 value in ER7 message");
086                        return HTTP_500_INTERNAL_SERVER_ERROR;
087
088                case XML:
089
090                        Pattern p = Pattern.compile("<MSA\\.1>(.*?)</MSA\\.1>");
091                        Matcher m = p.matcher(theRawMessage);
092                        if (m.find()) {
093                                String code = m.group(1);
094                                return forAcknowledgementCode(code);
095                        } else {
096                                ourLog.warn("Could not detect MSA.1 value in XML message");
097                                return ResponseCode.HTTP_500_INTERNAL_SERVER_ERROR;
098                        }
099                }
100        }
101
102        /**
103         * @return the code
104         */
105        public int getCode() {
106                return myCode;
107        }
108
109        /**
110         * @param theCode
111         *            the code to set
112         */
113        public void setCode(int theCode) {
114                myCode = theCode;
115        }
116
117        /**
118         * @return the message
119         */
120        public String getMessage() {
121                return myMessage;
122        }
123
124        /**
125         * @param theMessage
126         *            the message to set
127         */
128        public void setMessage(String theMessage) {
129                myMessage = theMessage;
130        }
131
132}