/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.openmrs.util.OpenmrsUtil;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
/**
* This class is the representation of a person's address. This class is many-to-one to the Person
* class, so a Person/Patient/User can have zero to n addresses
*/
@Root(strict = false)
@Indexed
public class PersonAddress extends BaseOpenmrsData implements java.io.Serializable, Cloneable, Comparable<PersonAddress>, Address {
public static final long serialVersionUID = 343333L;
private static final Log log = LogFactory.getLog(PersonAddress.class);
// Fields
@DocumentId
@Field
private Integer personAddressId;
//@Field
private Person person;
@Field
private Boolean preferred = false;
@Field
private String address1;
@Field
private String address2;
@Field
private String cityVillage;
@Field
private String address3;
@Field
private String countyDistrict;
@Field
private String address4;
@Field
private String address6;
@Field
private String address5;
@Field
private String stateProvince;
@Field
private String country;
@Field
private String postalCode;
@Field
private String latitude;
@Field
private String longitude;
@Field
private Date startDate;
@Field
private Date endDate;
// Constructors
/** default constructor */
public PersonAddress() {
}
/** constructor with id */
public PersonAddress(Integer personAddressId) {
this.personAddressId = personAddressId;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "a1:" + getAddress1() + ", a2:" + getAddress2() + ", cv:" + getCityVillage() + ", sp:" + getStateProvince()
+ ", c:" + getCountry() + ", cd:" + getCountyDistrict() + ", nc:" + getAddress3() + ", pc:"
+ getPostalCode() + ", lat:" + getLatitude() + ", long:" + getLongitude();
}
/**
* Compares this address to the given object/address for similarity. Uses the very basic
* comparison of just the PersonAddress.personAddressId
*
* @param obj Object (Usually PersonAddress) with which to compare
* @return boolean true/false whether or not they are the same objects
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof PersonAddress) {
PersonAddress p = (PersonAddress) obj;
if (this.getPersonAddressId() != null && p.getPersonAddressId() != null)
return (this.getPersonAddressId().equals(p.getPersonAddressId()));
}
return false;
}
/**
* Compares this PersonAddress object to the given otherAddress. This method differs from
* {@link #equals(Object)} in that this method compares the inner fields of each address for
* equality. Note: Null/empty fields on <code>otherAddress</code> /will not/ cause a false value
* to be returned
*
* @param otherAddress PersonAddress with which to compare
* @return boolean true/false whether or not they are the same addresses
*/
@SuppressWarnings("unchecked")
public boolean equalsContent(PersonAddress otherAddress) {
boolean returnValue = true;
// these are the methods to compare. All are expected to be Strings
String[] methods = { "getAddress1", "getAddress2", "getAddress3", "getAddress4", "getAddress5", "getAddress6",
"getCityVillage", "getCountyDistrict", "getStateProvince", "getCountry", "getPostalCode", "getLatitude",
"getLongitude" };
Class addressClass = this.getClass();
// loop over all of the selected methods and compare this and other
for (String methodName : methods) {
try {
Method method = addressClass.getMethod(methodName, new Class[] {});
String thisValue = (String) method.invoke(this);
String otherValue = (String) method.invoke(otherAddress);
if (otherValue != null && otherValue.length() > 0)
returnValue &= otherValue.equals(thisValue);
}
catch (NoSuchMethodException e) {
log.warn("No such method for comparison " + methodName, e);
}
catch (IllegalAccessException e) {
log.error("Error while comparing addresses", e);
}
catch (InvocationTargetException e) {
log.error("Error while comparing addresses", e);
}
}
return returnValue;
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
if (this.getPersonAddressId() == null)
return super.hashCode();
return this.getPersonAddressId().hashCode();
}
/**
* bitwise copy of the personAddress object. NOTICE: THIS WILL NOT COPY THE PATIENT OBJECT. The
* PersonAddress.person object in this object AND the cloned object will point at the same
* person
*
* @return New PersonAddress object
*/
public Object clone() {
try {
return super.clone();
}
catch (CloneNotSupportedException e) {
throw new InternalError("PersonAddress should be cloneable");
}
}
/**
* @return Returns the address1.
*/
@Element(data = true, required = false)
public String getAddress1() {
return address1;
}
/**
* @param address1 The address1 to set.
*/
@Element(data = true, required = false)
public void setAddress1(String address1) {
this.address1 = address1;
}
/**
* @return Returns the address2.
*/
@Element(data = true, required = false)
public String getAddress2() {
return address2;
}
/**
* @param address2 The address2 to set.
*/
@Element(data = true, required = false)
public void setAddress2(String address2) {
this.address2 = address2;
}
/**
* @return Returns the cityVillage.
*/
@Element(data = true, required = false)
public String getCityVillage() {
return cityVillage;
}
/**
* @param cityVillage The cityVillage to set.
*/
@Element(data = true, required = false)
public void setCityVillage(String cityVillage) {
this.cityVillage = cityVillage;
}
/**
* @return Returns the country.
*/
@Element(data = true, required = false)
public String getCountry() {
return country;
}
/**
* @param country The country to set.
*/
@Element(data = true, required = false)
public void setCountry(String country) {
this.country = country;
}
/**
* @return Returns the preferred.
*/
public Boolean isPreferred() {
if (preferred == null)
return new Boolean(false);
return preferred;
}
@Attribute(required = true)
public Boolean getPreferred() {
return isPreferred();
}
/**
* @param preferred The preferred to set.
*/
@Attribute(required = true)
public void setPreferred(Boolean preferred) {
this.preferred = preferred;
}
/**
* @return Returns the latitude.
*/
@Attribute(required = false)
public String getLatitude() {
return latitude;
}
/**
* @param latitude The latitude to set.
*/
@Attribute(required = false)
public void setLatitude(String latitude) {
this.latitude = latitude;
}
/**
* @return Returns the longitude.
*/
@Attribute(required = false)
public String getLongitude() {
return longitude;
}
/**
* @param longitude The longitude to set.
*/
@Attribute(required = false)
public void setLongitude(String longitude) {
this.longitude = longitude;
}
/**
* @return Returns the person.
*/
@Element(required = true)
public Person getPerson() {
return person;
}
/**
* @param person The person to set.
*/
@Element(required = true)
public void setPerson(Person person) {
this.person = person;
}
/**
* @return Returns the personAddressId.
*/
@Attribute(required = true)
public Integer getPersonAddressId() {
return personAddressId;
}
/**
* @param personAddressId The personAddressId to set.
*/
@Attribute(required = true)
public void setPersonAddressId(Integer personAddressId) {
this.personAddressId = personAddressId;
}
/**
* @return Returns the postalCode.
*/
@Element(data = true, required = false)
public String getPostalCode() {
return postalCode;
}
/**
* @param postalCode The postalCode to set.
*/
@Element(data = true, required = false)
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
/**
* @return Returns the stateProvince.
*/
@Element(data = true, required = false)
public String getStateProvince() {
return stateProvince;
}
/**
* @param stateProvince The stateProvince to set.
*/
@Element(data = true, required = false)
public void setStateProvince(String stateProvince) {
this.stateProvince = stateProvince;
}
/**
* @return Returns the countyDistrict.
*/
@Element(data = true, required = false)
public String getCountyDistrict() {
return countyDistrict;
}
/**
* @param countyDistrict The countyDistrict to set.
*/
@Element(data = true, required = false)
public void setCountyDistrict(String countyDistrict) {
this.countyDistrict = countyDistrict;
}
/**
* @deprecated As of 1.8, replaced by {@link #getAddress3()}
* @return Returns the neighborhoodCell.
*/
@Deprecated
@Element(data = true, required = false)
public String getNeighborhoodCell() {
return getAddress3();
}
/**
* @deprecated As of 1.8, replaced by {@link #setAddress3(String)}
* @param address3 The neighborhoodCell to set.
*/
@Deprecated
@Element(data = true, required = false)
public void setNeighborhoodCell(String address3) {
this.setAddress3(address3);
}
/**
* Convenience method to test whether any of the fields in this address are set
*
* @return whether any of the address fields (address1, address2, cityVillage, stateProvince,
* country, countyDistrict, neighborhoodCell, postalCode, latitude, longitude) are
* non-null
*/
public boolean isBlank() {
return getAddress1() == null && getAddress2() == null && getCityVillage() == null && getStateProvince() == null
&& getCountry() == null && getCountyDistrict() == null && getAddress3() == null && getPostalCode() == null
&& getLatitude() == null && getLongitude() == null;
}
/**
* @deprecated As of 1.8, replaced by {@link #getAddress6()}
* @return the region
*/
@Deprecated
@Element(data = true, required = false)
public String getRegion() {
return getAddress6();
}
/**
* @deprecated As of 1.8, replaced by {@link #setAddress6(String)}
* @param address6 the region to set
*/
@Deprecated
@Element(data = true, required = false)
public void setRegion(String address6) {
this.setAddress6(address6);
}
/**
* @deprecated As of 1.8, replaced by {@link #getAddress5()}
* @return the subregion
*/
@Deprecated
@Element(data = true, required = false)
public String getSubregion() {
return getAddress5();
}
/**
* @deprecated As of 1.8, replaced by {@link #setAddress5(String)}
* @param address5 the subregion to set
*/
@Deprecated
@Element(data = true, required = false)
public void setSubregion(String address5) {
this.setAddress5(address5);
}
/**
* @deprecated As of 1.8, replaced by {@link #getAddress4()}
* @return the townshipDivision
*/
@Deprecated
@Element(data = true, required = false)
public String getTownshipDivision() {
return getAddress4();
}
/**
* @deprecated As of 1.8, replaced by {@link #setAddress4(String)}
* @param address4 the address4 to set
*/
@Deprecated
@Element(data = true, required = false)
public void setTownshipDivision(String address4) {
this.setAddress4(address4);
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(PersonAddress other) {
int retValue = 0;
if (other != null) {
retValue = isVoided().compareTo(other.isVoided());
if (retValue == 0)
retValue = other.isPreferred().compareTo(isPreferred());
if (retValue == 0 && getDateCreated() != null)
retValue = OpenmrsUtil.compareWithNullAsLatest(getDateCreated(), other.getDateCreated());
if (retValue == 0)
retValue = OpenmrsUtil.compareWithNullAsGreatest(getPersonAddressId(), other.getPersonAddressId());
// if we've gotten this far, just check all address values. If they are
// equal, leave the objects at 0. If not, arbitrarily pick retValue=1
// and return that (they are not equal).
if (retValue == 0 && !equalsContent(other))
retValue = 1;
}
return retValue;
}
/**
* @since 1.8
* @return the address3
*/
public String getAddress3() {
return address3;
}
/**
* @since 1.8
* @param address3 the address3 to set
*/
public void setAddress3(String address3) {
this.address3 = address3;
}
/**
* @since 1.8
* @return the address4
*/
public String getAddress4() {
return address4;
}
/**
* @since 1.8
* @param address4 the address4 to set
*/
public void setAddress4(String address4) {
this.address4 = address4;
}
/**
* @since 1.8
* @return the address6
*/
public String getAddress6() {
return address6;
}
/**
* @since 1.8
* @param address6 the address6 to set
*/
public void setAddress6(String address6) {
this.address6 = address6;
}
/**
* @since 1.8
* @return the address5
*/
public String getAddress5() {
return address5;
}
/**
* @since 1.8
* @param address5 the address5 to set
*/
public void setAddress5(String address5) {
this.address5 = address5;
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#getId()
*/
public Integer getId() {
return getPersonAddressId();
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
*/
public void setId(Integer id) {
setPersonAddressId(id);
}
/**
* @return the startDate
* @since 1.9
*/
public Date getStartDate() {
return startDate;
}
/**
* @param startDate to set to
* @since 1.9
*/
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
/**
* @return the endDate
* @since 1.9
*/
public Date getEndDate() {
return this.endDate;
}
/**
* @param endDate to set to
* @since 1.9
*/
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
/**
* Returns true if the address' endDate is null
*
* @return true or false
* @since 1.9
*/
public Boolean isActive() {
return (this.endDate == null);
}
/**
* Makes an address inactive by setting its endDate to the current time
*
* @since 1.9
*/
public void deactivate() {
setEndDate(Calendar.getInstance().getTime());
}
/**
* Makes an address active by setting its endDate to null
*
* @since 1.9
*/
public void activate() {
setEndDate(null);
}
}