3 # Sapan Bhatia <sapanb@cs.princeton.edu>
5 # Generates a WSDL for plcapi
7 # - Invalid for the following reasons
8 # - The types are python types, not WSDL types
9 # - I'm not sure of what to do with the auth structure
14 import xml.dom.minidom
18 from PLC.API import PLCAPI
19 from PLC.Method import *
20 from PLC.Auth import Auth
21 from PLC.Parameter import Parameter, Mixed, python_type, xmlrpc_type
28 def param_type(param):
29 if isinstance(param, Mixed) and len(param):
30 subtypes = [param_type(subparam) for subparam in param]
31 return " or ".join(subtypes)
32 elif isinstance(param, (list, tuple, set)) and len(param):
33 return "array of " + " or ".join([param_type(subparam) for subparam in param])
35 return xmlrpc_type(python_type(param))
38 def add_wsdl_ports_and_bindings (wsdl):
39 api.all_methods.sort()
40 for method in api.all_methods:
41 # Skip system. methods
42 if "system." in method:
45 function = api.callable(method)
47 # Commented documentation
48 #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
49 #print "\n".join(lines)
53 in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
54 in_el.setAttribute("name", function.name + "_in")
58 if (function.accepts):
59 (min_args, max_args, defaults) = function.args()
60 for (argname,argtype) in zip(max_args,function.accepts):
61 arg_part = in_el.appendChild(wsdl.createElement("wsdl:part"))
62 arg_part.setAttribute("name", argname)
63 arg_part.setAttribute("type", param_type(argtype))
66 return_type = function.returns
67 out_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
68 out_el.setAttribute("name", function.name + "_out")
69 ret_part = out_el.appendChild(wsdl.createElement("wsdl:part"))
70 ret_part.setAttribute("name", "returnvalue")
71 ret_part.setAttribute("type", param_type(return_type))
73 # Port connecting arguments with return type
75 port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
76 port_el.setAttribute("name", function.name + "_port")
78 op_el = port_el.appendChild(wsdl.createElement("wsdl:operation"))
79 op_el.setAttribute("name", function.name)
80 op_el.appendChild(wsdl.createElement("wsdl:input")).setAttribute("message","tns:" + function.name + "_in")
81 op_el.appendChild(wsdl.createElement("wsdl:output")).setAttribute("message","tns:" + function.name + "_out")
85 bind_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:binding"))
86 bind_el.setAttribute("name", function.name + "_binding")
87 bind_el.setAttribute("type", "tns:" + function.name + "_port")
89 soap_bind = bind_el.appendChild(wsdl.createElement("soap:binding"))
90 soap_bind.setAttribute("style", "rpc")
91 soap_bind.setAttribute("transport","http://schemas.xmlsoap.org/soap/http")
94 wsdl_op = bind_el.appendChild(wsdl.createElement("wsdl:operation"))
95 wsdl_op.setAttribute("name", function.name)
96 wsdl_op.appendChild(wsdl.createElement("soap:operation")).setAttribute("soapAction",
97 "urn:" + function.name)
100 wsdl_input = wsdl_op.appendChild(wsdl.createElement("wsdl:input"))
101 input_soap_body = wsdl_input.appendChild(wsdl.createElement("soap:body"))
102 input_soap_body.setAttribute("use", "encoded")
103 input_soap_body.setAttribute("namespace", "urn:" + function.name)
104 input_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
107 wsdl_output = wsdl_op.appendChild(wsdl.createElement("wsdl:output"))
108 output_soap_body = wsdl_output.appendChild(wsdl.createElement("soap:body"))
109 output_soap_body.setAttribute("use", "encoded")
110 output_soap_body.setAttribute("namespace", "urn:" + function.name)
111 output_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
114 def add_wsdl_service(wsdl):
115 service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
116 service_el.setAttribute("name", "plc_api_service")
118 for method in api.all_methods:
119 name=api.callable(method).name
120 servport_el = service_el.appendChild(wsdl.createElement("wsdl:port"))
121 servport_el.setAttribute("name", name + "_port")
122 servport_el.setAttribute("binding", "tns:" + name + "_binding")
124 soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
125 soapaddress.setAttribute("location", "%s" % globals.plc_ns)
128 def get_wsdl_definitions():
129 wsdl_text_header = """
131 name="auto_generated"
133 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
135 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
136 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>""" % (globals.plc_ns,globals.plc_ns)
138 wsdl = xml.dom.minidom.parseString(wsdl_text_header)
143 wsdl = get_wsdl_definitions()
144 add_wsdl_ports_and_bindings(wsdl)
145 add_wsdl_service(wsdl)
148 print wsdl.toprettyxml()