001/** 002The 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. 004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005Software distributed under the License is distributed on an "AS IS" basis, 006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007specific language governing rights and limitations under the License. 008 009The Original Code is "RuleTypeBuilder.java". Description: 010"RuleBuilder that determines which kind of rule shall be built" 011 012The Initial Developer of the Original Code is University Health Network. Copyright (C) 0132004. All Rights Reserved. 014 015Contributor(s): ______________________________________. 016 017Alternatively, the contents of this file may be used under the terms of the 018GNU General Public License (the "GPL"), in which case the provisions of the GPL are 019applicable instead of those above. If you wish to allow use of your version of this 020file only under the terms of the GPL and not to allow others to use your version 021of this file under the MPL, indicate your decision by deleting the provisions above 022and replace them with the notice and other provisions required by the GPL License. 023If you do not delete the provisions above, a recipient may use your version of 024this file under either the MPL or the GPL. 025 */ 026package ca.uhn.hl7v2.validation.builder; 027 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.Collections; 032import java.util.HashSet; 033import java.util.List; 034import java.util.Set; 035 036import ca.uhn.hl7v2.Version; 037import ca.uhn.hl7v2.validation.MessageRule; 038import ca.uhn.hl7v2.validation.PrimitiveTypeRule; 039import ca.uhn.hl7v2.validation.Rule; 040import ca.uhn.hl7v2.Severity; 041import ca.uhn.hl7v2.validation.impl.RuleBinding; 042import ca.uhn.hl7v2.validation.impl.RuleSupport; 043 044/** 045 * Defines the type of rule to be built. 046 * <p> 047 * The recursive type parameter allows the builder methods common to all subclasses (e.g. 048 * {@link #refersToSection}, {@link #active}, {@link #test}) to return their specific builder type. 049 * 050 * @author Christian Ohr 051 */ 052@SuppressWarnings("serial") 053public class RuleTypeBuilder<S extends RuleTypeBuilder<S, T>, T extends Rule<?>> extends 054 BuilderSupport { 055 056 private List<RuleBinding<? extends Rule<?>>> rules = new ArrayList<RuleBinding<? extends Rule<?>>>(); 057 private Set<Version> versions; 058 private String description; 059 private String sectionReference; 060 private boolean active = true; 061 private Severity severity = Severity.ERROR; 062 063 protected RuleTypeBuilder() { 064 super(); 065 } 066 067 protected RuleTypeBuilder(List<RuleBinding<? extends Rule<?>>> rules, Set<Version> versions) { 068 super(); 069 if (versions.size() == 0) 070 throw new IllegalArgumentException("Must specify a version"); 071 this.rules = rules; 072 this.versions = versions; 073 } 074 075 protected RuleTypeBuilder(List<RuleBinding<? extends Rule<?>>> rules, Version... versions) { 076 super(); 077 if (versions.length == 0) 078 throw new IllegalArgumentException("Must specify a version"); 079 this.rules = rules; 080 this.versions = new HashSet<Version>(Arrays.asList(versions)); 081 } 082 083 @SuppressWarnings("unchecked") 084 protected S instance() { 085 return (S) this; 086 } 087 088 protected List<RuleBinding<? extends Rule<?>>> getRules() { 089 return rules; 090 } 091 092 protected T prepareRule(T rule) { 093 if (rule instanceof RuleSupport) { 094 RuleSupport<?> rs = (RuleSupport<?>)rule; 095 if (description != null) rs.setDescription(description); 096 if (sectionReference != null) rs.setSectionReference(sectionReference); 097 rs.setSeverity(severity); 098 } 099 return rule; 100 } 101 102 /** 103 * Adds a description to the rule 104 * 105 * @param description description 106 * @return this instance to build more rules 107 */ 108 public S description(String description) { 109 this.description = description; 110 return instance(); 111 } 112 113 /** 114 * Adds a HL7 section reference to a rule 115 * 116 * @param sectionReference the section in the HL7 specification 117 * @return this instance to build more rules 118 */ 119 public S refersToSection(String sectionReference) { 120 this.sectionReference = sectionReference; 121 return instance(); 122 } 123 124 /** 125 * Sets the severity of the rule 126 * 127 * @param severity the the severity of the rule 128 * @return this instance to build more rules 129 */ 130 public S severity(Severity severity) { 131 this.severity = severity; 132 return instance(); 133 } 134 135 /** 136 * Marks the rule as being active (default) or inactive 137 * 138 * @param active true if this rule shall be active 139 * @return this instance to build more rules 140 */ 141 public S active(boolean active) { 142 this.active = active; 143 return instance(); 144 } 145 146 /** 147 * Adds the specified rule to the set of rules. 148 * 149 * @param rule the rule to be tested 150 * @return this instance to build more rules 151 */ 152 public S test(T rule) { 153 addRuleBindings(rule); 154 return instance(); 155 } 156 157 /** 158 * Builds {@link PrimitiveTypeRule}s for the specified types 159 * 160 * @param type an array of types 161 * @return this instance to continue building rules 162 */ 163 public PrimitiveRuleBuilder primitive(String... type) { 164 if (type.length == 0) { 165 throw new IllegalArgumentException("Must specify a type"); 166 } 167 return new PrimitiveRuleBuilder(rules, versions, new HashSet<String>(Arrays.asList(type))); 168 } 169 170 /** 171 * Builds {@link MessageRule}s for the specified event types and triggers 172 * 173 * @param eventType Event type, e.g. "ADT", or "*" for all types 174 * @param triggerEvent, e.g. "A01" or "*" for all trigger events 175 * @return this instance to continue building rules 176 */ 177 public MessageRuleBuilder message(String eventType, String triggerEvent) { 178 return new MessageRuleBuilder(rules, versions, eventType, triggerEvent); 179 } 180 181 /** 182 * Builds {@link MessageRule}s for event types and triggers to be specified 183 * using the returned MessageExpressionBuilder. 184 * 185 * @return MessageExpressionBuilder instance to continue building rules 186 */ 187 public MessageExpressionBuilder message() { 188 return new MessageExpressionBuilder(); 189 } 190 191 /** 192 * Builds {@link MessageRule}s for the specified encoding 193 * 194 * @param encoding "XML" or "VB" 195 * @return this instance to continue building rules 196 */ 197 public EncodingRuleBuilder encoding(String encoding) { 198 return new EncodingRuleBuilder(rules, versions, encoding); 199 } 200 201 /** 202 * Add {@link RuleBinding}s for the rule that have been built 203 * 204 * @param rule the rule for which bindings shall be added 205 */ 206 protected void addRuleBindings(T rule) { 207 if (Version.allVersions(versions)) { 208 // Save some bindings when all HL7 versions are affected 209 rules.addAll(getRuleBindings(rule, "*")); 210 } else { 211 for (Version version : versions) { 212 rules.addAll(getRuleBindings(rule, version.getVersion())); 213 } 214 } 215 } 216 217 /** 218 * Builder implementation must overwrite this method to return all {@link RuleBinding}s for 219 * rules that have been built. 220 * 221 * @param rule the rule for which bindings shall be retrieved 222 * @param version the HL7 version for which bindings shall be retrieved 223 * @return a collection of {@link RuleBinding}s 224 */ 225 @SuppressWarnings("unchecked") 226 protected Collection<RuleBinding<T>> getRuleBindings(T rule, String version) { 227 return (Collection<RuleBinding<T>>) Collections.EMPTY_LIST; 228 } 229 230 protected Collection<RuleBinding<T>> activate(Collection<RuleBinding<T>> bindings) { 231 for (RuleBinding<T> ruleBinding : bindings) { 232 ruleBinding.setActive(active); 233 } 234 return bindings; 235 } 236 237 // for tests only 238 Set<Version> getVersions() { 239 return versions; 240 } 241 242 /** 243 * Helper builder when the versions are not given explicitly but in form of an expression. 244 */ 245 public class MessageExpressionBuilder { 246 247 /** 248 * Applies {@link MessageRule}s for all event types and trigger events 249 * @return rule builder 250 */ 251 public MessageRuleBuilder all() { 252 return new MessageRuleBuilder(rules, versions, "*", "*"); 253 } 254 255 /** 256 * Applies {@link MessageRule}s for all trigger events of a given event type 257 * @param eventType event type, e.g. "ADT" 258 * @return rule builder 259 */ 260 public MessageRuleBuilder allOfEventType(String eventType) { 261 return new MessageRuleBuilder(rules, versions, eventType, "*"); 262 } 263 264 } 265 266}