Search in sources :

Example 66 with ConceptName

use of org.openmrs.ConceptName in project openmrs-core by openmrs.

the class OrderFrequencyValidatorTest method validate_shouldPassValidationIfFieldLengthsAreCorrect.

/**
 * @see OrderFrequencyValidator#validate(Object, org.springframework.validation.Errors)
 */
@Test
public void validate_shouldPassValidationIfFieldLengthsAreCorrect() {
    ConceptService cs = Context.getConceptService();
    Concept concept = new Concept();
    ConceptName cn = new ConceptName("new name", Context.getLocale());
    concept.setDatatype(cs.getConceptDatatype(1));
    concept.setConceptClass(cs.getConceptClass(19));
    concept.addName(cn);
    concept.addDescription(new ConceptDescription("some description", null));
    cs.saveConcept(concept);
    OrderFrequency orderFrequency = new OrderFrequency();
    orderFrequency.setConcept(concept);
    orderFrequency.setRetireReason("retireReason");
    Errors errors = new BindException(orderFrequency, "orderFrequency");
    new OrderFrequencyValidator().validate(orderFrequency, errors);
    Assert.assertFalse(errors.hasErrors());
}
Also used : Concept(org.openmrs.Concept) Errors(org.springframework.validation.Errors) ConceptName(org.openmrs.ConceptName) BindException(org.springframework.validation.BindException) ConceptDescription(org.openmrs.ConceptDescription) ConceptService(org.openmrs.api.ConceptService) OrderFrequency(org.openmrs.OrderFrequency) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 67 with ConceptName

use of org.openmrs.ConceptName in project openmrs-core by openmrs.

the class ConceptValidatorChangeSet method validateAndCleanUpConcepts.

/**
 * This method is called by the execute {@link #execute(Database)} method to run through all
 * concept and their conceptNames and validates them, It also tries to fix any constraints that
 * are being violated.
 *
 * @param connection The database connection
 */
private void validateAndCleanUpConcepts(JdbcConnection connection) {
    List<Integer> conceptIds = getAllUnretiredConceptIds(connection);
    allowedLocales = getAllowedLocalesList(connection);
    // default locale(if none, then 'en') is always the last in the list.
    defaultLocale = allowedLocales.get(allowedLocales.size() - 1);
    // a map to store all duplicates names found for each locale
    Map<Locale, Set<String>> localeDuplicateNamesMap = null;
    for (Integer conceptId : conceptIds) {
        Map<Locale, List<ConceptName>> localeConceptNamesMap = getLocaleConceptNamesMap(connection, conceptId);
        if (localeConceptNamesMap == null) {
            updateWarnings.add("No names added for concept with id: " + conceptId);
            continue;
        }
        boolean hasFullySpecifiedName = false;
        List<ConceptName> namesWithNoLocale = null;
        // for each locale
        for (Map.Entry<Locale, List<ConceptName>> e : localeConceptNamesMap.entrySet()) {
            Locale conceptNameLocale = e.getKey();
            boolean fullySpecifiedNameForLocaleFound = false;
            boolean preferredNameForLocaleFound = false;
            boolean shortNameForLocaleFound = false;
            // map to hold a name and a list of conceptNames that are found as duplicates
            Map<String, List<ConceptName>> nameDuplicateConceptNamesMap = new HashMap<>();
            // for each name in the locale
            for (ConceptName nameInLocale : e.getValue()) {
                if (StringUtils.isBlank(nameInLocale.getName())) {
                    updateWarnings.add("ConceptName with id " + nameInLocale.getConceptNameId() + " (" + nameInLocale.getName() + ") is null, white space character or empty string");
                }
                // if the concept name has no locale, wonder why this would be the case but there was no not-null constraint originally
                if (conceptNameLocale == null) {
                    if (namesWithNoLocale == null) {
                        namesWithNoLocale = new LinkedList<>();
                    }
                    namesWithNoLocale.add(nameInLocale);
                    continue;
                }
                // The concept's locale should be among the allowed locales listed in global properties
                if (!allowedLocales.contains(conceptNameLocale)) {
                    updateWarnings.add("ConceptName with id: " + nameInLocale.getConceptNameId() + " (" + nameInLocale.getName() + ") has a locale (" + conceptNameLocale + ") that isn't listed among the allowed ones by the system admin");
                }
                if (nameInLocale.getLocalePreferred() != null) {
                    if (nameInLocale.getLocalePreferred() && !preferredNameForLocaleFound) {
                        if (nameInLocale.isIndexTerm()) {
                            nameInLocale.setLocalePreferred(false);
                            reportUpdatedName(nameInLocale, "Preferred name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been dropped as the preferred name because it is a search term");
                        } else if (nameInLocale.isShort()) {
                            nameInLocale.setLocalePreferred(false);
                            reportUpdatedName(nameInLocale, "Preferred name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been dropped as the preferred name because it is a short name");
                        } else {
                            preferredNameForLocaleFound = true;
                        }
                    } else // should have one preferred name per locale
                    if (nameInLocale.getLocalePreferred() && preferredNameForLocaleFound) {
                        // drop this name as locale preferred so that we have only one
                        nameInLocale.setLocalePreferred(false);
                        reportUpdatedName(nameInLocale, "Preferred name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been dropped as the preferred name because there is already another preferred name in the same locale");
                    }
                } else {
                    // Enforce not-null on locale preferred field constraint from the database table
                    nameInLocale.setLocalePreferred(false);
                    reportUpdatedName(nameInLocale, "The locale preferred property of name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been updated to false from null");
                }
                if (nameInLocale.isFullySpecifiedName()) {
                    if (!hasFullySpecifiedName) {
                        hasFullySpecifiedName = true;
                    }
                    if (!fullySpecifiedNameForLocaleFound) {
                        fullySpecifiedNameForLocaleFound = true;
                    } else {
                        nameInLocale.setConceptNameType(null);
                        reportUpdatedName(nameInLocale, "The name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been converted from fully specified to a synonym");
                    }
                }
                if (nameInLocale.isShort()) {
                    if (!shortNameForLocaleFound) {
                        shortNameForLocaleFound = true;
                    } else // should have one short name per locale
                    {
                        nameInLocale.setConceptNameType(null);
                        reportUpdatedName(nameInLocale, "The name '" + nameInLocale.getName() + "' in locale '" + conceptNameLocale.getDisplayName() + "' has been converted from a short name to a synonym");
                    }
                }
                if ((nameInLocale.isFullySpecifiedName() || nameInLocale.isPreferred()) && !isNameUniqueInLocale(connection, nameInLocale, conceptId)) {
                    if (localeDuplicateNamesMap == null) {
                        localeDuplicateNamesMap = new HashMap<>();
                    }
                    if (!localeDuplicateNamesMap.containsKey(conceptNameLocale)) {
                        localeDuplicateNamesMap.put(conceptNameLocale, new HashSet<>());
                    }
                    localeDuplicateNamesMap.get(conceptNameLocale).add(nameInLocale.getName());
                }
                String name = nameInLocale.getName().toLowerCase();
                if (!nameDuplicateConceptNamesMap.containsKey(name)) {
                    nameDuplicateConceptNamesMap.put(name, new ArrayList<>());
                }
                nameDuplicateConceptNamesMap.get(name).add(nameInLocale);
            }
            // No duplicate names allowed for the same locale and concept
            for (Map.Entry<String, List<ConceptName>> entry : nameDuplicateConceptNamesMap.entrySet()) {
                // no duplicates found for the current name
                if (entry.getValue().size() < 2) {
                    continue;
                }
                logMessages.add("The name '" + entry.getKey() + "' was found multiple times for the concept with id '" + conceptId + "' in locale '" + conceptNameLocale.getDisplayName() + "'");
            }
            // if this locale has no preferred name found, set one
            if (!preferredNameForLocaleFound) {
                // find the fully specified name and set it as the locale preferred
                for (ConceptName cn : localeConceptNamesMap.get(conceptNameLocale)) {
                    if (cn.isFullySpecifiedName()) {
                        cn.setLocalePreferred(true);
                        preferredNameForLocaleFound = true;
                        break;
                    }
                }
                // if there was no fully specified name found, mark one of the synonyms as locale preferred
                if (!preferredNameForLocaleFound) {
                    for (ConceptName cn : localeConceptNamesMap.get(conceptNameLocale)) {
                        if (cn.isSynonym()) {
                            cn.setLocalePreferred(true);
                            break;
                        }
                    }
                }
            }
        }
        // Make the first name found the fully specified name if none exists
        if (!hasFullySpecifiedName) {
            hasFullySpecifiedName = setFullySpecifiedName(conceptId, localeConceptNamesMap);
        }
        // set the first name found as the fully specified and drop locale preferred mark and short name concept name type
        if (!CollectionUtils.isEmpty(namesWithNoLocale)) {
            for (ConceptName conceptName : namesWithNoLocale) {
                conceptName.setLocale(defaultLocale);
                reportUpdatedName(conceptName, "The locale for ConceptName with id " + conceptName.getConceptNameId() + " (" + conceptName.getName() + ") has been set to '" + defaultLocale.getDisplayName() + "'");
                if (!hasFullySpecifiedName) {
                    conceptName.setConceptNameType(ConceptNameType.FULLY_SPECIFIED);
                    hasFullySpecifiedName = true;
                    reportUpdatedName(conceptName, "ConceptName with id " + conceptName.getConceptNameId() + " (" + conceptName.getName() + ") in locale '" + defaultLocale.getDisplayName() + "' has been set as the fully specified name for concept with id : " + conceptId);
                } else // convert to a synonym and should not be preferred, this will avoid inconsistencies, in case
                // already short, fully specified and preferred names exist
                {
                    conceptName.setLocalePreferred(false);
                    reportUpdatedName(conceptName, "ConceptName with id " + conceptName.getConceptNameId() + " (" + conceptName.getName() + ") is no longer marked as preferred because it had no locale");
                    if (conceptName.isFullySpecifiedName() || conceptName.isShort()) {
                        conceptName.setConceptNameType(null);
                        reportUpdatedName(conceptName, "The name '" + conceptName.getName() + "' in locale '" + conceptName.toString() + "' has been converted to a synonym because it had no locale");
                    }
                }
            }
        }
        if (!hasFullySpecifiedName) {
            updateWarnings.add("Concept with id: " + conceptId + " has no fully specified name");
        }
    }
    if (!MapUtils.isEmpty(localeDuplicateNamesMap)) {
        for (Map.Entry<Locale, Set<String>> entry : localeDuplicateNamesMap.entrySet()) {
            // no duplicates found in the locale
            if (CollectionUtils.isEmpty(entry.getValue())) {
                continue;
            }
            for (String duplicateName : entry.getValue()) {
                updateWarnings.add("Concept Name '" + duplicateName + "' was found multiple times in locale '" + entry.getKey() + "'");
            }
        }
    }
    logMessages.add("Number of Updated ConceptNames: " + updatedConceptNames.size());
}
Also used : Locale(java.util.Locale) HashSet(java.util.HashSet) ResultSet(java.sql.ResultSet) ListOrderedSet(org.apache.commons.collections.set.ListOrderedSet) Set(java.util.Set) HashMap(java.util.HashMap) ConceptName(org.openmrs.ConceptName) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 68 with ConceptName

use of org.openmrs.ConceptName in project openmrs-core by openmrs.

the class ConceptValidatorChangeSet method setFullySpecifiedName.

/**
 * Sets the fully specified name from available names
 *
 * @param localeConceptNamesMap, list of all concept names for the concept
 * @return
 */
private boolean setFullySpecifiedName(int conceptId, Map<Locale, List<ConceptName>> localeConceptNamesMap) {
    // Pick the first name in any locale by searching in order from the allowed locales
    for (Locale allowedLoc : allowedLocales) {
        List<ConceptName> possibleFullySpecNames = localeConceptNamesMap.get(allowedLoc);
        if (CollectionUtils.isEmpty(possibleFullySpecNames)) {
            continue;
        }
        // try the synonyms
        for (ConceptName cn : possibleFullySpecNames) {
            if (cn.isSynonym()) {
                cn.setConceptNameType(ConceptNameType.FULLY_SPECIFIED);
                reportUpdatedName(cn, "ConceptName with id " + cn.getConceptNameId() + " (" + cn.getName() + ") in locale '" + allowedLoc.getDisplayName() + "' has been set as the fully specified name for concept with id : " + conceptId);
                return true;
            }
        }
        // try the short names
        for (ConceptName cn : possibleFullySpecNames) {
            if (cn.isShort()) {
                cn.setConceptNameType(ConceptNameType.FULLY_SPECIFIED);
                reportUpdatedName(cn, "ConceptName with id " + cn.getConceptNameId() + " (" + cn.getName() + ") in locale '" + allowedLoc.getDisplayName() + "' has been changed from short to fully specified name for concept with id : " + conceptId);
                return true;
            }
        }
    }
    // pick a name randomly from the conceptName map
    for (Map.Entry<Locale, List<ConceptName>> entry : localeConceptNamesMap.entrySet()) {
        Locale locale = entry.getKey();
        if (locale != null) {
            ConceptName fullySpecName = entry.getValue().get(0);
            fullySpecName.setConceptNameType(ConceptNameType.FULLY_SPECIFIED);
            reportUpdatedName(fullySpecName, "ConceptName with id " + fullySpecName.getConceptNameId() + " (" + fullySpecName.getName() + ") in locale '" + locale.getDisplayName() + "' has been set as the fully specified name for concept with id : " + conceptId);
            return true;
        }
    }
    // most probably this concept has no names added to it yet
    return false;
}
Also used : Locale(java.util.Locale) ConceptName(org.openmrs.ConceptName) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 69 with ConceptName

use of org.openmrs.ConceptName in project openmrs-core by openmrs.

the class ConceptValidatorTest method validate_shouldFailIfAnyNameIsANullValue.

@Test
public void validate_shouldFailIfAnyNameIsANullValue() {
    concept.addDescription(new ConceptDescription("some description", null));
    concept.setConceptClass(new ConceptClass(1));
    concept.setDatatype(new ConceptDatatype(1));
    concept.addName(new ConceptName("name", Context.getLocale()));
    concept.addName(new ConceptName(null, Context.getLocale()));
    validator.validate(concept, errors);
    assertThat(errors, hasGlobalErrors("Concept.name.empty"));
}
Also used : ConceptClass(org.openmrs.ConceptClass) ConceptName(org.openmrs.ConceptName) ConceptDescription(org.openmrs.ConceptDescription) ConceptDatatype(org.openmrs.ConceptDatatype) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 70 with ConceptName

use of org.openmrs.ConceptName in project openmrs-core by openmrs.

the class ConceptValidatorTest method validate_shouldFailIfAnyNameIsAnEmptyString.

@Test
public void validate_shouldFailIfAnyNameIsAnEmptyString() {
    concept.addDescription(new ConceptDescription("some description", null));
    concept.setConceptClass(new ConceptClass(1));
    concept.setDatatype(new ConceptDatatype(1));
    concept.addName(new ConceptName("name", Context.getLocale()));
    concept.addName(new ConceptName("", Context.getLocale()));
    validator.validate(concept, errors);
    assertThat(errors, hasGlobalErrors("Concept.name.empty"));
}
Also used : ConceptClass(org.openmrs.ConceptClass) ConceptName(org.openmrs.ConceptName) ConceptDescription(org.openmrs.ConceptDescription) ConceptDatatype(org.openmrs.ConceptDatatype) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Aggregations

ConceptName (org.openmrs.ConceptName)100 Test (org.junit.Test)78 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)71 Concept (org.openmrs.Concept)62 ConceptDescription (org.openmrs.ConceptDescription)42 ConceptDatatype (org.openmrs.ConceptDatatype)34 ConceptClass (org.openmrs.ConceptClass)33 Locale (java.util.Locale)32 OpenmrsMatchers.hasConcept (org.openmrs.test.OpenmrsMatchers.hasConcept)22 ArrayList (java.util.ArrayList)11 Date (java.util.Date)9 Obs (org.openmrs.Obs)9 BindException (org.springframework.validation.BindException)8 ConceptMap (org.openmrs.ConceptMap)7 Errors (org.springframework.validation.Errors)7 LinkedList (java.util.LinkedList)6 List (java.util.List)6 Patient (org.openmrs.Patient)6 Encounter (org.openmrs.Encounter)5 OrderFrequency (org.openmrs.OrderFrequency)5