Coverage Report - ca.uhn.hl7v2.validation.AbstractValidator
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractValidator
39%
37/93
32%
19/58
3.357
 
 1  
 /**
 2  
 The contents of this file are subject to the Mozilla Public License Version 1.1 
 3  
 (the "License"); you may not use this file except in compliance with the License. 
 4  
 You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
 5  
 Software distributed under the License is distributed on an "AS IS" basis, 
 6  
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
 7  
 specific language governing rights and limitations under the License. 
 8  
 
 9  
 The Original Code is "AbstractValidator.java".  Description: 
 10  
 "Abstract implementation of a message validator." 
 11  
 
 12  
 The Initial Developer of the Original Code is University Health Network. Copyright (C) 
 13  
 2012.  All Rights Reserved. 
 14  
 
 15  
 Contributor(s): ______________________________________. 
 16  
 
 17  
 Alternatively, the contents of this file may be used under the terms of the 
 18  
 GNU General Public License (the "GPL"), in which case the provisions of the GPL are 
 19  
 applicable instead of those above.  If you wish to allow use of your version of this 
 20  
 file only under the terms of the GPL and not to allow others to use your version 
 21  
 of this file under the MPL, indicate your decision by deleting  the provisions above 
 22  
 and replace  them with the notice and other provisions required by the GPL License.  
 23  
 If you do not delete the provisions above, a recipient may use your version of 
 24  
 this file under either the MPL or the GPL. 
 25  
  */
 26  
 package ca.uhn.hl7v2.validation;
 27  
 
 28  
 import java.util.ArrayList;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 
 32  
 import org.slf4j.Logger;
 33  
 import org.slf4j.LoggerFactory;
 34  
 
 35  
 import ca.uhn.hl7v2.HL7Exception;
 36  
 import ca.uhn.hl7v2.Location;
 37  
 import ca.uhn.hl7v2.model.Composite;
 38  
 import ca.uhn.hl7v2.model.Message;
 39  
 import ca.uhn.hl7v2.model.Primitive;
 40  
 import ca.uhn.hl7v2.model.Segment;
 41  
 import ca.uhn.hl7v2.model.Structure;
 42  
 import ca.uhn.hl7v2.model.Type;
 43  
 import ca.uhn.hl7v2.model.Varies;
 44  
 import ca.uhn.hl7v2.util.ReadOnlyMessageIterator;
 45  
 import ca.uhn.hl7v2.util.Terser;
 46  
 
 47  
 /**
 48  
  * Abstract implementation of a message validator.
 49  
  * 
 50  
  * @param <R> The type parameter R denotes the result type of the validation
 51  
  *            process.
 52  
  * 
 53  
  * @author Christian Ohr
 54  
  */
 55  1365
 public abstract class AbstractValidator<R> implements Validator<R> {
 56  
 
 57  5
         private static final Logger LOG = LoggerFactory.getLogger(AbstractValidator.class);
 58  
 
 59  
         private boolean validatePrimitives;
 60  
 
 61  
         /**
 62  
          * Turns validating primtives on and off (default). Note that primitive validation
 63  
          * will significantly slow down the validation process.
 64  
          *
 65  
          * @param validatePrimitives true if primitive fields shall be validated, false if not
 66  
          */
 67  
         public void setValidatePrimitives(boolean validatePrimitives) {
 68  0
                 this.validatePrimitives = validatePrimitives;
 69  0
         }
 70  
 
 71  
         /**
 72  
          * @return true if primitive fields shall be validated, false if not
 73  
          */
 74  
         public boolean isValidatePrimitives() {
 75  5623
                 return validatePrimitives;
 76  
         }
 77  
 
 78  
         /**
 79  
          * Calls {@link #initializeHandler()} to obtain a default instance of a
 80  
          * {@link ValidationExceptionHandler} before starting the validation.
 81  
          * 
 82  
          * @see ca.uhn.hl7v2.validation.Validator#validate(ca.uhn.hl7v2.model.Message)
 83  
          */
 84  
         public R validate(Message message) throws HL7Exception {
 85  20
                 return validate(message, initializeHandler());
 86  
         }
 87  
 
 88  
         /**
 89  
          * @see ca.uhn.hl7v2.validation.Validator#validate(ca.uhn.hl7v2.model.Message,
 90  
          *      ca.uhn.hl7v2.validation.ValidationExceptionHandler)
 91  
          */
 92  
         public R validate(Message message, ValidationExceptionHandler<R> handler) throws HL7Exception {
 93  5623
                 if (message == null) {
 94  0
                         throw new NullPointerException("Message may not be null");
 95  
                 }
 96  5623
                 if (handler == null) {
 97  0
                         throw new NullPointerException("ValidationExceptionHandler may not be null");
 98  
                 }
 99  5623
                 handler.setValidationSubject(message);
 100  5623
                 if (isValidatePrimitives()) testPrimitiveRules(message, handler);
 101  5623
                 testMessageRules(message, handler);
 102  5623
                 return handler.result();
 103  
         }
 104  
 
 105  
         private void testMessageRules(Message message, ValidationExceptionHandler<R> handler)
 106  
                         throws HL7Exception {
 107  5623
                 Terser t = new Terser(message);
 108  5623
                 String messageType = t.get("MSH-9-1");
 109  5623
                 String triggerEvent = t.get("MSH-9-2");
 110  5623
                 List<MessageRule> rules = new ArrayList<MessageRule>();
 111  5623
                 if (getValidationContext() != null) {
 112  5623
                         rules.addAll(getValidationContext().getMessageRules(message.getVersion(), messageType,
 113  
                                         triggerEvent));
 114  
                 }
 115  5623
                 LOG.debug("Validating message against {} message rules", rules.size());
 116  5623
                 for (MessageRule rule : rules) {
 117  10046
                         ValidationException[] ex = rule.apply(message);
 118  10046
                         if (ex != null && ex.length > 0) {
 119  45
                                 handler.onExceptions(ex);
 120  
                         }
 121  10046
                 }
 122  5623
         }
 123  
 
 124  
         private void testPrimitiveRules(Message message, ValidationExceptionHandler<R> handler)
 125  
                         throws HL7Exception {
 126  0
                 LOG.debug("Validating message against primitive type rules");
 127  0
                 for (Iterator<Structure> iter = ReadOnlyMessageIterator
 128  0
                                 .createPopulatedSegmentIterator(message); iter.hasNext();) {
 129  0
                         Segment s = (Segment) iter.next();
 130  0
                         for (int field = 1; field <= s.numFields(); field++) {
 131  0
                                 Type[] t = s.getField(field);
 132  0
                                 for (int rep = 0; rep < t.length; rep++) {
 133  0
                                         Location location = new Location();
 134  0
                                         location
 135  0
                                             .withSegmentName(s.getName())
 136  0
                                             .withField(field)
 137  0
                                             .withFieldRepetition(rep);
 138  0
                                         testType(t[rep], handler, location);
 139  
                                 }
 140  
                         }
 141  0
                 }
 142  0
         }
 143  
 
 144  
         private void testType(Type type, ValidationExceptionHandler<R> handler, Location l) {
 145  0
                 if (type instanceof Composite) {
 146  0
                         Type[] components = ((Composite) type).getComponents();
 147  0
                         for (int comp = 0; comp < components.length; comp++) {
 148  0
                                 Location location = new Location(l).withComponent(comp + 1);
 149  0
                                 testComponent(components[comp], handler, location);
 150  
                         }
 151  0
                 } else if (type instanceof Varies) {
 152  0
                         testType(((Varies) type).getData(), handler, l);
 153  
                 } else {
 154  0
                         testPrimitive((Primitive) type, handler, l);
 155  
                 }
 156  0
         }
 157  
 
 158  
         private void testComponent(Type type, ValidationExceptionHandler<R> handler, Location l) {
 159  0
                 if (type instanceof Composite) {
 160  0
                         Type[] component = ((Composite) type).getComponents();
 161  0
                         for (int sub = 0; sub < component.length; sub++) {
 162  0
                                 Location location = new Location(l).withSubcomponent(sub + 1);
 163  0
                                 testSubComponent(component[sub], handler, location);
 164  
                         }
 165  0
                 } else if (type instanceof Varies) {
 166  0
                         testComponent(((Varies) type).getData(), handler, l);
 167  
                 } else {
 168  0
                         testPrimitive((Primitive) type, handler, l);
 169  
                 }
 170  0
         }
 171  
 
 172  
         private void testSubComponent(Type type, ValidationExceptionHandler<R> handler, Location l) {
 173  0
                 if (type instanceof Primitive) {
 174  0
                         testPrimitive((Primitive) type, handler, l);
 175  0
                 } else if (type instanceof Varies) {
 176  0
                         testSubComponent(((Varies) type).getData(), handler, l);
 177  
                 }
 178  0
         }
 179  
 
 180  
         private void testPrimitive(Primitive p, ValidationExceptionHandler<R> handler, Location l) {
 181  0
                 List<PrimitiveTypeRule> rules = new ArrayList<PrimitiveTypeRule>();
 182  0
                 Message m = p.getMessage();
 183  0
                 if (getValidationContext() != null) {
 184  0
                         rules.addAll(getValidationContext().getPrimitiveRules(m.getVersion(), p.getName(), p));
 185  
                 }
 186  0
                 for (PrimitiveTypeRule rule : rules) {
 187  0
                         ValidationException[] exceptions = rule.apply(p.getValue());
 188  0
                         for (ValidationException ve : exceptions) {
 189  0
                 ve.setLocation(l);
 190  
                         }
 191  0
                         if (exceptions.length > 0) {
 192  0
                                 handler.onExceptions(exceptions);
 193  
                         }
 194  0
                 }
 195  0
         }
 196  
 
 197  
         /**
 198  
          * Calls {@link #initializeHandler()} to obtain a default instance of a
 199  
          * {@link ValidationExceptionHandler} before starting the validation.
 200  
          * 
 201  
          * @see ca.uhn.hl7v2.validation.Validator#validate(Message,
 202  
          *      ValidationExceptionHandler)
 203  
          */
 204  
         public R validate(String message, boolean isXML, String version) throws HL7Exception {
 205  10
                 return validate(message, isXML, version, initializeHandler());
 206  
         }
 207  
 
 208  
         /**
 209  
          * @see ca.uhn.hl7v2.validation.Validator#validate(java.lang.String,
 210  
          *      boolean, java.lang.String,
 211  
          *      ca.uhn.hl7v2.validation.ValidationExceptionHandler)
 212  
          */
 213  
         public R validate(String message, boolean isXML, String version,
 214  
                         ValidationExceptionHandler<R> handler) throws HL7Exception {
 215  5640
                 if (message == null) {
 216  0
                         throw new NullPointerException("Message may not be null");
 217  
                 }
 218  5640
                 if (handler == null) {
 219  0
                         throw new NullPointerException("ValidationExceptionHandler may not be null");
 220  
                 }
 221  5640
                 handler.setValidationSubject(message);
 222  5640
                 List<EncodingRule> rules = new ArrayList<EncodingRule>();
 223  5640
                 if (getValidationContext() != null) {
 224  5640
                         rules.addAll(getValidationContext().getEncodingRules(version, isXML ? "XML" : "ER7"));
 225  
                 }
 226  5640
                 LOG.debug("Validating message against {} encoding rules", rules.size());
 227  5640
                 for (EncodingRule rule : rules) {
 228  30
                         ValidationException[] ex = rule.apply(message);
 229  30
                         if (ex != null && ex.length > 0) {
 230  15
                                 handler.onExceptions(ex);
 231  
                         }
 232  30
                 }
 233  5640
                 return handler.result();
 234  
         }
 235  
 
 236  
         protected abstract ValidationContext getValidationContext();
 237  
 
 238  
         protected abstract ValidationExceptionHandler<R> initializeHandler();
 239  
 
 240  
 }