Java tutorial
/* * component: "openEHR Reference Java Implementation" description: "Class * DataValidatorImpl" keywords: "validator" * * author: "Rong Chen <rong.acode@gmail.com>" support: "openEHR Java Project * <ref_impl_java@openehr.org>" copyright: "Copyright (c) 2008 Cambio Healthcare * Systems, Sweden" license: "See notice at bottom of class" * * file: "$URL$" revision: "$LastChangedRevision$" last_change: * "$LastChangedDate$" */ package org.openehr.validation; import br.ufg.inf.fs.pep.archetypes.ArchetypeRepositoryFactory; import br.ufg.inf.fs.pep.utils.log.Trace; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.openehr.am.archetype.Archetype; import org.openehr.am.archetype.assertion.Assertion; import org.openehr.am.archetype.assertion.ExpressionBinaryOperator; import org.openehr.am.archetype.assertion.ExpressionLeaf; import org.openehr.am.archetype.constraintmodel.*; import org.openehr.am.archetype.constraintmodel.primitive.CString; import org.openehr.am.archetype.ontology.ArchetypeOntology; import org.openehr.am.archetype.ontology.ArchetypeTerm; import org.openehr.am.archetype.ontology.OntologyDefinitions; import org.openehr.rm.common.archetyped.Locatable; import org.openehr.rm.datatypes.basic.DataValue; import org.openehr.rm.support.basic.Interval; import org.openehr.rm.support.identification.ArchetypeID; import org.openehr.validation.exceptions.GenericValidationException; /** * Implementation of an archetype-based data validator * @author rong.chen */ public class DataValidatorImpl implements DataValidator { /** * Validates the data using given archetype * * @param data * @return errors empty if data pass validation without error */ @Override public List<ValidationError> validate(Locatable data) throws GenericValidationException { String archetypeId = data.getArchetypeNodeId(); Archetype archetype = ArchetypeRepositoryFactory.getInstance().getArchetype(archetypeId); if (archetype == null) { throw new GenericValidationException("Archetype " + archetypeId + " not found."); } return this.validate(data, archetype); } /** * Validates the data using given archetype * * @param data * @param archetype * @return errors empty if data pass validation without error */ @Override public List<ValidationError> validate(Locatable data, Archetype archetype) throws GenericValidationException { log.debug("validate archetype: " + archetype.getArchetypeId()); List<ValidationError> errors = new ArrayList<ValidationError>(); validateComplex(archetype.getDefinition(), data, Locatable.PATH_SEPARATOR, errors, archetype); return errors; } /** * Valida as restries contidas em um CComplexObject * @param ccobj * @param object * @param path * @param errors * @param archetype * @throws GenericValidationException */ void validateComplex(CComplexObject ccobj, Object object, String path, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { log.debug("validate CComplexObject of type: " + ccobj.getRmTypeName() + " at path: " + path); String newPath = null; // loop through the attributes for (CAttribute cattr : ccobj.getAttributes()) { Object attribute = null; try { attribute = fetchAttribute(object, cattr); } catch (NoSuchMethodException ex) { continue; } catch (IllegalAccessException ex) { continue; } catch (InvocationTargetException ex) { continue; } log.debug("attribute " + cattr.getRmAttributeName() + " isRequired: " + cattr.isRequired() + ", attribute == null ? " + (attribute == null)); newPath = includePathSeparator(path); newPath += cattr.getRmAttributeName(); String description = getErrorDescription(archetype, ccobj, null); validateAttribute(cattr, attribute, path, archetype, description, errors, newPath); } } /** * Verifica se a quantidade de membros de values menor do que o mnimo * permitido * @param interval * @param values * @return */ private boolean abaixoDoMinimo(Interval interval, Collection values) { return interval.getLower() != null && interval.getLower().compareTo(values.size()) > 0; } /** * Verifica se a quantidade de membros de values maior do que o mximo * permitido * @param interval * @param values * @return */ private boolean acimaMaximo(Interval interval, Collection values) { return interval.getUpper() != null && interval.getUpper().compareTo(values.size()) < 0; } /** * Assegurar que o argumento desejado no nulo e/ou vazio * @param argument * @param argumentName * @throws IllegalArgumentException */ private void argumentoNaoVazioENaoNulo(Object argument, String argumentName) { String mens = null; if (argument instanceof String && StringUtils.isEmpty((String) argument)) { mens = argumentName + " is null or is empty"; } else if (argument == null) { mens = argumentName + " is null"; } else { return; } throw new IllegalArgumentException(mens); } /** * A partir de um construtor e de um argumento para o construtor, retorna * o objeto construido. * @param constructor * @param argument * @return */ private Object build(Constructor constructor, Object argument) { if (constructor != null) { try { return constructor.newInstance(argument); } catch (Exception ex) { Trace.log(ex.getMessage()); } } return argument; } private void decideSubtipoConstraint(ArchetypeConstraint constraint, Object value, String path, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { if (restricaoCObject(constraint)) { CObject cObject = castToCobject(constraint); validateObject(cObject, value, path, errors, archetype); } else { defineTipoAtributoParaValidar((CAttribute) constraint, value, path, errors, archetype); } } /** * Realiza cast para {@link CObject} * @param object * @return */ private CObject castToCobject(Object object) { return (CObject) object; } /** * Realiza cast para {@link CMultipleAttribute} * @param object * @return */ private CMultipleAttribute castToCMultipleAttribute(Object object) { return (CMultipleAttribute) object; } /** * Realiza cast para {@link CSingleAttribute} * @param object * @return */ private CSingleAttribute castToCSingleAttribute(Object object) { return (CSingleAttribute) object; } /** * Verifica se a restrio um {@link CObject} * @param constraint * @return */ private boolean restricaoCObject(ArchetypeConstraint constraint) { return constraint instanceof CObject; } /** * Verifica se a restrio um {@link CPrimitiveObject} * @param cobj * @return */ private boolean restricaoCPrimitiveObject(CObject cobj) { return cobj instanceof CPrimitiveObject; } /** * Verifica se a restrio um {@link CSingleAttribute} * @param constraint * @return */ private boolean restricaoSingleAttribute(ArchetypeConstraint constraint) { return constraint instanceof CSingleAttribute; } /** * Obtem termo arqutipo * @param termosArquetipos * @param nodeId * @return */ private String getArchetypeTerm(List<ArchetypeTerm> termosArquetipos, String nodeId) { String description = null; if (termosArquetipos != null) { for (ArchetypeTerm archetypeTerm : termosArquetipos) { String term = archetypeTerm.getCode(); if (nodeId.equals(term)) { description = archetypeTerm.getDescription(); break; } } } return description; } /** * Extrai lista de termos arqutipos de um determinado idioma * @param ontologyDefinitions * @param idioma * @return */ private List<ArchetypeTerm> getArchetypeTerms(List<OntologyDefinitions> ontologyDefinitions, String idioma) { List<ArchetypeTerm> archetypeTerms = null; for (OntologyDefinitions ontologyDefinition : ontologyDefinitions) { if (ontologyDefinition.getLanguage().equals(idioma)) { archetypeTerms = ontologyDefinition.getDefinitions(); break; } } return archetypeTerms; } /** * Retorna construtor de um parametro {@link String} * @param klass * @return * @throws SecurityException */ private Constructor getConstructorWithStringArgument(Class klass) { Constructor constructor = null; for (Constructor constr : klass.getConstructors()) { if (constr.getParameterTypes().length == 1 && constr.getParameterTypes()[0].equals(String.class)) { constructor = constr; break; } } return constructor; } /** * Retorna se a restrio instancia de {@link ArchetypeSlot} * @param constraint * @return */ private boolean restricaoArchetypeSlot(ArchetypeConstraint constraint) { return constraint instanceof ArchetypeSlot; } /** * Retorna se uma restrio atendida no dado * @param cObj * @param data * @return */ private boolean objetoAtendeRestricao(CObject cObj, Locatable data) { if (restricaoArchetypeSlot(cObj)) { log.debug("ArchetypeSlot : " + data.getArchetypeNodeId()); ArchetypeSlot slot = (ArchetypeSlot) cObj; return validateRootSlot(slot, data); } else { return cObj.getNodeId().equals(data.getArchetypeNodeId()); } } /** * Valida {@link CSingleAttribute} quando a restrio possui mais de uma * alternativa * @param cattr * @param attribute * @param path * @param archetype * @param errors * @throws GenericValidationException */ private void validaAlternativasSingleAttribute(CSingleAttribute cattr, Object attribute, String path, Archetype archetype, List<ValidationError> errors) throws GenericValidationException { List<ValidationError> newErrors = null; for (CObject cobj : cattr.alternatives()) { newErrors = new ArrayList<ValidationError>(); validateObject(cobj, attribute, path, newErrors, archetype); if (newErrors.isEmpty()) { return; } } ValidationError error = new ValidationError(archetype.getArchetypeId(), path, path, ErrorType.ALTERNATIVES_NOT_SATISFIED, getErrorDescription(archetype, cattr, null)); errors.add(error); } /** * Percorre os objetos em uma lista validando cada um dos membros * @param objects * @param path * @param cobj * @param newPath * @param errors * @param archetype * @throws GenericValidationException */ private void validaObjetosEmCollections(List<Object> objects, String path, CObject cobj, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { for (Object obj : objects) { String newPath = path + "[" + cobj.getNodeId() + "]"; validateObject(cobj, obj, newPath, errors, archetype); } } /** * Valida as restries contidas em um CAttribute * @param cattr * @param attribute * @param path * @param archetype * @param description * @param errors * @param newPath * @throws GenericValidationException */ private void validateAttribute(CAttribute cattr, Object attribute, String path, Archetype archetype, String description, List<ValidationError> errors, String newPath) throws GenericValidationException { if (cattr.isRequired() && attribute == null) { log.debug("ERROR --> attribute missing at " + path); errors.add(new ValidationError(archetype.getArchetypeId(), path, cattr.path(), ErrorType.ATTRIBUTE_MISSING, description)); } else if (!cattr.isAllowed() && attribute != null) { errors.add(new ValidationError(archetype.getArchetypeId(), path, cattr.path(), ErrorType.ATTRIBUTE_NOT_ALLOWED, description)); } else if (attribute != null) { defineTipoAtributoParaValidar(cattr, attribute, newPath, errors, archetype); } } /** * Decide se a restrio um CSingleAttribute ou CMultipleAttribute * @param cattr * @param attribute * @param newPath * @param errors * @param archetype * @throws GenericValidationException */ private void defineTipoAtributoParaValidar(CAttribute cattr, Object attribute, String newPath, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { if (restricaoSingleAttribute(cattr)) { validateSingleAttribute(castToCSingleAttribute(cattr), attribute, newPath, errors, archetype); } else { validateMultipleAttribute(castToCMultipleAttribute(cattr), attribute, newPath, errors, archetype); } } /** * Executar o mtodo de obteno do valor de um atributo * @param object * @param getter * @return * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException */ private Object executeGetter(Object object, String getter) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { Method method = null; method = object.getClass().getMethod(getter, null); return method.invoke(object, null); } /** * Extrai determinado termo arqutipo de um respectivo idioma * @param archetype * @param language * @param nodeId * @return */ private String extractTerm(Archetype archetype, String language, String nodeId) { ArchetypeOntology ontology = archetype.getOntology(); String lang = language == null ? "pt-br" : language; String description = null; List<OntologyDefinitions> ontologyDefinitions = ontology.getTermDefinitionsList(); List<ArchetypeTerm> archetypeTerms = null; archetypeTerms = getArchetypeTerms(ontologyDefinitions, lang); description = getArchetypeTerm(archetypeTerms, nodeId); return description; } /** * Inclui path separator "/" no path * @param path * @return */ private String includePathSeparator(String path) { if (!path.equals(Locatable.PATH_SEPARATOR)) { return path + Locatable.PATH_SEPARATOR; } return path; } /** * Valida a conformidade de restries descritas em {@link CSingleAttribute} * @param cattr * @param attribute * @param path * @param errors * @param archetype * @throws GenericValidationException */ void validateSingleAttribute(CSingleAttribute cattr, Object attribute, String path, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { log.debug("validateSingleAttribute.."); if (cattr.alternatives().size() > 1) { validaAlternativasSingleAttribute(cattr, attribute, path, archetype, errors); } else if (cattr.alternatives().size() == 1) { CObject cobj = cattr.alternatives().get(0); validateObject(cobj, attribute, path, errors, archetype); } } /** * Verificar conformidade de objetos {@link Collection} com as restries * contidas em {@link CMultipleAttribute} * @param cattr * @param attribute * @param path * @param errors * @param archetype * @throws GenericValidationException */ void validateMultipleAttribute(CMultipleAttribute cattr, Object attribute, String path, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { log.debug("validateMultipleAttribute.."); List<CObject> children = cattr.getChildren(); if (children == null) { return; } Collection<Object> values = (Collection<Object>) attribute; ValidationError errorCardinality = validateCardinality(values, archetype, path, cattr); if (errorCardinality != null) { errors.add(errorCardinality); return; } log.debug("validating total cobj: " + children.size() + ", values: " + values.size()); List<Object> objects = null; int contador = 0; for (CObject cobj : children) { log.debug("validating sub-cobj at: " + cobj.path()); objects = findMatchingNodes(values, cobj); contador += objects.size(); ValidationError occurrenceError = validateOccurrence(cobj, objects, archetype, path); if (occurrenceError != null) { errors.add(occurrenceError); return; } validaObjetosEmCollections(objects, path, cobj, errors, archetype); } if (contador != values.size()) { errors.add(new ValidationError(archetype.getArchetypeId(), path, cattr.path(), ErrorType.OCCURRENCES_NOT_DESCRIBED, null)); } } /** * Valida a ocorrencia de cada {@link CObject} em um {@link Collection} * @param cobj * @param objects * @param archetype * @param path * @return */ private ValidationError validateOccurrence(CObject cobj, Collection<Object> objects, Archetype archetype, String path) { Interval<Integer> occurrences = cobj.getOccurrences(); if (occurrences == null) { return null; } ValidationError error = null; if (abaixoDoMinimo(occurrences, objects)) { error = new ValidationError(archetype.getArchetypeId(), path, cobj.path(), ErrorType.OCCURRENCES_TOO_FEW, null); } else if (acimaMaximo(occurrences, objects)) { error = new ValidationError(archetype.getArchetypeId(), path, cobj.path(), ErrorType.OCCURRENCES_TOO_MANY, null); } return error; } /** * * @param values * @param archetype * @param path * @param cattr * @return */ private ValidationError validateCardinality(Collection<Object> values, Archetype archetype, String path, CMultipleAttribute cattr) { Cardinality cardinality = cattr.getCardinality(); Interval<Integer> interval = cardinality.getInterval(); log.debug("cardinality.interval: " + interval); if (abaixoDoMinimo(interval, values)) { return new ValidationError(archetype.getArchetypeId(), path, cattr.path(), ErrorType.ITEMS_TOO_FEW, null); } else if (acimaMaximo(interval, values)) { return new ValidationError(archetype.getArchetypeId(), path, cattr.path(), ErrorType.ITEMS_TOO_MANY, null); } return null; } /** * Finds matching value node using AT code of CObject * * @param values * @param code * @return empty list if not found */ List<Object> findMatchingNodes(Collection<Object> values, CObject cObj) { String type = cObj.getRmTypeName().toUpperCase(KnownTypes.getLocale()).replace("_", ""); Class klasse = KnownTypes.getAllTypes().get(type); if (Locatable.class.isAssignableFrom(klasse)) { return findMatchingObjects(values, cObj); } return findMatchingDataValue(values, cObj, klasse); } /** * Captura objetos em um {@link Collection} que esteja em conformidade com * uma restrio * @param dados * @param constraint * @return */ private List<Object> findMatchingObjects(Collection<Object> dados, CObject constraint) { List<Object> objects = new ArrayList<Object>(); Locatable lo = null; for (Object value : dados) { if (!(value instanceof Locatable)) { log.warn("trying to find matching value on un-pathable obj.."); continue; } lo = (Locatable) value; if (objetoAtendeRestricao(constraint, lo)) { objects.add(lo); } } return objects; } /** * Captura os objetos que herdam de {@link DataValue} * @param values * @param cObj * @param klass * @return */ private List<Object> findMatchingDataValue(Collection<Object> values, CObject cObj, Class klass) { List<Object> objects = new ArrayList<Object>(); DataValue dv = null; for (Object value : values) { if (!(value instanceof DataValue)) { log.warn("trying to find matching value on un-pathable obj.."); continue; } dv = (DataValue) value; if (klass.isAssignableFrom(value.getClass())) { log.debug("value found for code: " + cObj.getNodeId()); objects.add(dv); } } return objects; } /** * Confronta um dado com um objeto de restrio * @param cobj * @param value * @param path * @param errors * @param archetype * @throws GenericValidationException */ void validateObject(CObject cobj, Object value, String path, List<ValidationError> errors, Archetype archetype) throws GenericValidationException { log.debug("validate CObject.."); Class dataClass = value.getClass(); String restrictionType = cobj.getRmTypeName().replace("_", "").toUpperCase(KnownTypes.getLocale()); restrictionType = restrictionType.split("<")[0]; Class restClass = KnownTypes.getAllTypes().get(restrictionType); if (!restClass.isAssignableFrom(dataClass) && (!(restricaoCPrimitiveObject(cobj)))) { // verificar se o tipo eh primitivo e se o dado eh String errors.add(new ValidationError(archetype.getArchetypeId(), path, cobj.path(), ErrorType.RM_TYPE_INVALID, getErrorDescription(archetype, cobj, null))); return; } if (cobj.isAnyAllowed()) { return; } if (cobj instanceof CComplexObject) { validateComplex((CComplexObject) cobj, value, path, errors, archetype); } else if (cobj instanceof CDomainType) { validateDomain(archetype, (CDomainType) cobj, value, path, errors); } else if (restricaoCPrimitiveObject(cobj)) { validatePrimitive(archetype, (CPrimitiveObject) cobj, value, path, errors); } else if (restricaoArchetypeSlot(cobj)) { this.validateArchetypeSlot((ArchetypeSlot) cobj, value, path, errors); } else if (cobj instanceof ArchetypeInternalRef) { this.validateArchetypeInternalRef(archetype, (ArchetypeInternalRef) cobj, value, path, errors); } else { log.error("Unknown CObject type.."); } } /** * Confronta um dado com uma restrio {@link CDomainType} * @param archetype * @param cdomain * @param value * @param path * @param errors */ void validateDomain(Archetype archetype, CDomainType cdomain, Object value, String path, List<ValidationError> errors) { log.debug("validate CDomaingType.."); if (!cdomain.validValue(value)) { log.debug("error found at " + cdomain.path()); errors.add(new ValidationError(archetype.getArchetypeId(), path, cdomain.path(), ErrorType.DOMAIN_TYPE_VALUE_ERROR, getErrorDescription(archetype, cdomain, null))); // DUMMY ERROR TYPE } } /** * Confronta um dado com uma restrio {@link CPrimitiveObject} * @param archetype * @param cpo * @param value * @param path * @param errors */ void validatePrimitive(Archetype archetype, CPrimitiveObject cpo, Object value, String path, List<ValidationError> errors) { log.debug("validate CPrimitiveObject.."); Object primitiveValue = value; Class klass = KnownTypes.getAllTypes().get(cpo.getItem().getType().toUpperCase(KnownTypes.getLocale())); if (primitiveValue instanceof String) { Constructor constructor = getConstructorWithStringArgument(klass); primitiveValue = build(constructor, primitiveValue); } if (!cpo.getItem().validValue(primitiveValue)) { errors.add(new ValidationError(archetype.getArchetypeId(), path, cpo.path(), ErrorType.PRIMITIVE_TYPE_VALUE_ERROR, getErrorDescription(archetype, cpo, null))); // DUMMY ERROR TYPE } } /** * Confronta um dado com uma restrio {@link ArchetypeSlot} * @param slot * @param value * @param path * @param errors * @throws GenericValidationException */ void validateArchetypeSlot(ArchetypeSlot slot, Object value, String path, List<ValidationError> errors) throws GenericValidationException { log.debug("validate ArchetypeSlot.."); Locatable lo = (Locatable) value; String archetypeId = lo.getArchetypeNodeId(); Archetype archetype = ArchetypeRepositoryFactory.getInstance().getArchetype(archetypeId); List<ValidationError> errorsSlot = new ArrayList<ValidationError>(); if (!validateRootSlot(slot, lo)) { errorsSlot.add(new ValidationError(archetype.getArchetypeId(), path, slot.path(), ErrorType.OCCURRENCES_NOT_DESCRIBED, getErrorDescription(archetype, slot, null))); } errorsSlot = this.validate(lo, archetype); errors.addAll(errorsSlot); } /** * Confronta um dado com uma restrio {@link ArchetypeInternalRef} * @param archetype * @param internalRef * @param value * @param path * @param errors * @throws GenericValidationException */ void validateArchetypeInternalRef(Archetype archetype, ArchetypeInternalRef internalRef, Object value, String path, List<ValidationError> errors) throws GenericValidationException { log.debug("validate ArchetypeInternalRef.."); ArchetypeConstraint constraint = archetype.node(internalRef.getTargetPath()); decideSubtipoConstraint(constraint, value, path, errors, archetype); } /** * Valida um objeto que seja raz de um arqutipo * @param slot * @param locatable * @return */ private boolean validateRootSlot(ArchetypeSlot slot, Locatable locatable) { String archetypeName = locatable.getArchetypeNodeId(); ArchetypeID archetypeID = null; try { archetypeID = new ArchetypeID(archetypeName); } catch (Exception ex) { return false; } String conceptName = archetypeID.getValue().substring(archetypeID.qualifiedRmEntity().length() + 1); if (slot.getExcludes() != null) { for (Assertion assertion : slot.getExcludes()) { ExpressionBinaryOperator operator = (ExpressionBinaryOperator) assertion.getExpression(); ExpressionLeaf rightLeaf = (ExpressionLeaf) operator.getRightOperand(); CString cString = (CString) rightLeaf.getItem(); if (cString.validValue(conceptName) || cString.validValue(archetypeName)) { return false; } } } if (slot.getIncludes() != null) { for (Assertion assertion : slot.getIncludes()) { ExpressionBinaryOperator operator = (ExpressionBinaryOperator) assertion.getExpression(); ExpressionLeaf rightLeaf = (ExpressionLeaf) operator.getRightOperand(); CString cString = (CString) rightLeaf.getItem(); if (cString.validValue(conceptName) || cString.validValue(archetypeName)) { return true; } } } return false; } /** * Retora o objeto que representa o valor de um {@link CAttribute} * @param object * @param cattr * @return * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException */ private Object fetchAttribute(Object object, CAttribute cattr) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { String[] names = cattr.getRmAttributeName().split("_"); StringBuilder attrName = new StringBuilder(); for (String name : names) { attrName.append(upperFirstLetter(name)); } String getter = "get" + attrName.toString(); return executeGetter(object, getter); } /** * Retorna a {@link String} capitular, ou seja, o primeiro caracter em * maisculo * @param value * @return */ private String upperFirstLetter(String value) { return value.substring(0, 1).toUpperCase(KnownTypes.getLocale()) + value.substring(1); } /** * Busca determinado termo em um arqutipo * @param code * @param archetype * @return */ String getTermText(String code, Archetype archetype) { ArchetypeOntology ont = archetype.getOntology(); String lang = archetype.getOriginalLanguage().getCodeString(); ArchetypeTerm term = ont.termDefinition(lang, code); if (term != null) { return term.getText(); } return null; } private static Logger log = Logger.getLogger(DataValidator.class); /** * Retorna a descrio do erro * @param archetype * @param constraint * @param language * @return */ private String getErrorDescription(Archetype archetype, ArchetypeConstraint constraint, String language) { argumentoNaoVazioENaoNulo(archetype, "archetype"); argumentoNaoVazioENaoNulo(constraint, "archetype"); String nodeId = null; if (restricaoCObject(constraint)) { nodeId = (castToCobject(constraint)).getNodeId(); } else if (restricaoSingleAttribute(constraint)) { nodeId = (castToCSingleAttribute(constraint)).getChildren().get(0).getNodeId(); } String description = null; if (nodeId != null && !nodeId.isEmpty()) { description = extractTerm(archetype, language, nodeId); } return description; } } /* * ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the 'License'); you may not use this file except in compliance with the * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * 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. * * The Original Code is DataValidatorImpl.java * * The Initial Developer of the Original Code is Rong Chen. Portions created by * the Initial Developer are Copyright (C) 2008 the Initial Developer. All * Rights Reserved. * * Contributor(s): * * 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. * * ***** END LICENSE BLOCK ***** */