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());
}
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());
}
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;
}
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"));
}
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"));
}
Aggregations