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
34 def param_type(param):
35 if isinstance(param, Mixed) and len(param):
36 subtypes = [param_type(subparam) for subparam in param]
37 return " or ".join(subtypes)
38 elif isinstance(param, (list, tuple, set)) and len(param):
39 return "array of " + " or ".join([param_type(subparam) for subparam in param])
41 return xmlrpc_type(python_type(param))
44 def add_wsdl_ports_and_bindings (wsdl):
45 api.all_methods.sort()
46 for method in api.all_methods:
47 # Skip system. methods
48 if "system." in method:
51 function = api.callable(method)
53 # Commented documentation
54 #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
55 #print "\n".join(lines)
59 in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
60 in_el.setAttribute("name", function.name + "_in")
64 if (function.accepts):
65 (min_args, max_args, defaults) = function.args()
66 for (argname,argtype) in zip(max_args,function.accepts):
67 arg_part = in_el.appendChild(wsdl.createElement("wsdl:part"))
68 arg_part.setAttribute("name", argname)
69 arg_part.setAttribute("type", param_type(argtype))
72 return_type = function.returns
73 out_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
74 out_el.setAttribute("name", function.name + "_out")
75 ret_part = out_el.appendChild(wsdl.createElement("wsdl:part"))
76 ret_part.setAttribute("name", "returnvalue")
77 ret_part.setAttribute("type", param_type(return_type))
79 # Port connecting arguments with return type
81 port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
82 port_el.setAttribute("name", function.name + "_port")
84 op_el = port_el.appendChild(wsdl.createElement("wsdl:operation"))
85 op_el.setAttribute("name", function.name)
86 op_el.appendChild(wsdl.createElement("wsdl:input")).setAttribute("message","tns:" + function.name + "_in")
87 op_el.appendChild(wsdl.createElement("wsdl:output")).setAttribute("message","tns:" + function.name + "_out")
91 bind_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:binding"))
92 bind_el.setAttribute("name", function.name + "_binding")
93 bind_el.setAttribute("type", "tns:" + function.name + "_port")
95 soap_bind = bind_el.appendChild(wsdl.createElement("soap:binding"))
96 soap_bind.setAttribute("style", "rpc")
97 soap_bind.setAttribute("transport","http://schemas.xmlsoap.org/soap/http")
100 wsdl_op = bind_el.appendChild(wsdl.createElement("wsdl:operation"))
101 wsdl_op.setAttribute("name", function.name)
102 wsdl_op.appendChild(wsdl.createElement("soap:operation")).setAttribute("soapAction",
103 "urn:" + function.name)
106 wsdl_input = wsdl_op.appendChild(wsdl.createElement("wsdl:input"))
107 input_soap_body = wsdl_input.appendChild(wsdl.createElement("soap:body"))
108 input_soap_body.setAttribute("use", "encoded")
109 input_soap_body.setAttribute("namespace", "urn:" + function.name)
110 input_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
113 wsdl_output = wsdl_op.appendChild(wsdl.createElement("wsdl:output"))
114 output_soap_body = wsdl_output.appendChild(wsdl.createElement("soap:body"))
115 output_soap_body.setAttribute("use", "encoded")
116 output_soap_body.setAttribute("namespace", "urn:" + function.name)
117 output_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
120 def add_wsdl_service(wsdl):
121 service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
122 service_el.setAttribute("name", "plc_api_service")
124 for method in api.all_methods:
125 name=api.callable(method).name
126 servport_el = service_el.appendChild(wsdl.createElement("wsdl:port"))
127 servport_el.setAttribute("name", name + "_port")
128 servport_el.setAttribute("binding", "tns:" + name + "_binding")
130 soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
131 soapaddress.setAttribute("location", "%s" % globals.plc_ns)
134 def get_wsdl_definitions():
135 wsdl_text_header = """
137 name="auto_generated"
139 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
141 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
142 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>""" % (globals.plc_ns,globals.plc_ns)
144 wsdl = xml.dom.minidom.parseString(wsdl_text_header)
149 wsdl = get_wsdl_definitions()
150 add_wsdl_ports_and_bindings(wsdl)
151 add_wsdl_service(wsdl)
154 print wsdl.toprettyxml()