Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
RuleTypeBuilder |
|
| 1.6521739130434783;1.652 | ||||
RuleTypeBuilder$MessageExpressionBuilder |
|
| 1.6521739130434783;1.652 | ||||
RuleTypeBuilder$MessageExpressionBuilder$1 |
|
| 1.6521739130434783;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 | } |