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