1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package ca.uhn.hl7v2.validation.impl;
27
28 import java.io.Serializable;
29 import java.util.*;
30
31 import ca.uhn.hl7v2.model.Primitive;
32 import ca.uhn.hl7v2.validation.EncodingRule;
33 import ca.uhn.hl7v2.validation.MessageRule;
34 import ca.uhn.hl7v2.validation.PrimitiveTypeRule;
35 import ca.uhn.hl7v2.validation.Rule;
36 import ca.uhn.hl7v2.validation.ValidationContext;
37 import ca.uhn.hl7v2.validation.builder.ValidationRuleBuilder;
38
39
40
41
42
43
44
45 @SuppressWarnings("serial")
46 public class ValidationContextImpl implements ValidationContext, Serializable {
47
48 private final List<RuleBinding<PrimitiveTypeRule>> myPrimitiveRuleBindings;
49 private final List<RuleBinding<MessageRule>> myMessageRuleBindings;
50 private final List<RuleBinding<EncodingRule>> myEncodingRuleBindings;
51
52 protected Map<String, Collection<PrimitiveTypeRule>> primitiveRuleCache;
53 protected Map<String, Collection<MessageRule>> messageRuleCache;
54 protected Map<String, Collection<EncodingRule>> encodingRuleCache;
55
56 public ValidationContextImpl() {
57 myPrimitiveRuleBindings = new ArrayList<>();
58 myMessageRuleBindings = new ArrayList<>();
59 myEncodingRuleBindings = new ArrayList<>();
60 initCaches();
61 }
62
63 ValidationContextImpl(ValidationRuleBuilder builder) {
64 this();
65 for (RuleBinding<? extends Rule<?>> ruleBinding : builder.initialize()) {
66 if (ruleBinding instanceof MessageRuleBinding)
67 myMessageRuleBindings.add((MessageRuleBinding)ruleBinding);
68 else if (ruleBinding instanceof EncodingRuleBinding)
69 myEncodingRuleBindings.add((EncodingRuleBinding)ruleBinding);
70 else if (ruleBinding instanceof PrimitiveTypeRuleBinding)
71 myPrimitiveRuleBindings.add((PrimitiveTypeRuleBinding)ruleBinding);
72 }
73 }
74
75
76
77
78
79
80
81
82
83
84 protected void initCaches() {
85 primitiveRuleCache = newRuleCache(100);
86 messageRuleCache = newRuleCache(100);
87 encodingRuleCache = newRuleCache(10);
88 }
89
90
91
92
93
94 public Collection<PrimitiveTypeRule> getPrimitiveRules(String theVersion, String theTypeName, Primitive theType) {
95 Collection<PrimitiveTypeRule> rules = primitiveRuleCache.get(theVersion + theTypeName);
96 if (rules == null) {
97 rules = getRules(myPrimitiveRuleBindings, theVersion, theTypeName);
98 primitiveRuleCache.put(theVersion + theTypeName, rules);
99 }
100 return rules;
101 }
102
103
104
105
106
107 public List<RuleBinding<PrimitiveTypeRule>> getPrimitiveRuleBindings() {
108 return myPrimitiveRuleBindings;
109 }
110
111
112
113
114
115 public Collection<MessageRule> getMessageRules(String theVersion, String theMessageType, String theTriggerEvent) {
116 Collection<MessageRule> rules = messageRuleCache.get(theVersion + theMessageType + theTriggerEvent);
117 if (rules == null) {
118 rules = getRules(myMessageRuleBindings, theVersion, theMessageType + "^" + theTriggerEvent);
119 messageRuleCache.put(theVersion + theMessageType + theTriggerEvent, rules);
120 }
121 return rules;
122 }
123
124
125
126
127 public List<RuleBinding<MessageRule>> getMessageRuleBindings() {
128 return myMessageRuleBindings;
129 }
130
131
132
133
134
135 public Collection<EncodingRule> getEncodingRules(String theVersion, String theEncoding) {
136 Collection<EncodingRule> rules = encodingRuleCache.get(theVersion + theEncoding);
137 if (rules == null) {
138 rules = getRules(myEncodingRuleBindings, theVersion, theEncoding);
139 encodingRuleCache.put(theVersion + theEncoding, rules);
140 }
141 return rules;
142 }
143
144
145
146
147 public List<RuleBinding<EncodingRule>> getEncodingRuleBindings() {
148 return myEncodingRuleBindings;
149 }
150
151 private <T extends Rule<?>> Collection<T> getRules(List<RuleBinding<T>> bindings, String version, String scope) {
152 List<T> active = new ArrayList<>(bindings.size());
153 for (RuleBinding<T> binding : bindings) {
154 if (applies(binding, version, scope))
155 active.add(binding.getRule());
156 }
157 return active;
158 }
159
160 private boolean applies(RuleBinding<?> binding, String version, String scope) {
161 return (binding.getActive() && binding.appliesToVersion(version) && binding.appliesToScope(scope));
162 }
163
164
165
166
167
168
169
170 private static class RuleCache<T extends Rule<?>> extends LinkedHashMap<String, Collection<T>> {
171
172 private final int size;
173
174 private RuleCache(int size) {
175 super(size);
176 this.size = size;
177 }
178
179 @Override
180 protected boolean removeEldestEntry(Map.Entry<String, Collection<T>> eldest) {
181 return size() > size;
182 }
183
184 }
185
186 protected static <T extends Rule<?>> Map<String, Collection<T>> newRuleCache(int size) {
187 Map<String, Collection<T>> cache = new RuleCache<>(size);
188 return Collections.synchronizedMap(cache);
189 }
190 }