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
19 from PLC.API import PLCAPI
20 from PLC.Method import *
21 from PLC.Auth import Auth
22 from PLC.Parameter import Parameter, Mixed, python_type, xmlrpc_type
35 def param_type(param):
36 if isinstance(param, Mixed) and len(param):
37 subtypes = [param_type(subparam) for subparam in param]
38 return " or ".join(subtypes)
39 elif isinstance(param, (list, tuple, set)) and len(param):
40 return "array of " + " or ".join([param_type(subparam) for subparam in param])
42 return xmlrpc_type(python_type(param))
45 def add_wsdl_ports_and_bindings (wsdl):
46 api.all_methods.sort()
47 for method in api.all_methods:
48 # Skip system. methods
49 if "system." in method:
52 function = api.callable(method)
54 # Commented documentation
55 #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
56 #print "\n".join(lines)
60 in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
61 in_el.setAttribute("name", function.name + "_in")
65 if (function.accepts):
66 (min_args, max_args, defaults) = function.args()
67 for (argname,argtype) in zip(max_args,function.accepts):
68 arg_part = in_el.appendChild(wsdl.createElement("wsdl:part"))
69 arg_part.setAttribute("name", argname)
70 arg_part.setAttribute("type", param_type(argtype))
73 return_type = function.returns
74 out_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
75 out_el.setAttribute("name", function.name + "_out")
76 ret_part = out_el.appendChild(wsdl.createElement("wsdl:part"))
77 ret_part.setAttribute("name", "returnvalue")
78 ret_part.setAttribute("type", param_type(return_type))
80 # Port connecting arguments with return type
82 port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
83 port_el.setAttribute("name", function.name + "_port")
85 op_el = port_el.appendChild(wsdl.createElement("wsdl:operation"))
86 op_el.setAttribute("name", function.name)
87 op_el.appendChild(wsdl.createElement("wsdl:input")).setAttribute("message","tns:" + function.name + "_in")
88 op_el.appendChild(wsdl.createElement("wsdl:output")).setAttribute("message","tns:" + function.name + "_out")
92 bind_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:binding"))
93 bind_el.setAttribute("name", function.name + "_binding")
94 bind_el.setAttribute("type", "tns:" + function.name + "_port")
96 soap_bind = bind_el.appendChild(wsdl.createElement("soap:binding"))
97 soap_bind.setAttribute("style", "rpc")
98 soap_bind.setAttribute("transport","http://schemas.xmlsoap.org/soap/http")
101 wsdl_op = bind_el.appendChild(wsdl.createElement("wsdl:operation"))
102 wsdl_op.setAttribute("name", function.name)
103 wsdl_op.appendChild(wsdl.createElement("soap:operation")).setAttribute("soapAction",
104 "urn:" + function.name)
107 wsdl_input = wsdl_op.appendChild(wsdl.createElement("wsdl:input"))
108 input_soap_body = wsdl_input.appendChild(wsdl.createElement("soap:body"))
109 input_soap_body.setAttribute("use", "encoded")
110 input_soap_body.setAttribute("namespace", "urn:" + function.name)
111 input_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
114 wsdl_output = wsdl_op.appendChild(wsdl.createElement("wsdl:output"))
115 output_soap_body = wsdl_output.appendChild(wsdl.createElement("soap:body"))
116 output_soap_body.setAttribute("use", "encoded")
117 output_soap_body.setAttribute("namespace", "urn:" + function.name)
118 output_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
121 def add_wsdl_service(wsdl):
122 service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
123 service_el.setAttribute("name", "plc_api_service")
125 for method in api.all_methods:
126 name=api.callable(method).name
127 servport_el = service_el.appendChild(wsdl.createElement("wsdl:port"))
128 servport_el.setAttribute("name", name + "_port")
129 servport_el.setAttribute("binding", "tns:" + name + "_binding")
131 soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
132 soapaddress.setAttribute("location", "%s" % globals.plc_ns)
135 def get_wsdl_definitions():
136 wsdl_text_header = """
138 name="auto_generated"
140 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
142 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
143 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>""" % (globals.plc_ns,globals.plc_ns)
145 wsdl = xml.dom.minidom.parseString(wsdl_text_header)
150 wsdl = get_wsdl_definitions()
151 add_wsdl_ports_and_bindings(wsdl)
152 add_wsdl_service(wsdl)
155 xml.dom.ext.PrettyPrint(wsdl)