org.patientview.radar.util.DemographicsDecryptData2SqlMapper.java Source code

Java tutorial

Introduction

Here is the source code for org.patientview.radar.util.DemographicsDecryptData2SqlMapper.java

Source

/*
 * PatientView
 *
 * Copyright (c) Worth Solutions Limited 2004-2013
 *
 * This file is part of PatientView.
 *
 * PatientView is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * PatientView is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with PatientView in a file
 * titled COPYING. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package PatientView
 * @link http://www.patientview.org
 * @author PatientView <info@patientview.org>
 * @copyright Copyright (c) 2004-2013, Worth Solutions Limited
 * @license http://www.gnu.org/licenses/gpl-3.0.html The GNU General Public License V3.0
 */

package org.patientview.radar.util;

import org.apache.commons.lang.StringUtils;
import org.patientview.model.Patient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.sql.DataSource;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * {@link #run(javax.servlet.ServletContext)} gets the encrypted field data from demographics table, decrypts it,
 *      and creates an .sql file with the update statements for setting the decrypted values.
 *
 * Please make sure the folders in the {@link #FILE} exists.
 */
public class DemographicsDecryptData2SqlMapper {

    protected JdbcTemplate jdbcTemplate;

    private static final String FILE = "/radarunencrypteddemograpicstableexport/output/decrypted_demographics_data.sql";

    private static final String DATE_FORMAT = "dd.MM.y";
    private static final String DATE_FORMAT_2 = "dd-MM-y";
    private static final String DATE_FORMAT_3 = "dd/MM/y";

    private static final Logger LOGGER = LoggerFactory.getLogger(DemographicsDecryptData2SqlMapper.class);

    public void run(ServletContext servletContext) throws Exception {
        WebApplicationContext webApplicationContext = WebApplicationContextUtils
                .getRequiredWebApplicationContext(servletContext);

        jdbcTemplate = new JdbcTemplate((DataSource) webApplicationContext.getBean("dataSource"));

        List<Patient> patientList = jdbcTemplate.query("SELECT * FROM patient",
                new EncryptedDemographicsRowMapper());

        StringBuilder outputText = new StringBuilder();
        for (Patient patient : patientList) {
            String updateStatement = "UPDATE patient SET ";

            if (patient.getNhsno() != null) {
                updateStatement += " nhsno = '" + patient.getNhsno() + "', ";
            }

            if (patient.getHospitalnumber() != null) {
                updateStatement += " hospitalnumber = \"" + patient.getHospitalnumber() + "\", ";
            }

            if (patient.getSurname() != null) {
                updateStatement += " surname = \"" + patient.getSurname() + "\", ";
            }

            if (patient.getForename() != null) {
                updateStatement += " forename = \"" + patient.getForename() + "\", ";
            }

            if (patient.getSurnameAlias() != null) {
                updateStatement += " surnameAlias = \"" + patient.getSurnameAlias() + "\", ";
            }

            if (patient.getDob() != null) {
                // just guess what a sane date format is
                updateStatement += " dateofbirth = \""
                        + new SimpleDateFormat(DATE_FORMAT_2).format(patient.getDob()) + "\", ";
            }

            if (patient.getAddress1() != null) {
                updateStatement += " address1 = \"" + patient.getAddress1() + "\", ";
            }

            if (patient.getAddress2() != null) {
                updateStatement += " address2 = \"" + patient.getAddress2() + "\", ";
            }

            if (patient.getAddress3() != null) {
                updateStatement += " address3 = \"" + patient.getAddress3() + "\", ";
            }

            if (patient.getAddress4() != null) {
                updateStatement += " address4 = \"" + patient.getAddress4() + "\", ";
            }

            if (patient.getPostcode() != null) {
                updateStatement += " POSTCODE = \"" + patient.getPostcode() + "\", ";
            }

            if (patient.getPostcodeOld() != null) {
                updateStatement += " postcodeOld = \"" + patient.getPostcodeOld() + "\", ";
            }

            updateStatement += " radarNo = " + patient.getId();
            updateStatement += " WHERE radarNo = " + patient.getId();
            updateStatement += " ;";

            outputText.append(updateStatement);
        }

        // output all sql stuff to file
        FileWriter fileWriter = new FileWriter(FILE);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        bufferedWriter.write(outputText.toString());
        //Close the output stream
        bufferedWriter.close();
    }

    private class EncryptedDemographicsRowMapper implements RowMapper<Patient> {
        public Patient mapRow(ResultSet resultSet, int i) throws SQLException {
            Patient patient = new Patient();
            patient.setId(resultSet.getLong("radarNo"));

            try {
                patient.setNhsno(getDecryptedString(patient.getId() + "", "nhsno", resultSet.getBytes("nhsno")));
                patient.setHospitalnumber(getDecryptedString(patient.getId() + "", "hospitalnumber",
                        resultSet.getBytes("hospitalnumber")));
                patient.setSurname(
                        getDecryptedString(patient.getId() + "", "surname", resultSet.getBytes("surname")));
                patient.setSurnameAlias(getDecryptedString(patient.getId() + "", "surnameAlias",
                        resultSet.getBytes("surnameAlias")));
                patient.setForename(
                        getDecryptedString(patient.getId() + "", "forename", resultSet.getBytes("forename")));

                // Date needs to be decrypted to string, then parsed
                String dateOfBirthString = getDecryptedString(patient.getId() + "", "dateofbirth",
                        resultSet.getBytes("dateofbirth"));

                if (StringUtils.isNotBlank(dateOfBirthString)) {
                    Date dateOfBirth = getDate(dateOfBirthString, DATE_FORMAT);

                    if (dateOfBirth == null) {
                        dateOfBirth = getDate(dateOfBirthString, DATE_FORMAT_2);
                    }

                    if (dateOfBirth == null) {
                        dateOfBirth = getDate(dateOfBirthString, DATE_FORMAT_3);
                    }

                    // If after trying those formats we don't have anything then log as error
                    if (dateOfBirth != null) {
                        patient.setDob(dateOfBirth);
                    } else {
                        LOGGER.error("Could not parse date of birth from any format for dob {}", dateOfBirthString);
                    }
                }

                // Addresses, all encrypted too
                patient.setAddress1(
                        getDecryptedString(patient.getId() + "", "address1", resultSet.getBytes("address1")));
                patient.setAddress2(
                        getDecryptedString(patient.getId() + "", "address2", resultSet.getBytes("address2")));
                patient.setAddress3(
                        getDecryptedString(patient.getId() + "", "address3", resultSet.getBytes("address3")));
                patient.setAddress4(
                        getDecryptedString(patient.getId() + "", "address4", resultSet.getBytes("address4")));
                patient.setPostcode(
                        getDecryptedString(patient.getId() + "", "POSTCODE", resultSet.getBytes("POSTCODE")));
                patient.setPostcodeOld(
                        getDecryptedString(patient.getId() + "", "postcodeOld", resultSet.getBytes("postcodeOld")));

            } catch (Exception e) {
                LOGGER.error("Could not decrypt demographics information for demographics {}", patient.getId());
                LOGGER.debug(e.getMessage(), e);
            }

            return patient;
        }
    }

    private String getDecryptedString(String radarNo, String fieldName, byte[] fieldData) throws Exception {
        if (fieldData != null && fieldData.length > 0) {
            try {
                byte[] copy = Arrays.copyOf(fieldData, fieldData.length);
                return TripleDes.decrypt(copy);
            } catch (Exception e) {
                LOGGER.error("Could not decrypt demographics information for radarNo {}, field {}, field data {}, "
                        + "message {}", new Object[] { radarNo, fieldName, fieldData, e.getMessage() });
            }
        }

        return null;
    }

    private Date getDate(String dobStr, String dateFormat) {
        // It seems that the encrypted strings in the DB have different date formats, nice.
        try {
            return new SimpleDateFormat(dateFormat).parse(dobStr);
        } catch (Exception e) {
            // cya
        }
        return null;
    }
}