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

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.dao.GroupDAOImpl.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.BuilderBean;
import com.sfs.beans.ObjectTypeBean;
import com.sfs.beans.PrivilegesBean;
import com.sfs.beans.UserBean;
import com.sfs.whichdoctor.beans.GroupBean;
import com.sfs.whichdoctor.beans.CandidateBean;
import com.sfs.whichdoctor.beans.IsbTransactionBean;
import com.sfs.whichdoctor.beans.ItemBean;
import com.sfs.whichdoctor.beans.VoteBean;
import com.sfs.whichdoctor.beans.WhichDoctorCoreIdentityBean;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Collection;
import java.util.TreeMap;
import java.util.ArrayList;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * The Class GroupDAOImpl.
 *
 * @author David Harrison
 */
public class GroupDAOImpl extends WhichDoctorCoreObjectDAOImpl implements GroupDAO {

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

    /** The isb transaction dao. */
    @Resource
    private IsbTransactionDAO isbTransactionDAO;

    /** The candidate dao. */
    @Resource
    private CandidateDAO candidateDAO;

    /** The vote dao. */
    @Resource
    private VoteDAO voteDAO;

    /**
     * Load a GroupBean for the specified groupId.
     *
     * @param groupId the group id
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean load(final int groupId) throws WhichDoctorDaoException {
        return load(groupId, new BuilderBean());
    }

    /**
     * Load a GroupBean for the specified groupId and provided load details.
     *
     * @param groupId the group id
     * @param loadDetails the load details
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean load(final int groupId, final BuilderBean loadDetails) throws WhichDoctorDaoException {
        return load(groupId, loadDetails, false);
    }

    /**
     * Load a GroupBean for the specified groupId and provided load details.
     *
     * @param groupId the group id
     * @param loadDetails the load details
     * @param useWriterConn use the writer connection
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private GroupBean load(final int groupId, final BuilderBean loadDetails, final boolean useWriterConn)
            throws WhichDoctorDaoException {

        GroupBean group = null;

        JdbcTemplate jdbcTemplate = this.getJdbcTemplateReader();
        if (useWriterConn) {
            jdbcTemplate = this.getJdbcTemplateWriter();
        }

        final String loadSQL = getSQL().getValue("group/load") + " AND groups.GroupId = ? GROUP BY groups.GroupId";

        try {
            group = (GroupBean) jdbcTemplate.queryForObject(loadSQL, new Object[] { groupId }, new RowMapper() {
                public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                    return loadGroup(rs, loadDetails);
                }
            });

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

    /**
     * Load a GroupBean for the specified groupId.
     *
     * @param name the name
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean load(final String name) throws WhichDoctorDaoException {
        return load(name, new BuilderBean());
    }

    /**
     * Load a GroupBean for the specified name and provided load details.
     *
     * @param name the name
     * @param loadDetails the load details
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean load(final String name, final BuilderBean loadDetails) throws WhichDoctorDaoException {

        final String loadSQL = getSQL().getValue("group/loadName");

        int groupGUID = 0;

        try {
            groupGUID = this.getJdbcTemplateReader().queryForInt(loadSQL, new Object[] { name });

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

        if (groupGUID > 0) {
            return loadGUID(groupGUID, loadDetails);
        } else {
            throw new WhichDoctorDaoException("No group matching that name could be identified");
        }
    }

    /**
     * Load a GroupBean for the specified GUID.
     *
     * @param guid the guid
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean loadGUID(final int guid) throws WhichDoctorDaoException {
        return loadGUID(guid, new BuilderBean());
    }

    /**
     * Load a GroupBean for the specified GUID and provided load details.
     *
     * @param guid the guid
     * @param loadDetails the load details
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean loadGUID(final int guid, final BuilderBean loadDetails) throws WhichDoctorDaoException {

        GroupBean group = null;

        final String loadSQL = getSQL().getValue("group/load") + " AND groups.Active = true AND groups.GUID = ?"
                + " GROUP BY groups.GroupId";

        try {
            group = (GroupBean) this.getJdbcTemplateReader().queryForObject(loadSQL, new Object[] { guid },
                    new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            return loadGroup(rs, loadDetails);
                        }
                    });

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

    /**
     * Creates the GroupBean.
     *
     * @param group the group
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean create(final GroupBean group, final UserBean checkUser, final PrivilegesBean privileges)
            throws WhichDoctorDaoException {
        group.setActive(true);
        int groupId = save(group, checkUser, privileges, "create");

        return load(groupId, new BuilderBean(), true);
    }

    /**
     * Modify the GroupBean.
     *
     * @param group the group
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return the group bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final GroupBean modify(final GroupBean group, final UserBean checkUser, final PrivilegesBean privileges)
            throws WhichDoctorDaoException {
        // Perform a GroupDN check - if changed need to refresh ISB state
        // Load the existing group
        String groupDN = "";
        try {
            GroupBean existingGroup = loadGUID(group.getGUID());
            groupDN = existingGroup.getGroupDN();
            dataLogger.debug("Existing GroupDN: " + groupDN);
        } catch (Exception e) {
            dataLogger.error("Error loading group prior to modify: " + e.getMessage());
        }
        group.setActive(true);
        int groupId = save(group, checkUser, privileges, "modify");

        // If the groupId is greater than 0 the modification was a success
        // Check to see if the existing value of the GroupDN is different
        // to the updated value.
        dataLogger.debug("Updated GroupDN: " + group.getGroupDN());
        if (!StringUtils.equalsIgnoreCase(group.getGroupDN(), groupDN)) {
            // The GroupDN values are different - revise the ISB
            dataLogger.debug("Updating the GroupDN values for the related objects");
            try {
                updateGroupDN(group.getGUID(), groupDN);
            } catch (Exception e) {
                dataLogger.error("Error updating ISB after change of GroupDN: " + e.getMessage());
            }
        }
        return load(groupId, new BuilderBean(), true);
    }

    /**
     * Deletes the GroupBean.
     *
     * @param group the group
     * @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 GroupBean group, final UserBean checkUser, final PrivilegesBean privileges)
            throws WhichDoctorDaoException {

        boolean success = false;

        if (privileges.getPrivilege(checkUser, group.getPermission(), "delete")) {
            // Before deleting the group remove its child objects
            final BuilderBean loadDetails = new BuilderBean();
            loadDetails.setParameter("LOAD_ALL", true);
            try {
                final GroupBean deleteObj = this.loadGUID(group.getGUID(), loadDetails);
                deleteAssociatedObjects(deleteObj, checkUser, privileges);

            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error deleting children: " + wde.getMessage(), wde);
                throw new WhichDoctorDaoException("Error deleting children objects: " + wde.getMessage());
            }
        }

        /* Delete the group */
        group.setActive(false);
        int deletedId = save(group, checkUser, privileges, "delete");
        if (deletedId > 0) {
            success = true;
        }

        return success;
    }

    /**
     * Save the updated GroupBean.
     *
     * @param group the group
     * @param checkUser the check user
     * @param privileges the privileges
     * @param action the action
     *
     * @return the int
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private int save(final GroupBean group, final UserBean checkUser, final PrivilegesBean privileges,
            final String action) throws WhichDoctorDaoException {

        // Save action requires the essential information
        // to be supplied within the group bean
        if (StringUtils.isBlank(group.getName())) {
            throw new WhichDoctorDaoException("Group field cannot be an empty string");
        }
        if (StringUtils.isBlank(group.getType())) {
            throw new WhichDoctorDaoException("Group type field cannot be an empty string");
        }
        int typeId = 0;
        try {
            ObjectTypeBean object = this.getObjectTypeDAO().load("Group Type", group.getType(),
                    group.getObjectType());
            typeId = object.getObjectTypeId();
            /* Set the security status */
            group.setPermission(object.getSecurity());
        } catch (Exception e) {
            dataLogger.error("Error loading objecttype for group: " + e.getMessage());
            throw new WhichDoctorDaoException("A valid group type is required");
        }
        if (!privileges.getPrivilege(checkUser, group.getPermission(), action)) {
            throw new WhichDoctorDaoException(
                    "Insufficient user credentials to " + action + " group (" + group.getPermission() + ")");
        }

        int groupId = 0;

        if (group.getYear() == 0) {
            Calendar currentDate = Calendar.getInstance();
            group.setYear(currentDate.get(Calendar.YEAR));
        }

        Timestamp sqlTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis());

        ArrayList<Object> parameters = new ArrayList<Object>();
        parameters.add(group.getName());
        parameters.add(group.getDescription());
        parameters.add(typeId);
        parameters.add(group.getYear());
        parameters.add(group.getColour());
        parameters.add(group.getWeighting());
        parameters.add(group.getGroupDN());
        parameters.add(group.getActive());
        parameters.add(sqlTimeStamp);
        parameters.add(checkUser.getDN());
        parameters.add(group.getLogMessage(action));

        try {
            Integer[] result = this.performUpdate("group", group.getGUID(), parameters, "Group", checkUser, action);
            /* Set the returned guid and id values */
            group.setGUID(result[0]);
            groupId = result[1];
        } catch (Exception e) {
            dataLogger.error("Error processing group record: " + e.getMessage());
            throw new WhichDoctorDaoException("Error processing group record: " + e.getMessage());
        }

        if (groupId > 0) {
            dataLogger.info(checkUser.getDN() + " created groupId: " + String.valueOf(groupId));
        }

        return groupId;
    }

    /**
     * Delete the objects associated with the supplied GroupBean.
     *
     * @param deleteObjects the delete objects
     * @param checkUser the check user
     * @param privileges the privileges
     */
    private void deleteAssociatedObjects(final GroupBean deleteObjects, final UserBean checkUser,
            final PrivilegesBean privileges) {

        if (deleteObjects.getItems() != null) {
            String isbMapping = null;
            if (StringUtils.isNotBlank(deleteObjects.getGroupDN())) {
                isbMapping = "";
            }
            for (ItemBean item : deleteObjects.getItems().values()) {
                try {
                    item.setLogMessage(item.getLogMessage("delete"));
                    this.getItemDAO().delete(item, checkUser, privileges, isbMapping);
                } catch (WhichDoctorDaoException wde) {
                    dataLogger.error("Error deleting group item: " + wde.getMessage());
                }
            }
        }

        if (deleteObjects.getVotesCast() != null) {
            for (VoteBean vote : deleteObjects.getVotesCast().values()) {
                try {
                    vote.setLogMessage(vote.getLogMessage("delete"));
                    this.voteDAO.delete(vote, checkUser, privileges);
                } catch (WhichDoctorDaoException wde) {
                    dataLogger.error("Error deleting cast vote: " + wde.getMessage());
                }
            }
        }

        if (deleteObjects.getCandidates() != null) {
            for (CandidateBean candidate : deleteObjects.getCandidates()) {
                try {
                    candidate.setLogMessage(candidate.getLogMessage("delete"));
                    this.candidateDAO.delete(candidate, checkUser, privileges);
                } catch (WhichDoctorDaoException wde) {
                    dataLogger.error("Error deleting candidate: " + wde.getMessage());
                }
            }
        }

        this.deleteMemos(deleteObjects, checkUser, privileges);
    }

    /**
     * Load group.
     *
     * @param rs the rs
     * @param loadDetails the load details
     *
     * @return the group bean
     *
     * @throws SQLException the SQL exception
     */
    private GroupBean loadGroup(final ResultSet rs, final BuilderBean loadDetails) throws SQLException {

        GroupBean group = new GroupBean();

        group.setId(rs.getInt("GroupId"));
        group.setGUID(rs.getInt("GUID"));
        group.setObjectType(rs.getString("ObjectType"));
        group.setType(rs.getString("Type"));
        group.setYear(rs.getInt("Year"));
        group.setColour(rs.getString("Colour"));
        group.setWeighting(rs.getInt("Weighting"));
        group.setPermission(rs.getString("Permission"));
        group.setName(rs.getString("Name"));
        group.setDescription(rs.getString("Description"));
        group.setGroupDN(rs.getString("GroupDN"));
        group.setItemCount(rs.getInt("ItemCount"));

        if (loadDetails.getBoolean("TAGS")) {
            try {
                group.setTags(this.getTagDAO().load(group.getGUID(), loadDetails.getString("USERDN"), true));
            } catch (Exception e) {
                dataLogger.error("Error loading tags for group: " + e.getMessage());
            }
        }

        group.setActive(rs.getBoolean("Active"));
        if (loadDetails.getBoolean("HISTORY")) {
            try {
                group.setCreatedDate(rs.getTimestamp("CreatedDate"));
            } catch (SQLException sqe) {
                dataLogger.debug("Error loading CreatedDate: " + sqe.getMessage());
            }
            group.setCreatedBy(rs.getString("CreatedBy"));
            try {
                group.setModifiedDate(rs.getTimestamp("ModifiedDate"));
            } catch (SQLException sqe) {
                dataLogger.debug("Error loading ModifiedDate: " + sqe.getMessage());
            }
            group.setModifiedBy(rs.getString("ModifiedBy"));
        }

        if (loadDetails.getBoolean("ITEMS")) {
            int referenceId = 0;
            try {
                referenceId = Integer.parseInt(loadDetails.getString("REFERENCEID"));
            } catch (Exception e) {
                dataLogger.debug("Error parsing ReferenceId: " + e.getMessage());
            }
            try {
                group.setItems(
                        this.getItemDAO().load(group.getGUID(), true, "Group", group.getObjectType(), referenceId,
                                loadDetails.getString("ITEMS_STARTDATE"), loadDetails.getString("ITEMS_ENDDATE")));
            } catch (Exception e) {
                dataLogger.error("Error loading items: " + e.getMessage());
            }
        }

        if (StringUtils.equalsIgnoreCase(group.getType(), "Election") && loadDetails.getBoolean("VOTES")) {
            /* Load the votes for this election group */
            try {
                TreeMap<Integer, VoteBean> votesCast = this.voteDAO.load(group.getGUID());
                group.setVotesCast(votesCast);
                group.setCastVoteCount(votesCast.keySet().size());
            } catch (Exception e) {
                dataLogger.error("Error loading votes cast: " + e.getMessage());
            }
            try {
                TreeMap<Integer, Integer> eligibleVotes = this.voteDAO.loadEligible(group.getGUID());
                group.setEligibleVoteCount(eligibleVotes.keySet().size());
            } catch (Exception e) {
                dataLogger.error("Error loading eligible vote count: " + e.getMessage());
            }
        }
        if (StringUtils.equalsIgnoreCase(group.getType(), "Election") && loadDetails.getBoolean("CANDIDATES")) {
            // * Load the candidates for this election group */
            try {
                Collection<CandidateBean> candidates = this.candidateDAO.load(group.getGUID(), loadDetails);
                group.setCandidates(candidates);
            } catch (Exception e) {
                dataLogger.error("Error loading votes cast: " + e.getMessage());
            }
        }

        if (loadDetails.getBoolean("IDENTITIES")) {

            boolean loadIdentities = false;
            if (StringUtils.equalsIgnoreCase(group.getObjectType(), "Organisations")
                    || StringUtils.equalsIgnoreCase(group.getObjectType(), "Members")) {
                loadIdentities = true;
            }
            if (loadIdentities && group.getItems() != null) {
                group.setItems(loadIdentities(group.getItems()));
            }
        }

        if (loadDetails.getBoolean("MEMO")) {
            try {
                group.setMemo(this.getMemoDAO().load(group.getGUID(), loadDetails.getBoolean("MEMO_FULL")));
            } catch (Exception e) {
                dataLogger.error("Error loading memos: " + e.getMessage());
            }
        }

        if (loadDetails.getBoolean("CREATED")) {
            UserBean user = new UserBean();
            user.setDN(rs.getString("CreatedBy"));
            user.setPreferredName(rs.getString("CreatedFirstName"));
            user.setLastName(rs.getString("CreatedLastName"));
            group.setCreatedUser(user);
        }
        if (loadDetails.getBoolean("MODIFIED")) {
            UserBean user = new UserBean();
            user.setDN(rs.getString("ModifiedBy"));
            user.setPreferredName(rs.getString("ModifiedFirstName"));
            user.setLastName(rs.getString("ModifiedLastName"));
            group.setModifiedUser(user);
        }
        return group;
    }

    /**
     * Load identities.
     *
     * @param items the group's items
     *
     * @return the tree map< string, item bean>
     */
    private TreeMap<String, ItemBean> loadIdentities(final TreeMap<String, ItemBean> items) {

        for (String key : items.keySet()) {
            ItemBean item = items.get(key);

            WhichDoctorCoreIdentityBean identity = new WhichDoctorCoreIdentityBean();

            identity.setGUID(item.getObject2GUID());
            identity.setDescription(item.getName());

            // Load the contact details for this identity
            try {
                // Load the first work address (or primary if none)
                identity.setAddress(this.getAddressDAO().load(identity.getGUID(), false, "Work", "Postal"));
            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error loading identity addresses: " + wde.getMessage());
            }
            try {
                // Load all the phone numbers (mobile, work phone + fax)
                identity.setPhone(this.getPhoneDAO().load(identity.getGUID(), true));
            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error loading identity phones: " + wde.getMessage());
            }
            try {
                // Load the work email (or primary if none)
                identity.setEmail(
                        this.getEmailDAO().load(identity.getGUID(), false, "Unsecured Email", "Work Email"));
            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error loading identity emails: " + wde.getMessage());
            }
            item.setIdentity(identity);

            items.put(key, item);
        }
        return items;
    }

    /**
     * Updates the the related ISB entities if a group's GroupDN value has
     * changed.
     *
     * @param guid - The GUID of the group
     * @param oldDN the old dn
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private void updateGroupDN(final int guid, final String oldDN) throws WhichDoctorDaoException {
        /* Load the Group along with its corresponding items */
        BuilderBean loadDetails = new BuilderBean();
        loadDetails.setParameter("ITEMS", true);
        GroupBean group = loadGUID(guid, loadDetails);

        TreeMap<String, ItemBean> items = new TreeMap<String, ItemBean>();
        if (group != null) {
            if (StringUtils.equalsIgnoreCase(group.getObjectType(), "Members") && group.getItems() != null) {
                /* This is a group of people that has a valid set of items */
                items = group.getItems();
            }
        }
        for (ItemBean item : items.values()) {
            /* Initiate the ISB transaction with the person's GUID */
            IsbTransactionBean isbTransaction = this.isbTransactionDAO.begin(item.getObject2GUID());
            /* Update the group DN */
            this.isbTransactionDAO.updateGroupDN(isbTransaction, group.getGUID(), oldDN);
        }
    }
}