/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openehealth.coala.builder; import java.io.StringWriter; import java.util.Date; import java.util.ResourceBundle; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.openehealth.coala.domain.Patient; import org.openehealth.coala.domain.PatientConsentPolicy; import org.openehealth.coala.exception.CDACreationException; import org.openehealth.coala.util.PXSDateConverter; import org.openehealth.ipf.commons.ihe.xds.core.metadata.DocumentEntry; import org.slf4j.Logger; /** * this Class is responsible for the Consent CDA creation. * * @author mnachtma, wkais */ public class CDABuilder { private static final Logger LOG = org.slf4j.LoggerFactory .getLogger(CDABuilder.class); private static final String TAG_CDA_FAMILY = "family"; private static final String TAG_CDA_GIVEN = "given"; private static final String TAG_CDA_BIRTHDATE = "birthTime"; private static final String TAG_CDA_VALIDFROM = "lowvalue"; private static final String TAG_CDA_VALIDUNTIL = "highvalue"; private static final String TAG_CDA_ADDRESS_STREET = "streetAddressLine"; private static final String TAG_CDA_ADDRESS_CITY = "city"; private static final String TAG_CDA_ADDRESS_STATE = "state"; private static final String TAG_CDA_ADDRESS_POSTALCODE = "postalCode"; private static final String TAG_CDA_ADDRESS_COUNTRY = "country"; private static final String TAG_CDA_PATIENT_ID = "pID"; private static final String TAG_CDA_PATIENT_GENDER = "administrativeGenderCode"; private static final String TAG_CDA_PATIENT_ID_ROOT = "pRoot"; private static final String TAG_CDA_ID_ROOT = "idRoot"; private static final String TAG_CDA_CODE_CODE = "cCode"; private static final String TAG_CDA_CODE_DISPLAYNAME = "cDisplayName"; private static final String TAG_CDA_CODE_CODESYSTEM = "cCodeSystem"; private static final String TAG_CDA_CODE_CODESYSTEMNAME = "cCodeSystemName"; private static final String TAG_CDA_TITlE = "title"; private static final String TAG_CDA_EFFECTIVETIME = "effectiveTime"; private static final String TAG_CDA_CONFIDENTIALTY_CODE = "confCode"; private static final String TAG_CDA_CONFIDENTIALTY_DISPLAYNAME = "confDisplayName"; private static final String TAG_CDA_CONFIDENTIALTY_CODESYSTEM = "confCodeSystem"; private static final String TAG_CDA_CONFIDENTIALTY_CODESYSTEMNAME = "confCodeSystemName"; private static final String TAG_CDA_LANGUAGECODE = "languageCode"; private static final String TAG_CDA_COMPONENT_TITLE = "ComponentTitle"; private static final String TAG_CDA_COMPONENT_TEXT = "ComponentText"; private static final String TAG_CDA_Author_TITLE = "aTitle"; private static final String TAG_CDA_Author_FAMILY = "aFamily"; private static final String TAG_CDA_Author_GIVEN = "aGiven"; private Template t; private static String CDA_CODE_CODESYSTEM_OID; private static String CDA_CONFIDENTIALTY_CODESYSTEM_OID; private PXSDateConverter pxsDateConverter; public void setPxsDateConverter(PXSDateConverter pxsDateConverter) { this.pxsDateConverter = pxsDateConverter; } /** * the constructor declares and initializes the Velocity-engine * * @param templateName * the filename ( no path here ! ) of the CDA template to be * used. Must not be null or empty. * @throws RuntimeException * thrown if any errors occurred during initialization */ public CDABuilder(String templateName) { try { ResourceBundle properties = ResourceBundle.getBundle("coala-document"); CDA_CODE_CODESYSTEM_OID = properties .getString("coala.cda.code.codeSystem"); CDA_CONFIDENTIALTY_CODESYSTEM_OID = properties .getString("coala.cda.confidentialty.codeSystem"); /* first, get and initialize an engine */ VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); ve.init(); /* next, get the Template */ t = ve.getTemplate(templateName); } catch (Exception e) { throw new RuntimeException(e.getLocalizedMessage(), e); } } /** * this method provides a valid consent CDA structure. * * @param patient * the {@link Patient} instance for which the CDA should be * created. Must not be null. * @param policy * the {@link PatientConsentPolicy} that was chosen for this new * consent CDA. Must not be null. * @param documentEntry * the {@link DocumentEntry} that was associated to the consent * CDA. Must not be null and have a valid {@link DocumentEntry} * state. * @return CDA XML Document * @throws CDACreationException * thrown if the new consent CDA could be generated. * @throws IllegalArgumentException * thrown if one of the given parameters is invalid. */ public String createConsentCDA(Patient patient, PatientConsentPolicy policy, DocumentEntry documentEntry) { // Basic checks if (patient == null) throw new IllegalArgumentException("Patient cannot be null."); if (policy == null) throw new IllegalArgumentException("policy cannot be null."); if (documentEntry == null) throw new IllegalArgumentException("documentEntry cannot be null."); StringWriter writer = new StringWriter(); /* create a context and add data */ VelocityContext context = new VelocityContext(); /* load Metadata */ context = createMetaContext(context, patient, policy, documentEntry); context.put(TAG_CDA_ID_ROOT, documentEntry.getUniqueId()); context.put(TAG_CDA_CODE_CODE, documentEntry.getTypeCode().getCode()); context.put(TAG_CDA_CODE_DISPLAYNAME, documentEntry.getTypeCode() .getDisplayName().getValue()); context.put(TAG_CDA_CODE_CODESYSTEM, CDA_CODE_CODESYSTEM_OID); context.put(TAG_CDA_CODE_CODESYSTEMNAME, documentEntry.getTypeCode() .getSchemeName()); context.put(TAG_CDA_EFFECTIVETIME, documentEntry.getCreationTime()); context.put(TAG_CDA_CONFIDENTIALTY_CODE, documentEntry .getConfidentialityCodes().get(0).getCode()); context.put(TAG_CDA_CONFIDENTIALTY_DISPLAYNAME, documentEntry .getConfidentialityCodes().get(0).getDisplayName().getValue()); context.put(TAG_CDA_CONFIDENTIALTY_CODESYSTEM, CDA_CONFIDENTIALTY_CODESYSTEM_OID); context.put(TAG_CDA_CONFIDENTIALTY_CODESYSTEMNAME, documentEntry .getConfidentialityCodes().get(0).getSchemeName()); context.put(TAG_CDA_LANGUAGECODE, documentEntry.getLanguageCode()); context.put(TAG_CDA_Author_TITLE, documentEntry.getAuthor() .getAuthorPerson().getName().getPrefix()); context.put(TAG_CDA_Author_FAMILY, documentEntry.getAuthor() .getAuthorPerson().getName().getFamilyName()); context.put(TAG_CDA_Author_GIVEN, documentEntry.getAuthor() .getAuthorPerson().getName().getGivenName()); context.put(TAG_CDA_VALIDFROM, documentEntry.getServiceStartTime()); context.put(TAG_CDA_VALIDUNTIL, documentEntry.getServiceStopTime()); try { /* now render the template into a StringWriter */ t.merge(context, writer); } catch (Exception e) { throw new CDACreationException(e.getLocalizedMessage(), e); } /* show the World */ LOG.debug(writer.toString()); return writer.toString(); } /** * this Method is called to create a cda document by * {@link #createConsentCDA(Patient, Date, Date, PatientConsentPolicy, DocumentEntry)} * * @param context * @param patient * @param policy * @return */ private VelocityContext createMetaContext(VelocityContext context, Patient patient, PatientConsentPolicy policy, DocumentEntry documentEntry) { context.put(TAG_CDA_FAMILY, patient.getLastName()); context.put(TAG_CDA_GIVEN, patient.getGivenName()); context.put(TAG_CDA_BIRTHDATE, pxsDateConverter.DateToShortString(patient.getBirthdate())); context.put(TAG_CDA_ADDRESS_STREET, patient.getAddress() .getStreetAddress()); context.put(TAG_CDA_ADDRESS_CITY, patient.getAddress().getCity()); context.put(TAG_CDA_ADDRESS_STATE, patient.getAddress() .getStateOrProvince()); context.put(TAG_CDA_ADDRESS_POSTALCODE, patient.getAddress() .getZipOrPostalCode()); context.put(TAG_CDA_ADDRESS_COUNTRY, patient.getAddress().getCountry()); context.put(TAG_CDA_PATIENT_ID, patient.getPatientID()); context.put(TAG_CDA_PATIENT_ID_ROOT, patient.getPatientIDAssigningAuthorityUniversalId()); context.put(TAG_CDA_TITlE, documentEntry.getTitle().getValue()); context.put(TAG_CDA_PATIENT_GENDER, patient.getSex()); context.put(TAG_CDA_COMPONENT_TITLE, policy.name()); context.put(TAG_CDA_COMPONENT_TEXT, policy.getShortName()); return context; } }