1# 2# Copyright (c), 2016-2020, SISSA (International School for Advanced Studies). 3# All rights reserved. 4# This file is distributed under the terms of the MIT License. 5# See the file 'LICENSE' in the root directory of the present 6# distribution, or http://opensource.org/licenses/MIT. 7# 8# @author Davide Brunato <brunato@sissa.it> 9# 10""" 11Observers for testing XMLSchema classes. 12""" 13from functools import wraps 14from typing import List 15 16from xmlschema.names import XSD_NAMESPACE, XSD_ANY_TYPE 17from xmlschema.validators import XMLSchema10, XMLSchema11, \ 18 XsdGroup, XsdAttributeGroup, XsdComplexType, XsdComponent 19 20 21class SchemaObserver: 22 """ 23 Observer that registers created components. Run the 'clear' method after each usage. 24 """ 25 components: List[XsdComponent] = [] 26 dummy_components: List[XsdComponent] = [] 27 28 @classmethod 29 def observed_builder(cls, builder): 30 if isinstance(builder, type): 31 class BuilderProxy(builder): 32 def __init__(self, *args, **kwargs): 33 super(BuilderProxy, self).__init__(*args, **kwargs) 34 if not cls.is_dummy_component(self): 35 cls.components.append(self) 36 else: 37 cls.dummy_components.append(self) 38 BuilderProxy.__name__ = builder.__name__ 39 return BuilderProxy 40 41 elif callable(builder): 42 @wraps(builder) 43 def builder_proxy(*args, **kwargs): 44 obj = builder(*args, **kwargs) 45 if not cls.is_dummy_component(obj): 46 cls.components.append(obj) 47 else: 48 cls.dummy_components.append(obj) 49 return obj 50 return builder_proxy 51 52 @classmethod 53 def clear(cls): 54 del cls.components[:] 55 del cls.dummy_components[:] 56 57 @classmethod 58 def is_dummy_component(cls, component): 59 # Dummy components are empty attribute groups and xs:anyType 60 # definitions not related to XSD namespace. 61 if component.parent in cls.dummy_components: 62 return True 63 elif isinstance(component, XsdAttributeGroup): 64 return not component 65 elif isinstance(component, XsdComplexType): 66 return component.name == XSD_ANY_TYPE and \ 67 component.target_namespace != XSD_NAMESPACE 68 elif isinstance(component, XsdGroup) and component.parent is not None: 69 return component.parent.name == XSD_ANY_TYPE and \ 70 component.target_namespace != XSD_NAMESPACE 71 return False 72 73 74observed_builder = SchemaObserver.observed_builder 75 76 77class ObservedXMLSchema10(XMLSchema10): 78 xsd_notation_class = observed_builder(XMLSchema10.xsd_notation_class) 79 xsd_complex_type_class = observed_builder(XMLSchema10.xsd_complex_type_class) 80 xsd_attribute_class = observed_builder(XMLSchema10.xsd_attribute_class) 81 xsd_any_attribute_class = observed_builder(XMLSchema10.xsd_any_attribute_class) 82 xsd_attribute_group_class = observed_builder(XMLSchema10.xsd_attribute_group_class) 83 xsd_group_class = observed_builder(XMLSchema10.xsd_group_class) 84 xsd_element_class = observed_builder(XMLSchema10.xsd_element_class) 85 xsd_any_class = observed_builder(XMLSchema10.xsd_any_class) 86 xsd_atomic_restriction_class = observed_builder(XMLSchema10.xsd_atomic_restriction_class) 87 xsd_list_class = observed_builder(XMLSchema10.xsd_list_class) 88 xsd_union_class = observed_builder(XMLSchema10.xsd_union_class) 89 xsd_key_class = observed_builder(XMLSchema10.xsd_key_class) 90 xsd_keyref_class = observed_builder(XMLSchema10.xsd_keyref_class) 91 xsd_unique_class = observed_builder(XMLSchema10.xsd_unique_class) 92 93 94class ObservedXMLSchema11(XMLSchema11): 95 xsd_notation_class = observed_builder(XMLSchema11.xsd_notation_class) 96 xsd_complex_type_class = observed_builder(XMLSchema11.xsd_complex_type_class) 97 xsd_attribute_class = observed_builder(XMLSchema11.xsd_attribute_class) 98 xsd_any_attribute_class = observed_builder(XMLSchema11.xsd_any_attribute_class) 99 xsd_attribute_group_class = observed_builder(XMLSchema11.xsd_attribute_group_class) 100 xsd_group_class = observed_builder(XMLSchema11.xsd_group_class) 101 xsd_element_class = observed_builder(XMLSchema11.xsd_element_class) 102 xsd_any_class = observed_builder(XMLSchema11.xsd_any_class) 103 xsd_atomic_restriction_class = observed_builder(XMLSchema11.xsd_atomic_restriction_class) 104 xsd_list_class = observed_builder(XMLSchema11.xsd_list_class) 105 xsd_union_class = observed_builder(XMLSchema11.xsd_union_class) 106 xsd_key_class = observed_builder(XMLSchema11.xsd_key_class) 107 xsd_keyref_class = observed_builder(XMLSchema11.xsd_keyref_class) 108 xsd_unique_class = observed_builder(XMLSchema11.xsd_unique_class) 109