001    /**
002    The contents of this file are subject to the Mozilla Public License Version 1.1 
003    (the "License"); you may not use this file except in compliance with the License. 
004    You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005    Software distributed under the License is distributed on an "AS IS" basis, 
006    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007    specific language governing rights and limitations under the License. 
008    
009    The Original Code is "MessageValidator.java".  Description: 
010    "Validates parsed message against MessageRules that are enabled according to runtime 
011     configuration information."
012     
013    The Initial Developer of the Original Code is University Health Network. Copyright (C) 
014    2002.  All Rights Reserved. 
015    
016    Contributor(s): ______________________________________. 
017    
018    Alternatively, the contents of this file may be used under the terms of the 
019    GNU General Public License (the  "GPL"), in which case the provisions of the GPL are 
020    applicable instead of those above.  If you wish to allow use of your version of this 
021    file only under the terms of the GPL and not to allow others to use your version 
022    of this file under the MPL, indicate your decision by deleting  the provisions above 
023    and replace  them with the notice and other provisions required by the GPL License.  
024    If you do not delete the provisions above, a recipient may use your version of 
025    this file under either the MPL or the GPL. 
026    */
027    
028    package ca.uhn.hl7v2.validation;
029    
030    import ca.uhn.hl7v2.HL7Exception;
031    import ca.uhn.hl7v2.model.Message;
032    import ca.uhn.hl7v2.util.Terser;
033    import ca.uhn.log.HapiLog;
034    import ca.uhn.log.HapiLogFactory;
035    
036    /**
037     * Validation utilities for parsed and encoded messages.  
038     *  
039     * @author Bryan Tripp
040     */
041    public class MessageValidator {
042    
043        private static final MessageRule[] EMPTY_MESSAGE_RULES_ARRAY = new MessageRule[0];
044        private static final EncodingRule[] EMPTY_ENCODING_RULES_ARRAY = new EncodingRule[0];
045            private static final HapiLog ourLog = HapiLogFactory.getHapiLog(MessageValidator.class);
046        
047        private ValidationContext myContext;
048        private boolean failOnError;
049    
050        /**
051         * @param theContext context that determines which validation rules apply 
052         * @param theFailOnErrorFlag
053         */
054        public MessageValidator(ValidationContext theContext, boolean theFailOnErrorFlag) {
055            myContext = theContext;
056            failOnError = theFailOnErrorFlag;
057        }
058        
059        /**
060         * @param message a parsed message to validate (note that MSH-9-1 and MSH-9-2 must be valued)
061         * @return true if the message is OK
062         * @throws HL7Exception if there is at least one error and this validator is set to fail on errors
063         */
064        public boolean validate(Message message) throws HL7Exception {
065            Terser t = new Terser(message);
066            
067            MessageRule[] rules = EMPTY_MESSAGE_RULES_ARRAY;
068            if (myContext != null) {
069                    rules = myContext.getMessageRules(message.getVersion(), t.get("MSH-9-1"), t.get("MSH-9-2"));
070            }
071            
072            ValidationException toThrow = null;
073            boolean result = true;
074            for (int i = 0; i < rules.length; i++) {
075                ValidationException[] ex = rules[i].test(message);
076                for (int j = 0; j < ex.length; j++) {
077                    result = false;
078                    ourLog.error("Invalid message", ex[j]);
079                    if (failOnError && toThrow == null) {
080                        toThrow = ex[j];
081                    }
082                }
083            }
084            
085            if (toThrow != null) {
086                throw new HL7Exception("Invalid message", toThrow);
087            }
088            
089            return result;
090        }
091        
092        /**
093         * @param message an ER7 or XML encoded message to validate 
094         * @param isXML true if XML, false if ER7
095         * @param version HL7 version (e.g. "2.2") to which the message belongs
096         * @return true if the message is OK
097         * @throws HL7Exception if there is at least one error and this validator is set to fail on errors
098         */
099        public boolean validate(String message, boolean isXML, String version) throws HL7Exception {
100            
101            EncodingRule[] rules = EMPTY_ENCODING_RULES_ARRAY;
102            if (myContext != null) {
103                    rules = myContext.getEncodingRules(version, isXML ? "XML" : "ER7");
104            }
105            
106            ValidationException toThrow = null;
107            boolean result = true;
108            for (int i = 0; i < rules.length; i++) {
109                ValidationException[] ex = rules[i].test(message);
110                for (int j = 0; j < ex.length; j++) {
111                    result = false;
112                    ourLog.error("Invalid message", ex[j]);
113                    if (failOnError && toThrow == null) {
114                        toThrow = ex[j];
115                    }
116                }
117            }
118            
119            if (toThrow != null) {
120                throw new HL7Exception("Invalid message", toThrow);
121            }
122    
123            return result;
124        }
125    }