Ejemplo n.º 1
0
 def parse(self, elt, ps):
     self.checkname(elt, ps)
     if self.nilled(elt, ps): return None
     p = self.tc.parse
     if self.aslist:
         v = []
         for c in _child_elements(elt):
             d = p(c, ps)
             v.append((d['key'], d['value']))
     else:
         v = {}
         for c in _child_elements(elt):
             d = p(c, ps)
             v[d['key']] = d['value']
     return v
Ejemplo n.º 2
0
 def parse(self, elt, ps):
     self.checkname(elt, ps)
     if self.nilled(elt, ps): return None
     p = self.tc.parse
     if self.aslist:
         v = []
         for c in _child_elements(elt):
             d = p(c, ps)
             v.append((d['key'], d['value']))
     else:
         v = {}
         for c in _child_elements(elt):
             d = p(c, ps)
             v[d['key']] = d['value']
     return v
Ejemplo n.º 3
0
    def parse(self, elt, ps):
        debug = self.logger.debugOn()
        debug and self.logger.debug('parse')

        xtype = self.checkname(elt, ps)
        if self.type and xtype not in [self.type, (None, None)]:
            if not isinstance(self, TypeDefinition):
                raise EvaluateException(\
                    'ComplexType for %s has wrong type(%s), looking for %s' %
                        (self.pname, self.checktype(elt,ps), self.type),
                                        ps.Backtrace(elt))
            else:
                #TODO: mabye change MRO to handle this
                debug and self.logger.debug('delegate to substitute type')
                what = TypeDefinition.getSubstituteType(self, elt, ps)
                return what.parse(elt, ps)

        href = _find_href(elt)
        if href:
            if _children(elt):
                raise EvaluateException('Struct has content and HREF',
                                        ps.Backtrace(elt))
            elt = ps.FindLocalHREF(href, elt)
        c = _child_elements(elt)
        if self.nilled(elt, ps): return Nilled

        # Create the object.
        if self.pyclass:
            # type definition must be informed of element tag (nspname,pname),
            # element declaration is initialized with a tag.
            try:
                pyobj = self.pyclass()
            except Exception, e:
                raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                    %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
Ejemplo n.º 4
0
    def parse(self, elt, ps):
        debug = self.logger.debugOn()
        debug and self.logger.debug('parse')

        xtype = self.checkname(elt, ps)
        if self.type and xtype not in [ self.type, (None,None) ]:
            if not isinstance(self, TypeDefinition):
                raise EvaluateException(\
                    'ComplexType for %s has wrong type(%s), looking for %s' %
                        (self.pname, self.checktype(elt,ps), self.type),
                                        ps.Backtrace(elt))
            else:
                #TODO: mabye change MRO to handle this
                debug and self.logger.debug('delegate to substitute type')
                what = TypeDefinition.getSubstituteType(self, elt, ps)
                return what.parse(elt, ps)

        href = _find_href(elt)
        if href:
            if _children(elt):
                raise EvaluateException('Struct has content and HREF',
                        ps.Backtrace(elt))
            elt = ps.FindLocalHREF(href, elt)
        c = _child_elements(elt)
        if self.nilled(elt, ps): return Nilled

        # Create the object.
        if self.pyclass:
            # type definition must be informed of element tag (nspname,pname),
            # element declaration is initialized with a tag.
            try:
                pyobj = self.pyclass()
            except Exception, e:
                raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                    %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
Ejemplo n.º 5
0
    def Receive(self, replytype, **kw):
        '''Parse message, create Python object.

        KeyWord data:
            faults   -- list of WSDL operation.fault typecodes
            wsaction -- If using WS-Address, must specify Action value we expect to
                receive.
        '''
        self.ReceiveSOAP(**kw)
        ps = self.ps
        tp = _find_type(ps.body_root)
        isarray = ((type(tp) in (tuple, list) and tp[1] == 'Array')
                   or _find_arraytype(ps.body_root))
        if self.typesmodule is None or isarray:
            return _Binding.Receive(self, replytype, **kw)

        if ps.IsAFault():
            msg = FaultFromFaultMessage(ps)
            raise FaultException(msg)

        tc = replytype
        if hasattr(replytype, 'typecode'):
            tc = replytype.typecode

        #Ignore response wrapper
        reply = {}
        for elt in _child_elements(ps.body_root):
            name = str(elt.localName)
            reply[name] = self.__parse_child(elt)

        if self.address is not None:
            self.address.checkResponse(ps, kw.get('wsaction'))

        return reply
Ejemplo n.º 6
0
 def parse(self, elt, ps):
     href = _find_href(elt)
     if href:
         if _children(elt):
             raise EvaluateException('Array has content and HREF',
                     ps.Backtrace(elt))
         elt = ps.FindLocalHREF(href, elt)
     if self.nilled(elt, ps): return Nilled
     if not _find_arraytype(elt) and self.undeclared is False:
         raise EvaluateException('Array expected', ps.Backtrace(elt))
     t = _find_type(elt)
     if t:
         pass # XXX should check the type, but parsing that is hairy.
     offset = self.parse_offset(elt, ps)
     v, vlen = [], 0
     if offset and not self.sparse:
         while vlen < offset:
             vlen += 1
             v.append(self.fill)
     for c in _child_elements(elt):
         item = self.ofwhat.parse(c, ps)
         position = self.parse_position(c, ps) or offset
         if self.sparse:
             v.append((position, item))
         else:
             while offset < position:
                 offset += 1
                 v.append(self.fill)
             v.append(item)
         offset += 1
     return v
Ejemplo n.º 7
0
 def parse(self, elt, ps):
     href = _find_href(elt)
     if href:
         if _children(elt):
             raise EvaluateException('Array has content and HREF',
                     ps.Backtrace(elt))
         elt = ps.FindLocalHREF(href, elt)
     if self.nilled(elt, ps): return Nilled
     if not _find_arraytype(elt) and self.undeclared is False:
         raise EvaluateException('Array expected', ps.Backtrace(elt))
     t = _find_type(elt)
     if t:
         pass # XXX should check the type, but parsing that is hairy.
     offset = self.parse_offset(elt, ps)
     v, vlen = [], 0
     if offset and not self.sparse:
         while vlen < offset:
             vlen += 1
             v.append(self.fill)
     for c in _child_elements(elt):
         item = self.ofwhat.parse(c, ps)
         position = self.parse_position(c, ps) or offset
         if self.sparse:
             v.append((position, item))
         else:
             while offset < position:
                 offset += 1
                 v.append(self.fill)
             v.append(item)
         offset += 1
     return v
Ejemplo n.º 8
0
 def XML(self, uri, tc, ps, **keywords):
     content = self.get(uri)
     if content:
         dom = ps.readerclass().fromStream(content)
         return _child_elements(dom)[0]
     if not self.next: raise EvaluateException("Unresolvable URI " + uri)
     return self.next.XML(uri, tc, ps, **keywords)
Ejemplo n.º 9
0
 def XML(self, uri, tc, ps, **keywords):
     content = self.get(uri)
     if content:
         dom = ps.readerclass().fromStream(content)
         return _child_elements(dom)[0]
     if not self.__next__: raise EvaluateException("Unresolvable URI " + uri)
     return self.next.XML(uri, tc, ps, **keywords)
Ejemplo n.º 10
0
    def Receive(self, replytype, **kw):
        '''Parse message, create Python object.

        KeyWord data:
            faults   -- list of WSDL operation.fault typecodes
            wsaction -- If using WS-Address, must specify Action value we expect to
                receive.
        '''
        self.ReceiveSOAP(**kw)
        ps = self.local.ps
        tp = _find_type(ps.body_root)
        isarray = ((isinstance(tp, _seqtypes) and tp[1] == 'Array') or _find_arraytype(ps.body_root))
        if self.typesmodule is None or isarray:
            return _Binding.Receive(self, replytype, **kw)

        if ps.IsAFault():
            msg = FaultFromFaultMessage(ps)
            raise FaultException(msg)

        #Ignore response wrapper
        reply = {}
        for elt in _child_elements(ps.body_root):
            name = str(elt.localName)
            reply[name] = self.__parse_child(elt)

        if self.address is not None:
            self.address.checkResponse(ps, kw.get('wsaction'))

        return reply
Ejemplo n.º 11
0
def XML(uri, tc, ps, **keywords):
    '''Resolve a URI and return its content as an XML DOM.
    '''
    source = urllib.request.urlopen(uri, **keywords)
    enc = source.info().getencoding()
    if enc in ['7bit', '8bit', 'binary']:
        data = source
    else:
        data = StringIO.StringIO()
        mimetools.decode(source, data, enc)
        data.seek(0)
    dom = ps.readerclass().fromStream(data)
    return _child_elements(dom)[0]
Ejemplo n.º 12
0
def XML(uri, tc, ps, **keywords):
    '''Resolve a URI and return its content as an XML DOM.
    '''
    source = urllib.urlopen(uri, **keywords)
    enc = source.info().getencoding()
    if enc in ['7bit', '8bit', 'binary']:
        data = source
    else:
        data = StringIO.StringIO()
        mimetools.decode(source, data, enc)
        data.seek(0)
    dom = ps.readerclass().fromStream(data)
    return _child_elements(dom)[0]
Ejemplo n.º 13
0
def XML(uri, tc, ps, **keywords):
    '''Resolve a URI and return its content as an XML DOM.
    '''
    source = urllib.request.urlopen(uri, **keywords)
    enc = source.info().get('Content-Transfer-Encoding', '7bit')
    if enc in ['7bit', '8bit', 'binary']:
        data = source
    else:
        raise NotImplementedError()
        #data = io.StringIO()
        #mimetools.decode(source, data, enc)
        #data.seek(0)
    dom = ps.readerclass().fromStream(data)
    return _child_elements(dom)[0]
Ejemplo n.º 14
0
            try:
                result = handler(arg)
            except Exception, ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

            try:
                tc = result.typecode
            except AttributeError, ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

        elif typesmodule is not None:
            kwargs = {}
            for e in _child_elements(ps.body_root):
                try:
                    tc = gettypecode(typesmodule, e)
                except Exception:
                    tc = TC.Any()

                try:
                    kwargs[str(e.localName)] = tc.parse(e, ps)
                except EvaluateException, ex:
                    SendFault(FaultFromZSIException(ex), **kw)
                    return

            result = handler(**kwargs)
            aslist = False
            # make sure data is wrapped, try to make this a Struct
            if isinstance(result, _seqtypes):
Ejemplo n.º 15
0
    def parse(self, elt, ps):
        debug = self.logger.debugOn()
        debug and self.logger.debug('parse')

        xtype = self.checkname(elt, ps)
        if self.type and xtype not in [ self.type, (None,None) ]:
            if not isinstance(self, TypeDefinition):
                raise EvaluateException(\
                    'ComplexType for %s has wrong type(%s), looking for %s' %
                        (self.pname, self.checktype(elt,ps), self.type),
                                        ps.Backtrace(elt))
            else:
                #TODO: mabye change MRO to handle this
                debug and self.logger.debug('delegate to substitute type')
                what = TypeDefinition.getSubstituteType(self, elt, ps)
                return what.parse(elt, ps)

        href = _find_href(elt)
        if href:
            if _children(elt):
                raise EvaluateException('Struct has content and HREF',
                        ps.Backtrace(elt))
            elt = ps.FindLocalHREF(href, elt)
        c = _child_elements(elt)
        if self.nilled(elt, ps): return Nilled

        # Create the object.
        if self.pyclass:
            # type definition must be informed of element tag (nspname,pname),
            # element declaration is initialized with a tag.
            try:
                pyobj = self.pyclass()
            except Exception as e:
                raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                    %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
        else:
            pyobj = ComplexType._DictHolder()

        # parse all attributes contained in attribute_typecode_dict (user-defined attributes),
        # the values (if not None) will be keyed in self.attributes dictionary.
        attributes = self.parse_attributes(elt, ps)
        if attributes:
            setattr(pyobj, self.attrs_aname, attributes)

        #MIXED
        if self.mixed is True:
            setattr(pyobj, self.mixed_aname, self.simple_value(elt,ps, mixed=True))

        # Clone list of kids (we null it out as we process)
        c, crange = c[:], list(range(len(c)))
        # Loop over all items we're expecting

        for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:

            for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]:

                # retrieve typecode if it is hidden
                if isinstance(what, collections.Callable): what = what()

                # Loop over all available kids
                # if debug:
                #     self.logger.debug("what: (%s,%s)", what.nspname, what.pname)

                # Parse value, and mark this one done.
                # if debug:
                #     self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName)
                match = False
                if what.name_match(c_elt):
                    match = True
                    value = what.parse(c_elt, ps)
                elif isinstance(what,AnyElement):
                    match = True
                    value = what.parse(c_elt, ps)
                else:
                    # substitutionGroup head must be a global element declaration
                    # if successful delegate to matching GED
                    subwhat = _get_substitute_element(what, c_elt, ps)
                    if subwhat:
                        match = True
                        value = subwhat.parse(c_elt, ps)

                    if debug:
                        self.logger.debug("substitutionGroup: %s", subwhat)

                if match:
                    if what.maxOccurs > 1:
                        attr = getattr(pyobj, what.aname, None)
                        if attr is not None:
                            attr.append(value)
                        else:
                            setattr(pyobj, what.aname, [value])
                        c[j] = None
                        continue
                    else:
                        setattr(pyobj, what.aname, value)
                    c[j] = None
                    break

                if debug:
                    self.logger.debug("no element (%s,%s)", what.nspname, what.pname)

                # No match; if it was supposed to be here, that's an error.
                if self.inorder is True and i == j:
                    raise EvaluateException('Out of order complexType',
                            ps.Backtrace(c_elt))
                else:
                    if hasattr(what, 'default'):
                        setattr(pyobj, what.aname, what.default)
                    # elif what.minOccurs > 0 and not hasattr(pyobj, what.aname):
                    #     raise EvaluateException('Element "' + what.aname + '" missing from complexType', ps.Backtrace(elt))

        if isinstance(pyobj, ComplexType._DictHolder):
            return pyobj.__dict__

        return pyobj
Ejemplo n.º 16
0
    def parse(self, elt, ps):
        debug = self.logger.debugOn()
        debug and self.logger.debug('parse')

        xtype = self.checkname(elt, ps)
        if self.type and xtype not in [self.type, (None, None)]:
            if not isinstance(self, TypeDefinition):
                raise EvaluateException(\
                    'ComplexType for %s has wrong type(%s), looking for %s' %
                        (self.pname, self.checktype(elt,ps), self.type),
                                        ps.Backtrace(elt))
            else:
                #TODO: mabye change MRO to handle this
                debug and self.logger.debug('delegate to substitute type')
                what = TypeDefinition.getSubstituteType(self, elt, ps)
                return what.parse(elt, ps)

        href = _find_href(elt)
        if href:
            if _children(elt):
                raise EvaluateException('Struct has content and HREF',
                                        ps.Backtrace(elt))
            elt = ps.FindLocalHREF(href, elt)
        c = _child_elements(elt)
        if self.nilled(elt, ps): return Nilled

        # Create the object.
        if self.pyclass:
            # type definition must be informed of element tag (nspname,pname),
            # element declaration is initialized with a tag.
            try:
                pyobj = self.pyclass()
            except Exception as e:
                raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                    %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
        else:
            pyobj = ComplexType._DictHolder()

        # parse all attributes contained in attribute_typecode_dict (user-defined attributes),
        # the values (if not None) will be keyed in self.attributes dictionary.
        attributes = self.parse_attributes(elt, ps)
        if attributes:
            setattr(pyobj, self.attrs_aname, attributes)

        #MIXED
        if self.mixed is True:
            setattr(pyobj, self.mixed_aname,
                    self.simple_value(elt, ps, mixed=True))

        # Clone list of kids (we null it out as we process)
        c, crange = c[:], list(range(len(c)))
        # Loop over all items we're expecting

        for j, c_elt in [(j, c[j]) for j in crange if c[j]]:

            for i, what in [(i, self.ofwhat[i])
                            for i in range(len(self.ofwhat))]:

                # retrieve typecode if it is hidden
                if isinstance(what, collections.Callable): what = what()

                # Loop over all available kids
                # if debug:
                #     self.logger.debug("what: (%s,%s)", what.nspname, what.pname)

                # Parse value, and mark this one done.
                # if debug:
                #     self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName)
                match = False
                if what.name_match(c_elt):
                    match = True
                    value = what.parse(c_elt, ps)
                elif isinstance(what, AnyElement):
                    match = True
                    value = what.parse(c_elt, ps)
                else:
                    # substitutionGroup head must be a global element declaration
                    # if successful delegate to matching GED
                    subwhat = _get_substitute_element(what, c_elt, ps)
                    if subwhat:
                        match = True
                        value = subwhat.parse(c_elt, ps)

                    if debug:
                        self.logger.debug("substitutionGroup: %s", subwhat)

                if match:
                    if what.maxOccurs > 1:
                        attr = getattr(pyobj, what.aname, None)
                        if attr is not None:
                            attr.append(value)
                        else:
                            setattr(pyobj, what.aname, [value])
                        c[j] = None
                        continue
                    else:
                        setattr(pyobj, what.aname, value)
                    c[j] = None
                    break

                if debug:
                    self.logger.debug("no element (%s,%s)", what.nspname,
                                      what.pname)

                # No match; if it was supposed to be here, that's an error.
                if self.inorder is True and i == j:
                    raise EvaluateException('Out of order complexType',
                                            ps.Backtrace(c_elt))
                else:
                    if hasattr(what, 'default'):
                        setattr(pyobj, what.aname, what.default)
                    # elif what.minOccurs > 0 and not hasattr(pyobj, what.aname):
                    #     raise EvaluateException('Element "' + what.aname + '" missing from complexType', ps.Backtrace(elt))

        if isinstance(pyobj, ComplexType._DictHolder):
            return pyobj.__dict__

        return pyobj
Ejemplo n.º 17
0
    def __init__(self, input, readerclass=None, keepdom=False,
    trailers=False, resolver=None,  envelope=True, **kw):
        '''Initialize.
        Keyword arguments:
            trailers -- allow trailer elments (default is zero)
            resolver -- function (bound method) to resolve URI's
            readerclass -- factory class to create a reader
            keepdom -- do not release the DOM
            envelope -- look for a SOAP envelope.
        '''
        self.readerclass = readerclass
        self.keepdom = keepdom
        if not self.readerclass:
            self.readerclass = self.defaultReaderClass

        try:
            self.reader = self.readerclass()
            if isinstance(input, str):
                self.dom = self.reader.fromString(input)
            elif isinstance(input, bytes):
                self.dom = self.reader.fromString(input.decode(UNICODE_ENCODING))
            else:
                self.dom = self.reader.fromStream(input)
        except Exception as e:
            # Is this in the header?  Your guess is as good as mine.
            #raise ParseException("Can't parse document (" + \
            #    str(e.__class__) + "): " + str(e), 0)
            raise

        self.ns_cache = {
            id(self.dom): {
                'xml': XMLNS.XML,
                'xmlns': XMLNS.BASE,
                '': ''
            }
        }
        self.trailers, self.resolver, self.id_cache = trailers, resolver, {}

        # Exactly one child element
        c = [ E for E in _children(self.dom)
                if E.nodeType == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException("Document has no Envelope", 0)
        if len(c) != 1:
            raise ParseException("Document has extra child elements", 0)

        if envelope is False:
            self.body_root = c[0]
            return

        # And that one child must be the Envelope
        elt = c[0]
        if elt.localName != "Envelope" \
        or elt.namespaceURI != SOAP.ENV:
            raise ParseException('Document has "' + elt.localName + \
                '" element, not Envelope', 0)
        self._check_for_legal_children("Envelope", elt)
        for a in _attrs(elt):
            name = a.nodeName
            if name.find(":") == -1 and name not in [ "xmlns", "id" ]:
                raise ParseException('Unqualified attribute "' + \
                        name + '" in Envelope', 0)
        self.envelope = elt
        if not _valid_encoding(self.envelope):
            raise ParseException("Envelope has invalid encoding", 0)

        # Get Envelope's child elements.
        c = [ E for E in _children(self.envelope)
                if E.nodeType == _Node.ELEMENT_NODE ]
        if len(c) == 0:
            raise ParseException("Envelope is empty (no Body)", 0)

        # Envelope's first child might be the header; if so, nip it off.
        elt = c[0]
        if elt.localName == "Header" \
        and elt.namespaceURI == SOAP.ENV:
            self._check_for_legal_children("Header", elt)
            self._check_for_pi_nodes(_children(elt), 1)
            self.header = c.pop(0)
            self.header_elements = _child_elements(self.header)
        else:
            self.header, self.header_elements = None, []

        # Now the first child must be the body
        if len(c) == 0:
            raise ParseException("Envelope has header but no Body", 0)
        elt = c.pop(0)
        if elt.localName != "Body" \
        or elt.namespaceURI != SOAP.ENV:
            if self.header:
                raise ParseException('Header followed by "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
            else:
                raise ParseException('Document has "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
        self._check_for_legal_children("Body", elt, 0)
        self._check_for_pi_nodes(_children(elt), 0)
        self.body = elt
        if not _valid_encoding(self.body):
            raise ParseException("Body has invalid encoding", 0)

        # Trailer elements.
        if not self.trailers:
            if len(c):
                raise ParseException("Element found after Body",
                        0, elt, self.dom)
            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.
        else:
            self.trailer_elements = c
            for elt in self.trailer_elements:
                if not elt.namespaceURI:
                    raise ParseException('Unqualified trailer element',
                            0, elt, self.dom)

        # Find the serialization root.  Divide the Body children into
        # root (root=1), no (root=0), maybe (no root attribute).
        self.body_root, no, maybe = None, [], []
        for elt in _child_elements(self.body):
            root = _find_root(elt)
            if root == "1":
                if self.body_root:
                    raise ParseException("Multiple seralization roots found",
                            0, elt, self.dom)
                self.body_root = elt
            elif root == "0":
                no.append(elt)
            elif not root:
                maybe.append(elt)
            else:
                raise ParseException('Illegal value for root attribute',
                        0, elt, self.dom)

        # If we didn't find a root, get the first one that didn't
        # say "not me", unless they all said "not me."
        if self.body_root is None:
            if len(maybe):
                self.body_root = maybe[0]
            else:
                raise ParseException('No serialization root found',
                        0, self.body, self.dom)
        if not _valid_encoding(self.body_root):
            raise ParseException("Invalid encoding", 0,
                    elt, self.dom)

        # Now get all the non-roots (in order!).
        rootid = id(self.body_root)
        self.data_elements = [ E for E in _child_elements(self.body)
                                if id(E) != rootid ]
        self._check_for_pi_nodes(self.data_elements, 0)
Ejemplo n.º 18
0
    def parse(self, elt, ps):
        debug = self.logger.debugOn()
        debug and self.logger.debug('parse')
       
        xtype = self.checkname(elt, ps)
        if self.type and xtype not in [ self.type, (None,None) ]:
            if not isinstance(self, TypeDefinition):
                raise EvaluateException(\
                    'ComplexType for %s has wrong type(%s), looking for %s' %
                        (self.pname, self.checktype(elt,ps), self.type), 
                                        ps.Backtrace(elt))
            else:
                #TODO: mabye change MRO to handle this 
                debug and self.logger.debug('delegate to substitute type')
                what = TypeDefinition.getSubstituteType(self, elt, ps)
                return what.parse(elt, ps)
            
        href = _find_href(elt)
        if href:
            if _children(elt):
                raise EvaluateException('Struct has content and HREF',
                        ps.Backtrace(elt))
            elt = ps.FindLocalHREF(href, elt)
        c = _child_elements(elt)
        count = len(c)
        if self.nilled(elt, ps): return Nilled

        # Create the object.
        v = {}

        # parse all attributes contained in attribute_typecode_dict (user-defined attributes),
        # the values (if not None) will be keyed in self.attributes dictionary.
        attributes = self.parse_attributes(elt, ps)
        if attributes:
            v[self.attrs_aname] = attributes

        #MIXED
        if self.mixed is True:
            v[self.mixed_aname] = self.simple_value(elt,ps, mixed=True)

        # Clone list of kids (we null it out as we process)
        c, crange = c[:], list(range(len(c)))
        # Loop over all items we're expecting
        
        if debug:
            self.logger.debug("ofwhat: %s",str(self.ofwhat))
            
        any = None
        for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]:
            
            # retrieve typecode if it is hidden
            if isinstance(what, collections.Callable): what = what()
            
            # Loop over all available kids
            if debug: 
                self.logger.debug("what: (%s,%s)", what.nspname, what.pname)
                
            for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
                # Parse value, and mark this one done. 
                if debug:
                    self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName)

                match = False
                if what.name_match(c_elt):
                    match = True
                    value = what.parse(c_elt, ps)
                else:
                    # substitutionGroup head must be a global element declaration
                    # if successful delegate to matching GED
                    subwhat = _get_substitute_element(what, c_elt, ps)
                    if subwhat:
                        match = True
                        value = subwhat.parse(c_elt, ps)

                    if debug: 
                        self.logger.debug("substitutionGroup: %s", subwhat)

                if match:
                    if what.maxOccurs == UNBOUNDED or what.maxOccurs > 1:
                        if what.aname in v:
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break

                if debug:
                    self.logger.debug("no element (%s,%s)", what.nspname, what.pname)

                # No match; if it was supposed to be here, that's an error.
                if self.inorder is True and i == j:
                    raise EvaluateException('Out of order complexType',
                            ps.Backtrace(c_elt))
            else:
                # only supporting 1 <any> declaration in content.
                if isinstance(what,AnyElement):
                    any = what
                elif hasattr(what, 'default'):
                    v[what.aname] = what.default
                elif what.minOccurs > 0 and what.aname not in v:
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from complexType', ps.Backtrace(elt))

        # Look for wildcards and unprocessed children
        # XXX Stick all this stuff in "any", hope for no collisions
        if any is not None:
            occurs = 0
            v[any.aname] = []
            for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
                value = any.parse(c_elt, ps)
                if any.maxOccurs == UNBOUNDED or any.maxOccurs > 1:
                    v[any.aname].append(value)
                else:
                    v[any.aname] = value

                occurs += 1

            # No such thing as nillable <any>
            if any.maxOccurs == 1 and occurs == 0:
                v[any.aname] = None
            elif occurs < any.minOccurs or (any.maxOccurs!=UNBOUNDED and any.maxOccurs<occurs):
                raise EvaluateException('occurances of <any> elements(#%d) bound by (%d,%s)' %(
                    occurs, any.minOccurs,str(any.maxOccurs)), ps.Backtrace(elt))

        if not self.pyclass: 
            return v

        # type definition must be informed of element tag (nspname,pname),
        # element declaration is initialized with a tag.
        try:
            pyobj = self.pyclass()
        except Exception as e:
            raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
        for key in list(v.keys()):
            setattr(pyobj, key, v[key])
        return pyobj
Ejemplo n.º 19
0
    def __init__(self, _input, readerclass=None, keepdom=False,
    trailers=False, resolver=None,  envelope=True, **kw):
        """Initialize.
        Keyword arguments:
            trailers -- allow trailer elments (default is zero)
            resolver -- function (bound method) to resolve URI's
            readerclass -- factory class to create a reader
            keepdom -- do not release the DOM
            envelope -- look for a SOAP envelope.
        """

        self.readerclass = readerclass
        self.keepdom = keepdom
        if not self.readerclass:
            self.readerclass = self.defaultReaderClass

        try:
            self.reader = self.readerclass()
            if isinstance(_input, _stringtypes):
                self.dom = self.reader.fromString(_input)
            else:
                self.dom = self.reader.fromStream(_input)
        except Exception:
            # Is this in the header?  Your guess is as good as mine.
            #raise ParseException("Can't parse document (" + \
            #    str(e.__class__) + "): " + str(e), 0)
            raise

        self.ns_cache = {
            id(self.dom): {
                'xml': XMLNS.XML,
                'xmlns': XMLNS.BASE,
                '': ''
            }
        }
        self.trailers, self.resolver, self.id_cache = trailers, resolver, {}

        # Exactly one child element
        c = [ E for E in _children(self.dom)
                if E.nodeType == _Node.ELEMENT_NODE]
        if len(c) == 0:
            raise ParseException("Document has no Envelope", 0)
        if len(c) != 1:
            raise ParseException("Document has extra child elements", 0)

        if envelope is False:
            self.body_root = c[0]
            return

        # And that one child must be the Envelope
        elt = c[0]
        if elt.localName != "Envelope" \
        or elt.namespaceURI != SOAP.ENV:
            raise ParseException('Document has "' + elt.localName + \
                '" element, not Envelope', 0)
        self._check_for_legal_children("Envelope", elt)
        for a in _attrs(elt):
            name = a.nodeName
            if name.find(":") == -1 and name not in [ "xmlns", "id" ]:
                raise ParseException('Unqualified attribute "' + \
                        name + '" in Envelope', 0)
        self.envelope = elt
        if not _valid_encoding(self.envelope):
            raise ParseException("Envelope has invalid encoding", 0)

        # Get Envelope's child elements.
        c = [ E for E in _children(self.envelope)
                if E.nodeType == _Node.ELEMENT_NODE ]
        if len(c) == 0:
            raise ParseException("Envelope is empty (no Body)", 0)

        # Envelope's first child might be the header; if so, nip it off.
        elt = c[0]
        if elt.localName == "Header" \
        and elt.namespaceURI == SOAP.ENV:
            self._check_for_legal_children("Header", elt)
            self._check_for_pi_nodes(_children(elt), 1)
            self.header = c.pop(0)
            self.header_elements = _child_elements(self.header)
        else:
            self.header, self.header_elements = None, []

        # Now the first child must be the body
        if len(c) == 0:
            raise ParseException("Envelope has header but no Body", 0)
        elt = c.pop(0)
        if elt.localName != "Body" \
        or elt.namespaceURI != SOAP.ENV:
            if self.header:
                raise ParseException('Header followed by "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
            else:
                raise ParseException('Document has "' + \
                        elt.localName + \
                        '" element, not Body', 0, elt, self.dom)
        self._check_for_legal_children("Body", elt, 0)
        self._check_for_pi_nodes(_children(elt), 0)
        self.body = elt
        if not _valid_encoding(self.body):
            raise ParseException("Body has invalid encoding", 0)

        # Trailer elements.
        if not self.trailers:
            if len(c):
                raise ParseException("Element found after Body",
                        0, elt, self.dom)
            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.
        else:
            self.trailer_elements = c
            for elt in self.trailer_elements:
                if not elt.namespaceURI:
                    raise ParseException('Unqualified trailer element',
                            0, elt, self.dom)

        # Find the serialization root.  Divide the Body children into
        # root (root=1), no (root=0), maybe (no root attribute).
        self.body_root, no, maybe = None, [], []
        for elt in _child_elements(self.body):
            root = _find_root(elt)
            if root == "1":
                if self.body_root:
                    raise ParseException("Multiple seralization roots found",
                            0, elt, self.dom)
                self.body_root = elt
            elif root == "0":
                no.append(elt)
            elif not root:
                maybe.append(elt)
            else:
                raise ParseException('Illegal value for root attribute',
                        0, elt, self.dom)

        # If we didn't find a root, get the first one that didn't
        # say "not me", unless they all said "not me."
        if self.body_root is None:
            if len(maybe):
                self.body_root = maybe[0]
            else:
                raise ParseException('No serialization root found',
                        0, self.body, self.dom)
        if not _valid_encoding(self.body_root):
            raise ParseException("Invalid encoding", 0,
                    elt, self.dom)

        # Now get all the non-roots (in order!).
        rootid = id(self.body_root)
        self.data_elements = [ E for E in _child_elements(self.body)
                                if id(E) != rootid ]
        self._check_for_pi_nodes(self.data_elements, 0)
Ejemplo n.º 20
0
def _Dispatch(ps,
              modules,
              SendResponse,
              SendFault,
              nsdict={},
              typesmodule=None,
              gettypecode=gettypecode,
              rpc=False,
              docstyle=False,
              **kw):
    '''Find a handler for the SOAP request in ps; search modules.
    Call SendResponse or SendFault to send the reply back, appropriately.

    Behaviors:
        default -- Call "handler" method with pyobj representation of body root, and return
            a self-describing request (w/typecode).  Parsing done via a typecode from 
            typesmodule, or Any.

        docstyle -- Call "handler" method with ParsedSoap instance and parse result with an
          XML typecode (DOM). Behavior, wrap result in a body_root "Response" appended message.

        rpc -- Specify RPC wrapper of result. Behavior, ignore body root (RPC Wrapper)
           of request, parse all "parts" of message via individual typecodes.  Expect
           the handler to return the parts of the message, whether it is a dict, single instance, 
           or a list try to serialize it as a Struct but if this is not possible put it in an Array.
           Parsing done via a typecode from typesmodule, or Any.

    '''
    global _client_binding
    try:
        what = str(ps.body_root.localName)

        # See what modules have the element name.
        if modules is None:
            modules = (sys.modules['__main__'], )

        handlers = [getattr(m, what) for m in modules if hasattr(m, what)]
        if len(handlers) == 0:
            raise TypeError("Unknown method " + what)

        # Of those modules, see who's callable.
        handlers = [h for h in handlers if isinstance(h, collections.Callable)]
        if len(handlers) == 0:
            raise TypeError("Unimplemented method " + what)
        if len(handlers) > 1:
            raise TypeError("Multiple implementations found: " +
                            repr(handlers))
        handler = handlers[0]

        _client_binding = ClientBinding(ps)
        if docstyle:
            result = handler(ps.body_root)
            tc = TC.XML(aslist=1, pname=what + 'Response')
        elif not rpc:
            try:
                tc = gettypecode(typesmodule, ps.body_root)
            except Exception:
                tc = TC.Any()

            try:
                arg = tc.parse(ps.body_root, ps)
            except EvaluateException as ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

            try:
                result = handler(arg)
            except Exception as ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

            try:
                tc = result.typecode
            except AttributeError as ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

        elif typesmodule is not None:
            kwargs = {}
            for e in _child_elements(ps.body_root):
                try:
                    tc = gettypecode(typesmodule, e)
                except Exception:
                    tc = TC.Any()

                try:
                    kwargs[str(e.localName)] = tc.parse(e, ps)
                except EvaluateException as ex:
                    SendFault(FaultFromZSIException(ex), **kw)
                    return

            result = handler(**kwargs)
            aslist = False
            # make sure data is wrapped, try to make this a Struct
            if type(result) in _seqtypes:
                for o in result:
                    aslist = hasattr(result, 'typecode')
                    if aslist: break
            elif type(result) is not dict:
                aslist = not hasattr(result, 'typecode')
                result = (result, )

            tc = TC.Any(pname=what + 'Response', aslist=aslist)
        else:
            # if this is an Array, call handler with list
            # if this is an Struct, call handler with dict
            tp = _find_type(ps.body_root)
            isarray = ((type(tp) in (tuple, list) and tp[1] == 'Array')
                       or _find_arraytype(ps.body_root))
            data = _child_elements(ps.body_root)
            tc = TC.Any()
            if isarray and len(data) == 0:
                result = handler()
            elif isarray:
                try:
                    arg = [tc.parse(e, ps) for e in data]
                except EvaluateException as e:
                    #SendFault(FaultFromZSIException(e), **kw)
                    SendFault(RuntimeError("THIS IS AN ARRAY: %s" % isarray))
                    return

                result = handler(*arg)
            else:
                try:
                    kwarg = dict([(str(e.localName), tc.parse(e, ps))
                                  for e in data])
                except EvaluateException as e:
                    SendFault(FaultFromZSIException(e), **kw)
                    return

                result = handler(**kwarg)

            # reponse typecode
            #tc = getattr(result, 'typecode', TC.Any(pname=what+'Response'))
            tc = TC.Any(pname=what + 'Response')

        sw = SoapWriter(nsdict=nsdict)
        sw.serialize(result, tc)
        return SendResponse(str(sw), **kw)
    except Fault as e:
        return SendFault(e, **kw)
    except Exception as e:
        # Something went wrong, send a fault.
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)
Ejemplo n.º 21
0
            try:
                result = handler(arg)
            except Exception,ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

            try:
                tc = result.typecode
            except AttributeError,ex:
                SendFault(FaultFromZSIException(ex), **kw)
                return

        elif typesmodule is not None:
            kwargs = {}
            for e in _child_elements(ps.body_root):
                try:
                    tc = gettypecode(typesmodule, e)
                except Exception:
                    tc = TC.Any()

                try:
                    kwargs[str(e.localName)] = tc.parse(e, ps)
                except EvaluateException, ex:
                    SendFault(FaultFromZSIException(ex), **kw)
                    return

            result = handler(**kwargs)
            aslist = False
            # make sure data is wrapped, try to make this a Struct
            if isinstance(result,_seqtypes):