예제 #1
0
    def build_class_attribute_types(self, target: Class,
                                    obj: ElementBase) -> List[AttrType]:
        """Convert real type and anonymous inner types to an attribute type
        list."""
        types = [
            self.build_data_type(target, name)
            for name in (obj.real_type or "").split(" ") if name
        ]

        for inner in self.build_inner_classes(obj):
            target.inner.append(inner)
            types.append(AttrType(name=inner.name, forward_ref=True))

        if len(types) == 0:
            types.append(AttrType(name=obj.default_type.code, native=True))

        return types
예제 #2
0
    def build_class_attribute_types(
        self, target: Class, obj: AttributeElement
    ) -> List[AttrType]:
        """Convert real type and anonymous inner elements to an attribute type
        list."""
        inner_class = self.build_inner_class(obj)

        types = [
            self.build_data_type(target, name)
            for name in (obj.real_type or "").split(" ")
            if name
        ]

        if inner_class:
            target.inner.append(inner_class)
            types.append(AttrType(name=inner_class.name, forward_ref=True))

        if len(types) == 0:
            types.append(AttrType(name=DataType.STRING.code, native=True))

        return types
예제 #3
0
    def create_mixed_attribute(cls, target: Class):
        if not target.mixed or target.has_wild_attr:
            return

        attr = Attr(
            name="content",
            local_name="content",
            index=0,
            types=[AttrType(name=DataType.ANY_TYPE.code, native=True)],
            tag=Tag.ANY,
            namespace=NamespaceType.ANY.value,
        )
        target.attrs.insert(0, attr)
예제 #4
0
    def create_reference_attribute(cls, source: Class, qname: QName):
        prefix = None
        if qname.namespace != source.source_namespace:
            prefix = source.source_prefix

        reference = f"{prefix}:{source.name}" if prefix else source.name
        return Attr(
            name=source.name,
            local_name=source.name,
            index=0,
            default=None,
            types=[AttrType(name=reference)],
            local_type=source.type.__name__,
            namespace=source.namespace,
        )
예제 #5
0
 def flatten_attribute_type(self, target: Class, attr: Attr,
                            attr_type: AttrType):
     """Flatten attribute type if it's a simple type otherwise check for
     circular reference or missing type."""
     simple_source = self.find_attr_simple_type(target, attr_type)
     if simple_source:
         self.merge_attribute_type(simple_source, target, attr, attr_type)
     else:
         complex_source = self.find_attr_type(target, attr_type)
         if complex_source:
             attr_type.self_ref = self.class_depends_on(
                 complex_source, target)
         else:
             logger.warning("Missing type: %s", attr_type.name)
             self.reset_attribute_type(attr_type)
예제 #6
0
    def build_data_type(self,
                        target: Class,
                        name: str,
                        index: int = 0,
                        forward_ref: bool = False) -> AttrType:
        prefix, suffix = text.split(name)
        native = False
        namespace = target.ns_map.get(prefix)

        if Namespace.get_enum(namespace) and DataType.get_enum(suffix):
            name = suffix
            native = True

        return AttrType(
            name=name,
            index=index,
            native=native,
            forward_ref=forward_ref,
        )
예제 #7
0
    def test_create_reference_attribute(self):
        item = ClassFactory.elements(1)
        actual = ClassUtils.create_reference_attribute(item, QName("foo"))

        expected = AttrFactory.create(
            name=item.name,
            index=0,
            default=None,
            types=[AttrType(name=f"{item.source_prefix}:{item.name}")],
            local_type=item.type.__name__,
        )

        self.assertEqual(expected, actual)

        actual = ClassUtils.create_reference_attribute(
            item, item.source_qname("foo"))
        self.assertEqual(item.name, actual.types[0].name)

        item.source_namespace = None
        actual = ClassUtils.create_reference_attribute(item, QName("foo"))
        self.assertEqual(item.name, actual.types[0].name)
예제 #8
0
    def test_create_mixed_attribute(self):
        item = ClassFactory.create()
        ClassUtils.create_mixed_attribute(item)
        self.assertEqual(0, len(item.attrs))

        item = ClassFactory.elements(2, mixed=True)
        ClassUtils.create_mixed_attribute(item)
        expected = AttrFactory.create(
            name="content",
            index=0,
            wildcard=True,
            types=[AttrType(name=DataType.ANY_TYPE.code, native=True)],
            local_type=TagType.ANY,
            namespace="##any",
        )

        self.assertEqual(expected, item.attrs[0])
        self.assertEqual(3, len(item.attrs))

        ClassUtils.create_mixed_attribute(item)
        self.assertEqual(3, len(item.attrs))
예제 #9
0
    def flatten_attribute_types(self, target: Class, attr: Attr):
        """
        Flatten attribute types by using the source attribute type.

        Steps:
            * Skip xsd native types
            * Detect circular references if no source is found
            * Skip enumeration types
            * Overwrite attribute type from source
        """
        types = []
        for attr_type in attr.types:
            source = None
            if not attr_type.native:
                type_qname = target.source_qname(attr_type.name)
                source = self.find_class(type_qname)

            if source is None:
                attr_type.self_ref = self.attr_depends_on(attr_type, target)
                types.append(attr_type)
            elif self.is_qname(source):
                types.append(source.extensions[0].type.clone())
            elif source.is_enumeration:
                types.append(attr_type)
            elif len(source.attrs) == 1:
                source_attr = source.attrs[0]
                types.extend(source_attr.types)
                restrictions = source_attr.restrictions.clone()
                restrictions.merge(attr.restrictions)
                attr.restrictions = restrictions
                self.copy_inner_classes(source, target)
            else:
                types.append(AttrType(name=DataType.STRING.code, native=True))
                logger.warning("Missing type implementation: %s",
                               source.type.__name__)

        attr.types = types
예제 #10
0
 def reset_attribute_type(cls, attr_type: AttrType):
     attr_type.name = DataType.STRING.code
     attr_type.native = True
     attr_type.self_ref = False
     attr_type.forward_ref = False