001    /*
002     * Created on 21-Apr-2004
003     */
004    package ca.uhn.hl7v2.protocol.impl;
005    
006    import java.io.IOException;
007    import java.util.ArrayList;
008    import java.util.StringTokenizer;
009    
010    import ca.uhn.hl7v2.HL7Exception;
011    import ca.uhn.hl7v2.model.Message;
012    import ca.uhn.hl7v2.parser.Parser;
013    import ca.uhn.log.HapiLog;
014    import ca.uhn.log.HapiLogFactory;
015    
016    /**
017     * A debugging utility that logs raw messages and parsed/encoded versions, and warnings about 
018     * apparent discrepancies between them.  This information is all logged to HapiLog under 
019     * the name of this class, at the "info" level.  
020     * 
021     * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
022     * @version $Revision: 1.1 $ updated on $Date: 2007/02/19 02:24:26 $ by $Author: jamesagnew $
023     */
024    public class ParseChecker {
025    
026        private static final HapiLog log = HapiLogFactory.getHapiLog(ParseChecker.class);
027    
028        /**
029         * Encodes the given message and compares it to the given string.  Any differences
030         * are noted in the file [hapi.home]/parse_check.txt.  Ignores extra field delimiters.
031         */
032        public static void checkParse(String originalMessageText, Message parsedMessage, Parser parser)
033                throws HL7Exception, IOException {
034            log.info("ParseChecker is checking parse integrity (turn this off if you are not testing)");
035            String newMessageText = parser.encode(parsedMessage);
036            
037            log.info("******************* Comparing Messages ****************\r\n");
038            log.info("Original:           " + originalMessageText + "\r\n");
039            log.info("Parsed and Encoded: " + newMessageText + "\r\n");
040            
041            if (!originalMessageText.equals(newMessageText)) {
042                //check each segment
043                StringTokenizer tok = new StringTokenizer(originalMessageText, "\r");
044                ArrayList one = new ArrayList();
045                while (tok.hasMoreTokens()) {
046                    String seg = tok.nextToken();
047                    if (seg.length() > 4)
048                        one.add(seg);
049                }
050                tok = new StringTokenizer(newMessageText, "\r");
051                ArrayList two = new ArrayList();
052                while (tok.hasMoreTokens()) {
053                    String seg = tok.nextToken();
054                    if (seg.length() > 4)
055                        two.add(stripExtraDelimiters(seg, seg.charAt(3)));
056                }
057                
058                if (one.size() != two.size()) {
059                    log.info("Warning: inbound and parsed messages have different numbers of segments: \r\n");
060                    log.info("Original: " + originalMessageText + "\r\n");
061                    log.info("Parsed:   " + newMessageText + "\r\n");
062                }
063                else {
064                    //check each segment
065                    for (int i = 0; i < one.size(); i++) {
066                        String origSeg = (String) one.get(i);
067                        String newSeg = (String) two.get(i);
068                        if (!origSeg.equals(newSeg)) {
069                            log.info("Warning: inbound and parsed message segment differs: \r\n");
070                            log.info("Original: " + origSeg + "\r\n");
071                            log.info("Parsed: " + newSeg + "\r\n");
072                        }
073                    }
074                }
075            }
076            else {
077                log.info("No differences found\r\n");
078            }
079            
080            log.info("********************  End Comparison  ******************\r\n");
081            
082        }
083        
084        /**
085         * Removes unecessary delimiters from the end of a field or segment.
086         * This is cut-and-pasted from PipeParser (just making it public in
087         * PipeParser would kind of cloud the purpose of PipeParser).
088         */
089        private static String stripExtraDelimiters(String in, char delim) {
090            char[] chars = in.toCharArray();
091            
092            //search from back end for first occurance of non-delimiter ...
093            int c = chars.length - 1;
094            boolean found = false;
095            while (c >= 0 && !found) {
096                if (chars[c--] != delim)
097                    found = true;
098            }
099            
100            String ret = "";
101            if (found)
102                ret = String.valueOf(chars, 0, c + 2);
103            return ret;
104        }
105        
106        
107    }