1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.openehealth.ipf.commons.audit.marshal.dicom;
17
18 import org.jdom2.Content;
19 import org.jdom2.Document;
20 import org.jdom2.Element;
21 import org.jdom2.output.Format;
22 import org.jdom2.output.XMLOutputter;
23 import org.openehealth.ipf.commons.audit.marshal.SerializationStrategy;
24 import org.openehealth.ipf.commons.audit.model.*;
25 import org.openehealth.ipf.commons.audit.types.AuditSource;
26 import org.openehealth.ipf.commons.audit.types.CodedValueType;
27 import org.openehealth.ipf.commons.audit.types.EnumeratedValueSet;
28
29 import java.io.IOException;
30 import java.io.Writer;
31 import java.nio.charset.StandardCharsets;
32
33
34
35
36
37 public class DICOM2016a implements SerializationStrategy {
38
39
40 private static final XMLOutputter PRETTY = new XMLOutputter(Format.getPrettyFormat().setOmitDeclaration(true));
41 private static final XMLOutputter COMPACT = new XMLOutputter(Format.getCompactFormat().setOmitDeclaration(true));
42
43
44 @Override
45 public void marshal(AuditMessage auditMessage, Writer writer, boolean pretty) throws IOException {
46 serialize(auditMessage, writer, pretty ? PRETTY : COMPACT);
47 }
48
49 private void serialize(AuditMessage auditMessage, Writer writer, XMLOutputter outputter) throws IOException {
50 Element element = new Element("AuditMessage");
51 element.addContent(eventIdentification(auditMessage.getEventIdentification()));
52
53 auditMessage.getActiveParticipants().stream()
54 .map(this::activeParticipant)
55 .forEach(element::addContent);
56
57 element.addContent(auditSourceIdentification(auditMessage.getAuditSourceIdentification()));
58
59 auditMessage.getParticipantObjectIdentifications().stream()
60 .map(this::participantObjectIdentification)
61 .forEach(element::addContent);
62
63 outputter.output(new Document(element), writer);
64 }
65
66 protected Content activeParticipant(ActiveParticipantType activeParticipant) {
67 Element element = new Element("ActiveParticipant");
68 element.setAttribute("UserID", activeParticipant.getUserID());
69 conditionallyAddAttribute(element, "AlternativeUserID", activeParticipant.getAlternativeUserID());
70 conditionallyAddAttribute(element, "UserName", activeParticipant.getUserName());
71 element.setAttribute("UserIsRequestor", Boolean.toString(activeParticipant.isUserIsRequestor()));
72 conditionallyAddAttribute(element, "NetworkAccessPointID", activeParticipant.getNetworkAccessPointID());
73 conditionallyAddAttribute(element, "NetworkAccessPointTypeCode", activeParticipant.getNetworkAccessPointTypeCode());
74 if (activeParticipant.getMediaType() != null) {
75 element.addContent(
76 new Element("MediaIdentifier")
77 .addContent(codedValueType("MediaType", activeParticipant.getMediaType())));
78 }
79 if (activeParticipant.getRoleIDCodes() != null) {
80 activeParticipant.getRoleIDCodes().stream()
81 .map(roleIdCode -> codedValueType("RoleIDCode", roleIdCode))
82 .forEach(element::addContent);
83 }
84 return element;
85 }
86
87 protected Element eventIdentification(EventIdentificationType eventIdentification) {
88 Element element = new Element("EventIdentification");
89 if (eventIdentification != null) {
90 element.setAttribute("EventActionCode", eventIdentification.getEventActionCode().getValue());
91 element.setAttribute("EventDateTime", eventIdentification.getEventDateTime().toString());
92 element.setAttribute("EventOutcomeIndicator", eventIdentification.getEventOutcomeIndicator().getValue().toString());
93 if (eventIdentification.getEventID() != null) {
94 element.addContent(codedValueType("EventID", eventIdentification.getEventID()));
95 }
96 eventIdentification.getEventTypeCode().stream()
97 .map(eventTypeCode -> codedValueType("EventTypeCode", eventTypeCode))
98 .forEach(element::addContent);
99 if (eventIdentification.getEventOutcomeDescription() != null) {
100 element.addContent(
101 new Element("EventOutcomeDescription")
102 .addContent(eventIdentification.getEventOutcomeDescription()));
103 }
104 eventIdentification.getPurposesOfUse().stream()
105 .map(purposeOfUse -> codedValueType("PurposeOfUse", purposeOfUse))
106 .forEach(element::addContent);
107 }
108 return element;
109 }
110
111 protected Element participantObjectIdentification(ParticipantObjectIdentificationType poi) {
112 Element element = new Element("ParticipantObjectIdentification");
113 if (poi != null) {
114 conditionallyAddAttribute(element, "ParticipantObjectID", poi.getParticipantObjectID());
115 conditionallyAddAttribute(element, "ParticipantObjectTypeCode", poi.getParticipantObjectTypeCode().getValue().toString());
116 conditionallyAddAttribute(element, "ParticipantObjectTypeCodeRole", poi.getParticipantObjectTypeCodeRole());
117 conditionallyAddAttribute(element, "ParticipantObjectDataLifeCycle", poi.getParticipantObjectDataLifeCycle());
118 conditionallyAddAttribute(element, "ParticipantObjectSensitivity", poi.getParticipantObjectSensitivity());
119 if (poi.getParticipantObjectIDTypeCode() != null) {
120 element.addContent(codedValueType("ParticipantObjectIDTypeCode", poi.getParticipantObjectIDTypeCode()));
121 }
122 if (poi.getParticipantObjectName() != null) {
123 element.addContent(new Element("ParticipantObjectName")
124 .addContent(poi.getParticipantObjectName()));
125 }
126 if (poi.getParticipantObjectQuery() != null) {
127 element.addContent(new Element("ParticipantObjectQuery")
128 .addContent(new String(poi.getParticipantObjectQuery(), StandardCharsets.UTF_8)));
129 }
130 poi.getParticipantObjectDetails().stream()
131 .map(participantObjectDetail -> typeValuePairType("ParticipantObjectDetail", participantObjectDetail))
132 .forEach(element::addContent);
133
134 poi.getParticipantObjectDescriptions().stream()
135 .map(this::dicomObjectDescription)
136 .forEach(element::addContent);
137 }
138 return element;
139 }
140
141 protected Element auditSourceIdentification(AuditSourceIdentificationType auditSourceIdentification) {
142 Element element = new Element("AuditSourceIdentification");
143 if (auditSourceIdentification != null) {
144 conditionallyAddAttribute(element, "AuditEnterpriseSiteID", auditSourceIdentification.getAuditEnterpriseSiteID());
145 conditionallyAddAttribute(element, "AuditSourceID", auditSourceIdentification.getAuditSourceID());
146
147 auditSourceIdentification.getAuditSourceType().stream()
148 .map(this::auditSourceType)
149 .forEach(element::addContent);
150 }
151 return element;
152 }
153
154 protected Element auditSourceType(AuditSource auditSourceType) {
155 return new Element("AuditSourceTypeCode").addContent(auditSourceType.getCode());
156 }
157
158 protected Element codedValueType(String tagName, CodedValueType codedValue) {
159 Element element = new Element(tagName);
160 element.setAttribute("csd-code", codedValue.getCode());
161 conditionallyAddAttribute(element, "codeSystemName", codedValue.getCodeSystemName());
162 conditionallyAddAttribute(element, "displayName", codedValue.getDisplayName());
163 conditionallyAddAttribute(element, "originalText", codedValue.getOriginalText());
164 return element;
165 }
166
167 protected Element typeValuePairType(String tagName, TypeValuePairType typeValuePair) {
168 Element element = new Element(tagName);
169 element.setAttribute("type", typeValuePair.getType());
170 element.setAttribute("value", new String(typeValuePair.getValue(), StandardCharsets.UTF_8));
171 return element;
172 }
173
174 protected Element dicomObjectDescription(DicomObjectDescriptionType dicomObjectDescription) {
175 Element pod = new Element("ParticipantObjectDescription");
176 dicomObjectDescription.getMPPS().forEach(mpps ->
177 pod.addContent(new Element("MPPS").setAttribute("UID", mpps)));
178 dicomObjectDescription.getAccession().forEach(accession ->
179 pod.addContent(new Element("Accession").setAttribute("Number", accession)));
180 dicomObjectDescription.getSOPClasses().forEach(sop -> {
181 Element sopClass = new Element("SOPClass")
182 .setAttribute("NumberOfInstances", String.valueOf(sop.getNumberOfInstances()));
183 conditionallyAddAttribute(sopClass, "UID", sop.getUid());
184 sop.getInstanceUids().forEach(uid ->
185 sopClass.addContent(new Element("Instance").setAttribute("UID", uid)));
186 pod.addContent(sopClass);
187 });
188 if (!dicomObjectDescription.getStudyIDs().isEmpty()) {
189 Element participantObjectContainsStudy = new Element("ParticipantObjectContainsStudy ");
190 dicomObjectDescription.getStudyIDs().forEach(studyID ->
191 participantObjectContainsStudy.addContent(
192 new Element("StudyIDs ")
193 .setAttribute("UID", studyID)));
194 pod.addContent(participantObjectContainsStudy);
195 }
196 if (dicomObjectDescription.getEncrypted() != null) {
197 pod.addContent(
198 new Element("Encrypted")
199 .addContent(String.valueOf(dicomObjectDescription.getEncrypted())));
200 }
201 if (dicomObjectDescription.getAnonymized() != null) {
202 pod.addContent(
203 new Element("Anonymized")
204 .addContent(String.valueOf(dicomObjectDescription.getAnonymized())));
205 }
206 return pod;
207 }
208
209 protected void conditionallyAddAttribute(Element element, String attributeName, String value) {
210 if (value != null) {
211 element.setAttribute(attributeName, value);
212 }
213 }
214
215 protected void conditionallyAddAttribute(Element element, String attributeName, EnumeratedValueSet<?> value) {
216 if (value != null) {
217 element.setAttribute(attributeName, value.getValue().toString());
218 }
219 }
220
221 }