1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.openehealth.ipf.commons.ihe.xds.core;
17
18 import org.apache.cxf.jaxb.JAXBDataBinding;
19 import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.lcm.SubmitObjectsRequest;
20 import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rim.*;
21
22 import javax.xml.bind.Marshaller;
23 import javax.xml.bind.Unmarshaller;
24 import java.util.*;
25
26
27
28
29
30
31
32
33
34 public class XdsJaxbDataBinding extends JAXBDataBinding {
35
36 public static final String SUBMISSION_SET_HAS_EXTRA_METADATA =
37 XdsJaxbDataBinding.class.getName() + ".submission.set.has.extra.metadata";
38
39 private static final Map<Object, Map<String, Object>> DATA =
40 Collections.synchronizedMap(new WeakHashMap<Object, Map<String, Object>>());
41
42
43
44
45
46
47
48
49
50
51
52 public static Map<String, Object> getCamelHeaders(Object ebXml) {
53 return DATA.computeIfAbsent(ebXml, k -> new HashMap<>());
54 }
55
56
57 public XdsJaxbDataBinding() {
58 super();
59 setUnmarshallerListener(new UnmarshallerListener());
60 setMarshallerListener(new MarshallerListener());
61 }
62
63
64 public static boolean isExtraMetadataSlotName(String name) {
65 return ((name != null) && name.startsWith("urn:") && (!name.startsWith("urn:ihe:")));
66 }
67
68
69 private static class UnmarshallerListener extends Unmarshaller.Listener {
70 static final ThreadLocal<Boolean> RESULTS = new ThreadLocal<>();
71
72 @Override
73 public void afterUnmarshal(Object target, Object parent) {
74 if (target instanceof ExtrinsicObjectType) {
75 ExtrinsicObjectType ebXml = (ExtrinsicObjectType) target;
76 findExtraMetadata(ebXml.getSlot(), ebXml);
77 } else if (target instanceof RegistryPackageType) {
78 RegistryPackageType ebXml = (RegistryPackageType) target;
79 findExtraMetadata(ebXml.getSlot(), ebXml);
80 } else if (target instanceof AssociationType1) {
81 AssociationType1 ebXml = (AssociationType1) target;
82 findExtraMetadata(ebXml.getSlot(), ebXml);
83 } else if ((target instanceof SubmitObjectsRequest) && Boolean.TRUE.equals(RESULTS.get())) {
84 getCamelHeaders(target).put(SUBMISSION_SET_HAS_EXTRA_METADATA, Boolean.TRUE);
85 RESULTS.remove();
86 }
87 }
88
89 private static void findExtraMetadata(List<SlotType1> slots, ExtraMetadataHolder holder) {
90 if (slots != null) {
91 for (SlotType1 slot : slots) {
92 String name = slot.getName();
93 if (isExtraMetadataSlotName(name)) {
94 Map<String, List<String>> extraMetadata = holder.getExtraMetadata();
95 if (extraMetadata == null) {
96 extraMetadata = new HashMap<>();
97 holder.setExtraMetadata(extraMetadata);
98 }
99 extraMetadata.put(name, new ArrayList<>(slot.getValueList().getValue()));
100 RESULTS.set(Boolean.TRUE);
101 }
102 }
103 }
104 }
105 }
106
107
108 private static class MarshallerListener extends Marshaller.Listener {
109 @Override
110 public void beforeMarshal(Object source) {
111 if (source instanceof ExtrinsicObjectType) {
112 ExtrinsicObjectType ebXml = (ExtrinsicObjectType) source;
113 injectExtraMetadata(ebXml.getSlot(), ebXml);
114 } else if (source instanceof RegistryPackageType) {
115 RegistryPackageType ebXml = (RegistryPackageType) source;
116 injectExtraMetadata(ebXml.getSlot(), ebXml);
117 } else if (source instanceof AssociationType1) {
118 AssociationType1 ebXml = (AssociationType1) source;
119 injectExtraMetadata(ebXml.getSlot(), ebXml);
120 }
121 }
122
123 private static void injectExtraMetadata(List<SlotType1> slots, ExtraMetadataHolder holder) {
124 if (holder.getExtraMetadata() != null) {
125 holder.getExtraMetadata().entrySet().stream()
126 .filter(entry -> isExtraMetadataSlotName(entry.getKey()))
127 .forEach(entry -> {
128 SlotType1 slot = new SlotType1();
129 slot.setName(entry.getKey());
130 ValueListType valueList = new ValueListType();
131 valueList.getValue().addAll(entry.getValue());
132 slot.setValueList(valueList);
133 slots.add(slot);
134 });
135 }
136 }
137 }
138
139 }