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.ObjectTypeBean; import com.sfs.beans.PrivilegesBean; import com.sfs.beans.UserBean; import com.sfs.dao.ObjectTypeDAO; import com.sfs.dao.SFSDaoException; import com.sfs.whichdoctor.beans.AddressBean; import com.sfs.whichdoctor.beans.IsbTransactionBean; import com.sfs.whichdoctor.beans.PreferencesBean; import com.sfs.whichdoctor.beans.WhichDoctorBean; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.net.URL; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.codehaus.xfire.client.Client; import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.RowMapper; /** * The Class AddressDAOImpl. */ public class AddressDAOImpl extends WhichDoctorBaseDAOImpl implements AddressDAO { /** The data logger. */ private static Logger dataLogger = Logger.getLogger(AddressDAOImpl.class); /** The postcode url. */ private String postcodeUrl; /** The object type dao. */ @Resource private ObjectTypeDAO objectTypeDAO; /** The isb transaction dao. */ @Resource private IsbTransactionDAO isbTransactionDAO; /** The address verification dao. */ @Resource private AddressVerificationDAO addressVerificationDAO; /** The person dao. */ @Resource private PersonDAO personDAO; /** The preferences dao. */ @Resource private PreferencesDAO preferencesDAO; /** The organisation dao. */ @Resource private OrganisationDAO organisationDAO; /** The search index dao. */ @Resource private SearchIndexDAO searchIndexDAO; /** The Constant MAX_ADDRESSES. */ private static final int MAXADDRESSLINES = 7; /** * Sets the postcode url. * * @param postcodeUrlVal the new postcode url */ public final void setPostcodeUrl(final String postcodeUrlVal) { this.postcodeUrl = postcodeUrlVal; } /** * Get a collection of AddressBeans for a specified GUID. * * @param guid the guid * @param allAddresses the all addresses * @param addressClass the address class * @param addressType the address type * * @return the collection< address bean> * * @throws com.sfs.whichdoctor.dao.WhichDoctorDaoException * @throws * WhichDoctorDaoException the which doctor dao exception */ @SuppressWarnings("unchecked") public final Collection<AddressBean> load(final int guid, final boolean allAddresses, final String addressClass, final String addressType) throws WhichDoctorDaoException { dataLogger.info("Addresses for GUID: " + guid + " requested"); boolean specificAddress = false; String sql = getSQL().getValue("address/load") + " WHERE address.Active = true AND address.ReferenceGUID = ?"; Collection<Object> variables = new ArrayList<Object>(); /* The GUID value is the first variable */ variables.add(guid); if (addressClass != null) { if (addressClass.compareTo("") != 0 && addressClass.compareTo("Preferred") != 0) { sql += " AND addresstype.Class = ?"; variables.add(addressClass); specificAddress = true; } } if (addressType != null) { if (addressType.compareTo("") != 0 && addressType.compareTo("Preferred") != 0) { sql += " AND addresstype.Name = ?"; variables.add(addressType); specificAddress = true; } } sql += " ORDER BY PrimaryAddress DESC"; if (!allAddresses) { sql += " LIMIT 1"; } Collection<AddressBean> addresses = new ArrayList<AddressBean>(); try { addresses = this.getJdbcTemplateReader().query(sql, variables.toArray(), new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadAddress(rs); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } if (specificAddress && addresses.size() == 0) { /** * Specific address type defined but no result found Try getting a * more generic address */ if (addressType != null) { if (addressType.compareTo("") != 0) { addresses = load(guid, allAddresses, addressClass, null); } } if (addresses.size() == 0) { if (addressClass != null) { if (addressClass.compareTo("") != 0) { addresses = load(guid, allAddresses, null, null); } } } } return addresses; } /** * Load and AddressBean based on its id. * * @param addressId the address id * @return the address bean * @throws WhichDoctorDaoException the which doctor dao exception */ @SuppressWarnings("unchecked") public final AddressBean load(final int addressId) throws WhichDoctorDaoException { dataLogger.info("Getting addressId:" + addressId); final String loadId = this.getSQL().getValue("address/load") + " WHERE address.AddressId = ?"; AddressBean address = null; try { address = (AddressBean) this.getJdbcTemplateReader().queryForObject(loadId, new Object[] { addressId }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadAddress(rs); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } return address; } /** * Load and AddressBean based on its guid. * * @param guid the guid * @return the address bean * @throws WhichDoctorDaoException the which doctor dao exception */ @SuppressWarnings("unchecked") public final AddressBean loadGUID(final int guid) throws WhichDoctorDaoException { dataLogger.info("Getting guid:" + guid); final String loadGUID = getSQL().getValue("address/load") + " WHERE address.GUID = ? AND Active = true"; AddressBean address = null; try { address = (AddressBean) this.getJdbcTemplateReader().queryForObject(loadGUID, new Object[] { guid }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadAddress(rs); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } return address; } /** * Load all the active AddressBeans. * * @return the collection * @throws WhichDoctorDaoException the which doctor dao exception */ @SuppressWarnings("unchecked") public final Collection<AddressBean> loadActive() throws WhichDoctorDaoException { final String loadActive = getSQL().getValue("address/load") + " WHERE address.Active = true"; Collection<AddressBean> addresses = new ArrayList<AddressBean>(); try { addresses = this.getJdbcTemplateReader().query(loadActive, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadAddress(rs); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for search: " + ie.getMessage()); } return addresses; } /** * Create the AddressBean. * * @param address the address * @param checkUser the check user * @param privileges the privileges * @return the int * @throws WhichDoctorDaoException the which doctor dao exception */ public final int create(final AddressBean address, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { // Get the geocode for the address address.setGeocode(getGeocode(address)); address.setActive(true); int id = save(address, checkUser, privileges, "create"); AddressBean newAddress = this.load(id); performAddressVerification(null, newAddress); return id; } /** * Modify the AddressBean. * * @param address the address * @param checkUser the check user * @param privileges the privileges * @return the int * @throws WhichDoctorDaoException the which doctor dao exception */ public final int modify(final AddressBean address, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { AddressBean oldAddress = this.loadGUID(address.getGUID()); if (oldAddress.compare(address, true)) { // The address has been changed, get the geocode for the address address.setGeocode(getGeocode(address)); address.setVerificationStatus("Unverified address"); } else { // The address has not been changed, carry over the geocode and verification address.setGeocode(oldAddress.getGeocode()); address.setVerificationStatus(oldAddress.getVerificationStatus()); } // If the address has been verified set the appropriate status if (StringUtils.equalsIgnoreCase(address.getLogMessage("modify"), "Automatic address verification update")) { address.setVerificationStatus("Verified address"); } address.setActive(true); int id = save(address, checkUser, privileges, "modify"); AddressBean newAddress = this.load(id); if (!StringUtils.equalsIgnoreCase(address.getLogMessage("modify"), "Automatic address verification update")) { performAddressVerification(oldAddress, newAddress); } return id; } /** * Delete the AddressBean. * * @param address the address * @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 AddressBean address, final UserBean checkUser, final PrivilegesBean privileges) throws WhichDoctorDaoException { address.setActive(false); int deleted = save(address, checkUser, privileges, "delete"); boolean success = false; if (deleted > 0) { success = true; performAddressVerification(address, null); } return success; } /** * Save the AddressBean. * * @param address the address * @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 AddressBean address, final UserBean checkUser, final PrivilegesBean privileges, final String action) throws WhichDoctorDaoException { // Check required information within address bean is present if (address.getContactClass() == null) { throw new WhichDoctorDaoException("Contact class cannot be null"); } if (address.getContactClass().compareTo("") == 0) { throw new WhichDoctorDaoException("Contact class cannot be an empty string"); } if (address.getContactType() == null) { throw new WhichDoctorDaoException("Contact type cannot be null"); } if (address.getContactType().compareTo("") == 0) { throw new WhichDoctorDaoException("Contact type cannot be an empty string"); } if (address.getState() == null) { address.setState(""); } if (address.getCountry() == null) { throw new WhichDoctorDaoException("Addresses' country field cannot be null"); } if (address.getCountry().compareTo("") == 0) { throw new WhichDoctorDaoException("Addresses' country field cannot be an empty string"); } if (address.getReferenceGUID() == 0) { throw new WhichDoctorDaoException("Address requires a valid Reference GUID number"); } if (!privileges.getPrivilege(checkUser, "addresses", action)) { throw new WhichDoctorDaoException("Insufficient user credentials to " + action + " address entry"); } /* Identify the AddressTypeId */ int addressTypeId = 0; try { ObjectTypeBean object = this.getObjectTypeDAO().load("Address Type", address.getContactType(), address.getContactClass()); addressTypeId = object.getObjectTypeId(); } catch (SFSDaoException sfe) { dataLogger.error("Error loading objecttype for address type: " + sfe.getMessage()); throw new WhichDoctorDaoException("Address type not found"); } /* Identify the VerificationStatusId */ int verificationStatusId = 0; try { ObjectTypeBean object = this.getObjectTypeDAO().load("Address Verification Status", "", address.getVerificationStatus()); verificationStatusId = object.getObjectTypeId(); } catch (SFSDaoException sfe) { dataLogger.error("Error loading address verification status for address: " + sfe.getMessage()); throw new WhichDoctorDaoException("Address requires a valid address verification status"); } /* Identify the StateId */ int stateId = 0; try { ObjectTypeBean object = this.getObjectTypeDAO().load("State/Country", address.getState(), address.getCountry()); stateId = object.getObjectTypeId(); } catch (SFSDaoException sfe) { dataLogger.error("Error loading state/country for address: " + sfe.getMessage()); throw new WhichDoctorDaoException("Address requires a valid country/state combination"); } /* Identify the RegionId */ if (StringUtils.isBlank(address.getRegion())) { address.setRegion(getRegion(address.getCity(), address.getState(), address.getCountry())); } int regionId = 0; try { ObjectTypeBean object = this.getObjectTypeDAO().load("Region", "", address.getRegion()); regionId = object.getObjectTypeId(); } catch (SFSDaoException sfe) { dataLogger.error( "Error loading objecttype for region: " + address.getRegion() + " - " + sfe.getMessage()); } int addressId = 0; /* Perform a postcode lookup if none is defined */ boolean postCodeExists = false; if (address.getPostCode() != null) { if (address.getPostCode().compareTo("") != 0) { // PostCode exists postCodeExists = true; } } if (!postCodeExists) { boolean doLookup = false; if (address.getCountry().compareTo("New Zealand") == 0) { doLookup = true; } if (address.getCountry().compareTo("Australia") == 0) { doLookup = true; } if (doLookup) { // Perform PostCode lookup address.setPostCode(this.getPostcode(address)); } } // The parameters for inserting into the database final ArrayList<Object> parameters = setParameters(address, addressTypeId, stateId, regionId, verificationStatusId, checkUser, action); /* Begin the ISB transaction */ IsbTransactionBean isbTransaction = this.isbTransactionDAO.begin(address.getReferenceGUID()); try { Integer[] result = this.performUpdate("address", address.getGUID(), parameters, "Address", checkUser, action); /* Set the returned guid and id values */ address.setGUID(result[0]); addressId = result[1]; } catch (Exception e) { dataLogger.error("Error processing accreditation record: " + e.getMessage()); throw new WhichDoctorDaoException("Error processing accreditation record: " + e.getMessage()); } if (addressId > 0) { // Update person city/region/primary address details // to reflect modification updatePrimary(address, action); /* Update the region and resident country indexes */ updateIndexes(address.getReferenceGUID()); /* Commit the ISB transaction */ this.isbTransactionDAO.commit(isbTransaction); } return addressId; } /** * Gets the postcode. * * @param address the address * * @return the postcode */ private String getPostcode(final AddressBean address) { String postCode = ""; String addressField = ""; for (int i = 0; i < address.getAddressFieldCount(); i++) { addressField += address.getAddressField(i); if (i + 1 < address.getAddressFieldCount()) { addressField += ","; } } String stateField = address.getState(); String countryField = address.getCountry(); /* Test that none of these fields are null */ if (stateField == null) { stateField = ""; } if (countryField == null) { countryField = ""; } dataLogger.info("Performing postcode lookup: " + addressField + "," + stateField + "," + countryField); /* Perform a web service call using XFire libraries */ try { Client client = new Client(new URL(this.postcodeUrl)); Object[] results = client.invoke("lookup", new Object[] { addressField, stateField, countryField }); postCode = (String) results[0]; dataLogger.info("Postcode returned: " + (String) results[0]); } catch (Exception e) { dataLogger.error("Error performing postcode web service lookup: " + e.getMessage()); } return postCode; } /** * Gets the geocode. * * @param address the address * * @return the geocode */ private String getGeocode(final AddressBean address) { String geoCode = ""; String addressField = ""; for (int i = 0; i < address.getAddressFieldCount(); i++) { addressField += address.getAddressField(i); if (i + 1 < address.getAddressFieldCount()) { addressField += ","; } } String stateField = address.getState(); String countryField = address.getCountry(); // Test that none of these fields are null if (stateField == null) { stateField = ""; } if (countryField == null) { countryField = ""; } dataLogger.info("Performing geocode lookup: " + addressField + "," + stateField + "," + countryField); /* Perform a web service call using XFire libraries */ try { Client client = new Client(new URL(this.postcodeUrl)); Object[] results = client.invoke("geocode", new Object[] { addressField, stateField, countryField }); geoCode = (String) results[0]; dataLogger.info("Geocode returned: " + (String) results[0]); } catch (Exception e) { dataLogger.error("Error performing geocode web service lookup: " + e.getMessage()); } return geoCode; } /** * Gets the state based on the supplied state abbreviation. * * @param stateAbbreviation the state abbreviation * @return the state */ public final String getStateFromAbbreviation(final String stateAbbreviation) { String state = ""; if (StringUtils.isNotBlank(stateAbbreviation)) { try { state = this.getJdbcTemplateReader().queryForObject( this.getSQL().getValue("address/findStateFromAbbreviation"), new Object[] { stateAbbreviation }, String.class); } catch (DataAccessException dae) { dataLogger.error("Error loading state: " + dae.getMessage()); } if (StringUtils.isBlank(state)) { state = stateAbbreviation; } } return state; } /** * Gets the country based on the supplied country abbreviation. * * @param countryAbbreviation the country abbreviation * @return the country */ public final String getCountryFromAbbreviation(final String countryAbbreviation) { String country = ""; if (StringUtils.isNotBlank(countryAbbreviation)) { try { country = this.getJdbcTemplateReader().queryForObject( this.getSQL().getValue("address/findCountryFromAbbreviation"), new Object[] { countryAbbreviation }, String.class); } catch (DataAccessException dae) { dataLogger.error("Error loading country: " + dae.getMessage()); } if (StringUtils.isBlank(country)) { country = countryAbbreviation; } } return country; } /** * Gets the state based on the supplied city and country values. * * @param city the city * @param country the country * @return the state */ public final String getState(final String city, final String country) { String state = ""; if (StringUtils.isNotBlank(city) && StringUtils.isNotBlank(country)) { try { state = this.getJdbcTemplateReader().queryForObject(this.getSQL().getValue("address/findState"), new Object[] { city, country }, String.class); } catch (DataAccessException dae) { dataLogger.error("Error loading state: " + dae.getMessage()); } } return state; } /** * Gets the region based on the supplied city, state and country values. * * @param city the city * @param state the state * @param country the country * @return the region */ public final String getRegion(final String city, final String state, final String country) { // By default the region is outside New Zealand String region = "Outside N.Z."; if (StringUtils.equalsIgnoreCase(country, "New Zealand")) { region = "Unknown"; try { region = this.getJdbcTemplateReader().queryForObject(this.getSQL().getValue("address/findRegion"), new Object[] { city, state, country }, String.class); } catch (DataAccessException dae) { dataLogger.error("Error loading region: " + dae.getMessage()); } } return region; } /** * If the AddressBean is primary ensure no other primary entry exists for * the ReferenceGUID. * * @param address the address * @param action the action * * @throws WhichDoctorDaoException the whichdoctor dao exception */ private void updatePrimary(final AddressBean address, final String action) throws WhichDoctorDaoException { if (address.getPrimary()) { if (action.compareTo("delete") != 0) { /* Find old primary address and turn off flag */ this.getJdbcTemplateWriter().update(this.getSQL().getValue("address/updatePrimary"), new Object[] { false, address.getReferenceGUID(), address.getGUID(), true }); } updateAddressIndexes(address, action); } } /** * Update the person/organisation City index field to match the new address. * * @param address the AddressBean * @param action the action * * @return boolean result * * @throws WhichDoctorDaoException the whichdoctor dao exception */ public final boolean updateAddressIndexes(final AddressBean address, final String action) throws WhichDoctorDaoException { String city = ""; String country = ""; int stateId = 0; // Delete the existing indexes try { this.searchIndexDAO.delete(address.getReferenceGUID(), "City"); this.searchIndexDAO.delete(address.getReferenceGUID(), "Country"); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error deleting address indexes: " + wde.getMessage()); } // Update the index if the action is not a delete if (!StringUtils.equalsIgnoreCase(action, "delete")) { if (StringUtils.isNotBlank(address.getCity())) { city = address.getCity(); } try { ObjectTypeBean countryObject = this.objectTypeDAO.load("State/Country", address.getState(), address.getCountry()); country = countryObject.getClassName(); stateId = countryObject.getObjectTypeId(); } catch (SFSDaoException e) { dataLogger.error("Error loading state/country object: " + e.getMessage()); } try { this.searchIndexDAO.update(address.getReferenceGUID(), "City", 0, 0, city); this.searchIndexDAO.update(address.getReferenceGUID(), "Country", stateId, 0, country); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error updating address indexes: " + wde.getMessage()); } } return true; } /** * Update the address geocode. * * @param address the address * @return true, if successful */ public final boolean updateGeocode(final AddressBean address) { boolean success = false; String geocode = getGeocode(address, 0); if (geocode == null) { geocode = ""; } try { final int updateCount = this.getJdbcTemplateWriter().update( this.getSQL().getValue("address/updateGeocode"), new Object[] { geocode, address.getId() }); if (updateCount > 0) { success = true; dataLogger.info("Successfully updated geocode for address Id: " + address.getId()); } } catch (Exception e) { dataLogger.error("Error updating geocode for address Id: " + address.getId() + ", " + e.getMessage()); } return success; } /** * Perform a geocode lookup. * * @param address the address * @param ignoreField the ignore field * @return the geocode */ public final String getGeocode(final AddressBean address, final int ignoreField) { String geoCode = ""; String addressField = ""; for (int i = 0; i < address.getAddressFieldCount(); i++) { addressField += address.getAddressField(i); if (i + 1 < address.getAddressFieldCount()) { addressField += ","; } } String stateField = address.getState(); String countryField = address.getCountry(); /* Test that none of these fields are null */ if (stateField == null) { stateField = ""; } if (countryField == null) { countryField = ""; } /* Perform a web service call using XFire libraries */ try { Client client = new Client(new URL(this.postcodeUrl)); Object[] results = client.invoke("geocode", new Object[] { addressField, stateField, countryField }); geoCode = (String) results[0]; dataLogger.info("Geocode returned: " + (String) results[0]); } catch (Exception e) { dataLogger.error("Error performing geocode web service lookup: " + e.getMessage()); } return geoCode; } /** * Updates the verification status of the supplied address guid. * * @param status the address verification status * @param guid the address guid */ public void updateVerificationStatus(final String status, final int guid) { /* Identify the VerificationStatusId */ int verificationStatusId = 0; try { ObjectTypeBean object = this.getObjectTypeDAO().load("Address Verification Status", "", status); verificationStatusId = object.getObjectTypeId(); } catch (SFSDaoException sfe) { dataLogger.error("Error loading address verification status for address: " + sfe.getMessage()); } if (verificationStatusId > 0) { this.getJdbcTemplateWriter().update(this.getSQL().getValue("address/updateVerificationStatus"), new Object[] { verificationStatusId, guid }); } } /** * Update postcode and geocode. * * @param countryVal the country * @param user the user * @param privileges the privileges * @return the hash map * @throws WhichDoctorDaoException the which doctor dao exception */ @SuppressWarnings("unchecked") public final HashMap<String, Collection<Integer>> updatePostcodeAndGeocode(final String countryVal, final UserBean user, final PrivilegesBean privileges) throws WhichDoctorDaoException { /** * Load the addresses based on the country and update their postcode. * Returns a hashmap containing the GUIDs of addresses 'updated' and * 'not updated' **/ HashMap<String, Collection<Integer>> results = new HashMap<String, Collection<Integer>>(); Collection<Integer> updated = new ArrayList<Integer>(); Collection<Integer> notUpdated = new ArrayList<Integer>(); String country = ""; if (StringUtils.isNotBlank(countryVal)) { country = countryVal; } Collection<AddressBean> addresses = new ArrayList<AddressBean>(); final String loadCountrySQL = getSQL().getValue("address/load") + " WHERE address.Active = true AND loc_state.Class = ?"; try { addresses = this.getJdbcTemplateReader().query(loadCountrySQL, new Object[] { country }, new RowMapper() { public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException { return loadAddress(rs); } }); } catch (IncorrectResultSizeDataAccessException ie) { dataLogger.debug("No results found for this search: " + ie.getMessage()); } for (AddressBean address : addresses) { try { String existingPostcode = address.getPostCode(); String existingGeocode = address.getGeocode(); if (existingPostcode == null) { existingPostcode = ""; } if (existingGeocode == null) { existingGeocode = ""; } String newPostcode = this.getPostcode(address); String newGeocode = this.getGeocode(address); if (newPostcode == null) { newPostcode = ""; } if (newGeocode == null) { newGeocode = ""; } boolean updateAddress = false; if (newPostcode.compareTo("") != 0) { if (newPostcode.compareTo(existingPostcode) != 0) { // A postcode was found update address.setPostCode(newPostcode); updateAddress = true; } } if (newGeocode.compareTo("") != 0) { if (newGeocode.compareTo(existingGeocode) != 0) { // A geocode was found update address.setGeocode(newGeocode); updateAddress = true; } } if (updateAddress) { address.setLogMessage("Refreshed postcode/geocode"); modify(address, user, privileges); updated.add(address.getGUID()); dataLogger.error("Updated postcode/geocode for address GUID: " + address.getGUID()); } else { dataLogger.error("Postcode/geocode not updated for address GUID: " + address.getGUID()); notUpdated.add(address.getGUID()); } } catch (Exception e) { dataLogger.error("Error updating postcode/geocode for address GUID " + address.getGUID() + ": " + e.getMessage()); notUpdated.add(address.getGUID()); } } dataLogger.error("Postcode/geocode update process complete, " + updated.size() + " addresses changed, " + notUpdated.size() + " not updated"); results.put("updated", updated); results.put("not updated", notUpdated); return results; } /** * Gets the region id for the supplied GUID. * Returns the id for "Unknown" region if no valid entries are found. * * @param referenceGUID the reference GUID * * @return the regionId for the supplied reference GUID */ public final int getRegionId(final int referenceGUID) { int regionId = 0; Collection<AddressBean> addresses = null; try { addresses = this.load(referenceGUID, true, null, null); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error loading addresses for GUID: " + wde.getMessage()); } HashMap<Integer, String> regions = new HashMap<Integer, String>(); if (addresses != null) { for (AddressBean address : addresses) { if (!address.getReturnedMail() && !StringUtils.equalsIgnoreCase(address.getRegion(), "Unknown")) { int x = 0; if (address.getRequestNoMail()) { x = 1; } if (address.getPrimary()) { x = 2; } regions.put(x, address.getRegion()); } } } String region = "Unknown"; for (int x : regions.keySet()) { region = regions.get(x); } try { ObjectTypeBean object = this.getObjectTypeDAO().load("Region", "", region); regionId = object.getObjectTypeId(); } catch (Exception e) { dataLogger.error("Error loading objecttype for region: " + e.getMessage()); } return regionId; } /** * Gets the state/country id for the supplied GUID. * Returns the id for "Unknown Country" if no valid entries are found. * * @param referenceGUID the reference GUID * * @return the stateCountryId for the supplied reference GUID */ public final int getStateCountryId(final int referenceGUID) { int stateCountryId = 0; Collection<AddressBean> addresses = null; try { addresses = this.load(referenceGUID, true, null, null); } catch (WhichDoctorDaoException wde) { dataLogger.error("Error loading addresses for GUID: " + wde.getMessage()); } HashMap<Integer, AddressBean> countries = new HashMap<Integer, AddressBean>(); if (addresses != null) { for (AddressBean address : addresses) { if (!address.getReturnedMail() && !StringUtils.equalsIgnoreCase(address.getRegion(), "Unknown")) { int x = 0; if (address.getRequestNoMail()) { x = 1; } if (address.getPrimary()) { x = 2; } countries.put(x, address); } } } String state = ""; String country = "Unknown Country"; for (int x : countries.keySet()) { AddressBean address = countries.get(x); state = address.getState(); country = address.getCountry(); } try { ObjectTypeBean object = this.getObjectTypeDAO().load("State/Country", state, country); stateCountryId = object.getObjectTypeId(); } catch (Exception e) { dataLogger.error("Error loading objecttype for state/country: " + e.getMessage()); } return stateCountryId; } /** * Update region. * * @param referenceGUID the reference guid */ private void updateIndexes(final int referenceGUID) { /* Load the WhichDoctor bean of this referenceGUID */ WhichDoctorBean wdObject = null; try { wdObject = this.getWhichDoctorDAO().load(referenceGUID); } catch (Exception e) { dataLogger.error("Error loading WhichDoctor object: " + e.getMessage()); } if (wdObject != null) { if (wdObject.getObjectType().compareToIgnoreCase("Person") == 0) { /* Update the person's region to reflect change */ try { this.personDAO.updateRegion(referenceGUID); } catch (Exception e) { dataLogger.error("Error updating region for person (" + referenceGUID + "): " + e.getMessage()); } try { this.personDAO.updateResidentCountry(referenceGUID); } catch (Exception e) { dataLogger.error("Error updating resident country for person (" + referenceGUID + "): " + e.getMessage()); } } if (wdObject.getObjectType().compareToIgnoreCase("Organisation") == 0) { /* Update this organisation's region to reflect change */ try { this.organisationDAO.updateRegion(referenceGUID); } catch (Exception e) { dataLogger.error( "Error updating region for organisation (" + referenceGUID + "): " + e.getMessage()); } try { this.organisationDAO.updateResidentCountry(referenceGUID); } catch (Exception e) { dataLogger.error("Error updating resident country for organisation (" + referenceGUID + "): " + e.getMessage()); } } } else { dataLogger.error("Region not updated WhichDoctorBean was null for GUID: " + referenceGUID); } } /** * Perform the address verification (if applicable). * * @param oldAddress the old address * @param newAddress the new address */ private void performAddressVerification(final AddressBean oldAddress, final AddressBean newAddress) { boolean verifyAddress = false; if (oldAddress == null && newAddress != null) { // New address verifyAddress = true; } if (oldAddress != null && newAddress != null && oldAddress.compare(newAddress, true)) { // Modified address verifyAddress = true; } if (verifyAddress) { // New or edited address that does not match the old one try { boolean submitForVerification = false; PreferencesBean pref = preferencesDAO.load(); if (pref != null && StringUtils.equalsIgnoreCase("true", pref.getOption("system", "addressverification"))) { submitForVerification = true; } if (oldAddress != null && StringUtils.equalsIgnoreCase(oldAddress.getVerificationStatus(), "Pending verification")) { submitForVerification = true; } if (submitForVerification) { // Submit the address for automatic verification this.addressVerificationDAO.create(newAddress); // Update the address verification status updateVerificationStatus("Pending verification", newAddress.getGUID()); } } catch (WhichDoctorDaoException wde) { dataLogger.error("Error performing address verification check: " + wde.getMessage()); } } } /** * Load the address bean. * * @param rs the rs * * @return the address bean * * @throws SQLException the SQL exception */ private AddressBean loadAddress(final ResultSet rs) throws SQLException { AddressBean address = new AddressBean(); address.setId(rs.getInt("AddressId")); address.setGUID(rs.getInt("GUID")); address.setReferenceGUID(rs.getInt("ReferenceGUID")); address.setContactClass(rs.getString("ContactClass")); address.setContactType(rs.getString("ContactType")); address.setDescription(rs.getString("Description")); address.setAddressField(rs.getString("Address1")); address.setAddressField(rs.getString("Address2")); address.setAddressField(rs.getString("Address3")); address.setAddressField(rs.getString("Address4")); address.setAddressField(rs.getString("Address5")); address.setAddressField(rs.getString("Address6")); address.setAddressField(rs.getString("Address7")); address.setState(rs.getString("State")); address.setStateAbbreviation(rs.getString("StateAbbreviation")); address.setCountry(rs.getString("Country")); address.setCountryAbbreviation(rs.getString("CountryAbbreviation")); address.setRegion(rs.getString("Region")); address.setPrimary(rs.getBoolean("PrimaryAddress")); address.setReturnedMail(rs.getBoolean("ReturnedMail")); address.setRequestNoMail(rs.getBoolean("RequestNoMail")); address.setPostCode(rs.getString("PostCode")); address.setGeocode(rs.getString("Geocode")); address.setVerificationStatus(rs.getString("VerificationStatus")); address.setActive(rs.getBoolean("Active")); try { address.setCreatedDate(rs.getTimestamp("CreatedDate")); } catch (SQLException sqe) { dataLogger.debug("Error parsing CreatedDate: " + sqe.getMessage()); } address.setCreatedBy(rs.getString("CreatedBy")); try { address.setModifiedDate(rs.getTimestamp("ModifiedDate")); } catch (SQLException sqe) { dataLogger.debug("Error parsing ModifiedDate: " + sqe.getMessage()); } address.setModifiedBy(rs.getString("ModifiedBy")); try { address.setExportedDate(rs.getTimestamp("ExportedDate")); } catch (SQLException sqe) { dataLogger.debug("Error parsing ExportedDate: " + sqe.getMessage()); } address.setExportedBy(rs.getString("ExportedBy")); return address; } /** * Sets the parameters for the object array that is inserted into the database. * * @param address the address * @param addressTypeId the address type id * @param stateId the state id * @param regionId the region id * @param checkUser the check user * @param action the action * @return the array list */ private ArrayList<Object> setParameters(final AddressBean address, final int addressTypeId, final int stateId, final int regionId, final int verificationStatusId, final UserBean checkUser, final String action) { final ArrayList<Object> parameters = new ArrayList<Object>(); Timestamp sqlTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis()); parameters.add(address.getReferenceGUID()); parameters.add(addressTypeId); parameters.add(address.getDescription()); for (int x = 0; x < MAXADDRESSLINES; x++) { parameters.add(address.getAddressField(x)); } parameters.add(address.getCity()); parameters.add(address.getPrimary()); parameters.add(address.getReturnedMail()); parameters.add(address.getRequestNoMail()); parameters.add(stateId); parameters.add(regionId); parameters.add(address.getPostCode()); parameters.add(address.getGeocode()); parameters.add(verificationStatusId); parameters.add(address.getActive()); parameters.add(sqlTimeStamp); parameters.add(checkUser.getDN()); parameters.add(address.getLogMessage(action)); return parameters; } }