def _check_known_element(el, ref, errs, warns): if ref is None: is_profile = False try: ref = load_reference(el.name, el.classname, el.version) except ChildNotFound: errs.append(ValidationError("Invalid element found: {}".format(el))) else: is_profile = ref[0] == 'mp' if is_profile: # it is a message profile ref = ref[1:] # ref[0] is 'mp' if ref[0] in ('sequence', 'choice'): element_children = {c.name for c in el.children if not c.is_z_element()} valid_children, valid_children_refs = _get_valid_children_info(ref, is_profile) z_children = [c for c in el.children if c.is_z_element()] # check that the children are all allowed children if not element_children <= valid_children: errs.append(ValidationError("Invalid children detected for {}: {}". format(el, list(element_children - valid_children)))) # iterates the valid children for child_ref in valid_children_refs: # it gets the structure of the children to check child_name, cardinality = _get_child_reference_info(child_ref, is_profile) try: # it gets all the occurrences of the children of a type children = el.children.get(child_name) except Exception: # TODO: it is due to the lack of element in the official reference files... should # we raise an exception here? pass else: _check_repetitions(el, children, cardinality, child_name, errs) # calls validation for every children for c in children: ref = child_ref if is_profile else None _is_valid(c, ref, errs, warns) # finally calls validation for z_elements for c in z_children: _is_valid(c, None, errs, warns) else: _check_table_compliance(el, ref, is_profile, warns) _check_length(el, ref, is_profile, warns) if el.datatype == 'varies': # TODO: it should check the real rule return True _check_datatype(el, ref, is_profile, errs) # For complex datatypes element, the reference is the one of the datatype if not is_base_datatype(el.datatype, el.version): # Component just to search in the datatypes.... ref = load_reference(el.datatype, 'Component', el.version) _is_valid(el, ref, errs, warns)
def _check_repetitions(el, children, cardinality, child_name, errs): children_num = len(children) min_repetitions, max_repetitions = cardinality if max_repetitions != -1: if children_num < min_repetitions: errs.append(ValidationError("Missing required child {}.{}".format(el.name, child_name))) elif children_num > max_repetitions: errs.append(ValidationError("Child limit exceeded {}.{}".format(child_name, el.name))) else: if children_num < min_repetitions: errs.append(ValidationError("Missing required child {}.{}".format(el.name, child_name)))
def _check_datatype(el, ref, errs): ref_datatype = ref[2] if el.datatype != ref_datatype: errs.append( ValidationError( "Datatype {} is not correct for {}.{} (it must be {})". format(el.datatype, el.parent.name, el.name, ref[1])))
def _is_valid(el, ref, errs, warns): if el.is_unknown(): errs.append(ValidationError("Unknown element found: {}.{}".format(el.parent, el))) return if el.is_z_element(): return _check_z_element(el, errs, warns) return _check_known_element(el, ref, errs, warns)