/**
* 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.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import org.apache.commons.lang.StringUtils;
import org.openmrs.api.ConceptNameType;
import org.openmrs.api.context.Context;
import org.openmrs.util.OpenmrsUtil;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
/**
* ConceptName is the real world term used to express a Concept within the idiom of a particular
* locale.
*/
@Root
public class ConceptName extends BaseOpenmrsObject implements Auditable, Voidable, java.io.Serializable {
public static final long serialVersionUID = 2L;
// Fields
private Integer conceptNameId;
private Concept concept;
private String name;
private Locale locale; // ABK: upgraded from a plain string to a full locale object
private User creator;
private Date dateCreated;
private Boolean voided = false;
private User voidedBy;
private Date dateVoided;
private String voidReason;
private Collection<ConceptNameTag> tags;
private ConceptNameType conceptNameType;
private Boolean localePreferred = false;
// Constructors
/** default constructor */
public ConceptName() {
}
/**
* Convenience constructor to create a ConceptName object by primary key
*
* @param conceptNameId
*/
public ConceptName(Integer conceptNameId) {
this.conceptNameId = conceptNameId;
}
public ConceptName(String name, Locale locale) {
setName(name);
setLocale(locale);
}
/**
* Short name and description are no longer attributes of ConceptName.
*
* @param name
* @param shortName
* @param description
* @param locale
* @deprecated
*/
@Deprecated
public ConceptName(String name, String shortName, String description, Locale locale) {
setName(name);
setLocale(locale);
}
/**
* @see java.lang.Object#equals(java.lang.Object)
* @should compare on conceptNameId if non null
* @should not return true with different objects and null ids
* @should default to object equality
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ConceptName)) {
return false;
}
ConceptName rhs = (ConceptName) obj;
if (this.conceptNameId != null && rhs.conceptNameId != null)
return (this.conceptNameId.equals(rhs.conceptNameId));
else
return this == obj;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
if (this.getConceptNameId() == null)
return super.hashCode();
int hash = 3;
hash = hash + 31 * this.getConceptNameId();
return hash;
}
/**
* @deprecated Use {@link Concept#getShortestName(Locale, Boolean)} instead.
* @return Returns the appropriate short name
*/
@Deprecated
public String getShortestName() {
if (concept != null) {
ConceptName bestShortName = concept.getShortestName(this.locale, false);
if (bestShortName != null)
return bestShortName.getName();
}
return getName();
}
/**
* @return Returns the conceptId.
*/
@Attribute
public Integer getConceptNameId() {
return conceptNameId;
}
/**
* @param conceptNameId The conceptId to set.
*/
@Attribute
public void setConceptNameId(Integer conceptNameId) {
this.conceptNameId = conceptNameId;
}
/**
*
*/
@Element
public Concept getConcept() {
return concept;
}
@Element
public void setConcept(Concept concept) {
this.concept = concept;
}
/**
*
*/
@Element(data = true)
public String getName() {
return name;
}
@Element(data = true)
public void setName(String name) {
this.name = name;
}
/**
*
*/
@Element
public Locale getLocale() {
return locale;
}
@Element
public void setLocale(Locale locale) {
this.locale = locale;
}
/**
* @deprecated
* @return Returns the shortName.
*/
@Deprecated
public String getShortName() {
if (concept != null) {
ConceptName bestShortName = concept.getShortNameInLocale(Context.getLocale());
if (bestShortName != null)
return bestShortName.getName();
}
return null;
}
/**
* @deprecated
* @return Returns the description.
*/
@Deprecated
public String getDescription() {
if (concept != null) {
ConceptDescription description = concept.getDescription();
if (description != null)
return description.getDescription();
}
return null;
}
/**
* @return Returns the creator.
*/
@Element
public User getCreator() {
return creator;
}
/**
* @param creator The creator to set.
*/
@Element
public void setCreator(User creator) {
this.creator = creator;
}
/**
* @return Returns the dateCreated.
*/
@Element
public Date getDateCreated() {
return dateCreated;
}
/**
* @param dateCreated The dateCreated to set.
*/
@Element
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
/**
* Returns whether the ConceptName has been voided.
*
* @return true if the ConceptName has been voided, false otherwise.
*/
public Boolean isVoided() {
return voided;
}
/**
* Returns whether the ConceptName has been voided.
*
* @return true if the ConceptName has been voided, false otherwise.
*/
@Attribute
public Boolean getVoided() {
return isVoided();
}
/**
* Sets the voided status of this ConceptName.
*
* @param voided the voided status to set.
*/
@Attribute
public void setVoided(Boolean voided) {
this.voided = voided;
}
/**
* Returns the User who voided this ConceptName.
*
* @return the User who voided this ConceptName, or null if not set
*/
@Element(required = false)
public User getVoidedBy() {
return voidedBy;
}
/**
* Sets the User who voided this ConceptName.
*
* @param voidedBy the user who voided this ConceptName.
*/
@Element(required = false)
public void setVoidedBy(User voidedBy) {
this.voidedBy = voidedBy;
}
/**
* Returns the Date this ConceptName was voided.
*
* @return the Date this ConceptName was voided.
*/
@Element(required = false)
public Date getDateVoided() {
return dateVoided;
}
/**
* Sets the Data this ConceptName was voided.
*
* @param dateVoided the date the ConceptName was voided.
*/
@Element(required = false)
public void setDateVoided(Date dateVoided) {
this.dateVoided = dateVoided;
}
/**
* Returns the reason this ConceptName was voided.
*
* @return the reason this ConceptName was voided
*/
@Element(required = false)
public String getVoidReason() {
return voidReason;
}
/**
* Sets the reason this ConceptName was voided.
*
* @param voidReason the reason this ConceptName was voided
*/
@Element(required = false)
public void setVoidReason(String voidReason) {
this.voidReason = voidReason;
}
/**
* Returns the tags which have been attached to this ConceptName.
*
* @return the tags.
*/
@ElementList
public Collection<ConceptNameTag> getTags() {
return tags;
}
/**
* Set the tags which are attached to this ConceptName.
*
* @see Concept#setPreferredName(ConceptName)
* @see Concept#setFullySpecifiedName(ConceptName)
* @see Concept#setShortName(ConceptName)
* @param tags the tags to set.
*/
@ElementList
public void setTags(Collection<ConceptNameTag> tags) {
this.tags = tags;
}
/**
* @return the conceptNameType
*/
public ConceptNameType getConceptNameType() {
return this.conceptNameType;
}
/**
* @param conceptNameType the conceptNameType to set
*/
public void setConceptNameType(ConceptNameType conceptNameType) {
this.conceptNameType = conceptNameType;
}
/**
* Getter for localePreferred
*
* @return localPreferred
*/
public Boolean isLocalePreferred() {
return localePreferred;
}
/**
* Getter to be used by spring, developers should use {@link #isLocalePreferred()}
*
* @return true if it is the localePreferred name otherwise false
*/
public Boolean getLocalePreferred() {
return localePreferred;
}
/**
* @param localePreferred the localePreferred to set
*/
public void setLocalePreferred(Boolean localePreferred) {
this.localePreferred = localePreferred;
}
/**
* Adds a tag to the concept name. If the tag is new (has no existing occurrences) a new
* ConceptNameTag will be created with a blank description.
*
* @see Concept#setPreferredName(ConceptName)
* @see Concept#setFullySpecifiedName(ConceptName)
* @see Concept#setShortName(ConceptName)
* @param tag human-readable text string for the tag
*/
public void addTag(String tag) {
addTag(tag, "");
}
/**
* Adds a tag to the concept name. If the tag is new (has no existing occurrences) a new
* ConceptNameTag will be created with the given description.
*
* @see Concept#setPreferredName(ConceptName)
* @see Concept#setFullySpecifiedName(ConceptName)
* @see Concept#setShortName(ConceptName)
* @param tag human-readable text string for the tag
* @param description description of the tag's purpose
*/
public void addTag(String tag, String description) {
ConceptNameTag nameTag = new ConceptNameTag(tag, description);
addTag(nameTag);
}
/**
* Attaches a tag to the concept name.
*
* @see Concept#setPreferredName(ConceptName)
* @see Concept#setFullySpecifiedName(ConceptName)
* @see Concept#setShortName(ConceptName)
* @param tag the tag to add
*/
public void addTag(ConceptNameTag tag) {
if (tags == null)
tags = new HashSet<ConceptNameTag>();
if (!tags.contains(tag))
tags.add(tag);
}
/**
* Removes a tag from the concept name.
*
* @see Concept#setPreferredName(ConceptName)
* @see Concept#setFullySpecifiedName(ConceptName)
* @see Concept#setShortName(ConceptName)
* @param tag the tag to remove
*/
public void removeTag(ConceptNameTag tag) {
if (tags.contains(tag))
tags.remove(tag);
}
/**
* Checks whether the name has a particular tag.
*
* @see #isPreferred()
* @see #isFullySpecifiedName()
* @see #isIndexTerm()
* @see #isSynonym()
* @see #isShort()
* @param tagToFind the tag for which to check
* @return true if the tags include the specified tag, false otherwise
*/
public Boolean hasTag(ConceptNameTag tagToFind) {
return hasTag(tagToFind.getTag());
}
/**
* Checks whether the name has a particular tag.
*
* @see #isPreferred()
* @see #isFullySpecifiedName()
* @see #isIndexTerm()
* @see #isSynonym()
* @see #isShort()
* @param tagToFind the string of the tag for which to check
* @return true if the tags include the specified tag, false otherwise
*/
public Boolean hasTag(String tagToFind) {
boolean foundTag = false;
if (tags != null) {
for (ConceptNameTag nameTag : getTags()) {
if (nameTag.getTag().equals(tagToFind)) {
foundTag = true;
break;
}
}
}
return foundTag;
}
/**
* Checks whether the name is explicitly marked as preferred in a locale with a matching
* language. E.g 'en_US' and 'en_UK' for language en
*
* @see {@link #isPreferredForLocale(Locale)}
* @param language ISO 639 2-letter code for a language
* @return true if the name is preferred in a locale with a matching language code, otherwise
* false
*/
public Boolean isPreferredInLanguage(String language) {
if (!StringUtils.isBlank(language) && this.locale != null) {
if (isPreferred() && this.locale.getLanguage().equals(language))
return true;
}
return false;
}
/**
* Checks whether the name is explicitly marked as preferred in a locale with a matching country
* code E.g 'fr_RW' and 'en_RW' for country RW
*
* @see {@link #isPreferredForLocale(Locale)}
* @param country ISO 3166 2-letter code for a country
* @return true if the name is preferred in a locale with a matching country code, otherwise
* false
*/
public Boolean isPreferredInCountry(String country) {
if (!StringUtils.isBlank(country) && this.locale != null) {
if (isPreferred() && this.locale.getCountry().equals(country))
return true;
}
return false;
}
/**
* Checks whether the name is explicitly marked as preferred for any locale. Note that this
* method is different from {@link #isPreferredForLocale(Locale)} in that it checks if the given
* name is marked as preferred irrespective of the locale in which it is preferred.
*
* @see {@link #isPreferredForLocale(Locale)}
*/
public Boolean isPreferred() {
return isLocalePreferred();
}
/**
* Checks whether the name is explicitly marked as preferred for the given locale
*
* @param locale the locale in which the name is preferred
* @return true if the name is marked as preferred for the given locale otherwise false.
*/
public Boolean isPreferredForLocale(Locale locale) {
return isLocalePreferred() && this.locale.equals(locale);
}
/**
* Checks whether the concept name is explicitly marked as fully specified
*
* @return true if the name is marked as 'fully specified' otherwise false
* @since Version 1.7
*/
public Boolean isFullySpecifiedName() {
return OpenmrsUtil.nullSafeEquals(getConceptNameType(), ConceptNameType.FULLY_SPECIFIED);
}
/**
* Convenience method for determining whether this is a short name.
*
* @return true if the name is marked as a short name, otherwise false
*/
public Boolean isShort() {
return OpenmrsUtil.nullSafeEquals(getConceptNameType(), ConceptNameType.SHORT);
}
/**
* Convenience method for checking whether this is an index Term.
*
* @return true if the name is marked as an index term, otherwise false
* @since Version 1.7
*/
public Boolean isIndexTerm() {
return OpenmrsUtil.nullSafeEquals(getConceptNameType(), ConceptNameType.INDEX_TERM);
}
/**
* Convenience method for determining whether this is an index Term for a given locale.
*
* @param locale The locale in which this concept name should belong as an index term
* @return true if the name is marked as an index term, otherwise false
*/
public Boolean isIndexTermInLocale(Locale locale) {
return getConceptNameType() != null && getConceptNameType().equals(ConceptNameType.INDEX_TERM)
&& locale.equals(getLocale());
}
/**
* Convenience method for determining whether this is a synonym in a given locale.
*
* @param locale The locale in which this synonym should belong
* @return true if the concept name is marked as a synonym in the given locale, otherwise false
*/
public Boolean isSynonymInLocale(Locale locale) {
return getConceptNameType() == null && locale.equals(getLocale());
}
/**
* Convenience method for checking whether this is a a synonym.
*
* @return true if the name is tagged as a synonym, false otherwise
* @since Version 1.7
*/
public Boolean isSynonym() {
return getConceptNameType() == null;
}
/**
* Checks if this conceptName is a short name in a locale with a matching language
*
* @deprecated as of version 1.7
* @see Concept#getShortNameInLocale(Locale)
* @see Concept#getShortestName(Locale, Boolean)
* @param language ISO 639 2-letter code for a language
* @return true if the name is a short name in a locale with a matching language code, otherwise
* false
*/
@Deprecated
public Boolean isPreferredShortInLanguage(String language) {
if (!StringUtils.isBlank(language) && this.locale != null) {
if (isShort() && this.locale.getLanguage().equals(language))
return true;
}
return false;
}
/**
* Checks if this conceptName is a short name in a locale with a matching country
*
* @deprecated since version 1.7
* @see Concept#getShortNameInLocale(Locale)
* @see Concept#getShortestName(Locale, Boolean)
* @param country ISO 639 2-letter code for a country
* @return true if the name is a short name in a locale with a matching country code, otherwise
* false
*/
@Deprecated
public Boolean isPreferredShortInCountry(String country) {
if (!StringUtils.isBlank(country) && this.locale != null) {
if (isShort() && this.locale.getCountry().equals(country))
return true;
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (this.name == null)
return "ConceptNameId: " + this.conceptNameId;
return this.name;
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#getId()
*/
public Integer getId() {
return getConceptNameId();
}
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
*/
public void setId(Integer id) {
setConceptNameId(id);
}
/**
* Not currently used. Always returns null.
*
* @see org.openmrs.Auditable#getChangedBy()
*/
public User getChangedBy() {
return null;
}
/**
* Not currently used. Always returns null.
*
* @see org.openmrs.Auditable#getDateChanged()
*/
public Date getDateChanged() {
return null;
}
/**
* Not currently used.
*
* @see org.openmrs.Auditable#setChangedBy(org.openmrs.User)
*/
public void setChangedBy(User changedBy) {
}
/**
* Not currently used.
*
* @see org.openmrs.Auditable#setDateChanged(java.util.Date)
*/
public void setDateChanged(Date dateChanged) {
}
}