Coverage Report - ca.uhn.hl7v2.validation.builder.RuleTypeBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
RuleTypeBuilder
83%
45/54
72%
13/18
1.652
RuleTypeBuilder$MessageExpressionBuilder
80%
4/5
N/A
1.652
RuleTypeBuilder$MessageExpressionBuilder$1
77%
7/9
100%
2/2
1.652
 
 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 "RuleTypeBuilder.java".  Description:
 10  
  "RuleBuilder that determines which kind of rule shall be built"
 11  
 
 12  
  The Initial Developer of the Original Code is University Health Network. Copyright (C)
 13  
  2004.  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.builder;
 27  
 
 28  
 import java.util.ArrayList;
 29  
 import java.util.Arrays;
 30  
 import java.util.Collection;
 31  
 import java.util.Collections;
 32  
 import java.util.HashSet;
 33  
 import java.util.List;
 34  
 import java.util.Set;
 35  
 
 36  
 import ca.uhn.hl7v2.HL7Exception;
 37  
 import ca.uhn.hl7v2.Version;
 38  
 import ca.uhn.hl7v2.model.Message;
 39  
 import ca.uhn.hl7v2.util.Terser;
 40  
 import ca.uhn.hl7v2.validation.MessageRule;
 41  
 import ca.uhn.hl7v2.validation.PrimitiveTypeRule;
 42  
 import ca.uhn.hl7v2.validation.Rule;
 43  
 import ca.uhn.hl7v2.Severity;
 44  
 import ca.uhn.hl7v2.validation.ValidationException;
 45  
 import ca.uhn.hl7v2.validation.impl.AbstractMessageRule;
 46  
 import ca.uhn.hl7v2.validation.impl.RuleBinding;
 47  
 import ca.uhn.hl7v2.validation.impl.RuleSupport;
 48  
 
 49  
 /**
 50  
  * Defines the type of rule to be built.
 51  
  * <p/>
 52  
  * The recursive type parameter allows the builder methods common to all subclasses (e.g.
 53  
  * {@link #refersToSection}, {@link #active}, {@link #test}) to return their specific builder type.
 54  
  *
 55  
  * @author Christian Ohr
 56  
  */
 57  
 @SuppressWarnings("serial")
 58  21720
 public class RuleTypeBuilder<S extends RuleTypeBuilder<S, T>, T extends Rule<?>> extends
 59  
         BuilderSupport {
 60  
 
 61  104630
     private List<RuleBinding<? extends Rule<?>>> rules = new ArrayList<RuleBinding<? extends Rule<?>>>();
 62  
     private Set<Version> versions;
 63  
     private String description;
 64  
     private String sectionReference;
 65  104630
     private boolean active = true;
 66  104630
     private Severity severity = Severity.ERROR;
 67  
 
 68  
     protected RuleTypeBuilder() {
 69  5875
         super();
 70  5875
     }
 71  
 
 72  
     protected RuleTypeBuilder(List<RuleBinding<? extends Rule<?>>> rules, Set<Version> versions) {
 73  76555
         super();
 74  76555
         if (versions.size() == 0)
 75  0
             throw new IllegalArgumentException("Must specify a version");
 76  76555
         this.rules = rules;
 77  76555
         this.versions = versions;
 78  76555
     }
 79  
 
 80  
     protected RuleTypeBuilder(List<RuleBinding<? extends Rule<?>>> rules, Version... versions) {
 81  22200
         super();
 82  22200
         if (versions.length == 0)
 83  0
             throw new IllegalArgumentException("Must specify a version");
 84  22200
         this.rules = rules;
 85  22200
         this.versions = new HashSet<Version>(Arrays.asList(versions));
 86  22200
     }
 87  
 
 88  
     @SuppressWarnings("unchecked")
 89  
     protected S instance() {
 90  103595
         return (S) this;
 91  
     }
 92  
 
 93  
     protected List<RuleBinding<? extends Rule<?>>> getRules() {
 94  33755
         return rules;
 95  
     }
 96  
 
 97  
     protected T prepareRule(T rule) {
 98  76445
         if (rule instanceof RuleSupport) {
 99  76445
             RuleSupport<?> rs = (RuleSupport<?>) rule;
 100  76445
             if (description != null) rs.setDescription(description);
 101  76445
             if (sectionReference != null) rs.setSectionReference(sectionReference);
 102  76445
             rs.setSeverity(severity);
 103  
         }
 104  76445
         return rule;
 105  
     }
 106  
 
 107  
     /**
 108  
      * Adds a description to the rule
 109  
      *
 110  
      * @param description description
 111  
      * @return this instance to build more rules
 112  
      */
 113  
     public S description(String description) {
 114  0
         this.description = description;
 115  0
         return instance();
 116  
     }
 117  
 
 118  
     /**
 119  
      * Adds a HL7 section reference to a rule
 120  
      *
 121  
      * @param sectionReference the section in the HL7 specification
 122  
      * @return this instance to build more rules
 123  
      */
 124  
     public S refersToSection(String sectionReference) {
 125  27075
         this.sectionReference = sectionReference;
 126  27075
         return instance();
 127  
     }
 128  
 
 129  
     /**
 130  
      * Sets the severity of the rule
 131  
      *
 132  
      * @param severity the the severity of the rule
 133  
      * @return this instance to build more rules
 134  
      */
 135  
     public S severity(Severity severity) {
 136  0
         this.severity = severity;
 137  0
         return instance();
 138  
     }
 139  
 
 140  
     /**
 141  
      * Marks the rule as being active (default) or inactive
 142  
      *
 143  
      * @param active true if this rule shall be active
 144  
      * @return this instance to build more rules
 145  
      */
 146  
     public S active(boolean active) {
 147  0
         this.active = active;
 148  0
         return instance();
 149  
     }
 150  
 
 151  
     /**
 152  
      * Adds the specified rule to the set of rules.
 153  
      *
 154  
      * @param rule the rule to be tested
 155  
      * @return this instance to build more rules
 156  
      */
 157  
     public S test(T rule) {
 158  76520
         addRuleBindings(rule);
 159  76520
         return instance();
 160  
     }
 161  
 
 162  
     /**
 163  
      * Builds {@link PrimitiveTypeRule}s for the specified types
 164  
      *
 165  
      * @param type an array of types
 166  
      * @return this instance to continue building rules
 167  
      */
 168  
     public PrimitiveRuleBuilder primitive(String... type) {
 169  65600
         if (type.length == 0) {
 170  0
             throw new IllegalArgumentException("Must specify a type");
 171  
         }
 172  65600
         return new PrimitiveRuleBuilder(rules, versions, new HashSet<String>(Arrays.asList(type)));
 173  
     }
 174  
 
 175  
     /**
 176  
      * Builds {@link MessageRule}s for the specified event types and triggers
 177  
      *
 178  
      * @param eventType      Event type, e.g. "ADT", or "*" for all types
 179  
      * @param triggerEvents, e.g. "A01" or "A01,A04", or "*" for all trigger events
 180  
      * @return this instance to continue building rules
 181  
      */
 182  
     public MessageRuleBuilder message(String eventType, String... triggerEvents) {
 183  70
         return new MessageRuleBuilder(rules, versions, eventType, triggerEvents);
 184  
     }
 185  
 
 186  
     /**
 187  
      * Builds {@link MessageRule}s for event types and triggers to be specified
 188  
      * using the returned MessageExpressionBuilder.
 189  
      *
 190  
      * @return MessageExpressionBuilder instance to continue building rules
 191  
      */
 192  
     public MessageExpressionBuilder message() {
 193  10860
         return new MessageExpressionBuilder();
 194  
     }
 195  
 
 196  
     /**
 197  
      * Builds {@link MessageRule}s for the specified encoding
 198  
      *
 199  
      * @param encoding "XML" or "VB"
 200  
      * @return this instance to continue building rules
 201  
      */
 202  
     public EncodingRuleBuilder encoding(String encoding) {
 203  25
         return new EncodingRuleBuilder(rules, versions, encoding);
 204  
     }
 205  
 
 206  
     /**
 207  
      * Add {@link RuleBinding}s for the rule that have been built
 208  
      *
 209  
      * @param rule the rule for which bindings shall be added
 210  
      */
 211  
     protected void addRuleBindings(T rule) {
 212  76520
         if (Version.allVersions(versions)) {
 213  
             // Save some bindings when all HL7 versions are affected
 214  65595
             rules.addAll(getRuleBindings(rule, "*"));
 215  
         } else {
 216  10925
             for (Version version : versions) {
 217  65075
                 rules.addAll(getRuleBindings(rule, version.getVersion()));
 218  65075
             }
 219  
         }
 220  76520
     }
 221  
 
 222  
     /**
 223  
      * Builder implementation must overwrite this method to return all {@link RuleBinding}s for
 224  
      * rules that have been built.
 225  
      *
 226  
      * @param rule    the rule for which bindings shall be retrieved
 227  
      * @param version the HL7 version for which bindings shall be retrieved
 228  
      * @return a collection of {@link RuleBinding}s
 229  
      */
 230  
     @SuppressWarnings("unchecked")
 231  
     protected Collection<RuleBinding<T>> getRuleBindings(T rule, String version) {
 232  5
         return (Collection<RuleBinding<T>>) Collections.EMPTY_LIST;
 233  
     }
 234  
 
 235  
     protected Collection<RuleBinding<T>> activate(Collection<RuleBinding<T>> bindings) {
 236  130670
         for (RuleBinding<T> ruleBinding : bindings) {
 237  174300
             ruleBinding.setActive(active);
 238  174300
         }
 239  130670
         return bindings;
 240  
     }
 241  
 
 242  
     // for tests only
 243  
     Set<Version> getVersions() {
 244  120
         return versions;
 245  
     }
 246  
 
 247  
     /**
 248  
      * Helper builder when the events are not given explicitly but in form of an expression.
 249  
      */
 250  10860
     public class MessageExpressionBuilder {
 251  
 
 252  
         /**
 253  
          * Applies {@link MessageRule}s for all event types and trigger events
 254  
          *
 255  
          * @return rule builder
 256  
          */
 257  
         public MessageRuleBuilder all() {
 258  10860
             return new MessageRuleBuilder(rules, versions, "*", "*");
 259  
         }
 260  
 
 261  
         /**
 262  
          * Applies {@link MessageRule}s for all trigger events of a given event type
 263  
          *
 264  
          * @param eventType event type, e.g. "ADT"
 265  
          * @return rule builder
 266  
          */
 267  
         public MessageRuleBuilder allOfEventType(String eventType) {
 268  0
             return new MessageRuleBuilder(rules, versions, eventType, "*");
 269  
         }
 270  
 
 271  
         /**
 272  
          * Applies a {@link MessageRule} for all event types and trigger events, checking
 273  
          * whether the message is of the specified event type and trigger event(s)
 274  
          *
 275  
          * @param triggerEvents trigger events, e.g. "A01", "A04"
 276  
          * @return rule builder
 277  
          */
 278  
         public MessageRuleBuilder rejectOtherThan(final String... triggerEvents) {
 279  15
             final Set<String> triggers = new HashSet<String>(Arrays.asList(triggerEvents));
 280  15
             return all().test(new AbstractMessageRule() {
 281  
                 public ValidationException[] apply(Message message) {
 282  
                     try {
 283  15
                         Terser t = new Terser(message);
 284  15
                         String eventType = t.get("MSH-9-1");
 285  15
                         String triggerEvent = t.get("MSH-9-2");
 286  30
                         return triggers.contains(triggerEvent) ?
 287  5
                                 passed() :
 288  10
                                 failed(eventType + "^" + triggerEvent + " is not accepted");
 289  0
                     } catch (HL7Exception e) {
 290  0
                         return failed(e);
 291  
                     }
 292  
                 }
 293  
             });
 294  
 
 295  
         }
 296  
 
 297  
     }
 298  
 }