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 | |
|
27 | |
package ca.uhn.hl7v2.parser; |
28 | |
|
29 | |
import java.lang.reflect.Constructor; |
30 | |
|
31 | |
import ca.uhn.hl7v2.ErrorCode; |
32 | |
import ca.uhn.hl7v2.HL7Exception; |
33 | |
import ca.uhn.hl7v2.Version; |
34 | |
import ca.uhn.hl7v2.model.*; |
35 | |
import org.slf4j.Logger; |
36 | |
import org.slf4j.LoggerFactory; |
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
public final class FixFieldDataType { |
43 | |
|
44 | 0 | private FixFieldDataType() {} |
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
public static final String DEFAULT_OBX2_TYPE_PROP = "ca.uhn.hl7v2.model.varies.default_obx2_type"; |
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
public static final String INVALID_OBX2_TYPE_PROP = "ca.uhn.hl7v2.model.varies.invalid_obx2_type"; |
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
|
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
|
85 | |
|
86 | |
public static final String ESCAPE_SUBCOMPONENT_DELIM_IN_PRIMITIVE = "ca.uhn.hl7v2.model.varies.escape_subcomponent_delim_in_primitive"; |
87 | |
|
88 | |
|
89 | 5 | private static final Logger LOG = LoggerFactory.getLogger(Varies.class); |
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | |
|
109 | |
public static void fixOBX5(Segment segment, ModelClassFactory factory, ParserConfiguration parserConfiguration) |
110 | |
throws HL7Exception { |
111 | 900 | if (!segment.getName().contains("OBX")) { |
112 | 0 | throw new IllegalArgumentException("Expected OBX segment, but was: " + segment.getName()); |
113 | |
} |
114 | 900 | String defaultOBX2Type = parserConfiguration.getDefaultObx2Type(); |
115 | 900 | if (defaultOBX2Type == null) { |
116 | 900 | defaultOBX2Type = System.getProperty(DEFAULT_OBX2_TYPE_PROP); |
117 | |
} |
118 | 900 | String invalidOBX2Type = parserConfiguration.getInvalidObx2Type(); |
119 | 900 | if (invalidOBX2Type == null) { |
120 | 900 | invalidOBX2Type = System.getProperty(INVALID_OBX2_TYPE_PROP); |
121 | |
} |
122 | |
|
123 | 900 | fix(segment, 2, 5, defaultOBX2Type, invalidOBX2Type, factory, parserConfiguration); |
124 | 895 | } |
125 | |
|
126 | |
public static void fixMFE4(Segment segment, ModelClassFactory factory, ParserConfiguration parserConfiguration) |
127 | |
throws HL7Exception { |
128 | 0 | if (!(segment.getName().contains("MFE")) && |
129 | 0 | Version.versionOf(segment.getMessage().getVersion()).isGreaterThan(Version.V23)) { |
130 | 0 | throw new IllegalArgumentException("Expected MFE segment, but was: " + segment.getName()); |
131 | |
} |
132 | 0 | fix(segment, 5, 4, null, null, factory, parserConfiguration); |
133 | 0 | } |
134 | |
|
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
|
146 | |
|
147 | |
public static void fix(Segment segment, int typeField, int dataField, String defaultType, String invalidType, ModelClassFactory factory, ParserConfiguration parserConfiguration) |
148 | |
throws HL7Exception { |
149 | |
try { |
150 | |
|
151 | 900 | Primitive type = (Primitive) segment.getField(typeField, 0); |
152 | 900 | Type[] reps = segment.getField(dataField); |
153 | 1675 | for (Type rep : reps) { |
154 | 780 | Varies v = (Varies)rep; |
155 | 780 | if (type.getValue() == null) { |
156 | 0 | if (defaultType != null) { |
157 | 0 | LOG.debug("setting default {}-{} type to {}", new Object[] {segment.getName(), typeField, defaultType}); |
158 | 0 | type.setValue(defaultType); |
159 | |
} |
160 | |
} |
161 | |
|
162 | 780 | if (type.getValue() == null) { |
163 | 0 | if (v.getData() != null) { |
164 | 0 | if (!(v.getData() instanceof Primitive) || ((Primitive) v.getData()).getValue() != null) { |
165 | 0 | throw new HL7Exception(String.format( |
166 | 0 | "A datatype for %s-%n must be specified in %s-%n.", segment.getName(), dataField, segment.getName(), typeField), |
167 | |
ErrorCode.REQUIRED_FIELD_MISSING); |
168 | |
} |
169 | |
} |
170 | |
} |
171 | |
else { |
172 | |
|
173 | 780 | String version = segment.getMessage().getVersion(); |
174 | 780 | String typeValue = type.getValue(); |
175 | 780 | Class<? extends Type> c = factory.getTypeClass(typeValue, version); |
176 | 780 | if (c == null) { |
177 | 10 | if (invalidType != null) { |
178 | 5 | c = factory.getTypeClass(invalidType, version); |
179 | |
} |
180 | |
|
181 | 10 | if (c == null) { |
182 | 5 | Primitive obx1 = (Primitive) segment.getField(1, 0); |
183 | 5 | HL7Exception h = new HL7Exception("\'" + |
184 | 5 | type.getValue() + "\' in record " + |
185 | 5 | obx1.getValue() + " is invalid for version " + version, |
186 | |
ErrorCode.DATA_TYPE_ERROR); |
187 | 5 | h.setSegmentName(segment.getName()); |
188 | 5 | h.setFieldPosition(typeField); |
189 | 5 | throw h; |
190 | |
} |
191 | |
} |
192 | |
|
193 | |
Type newTypeInstance; |
194 | |
try { |
195 | 775 | Constructor<? extends Type> constr = c.getConstructor(new Class[]{Message.class}); |
196 | 775 | newTypeInstance = constr.newInstance(v.getMessage()); |
197 | 0 | } catch (NoSuchMethodException e) { |
198 | 0 | Constructor<? extends Type> constr = c.getConstructor(new Class[]{Message.class, Integer.class}); |
199 | 0 | newTypeInstance = constr.newInstance(v.getMessage(), 0); |
200 | 775 | } |
201 | |
|
202 | 775 | boolean escapeSubcomponentDelimInPrimitive = |
203 | 775 | parserConfiguration.isEscapeSubcomponentDelimiterInPrimitive() || |
204 | 770 | escapeSubcomponentDelimInPrimitive(); |
205 | |
|
206 | |
|
207 | 775 | if (newTypeInstance instanceof Primitive) { |
208 | 710 | Type[] subComponentsInFirstField = getFirstComponentSubcomponentsOnlyIfMoreThanOne(v); |
209 | 710 | if (subComponentsInFirstField != null) { |
210 | |
|
211 | 25 | if (escapeSubcomponentDelimInPrimitive) { |
212 | |
|
213 | 20 | StringBuilder firstComponentValue = new StringBuilder(); |
214 | 65 | for (Type stype : subComponentsInFirstField) { |
215 | 45 | if (firstComponentValue.length() != 0) { |
216 | 25 | char subComponentSeparator = EncodingCharacters.getInstance(segment.getMessage()).getSubcomponentSeparator(); |
217 | 25 | firstComponentValue.append(subComponentSeparator); |
218 | |
} |
219 | 45 | firstComponentValue.append(stype.encode()); |
220 | |
} |
221 | |
|
222 | 20 | setFirstComponentPrimitiveValue(v, firstComponentValue.toString()); |
223 | |
|
224 | |
} |
225 | |
|
226 | |
} |
227 | |
} |
228 | |
|
229 | 775 | v.setData(newTypeInstance); |
230 | |
} |
231 | |
|
232 | |
} |
233 | |
|
234 | |
} |
235 | 5 | catch (HL7Exception e) { |
236 | 5 | throw e; |
237 | |
} |
238 | 0 | catch (Exception e) { |
239 | 0 | throw new HL7Exception( |
240 | 0 | e.getClass().getName() + " trying to set data type of " + segment.getName() + "-" + dataField, e); |
241 | 895 | } |
242 | 895 | } |
243 | |
|
244 | |
private static boolean escapeSubcomponentDelimInPrimitive() { |
245 | 770 | String property = System.getProperty(ESCAPE_SUBCOMPONENT_DELIM_IN_PRIMITIVE); |
246 | 770 | return property == null || "true".equalsIgnoreCase(property); |
247 | |
} |
248 | |
|
249 | |
private static void setFirstComponentPrimitiveValue(Varies v, String theValue) throws DataTypeException { |
250 | 20 | Composite c = (Composite) v.getData(); |
251 | 20 | Type firstComponent = c.getComponent(0); |
252 | 20 | setFirstComponentPrimitiveValue(firstComponent, theValue); |
253 | 20 | } |
254 | |
|
255 | |
|
256 | |
private static void setFirstComponentPrimitiveValue(Type theFirstComponent, String theValue) |
257 | |
throws DataTypeException { |
258 | |
|
259 | 65 | if (theFirstComponent instanceof Varies) { |
260 | 65 | Varies firstComponentVaries = (Varies)theFirstComponent; |
261 | 65 | if (((Varies) theFirstComponent).getData() instanceof Composite) { |
262 | 20 | Type[] subComponents = ((Composite)firstComponentVaries.getData()).getComponents(); |
263 | 20 | setFirstComponentPrimitiveValue(subComponents[0], theValue); |
264 | 45 | for (int i = 1; i < subComponents.length; i++) { |
265 | 25 | setFirstComponentPrimitiveValue(subComponents[i], ""); |
266 | |
} |
267 | 20 | } else { |
268 | 45 | Primitive p = (Primitive) firstComponentVaries.getData(); |
269 | 45 | p.setValue(theValue); |
270 | |
} |
271 | 65 | } else if (theFirstComponent instanceof Composite) { |
272 | 0 | Type[] subComponents = ((Composite)theFirstComponent).getComponents(); |
273 | 0 | setFirstComponentPrimitiveValue(subComponents[0], theValue); |
274 | 0 | for (int i = 1; i < subComponents.length; i++) { |
275 | 0 | setFirstComponentPrimitiveValue(subComponents[i], ""); |
276 | |
} |
277 | 0 | } else { |
278 | 0 | ((Primitive)theFirstComponent).setValue(theValue); |
279 | |
} |
280 | 65 | } |
281 | |
|
282 | |
|
283 | |
|
284 | |
|
285 | |
|
286 | |
private static Type[] getFirstComponentSubcomponentsOnlyIfMoreThanOne(Varies v) throws DataTypeException { |
287 | 710 | if (v.getData() instanceof Composite) { |
288 | 35 | Composite c = (Composite) v.getData(); |
289 | 35 | Type firstComponent = c.getComponent(0); |
290 | 35 | if (firstComponent instanceof Varies) { |
291 | 35 | Varies firstComponentVaries = (Varies) firstComponent; |
292 | 35 | if (firstComponentVaries.getData() instanceof Composite) { |
293 | 25 | return ((Composite)firstComponentVaries.getData()).getComponents(); |
294 | |
} |
295 | |
} |
296 | |
} |
297 | 685 | return null; |
298 | |
} |
299 | |
} |