/** * 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) { } }