/Users/maurits/Documents/studie/afstuderen/biosphere/python/biosphere/xlate.py

Go to the documentation of this file.
00001 from biosphere.types import *
00002 from xml.dom import minidom
00003 import base64
00004 
00005 """The xlate module is used to parse XML into either a bs_definition
00006 class or a bs_service_response class. Since this python package will
00007 only be used on the client side, no bs_service_request functionality
00008 is present.
00009 """
00010 
00011 
00012 class XMLParser:
00013     """Parses the three different Bio-SPHERE XML representations
00014     into their respective classes."""
00015     
00016     def __init__(self):
00017         """Initialize the XMLParser."""
00018         self.errorerror = None
00019     
00020     def Parse(self, xmldata):
00021         """Parses a giving buffer with XML data into the correct
00022         data type. If an error is encountered, None is returned
00023         and the error can be examined at self.error.
00024         
00025         Args:
00026         xmldata -- A buffer with XML data to parse.
00027         """
00028         dom = minidom.parseString(xmldata)
00029         if dom.documentElement.tagName == 'definitions':
00030             return self.ParseDefinitionsParseDefinitions(dom)
00031         elif dom.documentElement.tagName == 'response':
00032             return self.ParseResponseParseResponse(dom)
00033         else:
00034             self.errorerror = (0x00000204, 'Unknown root element')
00035             return None
00036     
00037     def ParseDefinitions(self, dom):
00038         """Parse a definition XML structure. This method creates
00039         a bs_definition class which is returned or None if there
00040         was an error.
00041         
00042         Args:
00043         dom -- The DOM of the XML
00044         """
00045         name = dom.documentElement.getAttribute('name')
00046         bsdef = bs_definition(name)
00047         
00048         self.AddTypesAddTypes(dom, bsdef)
00049         self.AddMessagesAddMessages(dom, bsdef)
00050         self.AddPortTypesAddPortTypes(dom, bsdef)
00051         self.AddServicesAddServices(dom, bsdef)
00052         
00053         dom.unlink()
00054         if self.errorerror != None:
00055             return None
00056         else:
00057             self.errorerror = None
00058             return bsdef
00059     
00060     def AddTypes(self, dom, bsdef):
00061         """Add the data types used in the definition to the given
00062         bs_definition class.
00063         
00064         Args:
00065         dom -- Part of the DOM with the data types.
00066         bsdef -- bs_definition class to add types to.
00067         """
00068         for type in dom.getElementsByTagName('type'):
00069             bstype = bs_data_type(type.getAttribute('name'))
00070             bsdef.types.append(bstype)
00071     
00072     def AddMessages(self, dom, bsdef):
00073         """Add the messages used in the definition to the
00074         bs_definition class.
00075         
00076         Args:
00077         dom -- Part of the DOM with the data types.
00078         bsdef -- bs_definition class to add messages to.
00079         """
00080         messages = dom.getElementsByTagName('message')
00081         for msg in messages:
00082             bsmsg = bs_message(msg.getAttribute('name'))
00083             self.AddMessagePartsAddMessageParts(msg, bsmsg, bsdef)
00084             bsdef.messages.append(bsmsg)
00085     
00086     def AddMessageParts(self, msg, bsmsg, bsdef):
00087         """Add the parts of the message, whose DOM is in msg, to the
00088         bs_message class (bsmsg), searching for the correct type in
00089         bsdef.
00090         
00091         Args:
00092         msg -- Part of the DOM tree related to the message.
00093         bsmsg -- bs_message class to add the parts to.
00094         bsdef -- bs_definition class for cross-referencing.
00095         """
00096         parts = msg.getElementsByTagName('part')
00097         for part in parts:
00098             name = part.getAttribute('name')
00099             typename = part.getAttribute('type')
00100             type = None
00101             for t in bsdef.types:
00102                 if t.name == typename:
00103                     type = t
00104                     break
00105             if type == None:
00106                 self.errorerror = (0x206, 'Data type unknown')
00107             bsmsg.parts.append(bs_message_part(name, type))
00108     
00109     def AddPortTypes(self, dom, bsdef):
00110         """Add the port types to the bs_definition class.
00111         
00112         Args:
00113         dom -- Part of the DOM containing the port types.
00114         bsdef -- bs_definition class to cross-reference.
00115         """
00116         pts = dom.getElementsByTagName('portType')
00117         for pt in pts:
00118             bspt = bs_port_type(pt.getAttribute('name'))
00119             self.AddOperationsAddOperations(pt, bspt, bsdef)
00120             bsdef.porttypes.append(bspt)
00121     
00122     def AddOperations(self, pt, bspt, bsdef):
00123         """Add all the operations in pt (DOM) to the given
00124         bs_port_type class, while cross-referencing in the
00125         bs_definition class.
00126         
00127         Args:
00128         pt -- Part of the DOM related to the portType.
00129         bspt -- bs_port_type class to add operations to.
00130         bsdef -- bs_definition class to use for crossreferencing.
00131         """
00132         ops = pt.getElementsByTagName('operation')
00133         for op in ops:
00134             bsop = bs_operation(op.getAttribute('name'))
00135             
00136             # Find an optional input tag:
00137             itag = op.getElementsByTagName('input')
00138             if itag != []:
00139                 mname = itag[0].getAttribute('message')
00140                 for msg in bsdef.messages:
00141                     if msg.name == mname:
00142                         bsop.input = msg
00143                 if bsop.input == None:
00144                     self.errorerror = (0x200, 'Couldnt find referenced message: %s' % mname)
00145             # Find an optional output tag:
00146             otag = op.getElementsByTagName('output')
00147             if otag != []:
00148                 mname = otag[0].getAttribute('message')
00149                 for msg in bsdef.messages:
00150                     if msg.name == mname:
00151                         bsop.output = msg
00152                 if bsop.output == None:
00153                     self.errorerror = (0x200, 'Couldnt find referenced message: %s' % mname)
00154             # Find an optional fault message:
00155             ftag = op.getElementsByTagName('fault')
00156             if ftag != []:
00157                 mname = ftag[0].getAttribute('message')
00158                 for msg in bsdef.messages:
00159                     if msg.name == mname:
00160                         bsop.fault = msg
00161                 if bsop.fault == None:
00162                     self.errorerror = (0x200, 'Couldnt find referenced message: %s' % mname)
00163                         
00164             bspt.operations.append(bsop)
00165     
00166     def AddServices(self, dom, bsdef):
00167         """Add the services to the bs_definition structure.
00168         
00169         Args:
00170         dom -- DOM structure of the definitions.
00171         bsdef -- bs_definition class to add them to.
00172         """
00173         services = dom.getElementsByTagName('service')
00174         for svc in services:
00175             bssvc = bs_service(svc.getAttribute('name'))
00176             self.AddPortsAddPorts(svc, bssvc, bsdef)
00177             bsdef.services.append(bssvc)
00178     
00179     def AddPorts(self, svc, bssvc, bsdef):
00180         """Add the ports to the service, by using a partially
00181         completed/parsed bs_definition class as a reference.
00182         
00183         Args:
00184         svc -- Part of the DOM used for searching the services.
00185         bssvc -- bs_service class to add the ports to.
00186         bsdef -- bs_definition class to search for port types.
00187         """
00188         ports = svc.getElementsByTagName('port')
00189         for port in ports:
00190             pname = port.getAttribute('name')
00191             tname = port.getAttribute('type')
00192             type = None
00193             for t in bsdef.porttypes:
00194                 if t.name == tname:
00195                     type = t
00196                     break
00197             if type == None:
00198                 self.errorerror(0x200, 'Couldnt find specified porttype: %s' % tname)
00199             else:
00200                 bssvc.ports.append(bs_port(pname, type))
00201     
00202     def ParseResponse(self, dom):
00203         uuid = dom.documentElement.getAttribute('uuid')
00204         resp = bs_service_response(None, None, None, uuid)
00205         
00206         self.AddUsedAddUsed(dom, resp)
00207         
00208         dom.unlink()
00209         if self.errorerror != None:
00210             return None
00211         else:
00212             self.errorerror = None
00213             return resp
00214     
00215     def AddUsed(self, dom, resp):
00216         used = dom.getElementsByTagName('used')[0]
00217         resp.service = used.getAttribute('service')
00218         resp.port = used.getAttribute('port')
00219         resp.operation = used.getAttribute('operation')
00220         
00221         output = dom.getElementsByTagName('output')
00222         if len(output) == 1:
00223             resp.output = self.AddMessageInstanceAddMessageInstance(dom, output[0],
00224                                                   'output')
00225         
00226         fault = dom.getElementsByTagName('fault')
00227         if len(fault) == 1:
00228             resp.fault = self.AddMessageInstanceAddMessageInstance(dom, fault[0],
00229                                                  'fault')
00230         
00231     def AddMessageInstance(self, dom, message, direction):
00232         name = message.getAttribute('message')
00233         msg = bs_message_instance(name, direction)
00234         
00235         parts = dom.getElementsByTagName('part')
00236         for part in parts:
00237             name = part.getAttribute('name')
00238             type = bs_data_type(part.getAttribute('type'))
00239             rawdata = ''
00240             if hasattr(part.firstChild, 'data'):
00241                 rawdata = part.firstChild.data
00242                 if not type.isBuiltin():
00243                     rawdata = base64.b64decode(rawdata)
00244             msg.parts.append(bs_part_instance(name, type, rawdata))
00245             
00246         return msg
00247             

Generated on Tue Jul 17 09:50:53 2007 for Bio-SPHERE by  doxygen 1.5.1