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 "MessageRuleBuilder.java". Description:
10 "Rule Builder for MessageRules."
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.builder;
27
28 import java.util.*;
29
30 import ca.uhn.hl7v2.Version;
31 import ca.uhn.hl7v2.model.MessageVisitorFactory;
32 import ca.uhn.hl7v2.validation.MessageRule;
33 import ca.uhn.hl7v2.validation.Rule;
34 import ca.uhn.hl7v2.validation.builder.support.*;
35 import ca.uhn.hl7v2.validation.impl.ConformanceProfileRule;
36 import ca.uhn.hl7v2.validation.impl.MessageRuleBinding;
37 import ca.uhn.hl7v2.validation.impl.RuleBinding;
38
39 /**
40 * Rule Builder for MessageRules
41 *
42 * @author Christian Ohr
43 */
44 @SuppressWarnings("serial")
45 public class MessageRuleBuilder extends RuleTypeBuilder<MessageRuleBuilder, MessageRule> {
46
47 private final String messageType;
48 private final String[] triggerEvents;
49
50 protected MessageRuleBuilder(List<RuleBinding<? extends Rule<?>>> rules, Set<Version> versions,
51 String messageType, String... triggerEvents) {
52 super(rules, versions);
53 this.messageType = messageType;
54 this.triggerEvents = triggerEvents;
55 }
56
57 /**
58 * Builds a {@link MessageRule} that extracts a primitive value using a {@link ca.uhn.hl7v2.util.Terser}
59 * expression and evaluates the specified {@link Predicate}.
60 *
61 * @param spec Terser expression
62 * @param predicate Predicate to evaluate against the value
63 * @return this instance to build more rules
64 */
65 public MessageRuleBuilder terser(String spec, Predicate predicate) {
66 return test(prepareRule(new TerserMessageRule(spec, predicate)));
67 }
68
69 /**
70 * Builds a {@link MessageRule} that runs a
71 * {@link ca.uhn.hl7v2.validation.builder.support.ValidatingMessageVisitor ValidatingMessageVisitor}
72 * over the message that collects {@link ca.uhn.hl7v2.validation.ValidationException ValidationExceptions}
73 * in a single pass.
74 *
75 * @param visitorFactory MessageVisitorFactory that creates ValidatingMessageVisitor instances
76 * @return this instance to build more rules
77 */
78 public MessageRuleBuilder inspect(MessageVisitorFactory<? extends ValidatingMessageVisitor> visitorFactory) {
79 return test(prepareRule(new VisitorMessageRule(visitorFactory)));
80 }
81
82 /**
83 * Builds a {@link MessageRule} that disallows the existence of {@link ca.uhn.hl7v2.model.GenericSegment}s, i.e.
84 * segments that are not defined in the structure of a message.
85 *
86 * @return this instance to build more rules
87 */
88 public MessageRuleBuilder onlyKnownSegments() {
89 return test(prepareRule(OnlyKnownSegmentsRule.ONLY_KNOWN_SEGMENTS));
90 }
91
92 /**
93 * Builds a {@link MessageRule} that disallows the existence of segments which
94 * are not alowed in a given message type when the message is an instance
95 * of {@link ca.uhn.hl7v2.model.SuperStructure} (e.g. PID2 within an ADT^A01)
96 *
97 * @return this instance to build more rules
98 */
99 public MessageRuleBuilder onlyAllowableSegmentsInSuperStructure() {
100 return test(prepareRule(OnlyAllowableSegmentsInSuperstructureRule.ONLY_ALLOWABLE_SEGMENTS));
101 }
102
103 /**
104 * Builds a {@link MessageRule} that enforces choice elements. This means that
105 * if several segments are listed as being a possible choice for the first segment
106 * in a group, only one of them may have content.
107 *
108 * @return this instance to build more rules
109 */
110 public MessageRuleBuilder choiceElementsRespected() {
111 return test(prepareRule(ChoiceElementsRespectedRule.CHOICE_ELEMENTS_RESPECTED));
112 }
113
114 /**
115 * Builds a {@link MessageRule} that disallows the selected HL7 version(s). It is basically
116 * equivalent with:
117 *
118 * <pre>
119 * forAllVersions().message(....).terser("MSH-12", in(allowedVersions))
120 * </pre>
121 *
122 * However, when using this specific rule the builder expression and the resulting exception
123 * message is more specific:
124 *
125 * <pre>
126 * forVersion().except(allowedVersions).message(...).wrongVersion()
127 * </pre>
128 *
129 * @return this instance to build more rules
130 */
131 public MessageRuleBuilder wrongVersion() {
132 return test(prepareRule(WrongVersionRule.WRONG_VERSION));
133 }
134
135 /**
136 * Builds a {@link MessageRule} that evaluates the message against the Conformance Profile
137 * referred to in MSH-21.
138 *
139 * @return this instance to build more rules
140 */
141 public MessageRuleBuilder conformance() {
142 return conformance(null);
143 }
144
145 /**
146 * Builds a {@link MessageRule} that evaluates the message against the Conformance Profile
147 * referred to by the profileId parameter
148 *
149 * @param profileId conformance profile id (file name)
150 * @return this instance to build more rules
151 */
152 public MessageRuleBuilder conformance(String profileId) {
153 return test(prepareRule(new ConformanceProfileRule(profileId)));
154 }
155
156 // for tests only
157 String getMessageType() {
158 return messageType;
159 }
160
161 // for tests only
162 String[] getTriggerEvents() {
163 return triggerEvents;
164 }
165
166 @Override
167 protected Collection<RuleBinding<MessageRule>> getRuleBindings(MessageRule rule, String version) {
168 List<RuleBinding<MessageRule>> bindings = new ArrayList<>();
169 for (String triggerEvent : triggerEvents) {
170 bindings.add(new MessageRuleBinding(version, messageType,
171 triggerEvent, rule));
172 }
173 return activate(bindings);
174 }
175
176 }