3 # Sapan Bhatia <sapanb@cs.princeton.edu>
5 # Generates a WSDL for geniwrapper
7 # - Invalid for the following reasons
8 # - The types are python types, not WSDL types
13 import xml.dom.minidom
19 from geni.util.auth import Auth
20 from geni.util.parameter import Parameter,Mixed
27 class SoapError(Exception):
28 def __init__(self, value):
31 return repr(self.value)
39 def name_vector_type(acc,arg):
41 name = name_complex_type(arg)
42 complex_types[arg]=name
46 python_is_f_braindead = name_complex_type(acc)
47 acc = [python_is_f_braindead,name]
50 def name_complex_type(arg):
53 types_section = types.firstChild.firstChild
54 if (isinstance(arg, Mixed)):
55 inner_types = reduce(name_vector_type, arg)
56 if (inner_types[-1]=="None"):
57 inner_types=inner_types[:-1]
63 type_name = "Type%d"%num_types
64 complex_type = types_section.appendChild(types.createElement("wsdl:complexType"))
65 complex_type.setAttribute("name", type_name)
67 choice = complex_type.appendChild(types.createElement("xsd:choice"))
69 element = choice.appendChild(types.createElement("element"))
70 element.setAttribute("name", "Foobar")
71 element.setAttribute("type", "tns:%s"%i)
72 element.setAttribute("minOccurs","%d"%min_args)
74 elif (isinstance(arg, Parameter)):
75 return (name_simple_type(arg.type))
76 elif type(arg) == ListType or type(arg) == TupleType:
78 elif type(arg) == DictType or arg == DictType:
81 return (name_simple_type(arg))
83 def name_simple_type(arg_type):
86 if arg_type == DictType:
88 elif arg_type == IntType or arg_type == LongType:
90 elif arg_type == bool:
92 elif arg_type == FloatType:
94 elif arg_type in StringTypes:
98 raise SoapError, "Cannot handle %s objects" % arg_type
101 return (name_complex_type(arg))
103 def add_wsdl_ports_and_bindings (wsdl):
104 for method in apistub.methods:
105 # Skip system. methods
106 if "system." in method:
109 function = apistub.callable(method) # Commented documentation
110 #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
111 #print "\n".join(lines)
115 in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
116 in_el.setAttribute("name", method + "_in")
118 for service_name in function.interfaces:
119 if (services.has_key(service_name)):
120 if (not method in services[service_name]):
121 services[service_name].append(method)
123 services[service_name]=[method]
127 if (function.accepts):
128 (min_args, max_args, defaults) = function.args()
129 for (argname,argtype) in zip(max_args,function.accepts):
130 arg_part = in_el.appendChild(wsdl.createElement("wsdl:part"))
131 arg_part.setAttribute("name", argname)
132 arg_part.setAttribute("type", param_type(argtype))
135 return_type = function.returns
136 out_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
137 out_el.setAttribute("name", method + "_out")
138 ret_part = out_el.appendChild(wsdl.createElement("wsdl:part"))
139 ret_part.setAttribute("name", "returnvalue")
140 ret_part.setAttribute("type", param_type(return_type))
142 # Port connecting arguments with return type
144 port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
145 port_el.setAttribute("name", method + "_port")
147 op_el = port_el.appendChild(wsdl.createElement("wsdl:operation"))
148 op_el.setAttribute("name", method)
149 op_el.appendChild(wsdl.createElement("wsdl:input")).setAttribute("message","tns:" + method + "_in")
150 op_el.appendChild(wsdl.createElement("wsdl:output")).setAttribute("message","tns:" + method + "_out")
154 bind_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:binding"))
155 bind_el.setAttribute("name", method + "_binding")
156 bind_el.setAttribute("type", "tns:" + method + "_port")
158 soap_bind = bind_el.appendChild(wsdl.createElement("soap:binding"))
159 soap_bind.setAttribute("style", "rpc")
160 soap_bind.setAttribute("transport","http://schemas.xmlsoap.org/soap/http")
163 wsdl_op = bind_el.appendChild(wsdl.createElement("wsdl:operation"))
164 wsdl_op.setAttribute("name", method)
165 wsdl_op.appendChild(wsdl.createElement("soap:operation")).setAttribute("soapAction",
169 wsdl_input = wsdl_op.appendChild(wsdl.createElement("wsdl:input"))
170 input_soap_body = wsdl_input.appendChild(wsdl.createElement("soap:body"))
171 input_soap_body.setAttribute("use", "encoded")
172 input_soap_body.setAttribute("namespace", "urn:" + method)
173 input_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
176 wsdl_output = wsdl_op.appendChild(wsdl.createElement("wsdl:output"))
177 output_soap_body = wsdl_output.appendChild(wsdl.createElement("soap:body"))
178 output_soap_body.setAttribute("use", "encoded")
179 output_soap_body.setAttribute("namespace", "urn:" + method)
180 output_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
183 def add_wsdl_service(wsdl):
184 for service in services.keys():
185 service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
186 service_el.setAttribute("name", service)
188 for method in services[service]:
190 servport_el = service_el.appendChild(wsdl.createElement("wsdl:port"))
191 servport_el.setAttribute("name", name + "_port")
192 servport_el.setAttribute("binding", "tns:" + name + "_binding")
194 soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
195 soapaddress.setAttribute("location", "%s/%s" % (globals.plc_ns,service))
198 def get_wsdl_definitions():
199 wsdl_text_header = """
201 name="auto_generated"
203 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
205 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
206 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
207 """ % (globals.plc_ns,globals.plc_ns)
209 wsdl = xml.dom.minidom.parseString(wsdl_text_header)
214 types = get_wsdl_definitions()
215 types.firstChild.appendChild(types.createElement("wsdl:types"))
216 wsdl = get_wsdl_definitions()
217 add_wsdl_ports_and_bindings(wsdl)
218 wsdl_types = wsdl.importNode(types.firstChild.firstChild, True)
219 wsdl.firstChild.appendChild(wsdl_types)
220 add_wsdl_service(wsdl)
222 xml.dom.ext.PrettyPrint(wsdl)