• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/opal/ZSI/ZSI/resolvers.py

00001 #! /usr/bin/env python
00002 # $Header$
00003 '''SOAP messaging parsing.
00004 '''
00005 
00006 from ZSI import _copyright, _child_elements, EvaluateException, TC
00007 import multifile, mimetools, urllib
00008 from base64 import decodestring as b64decode
00009 import cStringIO as StringIO
00010 
00011 
00012 def Opaque(uri, tc, ps, **keywords):
00013     '''Resolve a URI and return its content as a string.
00014     '''
00015     source = urllib.urlopen(uri, **keywords)
00016     enc = source.info().getencoding()
00017     if enc in ['7bit', '8bit', 'binary']: return source.read()
00018 
00019     data = StringIO.StringIO()
00020     mimetools.decode(source, data, enc)
00021     return data.getvalue()
00022 
00023 
00024 def XML(uri, tc, ps, **keywords):
00025     '''Resolve a URI and return its content as an XML DOM.
00026     '''
00027     source = urllib.urlopen(uri, **keywords)
00028     enc = source.info().getencoding()
00029     if enc in ['7bit', '8bit', 'binary']:
00030         data = source
00031     else:
00032         data = StringIO.StringIO()
00033         mimetools.decode(source, data, enc)
00034         data.seek(0)
00035     dom = ps.readerclass().fromStream(data)
00036     return _child_elements(dom)[0]
00037 
00038 
00039 class NetworkResolver:
00040     '''A resolver that support string and XML.
00041     '''
00042 
00043     def __init__(self, prefix=None):
00044         self.allowed = prefix or []
00045 
00046     def _check_allowed(self, uri):
00047         for a in self.allowed:
00048             if uri.startswith(a): return
00049         raise EvaluateException("Disallowed URI prefix")
00050 
00051     def Opaque(self, uri, tc, ps, **keywords):
00052         self._check_allowed(uri)
00053         return Opaque(uri, tc, ps, **keywords)
00054 
00055     def XML(self, uri, tc, ps, **keywords):
00056         self._check_allowed(uri)
00057         return XML(uri, tc, ps, **keywords)
00058 
00059     def Resolve(self, uri, tc, ps, **keywords):
00060         if isinstance(tc, TC.XML):
00061             return XML(uri, tc, ps, **keywords)
00062         return Opaque(uri, tc, ps, **keywords)
00063 
00064 
00065 class MIMEResolver:
00066     '''Multi-part MIME resolver -- SOAP With Attachments, mostly.
00067     '''
00068 
00069     def __init__(self, ct, f, next=None, uribase='thismessage:/',
00070     seekable=0, **kw):
00071         # Get the boundary.  It's too bad I have to write this myself,
00072         # but no way am I going to import cgi for 10 lines of code!
00073         for param in ct.split(';'):
00074             a = param.strip()
00075             if a.startswith('boundary='):
00076                 if a[9] in [ '"', "'" ]:
00077                     boundary = a[10:-1]
00078                 else:
00079                     boundary = a[9:]
00080                 break
00081         else:
00082             raise ValueError('boundary parameter not found')
00083 
00084         self.id_dict, self.loc_dict, self.parts = {}, {}, []
00085         self.next = next
00086         self.base = uribase
00087 
00088         mf = multifile.MultiFile(f, seekable)
00089         mf.push(boundary)
00090         while mf.next():
00091             head = mimetools.Message(mf)
00092             body = StringIO.StringIO()
00093             mimetools.decode(mf, body, head.getencoding())
00094             body.seek(0)
00095             part = (head, body)
00096             self.parts.append(part)
00097             key = head.get('content-id')
00098             if key:
00099                 if key[0] == '<' and key[-1] == '>': key = key[1:-1]
00100                 self.id_dict[key] = part
00101             key = head.get('content-location')
00102             if key: self.loc_dict[key] = part
00103         mf.pop()
00104 
00105     def GetSOAPPart(self):
00106         '''Get the SOAP body part.
00107         '''
00108         head, part = self.parts[0]
00109         return StringIO.StringIO(part.getvalue())
00110 
00111     def get(self, uri):
00112         '''Get the content for the bodypart identified by the uri.
00113         '''
00114         if uri.startswith('cid:'):
00115             # Content-ID, so raise exception if not found.
00116             head, part = self.id_dict[uri[4:]]
00117             return StringIO.StringIO(part.getvalue())
00118         if self.loc_dict.has_key(uri):
00119             head, part = self.loc_dict[uri]
00120             return StringIO.StringIO(part.getvalue())
00121         return None
00122 
00123     def Opaque(self, uri, tc, ps, **keywords):
00124         content = self.get(uri)
00125         if content: return content.getvalue()
00126         if not self.next: raise EvaluateException("Unresolvable URI " + uri)
00127         return self.next.Opaque(uri, tc, ps, **keywords)
00128 
00129     def XML(self, uri, tc, ps, **keywords):
00130         content = self.get(uri)
00131         if content:
00132             dom = ps.readerclass().fromStream(content)
00133             return _child_elements(dom)[0]
00134         if not self.next: raise EvaluateException("Unresolvable URI " + uri)
00135         return self.next.XML(uri, tc, ps, **keywords)
00136 
00137     def Resolve(self, uri, tc, ps, **keywords):
00138         if isinstance(tc, TC.XML):
00139             return self.XML(uri, tc, ps, **keywords)
00140         return self.Opaque(uri, tc, ps, **keywords)
00141 
00142     def __getitem__(self, cid):
00143         head, body = self.id_dict[cid]
00144         newio = StringIO.StringIO(body.getvalue())
00145         return newio
00146 
00147 if __name__ == '__main__': print _copyright

Generated on Wed Oct 20 2010 11:12:16 for APBS by  doxygen 1.7.2