com.sfs.whichdoctor.dao.IsbMessageDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.dao.IsbMessageDAOImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2009 David Harrison.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl-3.0.html
 *
 * Contributors:
 *     David Harrison - initial API and implementation
 ******************************************************************************/
package com.sfs.whichdoctor.dao;

import com.sfs.beans.PrivilegesBean;
import com.sfs.beans.UserBean;
import com.sfs.whichdoctor.beans.IsbMessageBean;
import com.sfs.whichdoctor.beans.IsbPayloadBean;

import java.sql.ResultSet;
import java.sql.Timestamp;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.RowMapper;

/**
 * The Class IsbMessageDAOImpl.
 */
public class IsbMessageDAOImpl extends BaseDAOImpl implements IsbMessageDAO {

    /** The data logger. */
    private static Logger dataLogger = Logger.getLogger(IsbMessageDAOImpl.class);

    /** The isb payload dao. */
    @Resource
    private IsbPayloadDAO isbPayloadDAO;

    /**
     * Used to get a IsbMessageBean for the the specified ISB Message Id.
     * Returns null if no isb message found
     *
     * @param isbMessageId the isb message id
     *
     * @return the isb message bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final IsbMessageBean load(final int isbMessageId) throws WhichDoctorDaoException {

        dataLogger.info("ISB message id: " + isbMessageId + " requested");

        IsbMessageBean isbMessage = null;

        try {
            isbMessage = (IsbMessageBean) this.getIsbJdbcTemplate().queryForObject(
                    this.getSQL().getValue("isbmessage/loadId"), new Object[] { isbMessageId }, new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            return loadIsbMessageBean(rs);
                        }
                    });

        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for this search: " + ie.getMessage());
        }
        return isbMessage;
    }

    /**
     * Load the oldest unprocessed IsbMessage that needs publishing to an ISB.
     *
     * @param isbName the name of the ISB being published to
     *
     * @return the isb message bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final IsbMessageBean loadFirstUnprocessed(final String isbName) throws WhichDoctorDaoException {

        dataLogger.info("Oldest unpublished ISB message requested for '" + isbName + "'");

        if (isbName == null) {
            throw new WhichDoctorDaoException("The ISB name cannot be null");
        }

        IsbMessageBean isbMessage = null;

        try {
            isbMessage = (IsbMessageBean) this.getIsbJdbcTemplate().queryForObject(
                    this.getSQL().getValue("isbmessage/loadUnprocessed"), new Object[] { isbName },
                    new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            return loadIsbMessageBean(rs);
                        }
                    });

        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for this search: " + ie.getMessage());
        }
        return isbMessage;
    }

    /**
     * Creates the IsbMessageBean.
     *
     * @param message the message
     *
     * @return the Id of the created IsbMessage if successful
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final int create(final IsbMessageBean message) throws WhichDoctorDaoException {

        int isbMessageId = 0;

        // Parse the ISB XML document and get the identifier
        // and action values for the message
        Element isbIdentityElement = null;
        try {
            Document isbDocument = message.getIsbPayload().getXmlDocument();
            isbIdentityElement = isbDocument.getRootElement().getChild("identity");
        } catch (Exception e) {
            dataLogger.error("Error parsing ISB XML into JDOM document: " + e.getMessage());
        }

        // A flag whether to record the ISB message or just drop it
        boolean processIsbMessage = false;

        if (isbIdentityElement != null) {
            // Get the ISB identifier of this message
            try {
                message.setIdentifier(isbIdentityElement.getAttribute("id").getValue());
            } catch (Exception e) {
                dataLogger.error("Error reading ISB XML id value: " + e.getMessage());
            }
            // Get the ISB action of this message
            try {
                message.setAction(isbIdentityElement.getAttribute("action").getValue());
            } catch (Exception e) {
                dataLogger.error("Error reading ISB XML action value: " + e.getMessage());
            }

            List<?> attributes = isbIdentityElement.getChildren("attribute");
            List<?> objects = isbIdentityElement.getChildren("object");

            if (attributes != null && attributes.size() > 0) {
                processIsbMessage = true;
            }
            if (objects != null && objects.size() > 0) {
                processIsbMessage = true;
            }
        }

        if (processIsbMessage) {
            // At least one attribute or object is present in the ISB
            // message. Record the incoming message.

            // Set the timestamp value
            Timestamp creationTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis());

            try {
                final int createCount = this.getIsbJdbcTemplate().update(
                        this.getSQL().getValue("isbmessage/create"),
                        new Object[] { message.getTarget(), message.getAction(), message.getSource(),
                                message.getIdentifier(), message.getIsInbound(), message.getProcessed(),
                                creationTimeStamp });

                if (createCount > 0) {
                    // Get the maximum id
                    isbMessageId = this.getIsbJdbcTemplate()
                            .queryForInt(this.getSQL().getValue("isbmessage/findMax"));

                    // Record the ISB Payload
                    IsbPayloadBean isbPayload = message.getIsbPayload();
                    isbPayload.setIsbMessageId(isbMessageId);
                    try {
                        this.isbPayloadDAO.create(isbPayload);
                    } catch (WhichDoctorDaoException wde) {
                        dataLogger.error("Error recording ISB payload: " + wde.getMessage());
                    }
                }

            } catch (DataAccessException de) {
                dataLogger.error("Error creating ISB message: " + de.getMessage());
            }
        }
        return isbMessageId;
    }

    /**
     * Update the process status of the ISB message.
     *
     * @param id the id
     * @param processed the processed
     *
     * @return true, if successful
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final boolean updateProcessStatus(final int id, final boolean processed) throws WhichDoctorDaoException {

        boolean success = false;

        final String updateSQL = this.getSQL().getValue("isbmessage/updateProcessStatus");

        try {
            final int updateCount = this.getIsbJdbcTemplate().update(updateSQL, new Object[] { processed, id });

            if (updateCount > 0) {
                success = true;
            }

        } catch (DataAccessException de) {
            dataLogger.error("Error updating the ISB message: " + de.getMessage());
        }
        return success;
    }

    /**
     * Delete the IsbMessageBean.
     *
     * @param message the message
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return true, if successful
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final boolean delete(final IsbMessageBean message, final UserBean checkUser,
            final PrivilegesBean privileges) throws WhichDoctorDaoException {

        if (!privileges.getPrivilege(checkUser, "systemAdmin", "delete")) {
            throw new WhichDoctorDaoException("Insufficient user credentials " + "to delete ISB messages");
        }

        boolean success = false;

        ArrayList<Object> parameters = new ArrayList<Object>();
        parameters.add(true);

        StringBuffer sqlWHERE = new StringBuffer();
        if (message.getId() > 0) {
            sqlWHERE.append(" AND isbmessages.Id = ?");
            parameters.add(String.valueOf(message.getId()));
        }
        if (StringUtils.isNotBlank(message.getAction())) {
            sqlWHERE.append(" AND isbmessages.Action = ?");
            parameters.add(message.getAction());
        }
        if (StringUtils.isNotBlank(message.getTarget())) {
            sqlWHERE.append(" AND isbmessages.IsbTarget = ?");
            parameters.add(message.getTarget());
        }
        if (StringUtils.isNotBlank(message.getIdentifier())) {
            sqlWHERE.append(" AND isbmessages.Identifier = ?");
            parameters.add(message.getIdentifier());
        }

        if (StringUtils.equalsIgnoreCase(message.getDescription(), "Inbound")) {
            sqlWHERE.append(" AND isbmessages.IsInbound = true");
        }

        if (StringUtils.equalsIgnoreCase(message.getDescription(), "Outbound")) {
            sqlWHERE.append(" AND isbmessages.IsInbound = false");
        }

        // Delete the related ISB payload first
        final String deletePayloadSQL = this.getSQL().getValue("isbpayload/delete") + sqlWHERE.toString();

        try {
            final int deleteCount = this.getIsbJdbcTemplate().update(deletePayloadSQL, parameters.toArray());

            dataLogger.info("ISB payload records deleted: " + deleteCount);

        } catch (DataAccessException de) {
            dataLogger.error("Error deleting ISB payload: " + de.getMessage());
        }

        final String deleteSQL = this.getSQL().getValue("isbmessage/delete") + sqlWHERE.toString();

        if (dataLogger.isDebugEnabled()) {
            dataLogger.debug("Delete SQL: " + deleteSQL);
            for (Object parameter : parameters) {
                dataLogger.debug("Delete parmater: " + String.valueOf(parameter));
            }
        }

        try {
            final int deleteCount = this.getIsbJdbcTemplate().update(deleteSQL, parameters.toArray());

            if (deleteCount > 0) {
                success = true;
            }

        } catch (DataAccessException de) {
            dataLogger.error("Error deleting ISB message: " + de.getMessage());
        }
        return success;
    }

    /**
     * Resend outbound ISB messages that have been processed (i.e. sent) to the ISB.
     * The function resets the processed status of the selected ISB messages to false.
     *
     * @param message the IsbMessage containing search parameters (Identifier, Target)
     * @param startDate the start time. If null no messages are resent.
     * @param endDate the end time. If null all messages since the start time are resent.
     *
     * @return the number of records resent
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final int resend(final IsbMessageBean message, final Date startDate, final Date endDate)
            throws WhichDoctorDaoException {

        int resendCount = 0;

        final StringBuffer resendWhere = new StringBuffer();
        final ArrayList<Object> parameters = new ArrayList<Object>();

        if (message != null) {

            if (StringUtils.isNotBlank(message.getIdentifier())) {
                resendWhere.append(" AND isbmessages.Identifier = ?");
                parameters.add(message.getIdentifier());
            }

            if (StringUtils.isNotBlank(message.getTarget())) {
                resendWhere.append(" AND isbmessages.IsbTarget = ?");
                parameters.add(message.getTarget());
            }
        }

        if (startDate != null) {

            if (endDate != null) {
                resendWhere.append(" AND isbmessages.Created BETWEEN ? AND ?");
                parameters.add(startDate);
                parameters.add(endDate);
            } else {
                resendWhere.append(" AND isbmessages.Created >= ?");
                parameters.add(startDate);
            }

            final String resendSQL = this.getSQL().getValue("isbmessage/resend") + resendWhere.toString();

            dataLogger.debug("Resend SQL: " + resendSQL);

            try {
                resendCount = this.getIsbJdbcTemplate().update(resendSQL, parameters.toArray());

            } catch (DataAccessException de) {
                dataLogger.error("Error resending ISB messages " + message.getId() + ": " + de.getMessage());
                throw new WhichDoctorDaoException("Error resending ISB messages: " + de.getMessage());
            }
        }
        return resendCount;
    }

    /**
     * Load isb message bean.
     *
     * @param rs the rs
     *
     * @return the isb message bean
     *
     * @throws SQLException the SQL exception
     */
    private IsbMessageBean loadIsbMessageBean(final ResultSet rs) throws SQLException {

        final IsbMessageBean message = new IsbMessageBean();

        message.setId(rs.getInt("Id"));
        message.setSource(rs.getString("Source"));
        message.setTarget(rs.getString("IsbTarget"));
        message.setAction(rs.getString("Action"));
        message.setIdentifier(rs.getString("Identifier"));
        message.setIsInbound(rs.getBoolean("IsInbound"));
        message.setProcessed(rs.getBoolean("Processed"));
        try {
            message.setCreatedDate(rs.getTimestamp("Created"));
        } catch (SQLException e) {
            dataLogger.debug("Error reading Created date: " + e.getMessage());
        }
        // Load the ISB payload
        try {
            message.setIsbPayload(this.isbPayloadDAO.loadSiblingOf(message.getId()));
        } catch (WhichDoctorDaoException wde) {
            dataLogger.debug("Error loading ISB payload: " + wde.getMessage());
        }

        return message;
    }
}