Java tutorial
/******************************************************************************* * 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); } } }