Пример #1
0
    def process_complex_type(self, c):
        def process_type(tn, name, wrapper=None, element=None, attribute=None):
            if wrapper is None:
                wrapper = lambda x: x
            else:
                assert issubclass(wrapper, XmlModifier), wrapper

            t = self.get_type(tn)
            key = (c.name, name)
            if t is None:
                self.pending_types[key] = c
                self.debug2("not found: %r(%s)", key, tn)
                return

            if key in self.pending_types:
                del self.pending_types[key]

            assert name is not None, (key, e)

            kwargs = {}
            if element is not None:
                if e.min_occurs != "0":  # spyne default
                    kwargs['min_occurs'] = int(e.min_occurs)

                if e.max_occurs == "unbounded":
                    kwargs['max_occurs'] = e.max_occurs
                elif e.max_occurs != "1":
                    kwargs['max_occurs'] = int(e.max_occurs)

                if e.nillable != True:  # spyne default
                    kwargs['nillable'] = e.nillable

                if e.default is not None:
                    kwargs['default'] = _prot.from_string(t, e.default)

                if len(kwargs) > 0:
                    t = t.customize(**kwargs)

            if attribute is not None:
                if attribute.default is not None:
                    kwargs['default'] = _prot.from_string(t, a.default)

                if len(kwargs) > 0:
                    t = t.customize(**kwargs)

            ti.append((name, wrapper(t)))
            self.debug2("    found: %r(%s), c: %r", key, tn, kwargs)

        def process_element(e):
            if e.ref is not None:
                tn = e.ref
                name = e.ref.split(":", 1)[-1]

            elif e.name is not None:
                tn = e.type
                name = e.name

                if tn is None:
                    # According to http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-element
                    # this means this element is now considered to be a
                    # http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#ur-type-itself
                    self.debug2("  skipped: %s ur-type", e.name)
                    return

            else:
                raise Exception("dunno")

            process_type(tn, name, element=e)

        ti = []
        base = ComplexModelBase
        if c.name in self.retval[self.tns].types:
            self.debug1("modifying existing %r", c.name)
        else:
            self.debug1("adding complex type: %s", c.name)

        if c.sequence is not None:
            if c.sequence.elements is not None:
                for e in c.sequence.elements:
                    process_element(e)

            if c.sequence.choices is not None:
                for ch in c.sequence.choices:
                    if ch.elements is not None:
                        for e in ch.elements:
                            process_element(e)

        if c.choice is not None:
            if c.choice.elements is not None:
                for e in c.choice.elements:
                    process_element(e)

        if c.attributes is not None:
            for a in c.attributes:
                if a.name is None:
                    continue
                if a.type is None:
                    continue

                process_type(a.type, a.name, XmlAttribute, attribute=a)

        if c.simple_content is not None:
            sc = c.simple_content
            ext = sc.extension
            restr = sc.restriction

            if ext is not None:
                base_name = ext.base
                b = self.get_type(ext.base)

                if ext.attributes is not None:
                    for a in ext.attributes:
                        ti.append(self.process_attribute(a))

            elif restr is not None:
                base_name = restr.base
                b = self.get_type(restr.base)

                if restr.attributes is not None:
                    for a in restr.attributes:
                        ti.append(self.process_attribute(a))

            else:
                raise Exception("Invalid simpleContent tag: %r", sc)

            if issubclass(b, ComplexModelBase):
                base = b
            else:
                process_type(base_name, "_data", XmlData)

        if c.name in self.retval[self.tns].types:
            r = self.retval[self.tns].types[c.name]
            r._type_info.update(ti)

        else:
            cls_dict = odict({
                '__type_name__': c.name,
                '__namespace__': self.tns,
                '_type_info': ti,
            })
            if self.repr is not None:
                cls_dict['__repr__'] = self.repr

            r = ComplexModelMeta(str(c.name), (base, ), cls_dict)
            self.retval[self.tns].types[c.name] = r

        return r
Пример #2
0
    def process_complex_type(self, c):
        def process_type(tn,
                         name,
                         wrapper=lambda x: x,
                         element=None,
                         attribute=None):
            t = self.get_type(tn)
            key = (c.name, name)
            if t is None:
                self.pending_types[key] = c
                self.debug2("not found: %r(%s)", key, tn)
                return

            if key in self.pending_types:
                del self.pending_types[key]

            assert name is not None, (key, e)

            kwargs = {}
            if element is not None:
                if e.min_occurs != "0":  # spyne default
                    kwargs['min_occurs'] = int(e.min_occurs)

                if e.max_occurs == "unbounded":
                    kwargs['max_occurs'] = e.max_occurs
                elif e.max_occurs != "1":
                    kwargs['max_occurs'] = int(e.max_occurs)

                if e.nillable != True:  # spyne default
                    kwargs['nillable'] = e.nillable

                if e.default is not None:
                    kwargs['default'] = _prot.from_string(t, e.default)

                if len(kwargs) > 0:
                    t = t.customize(**kwargs)

            if attribute is not None:
                if attribute.default is not None:
                    kwargs['default'] = _prot.from_string(t, a.default)

                if len(kwargs) > 0:
                    t = t.customize(**kwargs)

            ti.append((name, wrapper(t)))
            self.debug2("    found: %r(%s), c: %r", key, tn, kwargs)

        def process_element(e):
            if e.ref is not None:
                tn = e.ref
                name = e.ref.split(":", 1)[-1]

            elif e.name is not None:
                tn = e.type
                name = e.name

            else:
                raise Exception("dunno")

            process_type(tn, name, element=e)

        class L(list):
            def append(self, a):
                k, v = a
                assert isinstance(k, six.string_types), k
                super(L, self).append(a)

        ti = L()
        base = ComplexModelBase
        if c.name in self.retval[self.tns].types:
            self.debug1("modifying existing %r", c.name)
        else:
            self.debug1("adding complex type: %s", c.name)

        if c.sequence is not None:
            if c.sequence.elements is not None:
                for e in c.sequence.elements:
                    process_element(e)

            if c.sequence.choices is not None:
                for ch in c.sequence.choices:
                    if ch.elements is not None:
                        for e in ch.elements:
                            process_element(e)

        if c.choice is not None:
            if c.choice.elements is not None:
                for e in c.choice.elements:
                    process_element(e)

        if c.attributes is not None:
            for a in c.attributes:
                if a.name is None:
                    continue
                if a.type is None:
                    continue

                process_type(a.type, a.name, XmlAttribute, attribute=a)

        if c.simple_content is not None:
            ext = c.simple_content.extension
            base_name = None
            if ext is not None:
                base_name = ext.base
                b = self.get_type(ext.base)

                if ext.attributes is not None:
                    for a in ext.attributes:
                        ti.append(self.process_attribute(a))

            restr = c.simple_content.restriction
            if restr is not None:
                base_name = restr.base
                b = self.get_type(restr.base)

                if restr.attributes is not None:
                    for a in restr.attributes:
                        ti.append(self.process_attribute(a))

            if issubclass(b, ComplexModelBase):
                base = b
            else:
                process_type(base_name, "_data", XmlData)

        if c.name in self.retval[self.tns].types:
            self.retval[self.tns].types[c.name]._type_info.update(ti)

        else:
            cls_dict = odict({
                '__type_name__': c.name,
                '__namespace__': self.tns,
                '_type_info': ti,
            })
            if self.repr is not None:
                cls_dict['__repr__'] = self.repr

            r = ComplexModelMeta(str(c.name), (base, ), cls_dict)
            self.retval[self.tns].types[c.name] = r