diff --git a/api/src/main/java/org/openmrs/Concept.java b/api/src/main/java/org/openmrs/Concept.java index 71b8be945e69..e349a8c12ccb 100644 --- a/api/src/main/java/org/openmrs/Concept.java +++ b/api/src/main/java/org/openmrs/Concept.java @@ -753,6 +753,25 @@ public ConceptName getPreferredName(Locale forLocale) { } } + // look for partially locale match - any language matches takes precedence over country matches. + ConceptName bestMatch = null; + + for (ConceptName nameInLocale : getPartiallyCompatibleNames(forLocale)) { + if (ObjectUtils.nullSafeEquals(nameInLocale.isLocalePreferred(), true)) { + Locale nameLocale = nameInLocale.getLocale(); + if (forLocale.getLanguage().equals(nameLocale.getLanguage())) { + return nameInLocale; + } else { + bestMatch = nameInLocale; + } + + } + } + + if (bestMatch != null) { + return bestMatch; + } + return getFullySpecifiedName(forLocale); } @@ -780,6 +799,20 @@ public ConceptName getFullySpecifiedName(Locale locale) { return conceptName; } } + + // look for partially locale match - any language matches takes precedence over country matches. + ConceptName bestMatch = null; + for (ConceptName conceptName : getPartiallyCompatibleNames(locale)) { + if (ObjectUtils.nullSafeEquals(conceptName.isFullySpecifiedName(), true)) { + Locale nameLocale = conceptName.getLocale(); + if (locale.getLanguage().equals(nameLocale.getLanguage())) { + return conceptName; + } + bestMatch = conceptName; + } + } + return bestMatch; + } return null; } @@ -802,6 +835,27 @@ public Collection getNames(Locale locale) { return localeNames; } + /** + * Returns all names available for locale langueage "or" country.
+ *
+ * + * @param locale locale for which names should be returned + * @return Collection of ConceptNames with the given locale langueage or country + */ + private Collection getPartiallyCompatibleNames(Locale locale) { + Collection localeNames = new Vector(); + String language = locale.getLanguage(); + String country = locale.getCountry(); + for (ConceptName possibleName : getNames()) { + Locale possibleLocale = possibleName.getLocale(); + if (language.equals(possibleLocale.getLanguage()) + || (StringUtils.isNotBlank(country) && country.equals(possibleLocale.getCountry()))) { + localeNames.add(possibleName); + } + } + return localeNames; + } + /** * Returns all names from compatible locales. A locale is considered compatible if it is exactly * the same locale, or if either locale has no country specified and the language matches.
@@ -961,14 +1015,23 @@ public ConceptName getShortNameInLanguage(String language) { * @return the short name, or null if none has been explicitly set */ public ConceptName getShortNameInLocale(Locale locale) { + ConceptName bestMatch = null; if (locale != null && getShortNames().size() > 0) { for (ConceptName shortName : getShortNames()) { - if (shortName.getLocale().equals(locale)) { + Locale nameLocale = shortName.getLocale(); + if (nameLocale.equals(locale)) { return shortName; } + // test for partially locale match - any language matches takes precedence over country matches. + if (OpenmrsUtil.nullSafeEquals(locale.getLanguage(), nameLocale.getLanguage())) { + bestMatch = shortName; + } else if (bestMatch == null && StringUtils.isNotBlank(locale.getCountry()) + && locale.getCountry().equals(nameLocale.getCountry())) { + bestMatch = shortName; + } } } - return null; + return bestMatch; } /** diff --git a/api/src/test/java/org/openmrs/ConceptTest.java b/api/src/test/java/org/openmrs/ConceptTest.java index bc8743fe554c..578487c8e192 100644 --- a/api/src/test/java/org/openmrs/ConceptTest.java +++ b/api/src/test/java/org/openmrs/ConceptTest.java @@ -952,6 +952,33 @@ public void getSynonyms_shouldSortPreferredFirst() throws Exception { assertEquals("Preferred", conceptNameExpectedPreferred.getName()); } + @Test + public void getShortNameInLocale_shouldReturnTheBestShortNameForAConcept() throws Exception { + Concept concept = new Concept(); + concept.addName(new ConceptName("Giant cat", new Locale("en"))); + concept.addName(new ConceptName("Gato gigante", new Locale("es", "MX"))); + + ConceptName shortName1 = new ConceptName("Cat", new Locale("en")); + shortName1.setConceptNameType(ConceptNameType.SHORT); + concept.addName(shortName1); + + ConceptName shortName2 = new ConceptName("Gato", new Locale("es")); + shortName2.setConceptNameType(ConceptNameType.SHORT); + concept.addName(shortName2); + + Assert.assertEquals("Gato", concept.getShortNameInLocale(new Locale("es", "ES")).getName()); + } + + @Test + @Verifies(value = "should return the language prefered name if no name is explicitly marked as locale preferred", method = "getPreferredName(Locale)") + public void getPreferredName_shouldReturnTheBesLocalePreferred() throws Exception { + Concept testConcept = createMockConcept(1, Locale.US); + // preferred name in en + ConceptName preferredNameEN = createMockConceptName(4, new Locale("en"), null, true); + testConcept.addName(preferredNameEN); + Assert.assertEquals(preferredNameEN.getName(), testConcept.getPreferredName(Locale.US).getName()); + } + /** * Convenient factory method to create a populated Concept with a one fully specified name and * one short name