/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.openmrs.annotation.Independent;
import org.openmrs.api.APIException;
import org.openmrs.api.context.Context;
/**
* A Location is a physical place, such as a hospital, a room, a clinic, or a district. Locations
* support a single hierarchy, such that each location may have one parent location. A
* non-geographical grouping of locations, such as "All Community Health Centers" is not a location,
* and should be modeled using {@link LocationTag}s.
* Note: Prior to version 1.9 this class extended BaseMetadata
*/
public class Location extends BaseCustomizableMetadata<LocationAttribute> implements java.io.Serializable, Attributable<Location>, Address {
public static final long serialVersionUID = 455634L;
public static final int LOCATION_UNKNOWN = 1;
// Fields
private Integer locationId;
private String address1;
private String address2;
private String cityVillage;
private String stateProvince;
private String country;
private String postalCode;
private String latitude;
private String longitude;
private String countyDistrict;
private String address3;
private String address4;
private String address6;
private String address5;
private String address7;
private String address8;
private String address9;
private String address10;
private String address11;
private String address12;
private String address13;
private String address14;
private String address15;
private Location parentLocation;
private Set<Location> childLocations;
@Independent
private Set<LocationTag> tags;
// Constructors
/** default constructor */
public Location() {
}
/** constructor with id */
public Location(Integer locationId) {
this.locationId = locationId;
}
// Property accessors
/**
* @return Returns the address1.
*/
@Override
public String getAddress1() {
return address1;
}
/**
* @param address1 The address1 to set.
*/
@Override
public void setAddress1(String address1) {
this.address1 = address1;
}
/**
* @return Returns the address2.
*/
@Override
public String getAddress2() {
return address2;
}
/**
* @param address2 The address2 to set.
*/
@Override
public void setAddress2(String address2) {
this.address2 = address2;
}
/**
* @return Returns the cityVillage.
*/
@Override
public String getCityVillage() {
return cityVillage;
}
/**
* @param cityVillage The cityVillage to set.
*/
@Override
public void setCityVillage(String cityVillage) {
this.cityVillage = cityVillage;
}
/**
* @return Returns the country.
*/
@Override
public String getCountry() {
return country;
}
/**
* @param country The country to set.
*/
@Override
public void setCountry(String country) {
this.country = country;
}
/**
* @return Returns the latitude.
*/
@Override
public String getLatitude() {
return latitude;
}
/**
* @param latitude The latitude to set.
*/
@Override
public void setLatitude(String latitude) {
this.latitude = latitude;
}
/**
* @return Returns the locationId.
*/
public Integer getLocationId() {
return locationId;
}
/**
* @param locationId The locationId to set.
*/
public void setLocationId(Integer locationId) {
this.locationId = locationId;
}
/**
* @return Returns the longitude.
*/
@Override
public String getLongitude() {
return longitude;
}
/**
* @param longitude The longitude to set.
*/
@Override
public void setLongitude(String longitude) {
this.longitude = longitude;
}
/**
* @return Returns the postalCode.
*/
@Override
public String getPostalCode() {
return postalCode;
}
/**
* @param postalCode The postalCode to set.
*/
@Override
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
/**
* @return Returns the stateProvince.
*/
@Override
public String getStateProvince() {
return stateProvince;
}
/**
* @param stateProvince The stateProvince to set.
*/
@Override
public void setStateProvince(String stateProvince) {
this.stateProvince = stateProvince;
}
@Override
public String toString() {
if (getName() != null) {
return getName();
}
if (getId() != null) {
return getId().toString();
}
return "";
}
/**
* @return Returns the countyDistrict.
*/
@Override
public String getCountyDistrict() {
return countyDistrict;
}
/**
* @param countyDistrict The countyDistrict to set.
*/
@Override
public void setCountyDistrict(String countyDistrict) {
this.countyDistrict = countyDistrict;
}
/**
* @see org.openmrs.Attributable#findPossibleValues(java.lang.String)
*/
@Override
public List<Location> findPossibleValues(String searchText) {
try {
return Context.getLocationService().getLocations(searchText);
}
catch (Exception e) {
return Collections.emptyList();
}
}
/**
* @see org.openmrs.Attributable#getPossibleValues()
*/
@Override
public List<Location> getPossibleValues() {
try {
return Context.getLocationService().getAllLocations();
}
catch (Exception e) {
return Collections.emptyList();
}
}
/**
* @see org.openmrs.Attributable#hydrate(java.lang.String)
*/
@Override
public Location hydrate(String locationId) {
try {
return Context.getLocationService().getLocation(Integer.valueOf(locationId));
}
catch (Exception e) {
return new Location();
}
}
/**
* @see org.openmrs.Attributable#serialize()
*/
@Override
public String serialize() {
if (getLocationId() != null) {
return "" + getLocationId();
} else {
return "";
}
}
/**
* @see org.openmrs.Attributable#getDisplayString()
*/
@Override
public String getDisplayString() {
return getName();
}
/**
* @return Returns the parentLocation.
* @since 1.5
*/
public Location getParentLocation() {
return parentLocation;
}
/**
* @param parentLocationId The parentLocation to set.
* @since 1.5
*/
public void setParentLocation(Location parentLocationId) {
this.parentLocation = parentLocationId;
}
/**
* @return Returns the childLocations.
* @since 1.5
*/
public Set<Location> getChildLocations() {
return childLocations;
}
/**
* Returns all childLocations where child.locationId = this.locationId.
*
* @param includeRetired specifies whether or not to include voided childLocations
* @return Returns a Set<Location> of all the childLocations.
* @since 1.5
* @should return a set of locations
*/
public Set<Location> getChildLocations(boolean includeRetired) {
Set<Location> ret = new HashSet<Location>();
if (includeRetired) {
ret = getChildLocations();
} else if (getChildLocations() != null) {
for (Location l : getChildLocations()) {
if (!l.getRetired()) {
ret.add(l);
}
}
}
return ret;
}
/**
* Returns the descendant locations.
*
* @param includeRetired specifies whether or not to include voided childLocations
* @return Returns a Set<Location> of the descendant location.
* @since 1.10
*/
public Set<Location> getDescendantLocations(boolean includeRetired) {
Set<Location> result = new HashSet<Location>();
for (Location childLocation : getChildLocations()) {
if (!childLocation.getRetired() || includeRetired) {
result.add(childLocation);
result.addAll(childLocation.getDescendantLocations(includeRetired));
}
}
return result;
}
/**
* @param childLocations The childLocations to set.
* @since 1.5
*/
public void setChildLocations(Set<Location> childLocations) {
this.childLocations = childLocations;
}
/**
* @param child The child location to add.
* @since 1.5
* @should return null given null parameter
* @should throw APIException given same object as child
* @should throw APIException if child already in hierarchy
*/
public void addChildLocation(Location child) {
if (child == null) {
return;
}
if (getChildLocations() == null) {
childLocations = new HashSet<Location>();
}
if (child.equals(this)) {
throw new APIException("Location.cannot.be.its.own.child", (Object[]) null);
}
// Traverse all the way up (down?) to the root, then check whether the child is already
// anywhere in the tree
Location root = this;
while (root.getParentLocation() != null) {
root = root.getParentLocation();
}
if (isInHierarchy(child, root)) {
throw new APIException("Location.hierarchy.loop", new Object[] { child, this });
}
child.setParentLocation(this);
childLocations.add(child);
}
/**
* Checks whether 'location' is a member of the tree starting at 'root'.
*
* @param location The location to be tested.
* @param root Location node from which to start the testing (down in the hierarchy).
* @since 1.5
* @should return false given any null parameter
* @should return true given same object in both parameters
* @should return true given location that is already somewhere in hierarchy
* @should return false given location that is not in hierarchy
* @should should find location in hierarchy
*/
public static Boolean isInHierarchy(Location location, Location root) {
if (root == null) {
return false;
}
while (true) {
if (location == null) {
return false;
} else if (root.equals(location)) {
return true;
}
location = location.getParentLocation();
}
}
/**
* @param child The child location to remove.
* @since 1.5
*/
public void removeChildLocation(Location child) {
if (getChildLocations() != null) {
childLocations.remove(child);
}
}
/**
* @return Returns the tags which have been attached to this Location.
* @since 1.5
*/
public Set<LocationTag> getTags() {
return tags;
}
/**
* Set the tags which are attached to this Location.
*
* @param tags The tags to set.
* @since 1.5
*/
public void setTags(Set<LocationTag> tags) {
this.tags = tags;
}
/**
* Attaches a tag to the Location.
*
* @param tag The tag to add.
* @since 1.5
*/
public void addTag(LocationTag tag) {
if (getTags() == null) {
tags = new HashSet<LocationTag>();
}
if (tag != null && !tags.contains(tag)) {
tags.add(tag);
}
}
/**
* Remove the tag from the Location.
*
* @param tag The tag to remove.
* @since 1.5
*/
public void removeTag(LocationTag tag) {
if (getTags() != null) {
tags.remove(tag);
}
}
/**
* Checks whether the Location has a particular tag.
*
* @param tagToFind the string of the tag for which to check
* @return true if the tags include the specified tag, false otherwise
* @since 1.5
* @should not fail given null parameter
* @should return false given empty string parameter
*/
public Boolean hasTag(String tagToFind) {
if (tagToFind != null && getTags() != null) {
for (LocationTag locTag : getTags()) {
if (locTag.getName().equals(tagToFind)) {
return true;
}
}
}
return false;
}
/**
* @since 1.8
* @return the address3
*/
@Override
public String getAddress3() {
return address3;
}
/**
* @since 1.8
* @param address3 the address3 to set
*/
@Override
public void setAddress3(String address3) {
this.address3 = address3;
}
/**
* @since 1.8
* @return the address4
*/
@Override
public String getAddress4() {
return address4;
}
/**
* @since 1.8
* @param address4 the address4 to set
*/
@Override
public void setAddress4(String address4) {
this.address4 = address4;
}
/**
* @since 1.8
* @return the address6
*/
@Override
public String getAddress6() {
return address6;
}
/**
* @since 1.8
* @param address6 the address6 to set
*/
@Override
public void setAddress6(String address6) {
this.address6 = address6;
}
/**
* @since 1.8
* @return the address5
*/
@Override
public String getAddress5() {
return address5;
}
/**
* @since 1.8
* @param address5 the address5 to set
*/
@Override
public void setAddress5(String address5) {
this.address5 = address5;
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#getId()
*/
@Override
public Integer getId() {
return getLocationId();
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
*/
@Override
public void setId(Integer id) {
setLocationId(id);
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress7() {
return address7;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress7(String address7) {
this.address7 = address7;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress8() {
return address8;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress8(String address8) {
this.address8 = address8;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress9() {
return address9;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress9(String address9) {
this.address9 = address9;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress10() {
return address10;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress10(String address10) {
this.address10 = address10;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress11() {
return address11;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress11(String address11) {
this.address11 = address11;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress12() {
return address12;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress12(String address12) {
this.address12 = address12;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress13() {
return address13;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress13(String address13) {
this.address13 = address13;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress14() {
return address14;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress14(String address14) {
this.address14 = address14;
}
/**
* {@inheritDoc}
*/
@Override
public String getAddress15() {
return address15;
}
/**
* {@inheritDoc}
*/
@Override
public void setAddress15(String address15) {
this.address15 = address15;
}
}