ConceptReferenceTermValidator.java
/**
* 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.validator;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.openmrs.ConceptReferenceTerm;
import org.openmrs.ConceptReferenceTermMap;
import org.openmrs.annotation.Handler;
import org.openmrs.api.APIException;
import org.openmrs.api.context.Context;
import org.openmrs.util.OpenmrsUtil;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* Validates {@link ConceptReferenceTerm} objects.
*
* @since 1.9
*/
@Handler(supports = { ConceptReferenceTerm.class }, order = 50)
public class ConceptReferenceTermValidator implements Validator {
/**
* Determines if the command object being submitted is a valid type
*
* @see org.springframework.validation.Validator#supports(java.lang.Class)
*/
@SuppressWarnings("rawtypes")
public boolean supports(Class c) {
return ConceptReferenceTerm.class.isAssignableFrom(c);
}
/**
* Checks that a given concept reference term object is valid.
*
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
* @should fail if the concept reference term object is null
* @should fail if the name is a white space character
* @should fail if the code is null
* @should fail if the code is an empty string
* @should fail if the code is a white space character
* @should fail if the concept reference term code is a duplicate in its concept source
* @should fail if the concept source is null
* @should pass if all the required fields are set and valid
* @should pass if the duplicate name is for a term from another concept source
* @should pass if the duplicate code is for a term from another concept source
* @should fail if a concept reference term map has no concept map type
* @should fail if termB of a concept reference term map is not set
* @should fail if a term is mapped to itself
* @should fail if a term is mapped multiple times to the same term
*/
public void validate(Object obj, Errors errors) throws APIException {
if (obj == null || !(obj instanceof ConceptReferenceTerm))
throw new IllegalArgumentException("The parameter obj should not be null and must be of type"
+ ConceptReferenceTerm.class);
ConceptReferenceTerm conceptReferenceTerm = (ConceptReferenceTerm) obj;
String code = conceptReferenceTerm.getCode();
if (!StringUtils.hasText(code)) {
errors.rejectValue("code", "ConceptReferenceTerm.error.codeRequired",
"The code property is required for a concept reference term");
return;
}
if (conceptReferenceTerm.getConceptSource() == null) {
errors.rejectValue("conceptSource", "ConceptReferenceTerm.error.sourceRequired",
"The conceptSource property is required for a concept reference term");
return;
}
code = code.trim();
//Ensure that there are no terms with the same code in the same source
ConceptReferenceTerm termWithDuplicateCode = Context.getConceptService().getConceptReferenceTermByCode(code,
conceptReferenceTerm.getConceptSource());
if (termWithDuplicateCode != null) {
if (!OpenmrsUtil.nullSafeEquals(termWithDuplicateCode.getId(), conceptReferenceTerm.getId())) {
errors.rejectValue("code", "ConceptReferenceTerm.duplicate.code",
"Duplicate concept reference term code in its concept source: " + code);
}
}
//validate the concept reference term maps
if (CollectionUtils.isNotEmpty(conceptReferenceTerm.getConceptReferenceTermMaps())) {
int index = 0;
Set<String> mappedTermUuids = null;
for (ConceptReferenceTermMap map : conceptReferenceTerm.getConceptReferenceTermMaps()) {
if (map == null)
throw new APIException("Cannot add a null concept reference term map");
if (map.getConceptMapType() == null) {
errors.rejectValue("conceptReferenceTermMaps[" + index + "].conceptMapType",
"ConceptReferenceTerm.error.mapTypeRequired", "Concept Map Type is required");
} else if (map.getTermB() == null) {
errors.rejectValue("conceptReferenceTermMaps[" + index + "].termB",
"ConceptReferenceTerm.error.termBRequired", "Mapped Term is required");
} else if (map.getTermB().equals(conceptReferenceTerm)) {
errors.rejectValue("conceptReferenceTermMaps[" + index + "].termB", "ConceptReferenceTerm.map.sameTerm",
"Cannot map a concept reference term to itself");
}
//don't proceed to the next map
if (errors.hasErrors())
return;
if (mappedTermUuids == null)
mappedTermUuids = new HashSet<String>();
//if we already have a mapping to this term, reject it this map
if (!mappedTermUuids.add(map.getTermB().getUuid())) {
errors.rejectValue("conceptReferenceTermMaps[" + index + "].termB",
"ConceptReferenceTerm.termToTerm.alreadyMapped",
"Cannot map a reference term multiple times to the same concept reference term");
}
index++;
}
}
}
}