Setting tag plcapi-5.4-2
[plcapi.git] / wsdl / api2wsdl.py
1 #!/usr/bin/python
2 #
3 # Sapan Bhatia <sapanb@cs.princeton.edu>
4 #
5 # Generates a WSDL for plcapi
6 # Current limitations:
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 
10
11 import os, sys
12 import time
13 import pdb
14 import xml.dom.minidom
15 import inspect
16 import globals
17
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
22
23
24 api = PLCAPI(None)
25
26 # Class functions
27
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])
34     else:
35         return xmlrpc_type(python_type(param))
36
37
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:
43             continue
44
45         function = api.callable(method)
46
47         # Commented documentation
48         #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
49         #print "\n".join(lines)
50         #print
51
52         
53         in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
54         in_el.setAttribute("name", function.name + "_in")
55
56         # Arguments
57
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))
64                 
65         # Return type            
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))
72
73         # Port connecting arguments with return type
74
75         port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
76         port_el.setAttribute("name", function.name + "_port")
77         
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")
82
83         # Bindings
84
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")
88         
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")
92
93         
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)
98
99         
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/")
105
106         
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/")
112         
113
114 def add_wsdl_service(wsdl):
115     service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
116     service_el.setAttribute("name", "plc_api_service")
117
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")
123
124     soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
125     soapaddress.setAttribute("location", "%s" % globals.plc_ns)
126
127
128 def get_wsdl_definitions():
129     wsdl_text_header = """
130         <wsdl:definitions
131         name="auto_generated"
132         targetNamespace="%s"
133         xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
134         xmlns:tns="xmlns:%s"
135         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
136         xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>""" % (globals.plc_ns,globals.plc_ns)
137         
138     wsdl = xml.dom.minidom.parseString(wsdl_text_header)
139
140     return wsdl
141     
142
143 wsdl = get_wsdl_definitions()
144 add_wsdl_ports_and_bindings(wsdl)
145 add_wsdl_service(wsdl)
146
147
148 print wsdl.toprettyxml()
149