예제 #1
0
    def test_local_serialize_schema(self):
        from ZSI import SoapWriter
        from ZSI import _child_elements
        from xml.dom.ext.reader import PyExpat
        msg = self.client_module.DSQueryRegistrySoapOut()
        msg.DSQueryRegistryResult = msg.new_DSQueryRegistryResult()
        msg.DSQueryRegistryResult.Any = 'hi'

        input = open('wsdl/nvo-admin.wsdl').read()
        reader = PyExpat.Reader()
        dom = reader.fromString(input)

        dnode =  _child_elements(dom)[0]
        tnode =  _child_elements(dnode)[0]
        snode =  _child_elements(tnode)[0]

        msg.DSQueryRegistryResult.Schema = snode

        sw = SoapWriter()
        sw.serialize(msg)
        soap = str(sw)
        print soap

        ps = ParsedSoap(soap)
        pyobj = ps.Parse(msg.typecode)
        self.failUnlessEqual(pyobj.DSQueryRegistryResult.Any, msg.DSQueryRegistryResult.Any)
        self.failUnless(_is_element(pyobj.DSQueryRegistryResult.Schema))
        print _get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema)
        self.failUnlessEqual(_get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema), (u'http://www.w3.org/2001/XMLSchema', u'schema'))
예제 #2
0
    def test_local_serialize_schema(self):
        from ZSI import SoapWriter
        from ZSI import _child_elements
        from xml.dom.ext.reader import PyExpat
        msg = self.client_module.DSQueryRegistrySoapOut()
        msg.DSQueryRegistryResult = msg.new_DSQueryRegistryResult()
        msg.DSQueryRegistryResult.Any = 'hi'

        input = open('wsdl/nvo-admin.wsdl').read()
        reader = PyExpat.Reader()
        dom = reader.fromString(input)

        dnode = _child_elements(dom)[0]
        tnode = _child_elements(dnode)[0]
        snode = _child_elements(tnode)[0]

        msg.DSQueryRegistryResult.Schema = snode

        sw = SoapWriter()
        sw.serialize(msg)
        soap = str(sw)
        print(soap)

        ps = ParsedSoap(soap)
        pyobj = ps.Parse(msg.typecode)
        self.assertEqual(pyobj.DSQueryRegistryResult.Any,
                         msg.DSQueryRegistryResult.Any)
        self.assertTrue(_is_element(pyobj.DSQueryRegistryResult.Schema))
        print(_get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema))
        self.assertEqual(
            _get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema),
            ('http://www.w3.org/2001/XMLSchema', 'schema'))
예제 #3
0
 def parse(self, elt, ps):
     (ns,type) = self.checkname(elt, ps)
     if not type and self.nilled(elt, ps): return None
     if len(_children(elt)) == 0:
         href = _find_href(elt)
         if not href:
             if self.optional: return None
             raise EvaluateException('Non-optional Any missing',
                     ps.Backtrace(elt))
         elt = ps.FindLocalHREF(href, elt)
         (ns,type) = self.checktype(elt, ps)
     if not type and elt.namespaceURI == SOAP.ENC:
         ns,type = SOAP.ENC, elt.localName
     if not type or (ns,type) == (SOAP.ENC,'Array'):
         if self.aslist or _find_arraytype(elt):
             return [ Any(aslist=self.aslist).parse(e, ps)
                         for e in _child_elements(elt) ]
         if len(_child_elements(elt)) == 0:
             raise EvaluateException("Any cannot parse untyped element",
                     ps.Backtrace(elt))
         return self.parse_into_dict_or_list(elt, ps)
     parser = Any.parsemap.get((ns,type))
     if not parser and _is_xsd_or_soap_ns(ns):
         parser = Any.parsemap.get((None,type))
     if not parser:
         raise EvaluateException('''Any can't parse element''',
                 ps.Backtrace(elt))
     return parser.parse(elt, ps)
예제 #4
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
예제 #5
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
예제 #6
0
def FaultFromFaultMessage(ps):
    '''Parse the message as a fault.
    '''
    d = { 'faultcode': None, 'faultstring': None, 'faultactor': None,
        'detail': None, }
    for elt in _child_elements(ps.body_root):
        n = elt.localName
        if n == 'detail':
            d['detail'] = _child_elements(elt)
        if n in [ 'faultcode', 'faultstring', 'faultactor' ]:
            d[n] = ''.join([E.nodeValue for E in _children(elt)
                            if E.nodeType 
                            in [ _Node.TEXT_NODE, _Node.CDATA_SECTION_NODE ]])
    return Fault(d['faultcode'], d['faultstring'],
                d['faultactor'], d['detail'])
예제 #7
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)
예제 #8
0
 def parse_into_dict_or_list(self, elt, ps):
     c = _child_elements(elt)
     count = len(c)
     v = {}
     if count == 0:
         href = _find_href(elt)
         if not href: return v
         elt = ps.FindLocalHREF(href, elt)
         self.checktype(elt, ps)
         c = _child_elements(elt)
         count = len(c)
         if count == 0: return self.listify(v)
     if self.nilled(elt, ps): return None
     for c_elt in c:
         v[str(c_elt.nodeName)] = self.parse(c_elt, ps)
     return self.listify(v)
예제 #9
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 None
     if not _find_arraytype(elt) and not self.undeclared:
         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
예제 #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.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
예제 #11
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)
예제 #12
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
예제 #13
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
예제 #14
0
    def Receive(self, replytype=None, **kw):
        '''Parse message, create Python object. if replytype is None, use
        TC.Any to dynamically parse; otherwise it can be a Python class
        or the typecode to use in parsing.
        '''
        self.ReceiveSOAP(**kw)
        if self.ps.IsAFault():
            msg = FaultFromFaultMessage(self.ps)
            raise FaultException(msg)

        if replytype is None:
            tc = TC.Any(aslist=1)

            # if the message is RPC style, skip the fooBarResponse
            elt_name = '%s' % self.ps.body_root.localName
            if elt_name.find('Response') > 0:
                data = _child_elements(self.ps.body_root)
            else:
                data = [self.ps.body_root]
                
            if len(data) == 0: return None

            # check for array type, loop and process if found
            for attr in _attrs(data[0]):
                if attr.localName.find('arrayType') >= 0:
                    data = _child_elements(data[0])

                    toReturn = []
                    for node in data:
                        type = node.localName

                        # handle case where multiple elements are returned
                        if type.find('element') >= 0:
                            node = _child_elements(node)[0]
                            type = node.localName

                        toReturn.append(self.__parse(node, type))
                    return toReturn

            # parse a complex or primitive type and return it
            type = data[0].localName
            return self.__parse(data[0], type)
        elif hasattr(replytype, 'typecode'):
            tc = replytype.typecode
        else:
            tc = replytype
        return self.ps.Parse(tc)
예제 #15
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]
예제 #16
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]
예제 #17
0
 def parse(self, elt, ps):
     if not self.wrapped:
         return elt
     c = _child_elements(elt)
     if not c:
         href = _find_href(elt)
         if not href:
             if self.optional: return None
             raise EvaluateException('Embedded XML document missing',
                     ps.Backtrace(elt))
         if href[0] != '#':
             return ps.ResolveHREF(href, self)
         elt = ps.FindLocalHREF(href, elt)
         c = _child_elements(elt)
     if _find_encstyle(elt) != "":
         #raise EvaluateException('Embedded XML has unknown encodingStyle',
         #       ps.Backtrace(elt)
         pass
     if len(c) != 1:
         raise EvaluateException('Embedded XML has more than one child',
                 ps.Backtrace(elt))
     if self.copyit: return c[0].cloneNode(1)
     return c[0]
예제 #18
0
def _Dispatch(ps, modules, SendResponse, SendFault, docstyle=0, nsdict={}, typesmodule=None, rpc=None, **kw):
    """Find a handler for the SOAP request in ps; search modules.
    Call SendResponse or SendFault to send the reply back, appropriately.
    """
    global _client_binding
    try:
        what = 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 callable(h)]
        if len(handlers) == 0:
            raise TypeError("Unimplemented method " + what)
        if len(handlers) > 1:
            raise TypeError("Multiple implementations found: " + ` handlers `)
        handler = handlers[0]

        _client_binding = ClientBinding(ps)
        if docstyle:
            result = handler(ps.body_root)
            tc = TC.XML(aslist=1, pname=what + "Response")
        else:
            data = _child_elements(ps.body_root)
            if len(data) == 0:
                arg = []
            else:
                try:
                    try:
                        type = data[0].localName
                        tc = getattr(typesmodule, type).typecode
                    except Exception, e:
                        tc = TC.Any()
                    arg = [tc.parse(e, ps) for e in data]
                except EvaluateException, e:
                    SendFault(FaultFromZSIException(e), **kw)
                    return
예제 #19
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.
        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)))
예제 #20
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.
        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)))
예제 #21
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:
            if self.defaultReaderClass != None:
                self.readerclass = self.defaultReaderClass
            else:
                from xml.dom.ext.reader import PyExpat

                self.readerclass = PyExpat.Reader
        try:
            self.reader = self.readerclass()
            if type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            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)
예제 #22
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[:], 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 callable(what): 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] ]:
                if debug:
                    self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, 
                                      c_elt.tagName)
                if what.name_match(c_elt):
                    # Parse value, and mark this one done. 
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        #what = _get_substitute_element(c_elt, what)
                        #value = what.parse(c_elt, ps)
                        raise
                    if what.maxOccurs > 1:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                else:
                    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 not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from complexType', ps.Backtrace(elt))
예제 #23
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)

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

        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)
예제 #24
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 type(result) in _seqtypes:
예제 #25
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 callable(h) ]
        if len(handlers) == 0:
            raise TypeError("Unimplemented method " + what)
        if len(handlers) > 1:
            raise TypeError("Multiple implementations found: %s" % 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 isinstance(result,_seqtypes):
                for _ in result:
                    aslist = hasattr(result, 'typecode')
                    if aslist: break
            elif not isinstance(result, 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 = ((isinstance(tp, (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)
예제 #26
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[:], 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 callable(what): 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 > 1:
                        if v.has_key(what.aname):
                            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 not v.has_key(what.aname):
                    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, e:
            raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
예제 #27
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[:], 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 callable(what): 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] ]:
                if debug:
                    self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, 
                                      c_elt.tagName)
                if what.name_match(c_elt):
                    # Parse value, and mark this one done. 
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        #what = _get_substitute_element(c_elt, what)
                        #value = what.parse(c_elt, ps)
                        raise
                    if what.maxOccurs > 1:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                else:
                    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 not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from complexType', ps.Backtrace(elt))
예제 #28
0
                SendFault(FaultFromZSIException(ex), **kw)
                return

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

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

        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 type(result) in _seqtypes:
예제 #29
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[:], 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 callable(what): 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 > 1:
                        if v.has_key(what.aname):
                            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 not v.has_key(what.aname):
                    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, e:
            raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
예제 #30
0
파일: parse.py 프로젝트: mikedougherty/ZSI
    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 type(input) in _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 not in (SOAP.ENV, SOAP.ENV12):
            raise ParseException('Document has %r element, not %s' %
                                 ((elt.namespaceURI, elt.localName), (SOAP.ENV12, '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 in (SOAP.ENV, SOAP.ENV12):
            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 not in (SOAP.ENV, SOAP.ENV12):
            if self.header:
                raise ParseException('Header followed by "%r" element, not Body' % ((elt.namespaceURI, elt.localName),), 0,
                        elt, self.dom)
            else:
                raise ParseException('Document has "%r element, not Body' % ((elt.namespaceURI, elt.localName),), 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)
        else:

            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.

            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)
예제 #31
0
class ParsedSoap:
    '''A Parsed SOAP object.
        Convert the text to a DOM tree and parse SOAP elements.
        Instance data:
            reader -- the DOM reader
            dom -- the DOM object
            ns_cache -- dictionary (by id(node)) of namespace dictionaries
            id_cache -- dictionary (by XML ID attr) of elements
            envelope -- the node holding the SOAP Envelope
            header -- the node holding the SOAP Header (or None)
            body -- the node holding the SOAP Body
            body_root -- the serialization root in the SOAP Body
            data_elements -- list of non-root elements in the SOAP Body
            trailer_elements -- list of elements following the SOAP body
    '''
    defaultReaderClass = DefaultReader

    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 type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            else:
                self.dom = self.reader.fromStream(input)
        except Exception, 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)
예제 #32
0
    def parse(self, elt, ps):
        #if elt.localName != self.pname:
        #    elt = elt.getElementsByTagName(self.pname)[0]
        self.checkname(elt, ps)
        if self.type and \
        self.checktype(elt, ps) not in [ self.type, (None,None) ]:
            raise EvaluateException('Struct has wrong type', ps.Backtrace(elt))
        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 None
        repeatable_args = False
        for tc in self.ofwhat:
            if tc.repeatable:
                repeatable_args = True
                break

        if not repeatable_args:
            if count > len(self.ofwhat) and not self.hasextras:
                raise EvaluateException('Too many sub-elements', ps.Backtrace(elt))

        # Create the object.
        v = {}

        # Clone list of kids (we null it out as we process)
        c, crange = c[:], range(len(c))
        # Loop over all items we're expecting
        for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]:
            # Loop over all available kids
            for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
                if what.name_match(c_elt):
                    # Parse value, and mark this one done.
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        e.str = '%s.%s: %s' % \
                                (self.pname or '?', what.aname or '?', e.str)
                        raise e
                    if what.repeatable:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                # No match; if it was supposed to be here, that's an error.
                if self.inorder and i == j:
                    raise EvaluateException('Out of order struct',
                            ps.Backtrace(c_elt))
            else:
                if not what.optional and not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from struct', ps.Backtrace(elt))
                if hasattr(what, 'default'):
                    v[what.aname] = what.default
예제 #33
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 callable(what): 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