예제 #1
0
    def process(self, target: Class):
        """
        Merge enumeration unions attributes.

        Lookup for the source class in the local namespace or inner
        class list.
        """
        if len(target.attrs) != 1 or target.attrs[0].tag != Tag.UNION:
            return

        enums: List[Any] = []
        for attr_type in target.attrs[0].types:
            if attr_type.forward:
                enums.extend(target.inner)
            elif not attr_type.native:
                qname = target.source_qname(attr_type.name)
                enums.append(self.container.find(qname))
            else:
                enums.append(None)

        merge = all(isinstance(x, Class) and x.is_enumeration for x in enums)
        if merge:
            target.attrs.clear()
            target.inner.clear()

            target.attrs.extend(attr.clone() for enum in enums
                                for attr in enum.attrs)
예제 #2
0
파일: validator.py 프로젝트: rmr1154/xsdata
        def is_invalid(source: Class, ext: Extension) -> bool:
            """Check if given type declaration is not native and is missing."""
            if ext.type.native:
                return False

            qname = source.source_qname(ext.type.name)
            return qname not in self.container
예제 #3
0
파일: resolver.py 프로젝트: rmr1154/xsdata
    def apply_aliases(self, obj: Class):
        """Walk the attributes tree and set the type aliases."""
        for attr in obj.attrs:
            for attr_type in attr.types:
                attr_type_qname = obj.source_qname(attr_type.name)
                attr_type.alias = self.aliases.get(attr_type_qname)

        collections.apply(obj.inner, self.apply_aliases)
예제 #4
0
    def process_attribute(self, target: Class, attr: Attr):
        """
        Find the source class the attribute refers to and copy its attributes
        to the target class.

        :raises AnalyzerValueError: if source class is not found.
        """
        qname = target.source_qname(attr.name)
        source = self.container.find(
            qname, condition=lambda x: x.type in (AttributeGroup, Group)
        )

        if not source:
            raise AnalyzerValueError(f"Group attribute not found: `{qname}`")

        if source is target:
            target.attrs.remove(attr)
        else:
            ClassUtils.copy_group_attributes(source, target, attr)
예제 #5
0
파일: sanitizer.py 프로젝트: rmr1154/xsdata
    def find_enum(self, source: Class, attr_type: AttrType) -> Optional[Class]:
        """
        Find the enumeration source class for the given class and attribute
        type.

        Search in root classes an inner class and exclude native types.
        """
        if attr_type.native:
            return None

        if attr_type.forward:
            return self.find_inner(
                source,
                condition=lambda x: x.is_enumeration and x.name == attr_type.
                name,
            )

        qname = source.source_qname(attr_type.name)
        return self.container.find(qname, condition=lambda x: x.is_enumeration)
예제 #6
0
    def find_dependency(self, target: Class,
                        attr_type: AttrType) -> Optional[Class]:
        """
        Find dependency for the given extension type with priority.

        Search priority: xs:SimpleType >  xs:ComplexType
        """

        conditions = (
            lambda x: x.type is SimpleType,
            lambda x: x.type is ComplexType,
        )

        qname = target.source_qname(attr_type.name)
        for condition in conditions:
            result = self.container.find(qname, condition=condition)
            if result:
                return result

        return None
예제 #7
0
    def find_dependency(self, target: Class,
                        attr_type: AttrType) -> Optional[Class]:
        """
        Find dependency for the given attribute.

        Avoid conflicts by search in order:
            1. Non element/complexType
            2. Non abstract
            3. anything
        """
        qname = target.source_qname(attr_type.name)
        conditions = (lambda obj: not obj.is_complex, lambda x: not x.abstract,
                      None)

        for condition in conditions:
            result = self.container.find(qname, condition=condition)
            if result:
                return result

        return None
예제 #8
0
    def process_attribute(self, target: Class, attr: Attr):
        """
        Check if the given attribute matches any substitution class in order to
        clone it's attributes to the target class.

        The cloned attributes are placed below the attribute the are
        supposed to substitute.
        """
        index = target.attrs.index(attr)
        qname = target.source_qname(attr.name)

        assert self.substitutions is not None

        for substitution in self.substitutions.get(qname, []):
            pos = collections.find(target.attrs, substitution)
            index = pos + 1 if pos > -1 else index

            clone = substitution.clone()
            clone.restrictions.merge(attr.restrictions)
            target.attrs.insert(index, clone)

            self.process_attribute(target, clone)
예제 #9
0
파일: container.py 프로젝트: rmr1154/xsdata
 def add(self, item: Class):
     """Add class item to the container."""
     self.data.setdefault(item.source_qname(), []).append(item)