001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
015 * Java(TM), hosted at https://github.com/gunterze/dcm4che3.
016 *
017 * The Initial Developer of the Original Code is
018 * Agfa Healthcare.
019 * Portions created by the Initial Developer are Copyright (C) 2012
020 * the Initial Developer. All Rights Reserved.
021 *
022 * Contributor(s):
023 * See @authors listed below
024 *
025 * Alternatively, the contents of this file may be used under the terms of
026 * either the GNU General Public License Version 2 or later (the "GPL"), or
027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
028 * in which case the provisions of the GPL or the LGPL are applicable instead
029 * of those above. If you wish to allow use of your version of this file only
030 * under the terms of either the GPL or the LGPL, and not to allow others to
031 * use your version of this file under the terms of the MPL, indicate your
032 * decision by deleting the provisions above and replace them with the notice
033 * and other provisions required by the GPL or the LGPL. If you do not delete
034 * the provisions above, a recipient may use your version of this file under
035 * the terms of any one of the MPL, the GPL or the LGPL.
036 *
037 * ***** END LICENSE BLOCK ***** */
038
039package org.dcm4che3.audit;
040
041import javax.xml.bind.*;
042import javax.xml.bind.util.JAXBSource;
043import javax.xml.transform.*;
044import javax.xml.transform.stream.StreamResult;
045import javax.xml.transform.stream.StreamSource;
046import java.io.*;
047import java.util.ArrayList;
048import java.util.Calendar;
049import java.util.List;
050import java.util.regex.Pattern;
051
052/**
053 * @author Gunter Zeilinger <gunterze@gmail.com>
054 * @author Michael Backhaus <michael.backhaus@agfa.com>
055 */
056public class AuditMessages {
057
058    private static final String TO_RFC3881_XSL = "dicom2rfc3881.xsl";
059    private static final Pattern IP4 =
060            Pattern.compile("\\d+(\\.\\d+){3}");
061    private static final Pattern IP6 =
062            Pattern.compile("[0-9a-fA-F]*(\\:[0-9a-fA-F]*){7}");
063    public static final String SCHEMA_URI =
064            "http://www.dcm4che.org/DICOM/audit-message.rnc";
065
066    private static final ObjectFactory of = new ObjectFactory();
067    private static JAXBContext jc;
068
069    private static JAXBContext jc() throws JAXBException {
070        JAXBContext jc = AuditMessages.jc;
071        if (jc == null)
072            AuditMessages.jc = jc = JAXBContext.newInstance("org.dcm4che3.audit", AuditMessage.class.getClassLoader());
073        return jc;
074    }
075
076    public static boolean isIP(String s) {
077        return IP4.matcher(s).matches() || IP6.matcher(s).matches();
078    }
079
080    /**
081     * Enumerated Value: C = (create) if the receiver did not hold 
082     * copies of the instances transferred 
083     * 
084     * R = (read) if the receiver already holds copies of the SOP 
085     * Instances transferred, and has determined that no changes are 
086     * needed to the copies held. 
087     * 
088     * U = (update) if the receiver is altering its held copies 
089     * to reconcile differences between the held copies and the received copies. 
090     * 
091     * If the Audit Source is either not the receiver, or otherwise does not 
092     * know whether or not the instances previously were held by the receiving 
093     * node, then use “R” = (Read). 
094     *
095     */
096    public static final class EventActionCode {
097        public static final String Create = "C";
098        public static final String Read = "R";
099        public static final String Update = "U";
100        public static final String Delete = "D";
101        public static final String Execute = "E";
102    }
103
104    public static final class EventOutcomeIndicator {
105        public static final String Success = "0";
106        public static final String MinorFailure = "4";
107        public static final String SeriousFailure = "8";
108        public static final String MajorFailure = "12";
109    }
110
111    public static final class EventID extends org.dcm4che3.audit.EventID {
112
113        public static final EventID ApplicationActivity =
114                new EventID("110100", "DCM", "Application Activity");
115        public static final EventID AuditLogUsed = 
116                new EventID("110101", "DCM", "Audit Log Used");
117        public static final EventID BeginTransferringDICOMInstances = 
118                new EventID("110102", "DCM", "Begin Transferring DICOM Instances");
119        public static final EventID DICOMInstancesAccessed = 
120                new EventID("110103", "DCM", "DICOM Instances Accessed");
121        public static final EventID DICOMInstancesTransferred = 
122                new EventID("110104", "DCM", "DICOM Instances Transferred");
123        public static final EventID DICOMStudyDeleted = 
124                new EventID("110105", "DCM", "DICOM Study Deleted");
125        public static final EventID Export =
126                new EventID("110106", "DCM", "Export");
127        public static final EventID Import =
128                new EventID("110107", "DCM", "Import");
129        public static final EventID NetworkEntry = 
130                new EventID("110108", "DCM", "Network Entry");
131        public static final EventID OrderRecord = 
132                new EventID("110109", "DCM", "Order Record");
133        public static final EventID PatientRecord = 
134                new EventID("110110", "DCM", "Patient Record");
135        public static final EventID ProcedureRecord = 
136                new EventID("110111", "DCM", "Procedure Record");
137        public static final EventID Query =
138                new EventID("110112", "DCM", "Query");
139        public static final EventID SecurityAlert = 
140                new EventID("110113", "DCM", "Security Alert");
141        public static final EventID UserAuthentication = 
142                new EventID("110114", "DCM", "User Authentication");
143        public static final EventID HealthServicesProvisionEvent = 
144                new EventID("IHE0001", "IHE", "Health Services Provision Event");
145        public static final EventID MedicationEvent = 
146                new EventID("IHE0002", "IHE", "Medication Event");
147        public static final EventID PatientCareResourceAssignment = 
148                new EventID("IHE0003", "IHE", "Patient Care Resource Assignment");
149        public static final EventID PatientCareEpisode = 
150                new EventID("IHE0004", "IHE", "Patient Care Episode");
151        public static final EventID PatientCareProtocol = 
152                new EventID("IHE0005", "IHE", "Patient Care Protocol");
153
154        EventID(String code, String codeSystemName, String displayName) {
155            super.code = code;
156            super.codeSystemName = codeSystemName;
157            super.originalText = displayName;
158        }
159
160        @Override
161        public void setCode(String value) {
162            throw new UnsupportedOperationException();
163        }
164
165        @Override
166        public void setDisplayName(String value) {
167            throw new UnsupportedOperationException();
168        }
169
170        @Override
171        public void setOriginalText(String value) {
172            throw new UnsupportedOperationException();
173        }
174
175        @Override
176        public void setCodeSystemName(String value) {
177            throw new UnsupportedOperationException();
178        }
179    }
180
181    public static final class EventTypeCode
182            extends org.dcm4che3.audit.EventTypeCode {
183
184        public static final EventTypeCode ApplicationStart = 
185                new EventTypeCode("110120", "DCM", "Application Start");
186        public static final EventTypeCode ApplicationStop = 
187                new EventTypeCode("110121", "DCM", "Application Stop");
188        public static final EventTypeCode Login = 
189                new EventTypeCode("110122", "DCM", "Login");
190        public static final EventTypeCode Logout = 
191                new EventTypeCode("110123", "DCM", "Logout");
192        public static final EventTypeCode Attach = 
193                new EventTypeCode("110124", "DCM", "Attach");
194        public static final EventTypeCode Detach = 
195                new EventTypeCode("110125", "DCM", "Detach");
196        public static final EventTypeCode NodeAuthentication = 
197                new EventTypeCode("110126", "DCM", "Node Authentication");
198        public static final EventTypeCode EmergencyOverrideStarted = 
199                new EventTypeCode("110127", "DCM", "Emergency Override Started");
200        public static final EventTypeCode NetworkConfiguration = 
201                new EventTypeCode("110128", "DCM", "Network Configuration");
202        public static final EventTypeCode SecurityConfiguration = 
203                new EventTypeCode("110129", "DCM", "Security Configuration");
204        public static final EventTypeCode HardwareConfiguration = 
205                new EventTypeCode("110130", "DCM", "Hardware Configuration");
206        public static final EventTypeCode SoftwareConfiguration = 
207                new EventTypeCode("110131", "DCM", "Software Configuration");
208        public static final EventTypeCode UseOfRestrictedFunction = 
209                new EventTypeCode("110132", "DCM", "Use of Restricted Function");
210        public static final EventTypeCode AuditRecordingStopped = 
211                new EventTypeCode("110133", "DCM", "Audit Recording Stopped");
212        public static final EventTypeCode AuditRecordingStarted = 
213                new EventTypeCode("110134", "DCM", "Audit Recording Started");
214        public static final EventTypeCode ObjectSecurityAttributesChanged = 
215                new EventTypeCode("110135", "DCM", "Object Security Attributes Changed");
216        public static final EventTypeCode SecurityRolesChanged = 
217                new EventTypeCode("110136", "DCM", "Security Roles Changed");
218        public static final EventTypeCode UserSecurityAttributesChanged = 
219                new EventTypeCode("110137", "DCM", "User security Attributes Changed");
220        public static final EventTypeCode EmergencyOverrideStopped = 
221                new EventTypeCode("110138", "DCM", "Emergency Override Stopped");
222        public static final EventTypeCode RemoteServiceOperationStarted = 
223                new EventTypeCode("110139", "DCM", "Remote Service Operation Started");
224        public static final EventTypeCode RemoteServiceOperationStopped = 
225                new EventTypeCode("110140", "DCM", "Remote Service Operation Stopped");
226        public static final EventTypeCode LocalServiceOperationStarted = 
227                new EventTypeCode("110141", "DCM", "Local Service Operation Started");
228        public static final EventTypeCode LocalServiceOperationStopped = 
229                new EventTypeCode("110142", "DCM", "Local Service Operation Stopped");
230        //Defined in IHE IT Infrastructure (ITI)
231        public static final EventTypeCode ITI_8_PatientIdentityFeed = 
232            new EventTypeCode("ITI-8", "IHE Transactions", "Patient Identity Feed");
233        public static final EventTypeCode ITI_9_PIXQuery = 
234            new EventTypeCode("ITI-9", "IHE Transactions", "PIX Query");
235        public static final EventTypeCode ITI_10_PIXUpdateNotification = 
236            new EventTypeCode("ITI-10", "IHE Transactions", "PIX Update Notification");
237        public static final EventTypeCode ITI_18_RegistryStoredQuery = 
238            new EventTypeCode("ITI-18", "IHE Transactions", "Registry Stored Query");
239        public static final EventTypeCode ITI_21_PatientDemographicsQuery = 
240            new EventTypeCode("ITI-21", "IHE Transactions", "Patient Demographics Query");
241        public static final EventTypeCode ITI_22_PatientDemographicsAndVisitQuery = 
242            new EventTypeCode("ITI-22", "IHE Transactions", "Patient Demographics and Visit Query");
243        public static final EventTypeCode ITI_38_CrossGatewayQuery = 
244            new EventTypeCode("ITI-38", "IHE Transactions", "Cross Gateway Query");
245        public static final EventTypeCode ITI_39_CrossGatewayRetrieve = 
246            new EventTypeCode("ITI-39", "IHE Transactions", "Cross Gateway Retrieve");
247        public static final EventTypeCode ITI_41_ProvideAndRegisterDocumentSetB = 
248            new EventTypeCode("ITI-41", "IHE Transactions", "Provide and Register Document Set-b");
249        public static final EventTypeCode ITI_42_RegisterDocumentSetB = 
250            new EventTypeCode("ITI-42", "IHE Transactions", "Register Document Set-b");
251        public static final EventTypeCode ITI_43_RetrieveDocumentSet = 
252            new EventTypeCode("ITI-43", "IHE Transactions", "Retrieve Document Set");
253        public static final EventTypeCode ITI_44_PatientIdentityFeed = 
254            new EventTypeCode("ITI-44", "IHE Transactions", "Patient Identity Feed");
255        public static final EventTypeCode ITI_45_PIXQuery = 
256            new EventTypeCode("ITI-45", "IHE Transactions", "PIX Query");
257        public static final EventTypeCode ITI_46_PIXUpdateNotification = 
258            new EventTypeCode("ITI-46", "IHE Transactions", "PIX Update Notification");
259        public static final EventTypeCode ITI_47_PatientDemographicsQuery = 
260            new EventTypeCode("ITI-47", "IHE Transactions", "Patient Demographics Query");
261        public static final EventTypeCode ITI_51_MultiPatientQuery = 
262            new EventTypeCode("ITI-51", "IHE Transactions", "Multi-Patient Query");
263        public static final EventTypeCode ITI_63_XCFFetch = 
264            new EventTypeCode("ITI-63", "IHE Transactions", "XCF Fetch");
265        public static final EventTypeCode ITI_65_ProvideDocumentBundle =
266                new EventTypeCode("ITI-65", "IHE Transactions", "Provide Document Bundle");
267        public static final EventTypeCode ITI_66_FindDocumentManifests =
268                new EventTypeCode("ITI-66", "IHE Transactions", "Find Document Manifests");
269        public static final EventTypeCode ITI_67_FindDocumentReferences =
270                new EventTypeCode("ITI-67", "IHE Transactions", "Find Document References");
271        public static final EventTypeCode ITI_68_RetrieceDocument =
272                new EventTypeCode("ITI-68", "IHE Transactions", "Retriece Document");
273
274        public EventTypeCode(String code, String codeSystemName,
275                String displayName) {
276            super.code = code;
277            super.codeSystemName = codeSystemName;
278            super.originalText = displayName;
279        }
280
281        @Override
282        public void setCode(String value) {
283            throw new UnsupportedOperationException();
284        }
285
286        @Override
287        public void setDisplayName(String value) {
288            throw new UnsupportedOperationException();
289        }
290
291        @Override
292        public void setOriginalText(String value) {
293            throw new UnsupportedOperationException();
294        }
295
296        @Override
297        public void setCodeSystemName(String value) {
298            throw new UnsupportedOperationException();
299        }
300
301    }
302
303    public static final class AuditSourceTypeCode extends org.dcm4che3.audit.AuditSourceTypeCode {
304
305        public static final AuditSourceTypeCode EndUserDisplayDevice = 
306                new AuditSourceTypeCode("1");
307        public static final AuditSourceTypeCode DataAcquisitionDevice = 
308                new AuditSourceTypeCode("2");
309        public static final AuditSourceTypeCode WebServerProcess = 
310                new AuditSourceTypeCode("3");
311        public static final AuditSourceTypeCode ApplicationServerProcess = 
312                new AuditSourceTypeCode("4");
313        public static final AuditSourceTypeCode DatabaseServerProcess = 
314                new AuditSourceTypeCode("5");
315        public static final AuditSourceTypeCode SecurityServer = 
316                new AuditSourceTypeCode("6");
317        public static final AuditSourceTypeCode NetworkComponent = 
318                new AuditSourceTypeCode("7");
319        public static final AuditSourceTypeCode OperatingSoftware = 
320                new AuditSourceTypeCode("8");
321        public static final AuditSourceTypeCode Other = 
322                new AuditSourceTypeCode("9");
323
324        public AuditSourceTypeCode(String code) {
325            super.code = code;
326        }
327
328        public AuditSourceTypeCode(String code, String codeSystemName,
329                String displayName) {
330            super.code = code;
331            super.codeSystemName = codeSystemName;
332            super.displayName = displayName;
333        }
334        
335        public void setCode(String value) {
336            throw new UnsupportedOperationException();
337        }
338
339        @Override
340        public void setDisplayName(String value) {
341            throw new UnsupportedOperationException();
342        }
343
344        @Override
345        public void setOriginalText(String value) {
346            throw new UnsupportedOperationException();
347        }
348
349        @Override
350        public void setCodeSystem(String value) {
351            throw new UnsupportedOperationException();
352        }
353
354        @Override
355        public void setCodeSystemName(String value) {
356            throw new UnsupportedOperationException();
357        }
358
359    }
360
361    public static final class RoleIDCode extends org.dcm4che3.audit.RoleIDCode {
362
363        public static final RoleIDCode Application = 
364                new RoleIDCode("110150","DCM","Application");
365        public static final RoleIDCode ApplicationLauncher = 
366                new RoleIDCode("110151","DCM","Application Launcher");
367        public static final RoleIDCode Destination = 
368                new RoleIDCode("110152","DCM","Destination Role ID");
369        public static final RoleIDCode Source = 
370                new RoleIDCode("110153","DCM","Source Role ID");
371        public static final RoleIDCode DestinationMedia = 
372                new RoleIDCode("110154","DCM","Destination Media");
373        public static final RoleIDCode SourceMedia = 
374                new RoleIDCode("110155","DCM","Source Media");
375
376        public RoleIDCode(String code, String codeSystemName,
377                String displayName) {
378            super.code = code;
379            super.codeSystemName = codeSystemName;
380            super.originalText = displayName;
381        }
382
383        @Override
384        public void setCode(String value) {
385            throw new UnsupportedOperationException();
386        }
387
388        @Override
389        public void setDisplayName(String value) {
390            throw new UnsupportedOperationException();
391        }
392
393        @Override
394        public void setOriginalText(String value) {
395            throw new UnsupportedOperationException();
396        }
397
398        @Override
399        public void setCodeSystemName(String value) {
400            throw new UnsupportedOperationException();
401        }
402
403    }
404
405    public static final class MediaType extends org.dcm4che3.audit.MediaType {
406
407        public static final MediaType USBDiskEmulation =
408                new MediaType("110030", "DCM", "USB Disk Emulation");
409        public static final MediaType Email =
410                new MediaType("110031", "DCM", "Email");
411        public static final MediaType CD =
412                new MediaType("110032", "DCM", "CD");
413        public static final MediaType DVD =
414                new MediaType("110033", "DCM", "DVD");
415        public static final MediaType CompactFlash =
416                new MediaType("110034", "DCM", "Compact Flash");
417        public static final MediaType MultiMediaCard =
418                new MediaType("110035", "DCM", "Multi-media Card");
419        public static final MediaType SecureDigitalCard =
420                new MediaType("110036", "DCM", "Secure Digital Card");
421        public static final MediaType URI =
422                new MediaType("110037", "DCM", "URI");
423        public static final MediaType Film =
424                new MediaType("110010", "DCM", "Film");
425        public static final MediaType PaperDocument =
426                new MediaType("110038", "DCM", "Paper Document");
427
428        public MediaType(String code, String codeSystemName,
429                String displayName) {
430            super.code = code;
431            super.codeSystemName = codeSystemName;
432            super.originalText = displayName;
433        }
434
435        @Override
436        public void setCode(String value) {
437            throw new UnsupportedOperationException();
438        }
439
440        @Override
441        public void setDisplayName(String value) {
442            throw new UnsupportedOperationException();
443        }
444
445        @Override
446        public void setOriginalText(String value) {
447            throw new UnsupportedOperationException();
448        }
449
450        @Override
451        public void setCodeSystemName(String value) {
452            throw new UnsupportedOperationException();
453        }
454
455    }
456
457    public static final class NetworkAccessPointTypeCode {
458        public static final String MachineName = "1";
459        public static final String IPAddress = "2";
460        public static final String TelephoneNumber = "3";
461        public static final String EmailAddress = "4";
462        public static final String URI = "5";
463    }
464
465    public static final class ParticipantObjectTypeCode {
466        public static final String Person = "1";
467        public static final String SystemObject = "2";
468        public static final String Organization = "3";
469        public static final String Other = "4";
470    }
471
472    public static final class ParticipantObjectTypeCodeRole {
473        public static final String Patient = "1";
474        public static final String Location = "2";
475        public static final String Report = "3";
476        public static final String Resource = "4";
477        public static final String MasterFile = "5";
478        public static final String User = "6";
479        public static final String List = "7";
480        public static final String Doctor = "8";
481        public static final String Subscriber = "9";
482        public static final String Guarantor = "10";
483        public static final String SecurityUserEntity = "11";
484        public static final String SecurityUserGroup = "12";
485        public static final String SecurityResource = "13";
486        public static final String SecurityGranualarityDefinition = "14";
487        public static final String Provider = "15";
488        public static final String ReportDestination = "16";
489        public static final String ReportLibrary = "17";
490        public static final String Schedule = "18";
491        public static final String Customer = "19";
492        public static final String Job = "20";
493        public static final String JobStream = "21";
494        public static final String Table = "22";
495        public static final String RoutingCriteria = "23";
496        public static final String Query = "24";
497    }
498
499    public static final class ParticipantObjectDataLifeCycle {
500        public static final String OriginationCreation = "1";
501        public static final String ImportCopyFromOriginal  = "2";
502        public static final String Amendment = "3";
503        public static final String Verification = "4";
504        public static final String Translation = "5";
505        public static final String AccessUse = "6";
506        public static final String DeIdentification = "7";
507        public static final String AggregationSummarizationDerivation = "8";
508        public static final String Report = "9";
509        public static final String ExportCopyToTarget = "10";
510        public static final String Disclosure = "11";
511        public static final String ReceiptOfDisclosure = "12";
512        public static final String Archiving = "13";
513        public static final String LogicalDeletion = "14";
514        public static final String PermanentErasurePhysicalDestruction  = "15";
515    }
516
517    public static final class ParticipantObjectIDTypeCode
518            extends org.dcm4che3.audit.ParticipantObjectIDTypeCode {
519
520        public static final ParticipantObjectIDTypeCode MedicalRecordNumber = 
521                new ParticipantObjectIDTypeCode("1", "RFC-3881", "Medical Record Number");
522        public static final ParticipantObjectIDTypeCode PatientNumber =
523                new ParticipantObjectIDTypeCode("2", "RFC-3881", "Patient Number");
524        public static final ParticipantObjectIDTypeCode EncounterNumber =
525                new ParticipantObjectIDTypeCode("3", "RFC-3881", "Encounter Number");
526        public static final ParticipantObjectIDTypeCode EnrolleeNumber =
527                new ParticipantObjectIDTypeCode("4", "RFC-3881", "Enrollee Number");
528        public static final ParticipantObjectIDTypeCode SocialSecurityNumber = 
529                new ParticipantObjectIDTypeCode("5", "RFC-3881", "Social Security Number");
530        public static final ParticipantObjectIDTypeCode AccountNumber =
531                new ParticipantObjectIDTypeCode("6", "RFC-3881", "Account Number");
532        public static final ParticipantObjectIDTypeCode GuarantorNumber =
533                new ParticipantObjectIDTypeCode("7", "RFC-3881", "Guarantor Number");
534        public static final ParticipantObjectIDTypeCode ReportName =
535                new ParticipantObjectIDTypeCode("8", "RFC-3881", "Report Name");    
536        public static final ParticipantObjectIDTypeCode ReportNumber =
537                new ParticipantObjectIDTypeCode("9", "RFC-3881", "Report Number");
538        public static final ParticipantObjectIDTypeCode SearchCriteria =
539                new ParticipantObjectIDTypeCode("10", "RFC-3881", "Search Criteria");
540        public static final ParticipantObjectIDTypeCode UserIdentifier =
541                new ParticipantObjectIDTypeCode("11", "RFC-3881", "User Identifier");
542        public static final ParticipantObjectIDTypeCode URI =
543                new ParticipantObjectIDTypeCode("12", "RFC-3881", "URI");
544        public static final ParticipantObjectIDTypeCode StudyInstanceUID = 
545                new ParticipantObjectIDTypeCode("110180","DCM","Study Instance UID");
546        public static final ParticipantObjectIDTypeCode SOPClassUID = 
547                new ParticipantObjectIDTypeCode("110181","DCM","SOP Class UID");
548        public static final ParticipantObjectIDTypeCode NodeID = 
549                new ParticipantObjectIDTypeCode("110182","DCM","Node ID");
550        public static final ParticipantObjectIDTypeCode ITI_PatientNumber = 
551                new ParticipantObjectIDTypeCode("2","RFC-3881","Patient Number");
552        public static final ParticipantObjectIDTypeCode ITI_ReportNumber = 
553                new ParticipantObjectIDTypeCode("9","RFC-3881","Report Number");
554        public static final ParticipantObjectIDTypeCode ITI_PIXQuery = 
555                new ParticipantObjectIDTypeCode("ITI-9","IHE Transactions","PIX Query");
556
557        public ParticipantObjectIDTypeCode(String code) {
558            this(code, "", "");//Use "" for codeSystemName and originalText to fit with DICOM schema (even that this is not defined in RFC-3881)
559        }
560
561        public ParticipantObjectIDTypeCode(String code, String codeSystemName,
562                String displayName) {
563            super.code = code;
564            super.codeSystemName = codeSystemName;
565            super.originalText = displayName;
566        }
567
568        @Override
569        public void setCode(String value) {
570            throw new UnsupportedOperationException();
571        }
572
573        @Override
574        public void setDisplayName(String value) {
575            throw new UnsupportedOperationException();
576        }
577
578        @Override
579        public void setOriginalText(String value) {
580            throw new UnsupportedOperationException();
581        }
582
583        @Override
584        public void setCodeSystemName(String value) {
585            throw new UnsupportedOperationException();
586        }
587
588    }
589    
590    public static EventIdentification createEventIdentification(
591            EventID eventID, String action, Calendar eventDateTime,
592            String outcome, String outcomeDescription, org.dcm4che3.audit.EventTypeCode... types) {
593        EventIdentification ei = new EventIdentification();
594        ei.setEventID(eventID);
595        ei.setEventDateTime(
596                eventDateTime != null ? eventDateTime : Calendar.getInstance());
597        ei.setEventActionCode(action);
598        ei.setEventOutcomeIndicator(outcome);
599        ei.setEventOutcomeDescription(outcomeDescription);
600        for (org.dcm4che3.audit.EventTypeCode type : types)
601            ei.getEventTypeCode().add(type);
602        return ei;
603    }
604
605    public static ActiveParticipant createActiveParticipant(
606            String userID, String altUserID, String name, boolean requestor,
607            String napID, String napTypeCode, MediaType mediaType,
608            RoleIDCode... roleIDs) {
609        ActiveParticipant ap = new ActiveParticipant();
610        ap.setUserID(userID);
611        ap.setAlternativeUserID(altUserID);
612        ap.setUserName(name);
613        ap.setUserIsRequestor(requestor);
614        ap.setNetworkAccessPointID(napID);
615        ap.setNetworkAccessPointTypeCode(napTypeCode);
616        if (mediaType != null) {
617            MediaIdentifier media = new MediaIdentifier();
618            media.setMediaType(mediaType);
619            ap.setMediaIdentifier(media);
620        }
621        for (RoleIDCode roleID : roleIDs)
622            ap.getRoleIDCode().add(roleID);
623        return ap;
624    }
625
626   public static AuditSourceIdentification createAuditSourceIdentification(
627            String siteID, String sourceID, AuditSourceTypeCode... types) {
628        AuditSourceIdentification asi = new AuditSourceIdentification();
629        asi.setAuditEnterpriseSiteID(siteID);
630        asi.setAuditSourceID(sourceID);
631        for (AuditSourceTypeCode type : types)
632            asi.getAuditSourceTypeCode().add(type);
633        return asi;
634   }
635
636    public static ParticipantObjectIdentification createParticipantObjectIdentification(
637            String id, ParticipantObjectIDTypeCode idType, String name,
638            byte[] query, String type, String role, String lifeCycle,
639            String sensitivity, ParticipantObjectDescription description,
640            ParticipantObjectDetail... details) {
641        ParticipantObjectIdentification poi = new ParticipantObjectIdentification();
642        poi.setParticipantObjectID(id);
643        poi.setParticipantObjectIDTypeCode(idType);
644        poi.setParticipantObjectName(name);
645        poi.setParticipantObjectQuery(query);
646        poi.setParticipantObjectTypeCode(type);
647        poi.setParticipantObjectTypeCodeRole(role);
648        poi.setParticipantObjectDataLifeCycle(lifeCycle);
649        poi.setParticipantObjectSensitivity(sensitivity);
650        poi.setParticipantObjectDescription(description);
651        for (ParticipantObjectDetail detail : details)
652            poi.getParticipantObjectDetail().add(detail);
653        return poi;
654    }
655   
656    public static ParticipantObjectDescription createParticipantObjectDescription(
657            Boolean encrypted, Boolean anonymized) {
658        ParticipantObjectDescription pod = new ParticipantObjectDescription();
659        pod.setEncrypted(encrypted);
660        pod.setAnonymized(anonymized);
661        return pod;
662    }
663
664    public static ParticipantObjectDetail createParticipantObjectDetail(
665            String type, byte[] value) {
666        ParticipantObjectDetail detail = new ParticipantObjectDetail();
667        detail.setType(type);
668        detail.setValue(value);
669        return detail;
670    }
671
672    public static MPPS createMPPS(String uid) {
673        MPPS mpps = new MPPS();
674        mpps.setUID(uid);
675        return mpps;
676    }
677
678    public static SOPClass createSOPClass(String uid, Integer numI) {
679        SOPClass sopClass = new SOPClass();
680        sopClass.setUID(uid);
681        sopClass.setNumberOfInstances(numI);
682        return sopClass;
683    }
684
685    public static Instance createInstance(String uid) {
686        Instance inst = new Instance();
687        inst.setUID(uid);
688        return inst;
689    }
690
691    public static ParticipantObjectContainsStudy
692            createParticipantObjectContainsStudy(String uid) {
693        ParticipantObjectContainsStudy study = new ParticipantObjectContainsStudy();
694        StudyIDs studyId = new StudyIDs();
695        studyId.setUID(uid);
696        study.getStudyIDs().add(studyId );
697        return study;
698    }
699
700    public static Accession createAccession(String accessionNumber) {
701        Accession accession = new Accession();
702        accession.setNumber(accessionNumber);
703        return accession;
704    }
705
706    public static String alternativeUserIDForAETitle(String... aets) {
707        if (aets.length == 0)
708            return null;
709
710        StringBuilder b = new StringBuilder();
711        b.append("AETITLES=").append(aets[0]);
712        for (int i = 1; i < aets.length; i++)
713            b.append(';').append(aets[i]);
714        return b.toString();
715    }
716
717    public static void toXML(AuditMessage message, OutputStream os)
718            throws IOException {
719        toXML(message, os, false, "UTF-8", SCHEMA_URI);
720    }
721
722    public static void toXML(AuditMessage message, OutputStream os,
723            boolean format) throws IOException {
724        toXML(message, os, format, "UTF-8", SCHEMA_URI);
725    }
726
727    public static void toXML(AuditMessage message, OutputStream os,
728            boolean format, String encoding) throws IOException {
729        toXML(message, os, format, encoding, SCHEMA_URI);
730    }
731
732    public static void toXML(AuditMessage message, OutputStream os,
733            boolean format, String encoding, String schemaURI)
734            throws IOException {
735        try {
736            Marshaller m = jc().createMarshaller();
737            if (format)
738                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
739            if (schemaURI != null)
740                m.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION,
741                        schemaURI);
742            if (encoding != null)
743                m.setProperty(Marshaller.JAXB_ENCODING, encoding);
744            m.marshal(of.createAuditMessage(message), os );
745        } catch( JAXBException jbe ){
746            if (jbe.getLinkedException() instanceof IOException)
747                throw (IOException) jbe.getLinkedException();
748            throw new IllegalStateException(jbe);
749        }
750    }
751
752    public static void toSupplement95XML(AuditMessage message, OutputStream os,
753            boolean format, String encoding, String schemaURI)
754            throws IOException {
755        try {
756            
757            TransformerFactory tf = TransformerFactory.newInstance();
758            ClassLoader cl = Thread.currentThread().getContextClassLoader();
759            StreamSource xslt = new StreamSource(cl.getResource(TO_RFC3881_XSL).toString());
760            Transformer transformer = tf.newTransformer(xslt);
761            JAXBSource source = new JAXBSource(jc(), of.createAuditMessage(message));
762            StreamResult result = new StreamResult(os);
763            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
764            transformer.setOutputProperty(OutputKeys.INDENT, format ? "yes" : "no");
765            transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
766            transformer.transform(source, result);
767        } catch( JAXBException jbe ){
768            if (jbe.getLinkedException() instanceof IOException)
769                throw (IOException) jbe.getLinkedException();
770            throw new IllegalStateException(jbe);
771        } catch (TransformerConfigurationException e) {
772            throw new IOException(e.getMessageAndLocation(), e);
773        } catch (TransformerException e) {
774            throw new IOException(e.getMessageAndLocation(), e);
775        }
776    }
777
778    public static String toXML(AuditMessage message)
779            throws IOException {
780        return toXML(message, false, "UTF-8", SCHEMA_URI);
781    }
782
783    public static String toXML(AuditMessage message,
784            boolean format) throws IOException {
785        return toXML(message, format, "UTF-8", SCHEMA_URI);
786    }
787
788    public static String toXML(AuditMessage message,
789            boolean format, String encoding) throws IOException {
790        return toXML(message, format, encoding, SCHEMA_URI);
791    }
792
793    public static String toXML(AuditMessage message, 
794            boolean format, String encoding, String schemaURL)
795            throws IOException {
796        ByteArrayOutputStream os = new ByteArrayOutputStream(256);
797        toXML(message, os, format, encoding, schemaURL);
798        return os.toString(encoding);
799    }
800
801    public static AuditMessage fromXML(InputStream is)
802            throws JAXBException {
803        Unmarshaller u = jc().createUnmarshaller();
804        @SuppressWarnings("unchecked")
805        JAXBElement<AuditMessage> je =
806                (JAXBElement<AuditMessage>) u.unmarshal(is);
807        return je.getValue();
808    }
809
810    public static AuditMessage fromXML(Reader is)
811            throws JAXBException {
812        Unmarshaller u = jc().createUnmarshaller();
813        @SuppressWarnings("unchecked")
814        JAXBElement<AuditMessage> je =
815                (JAXBElement<AuditMessage>) u.unmarshal(is);
816        return je.getValue();
817    }
818}