/tools/Ruby/lib/ruby/1.8/soap/rpc/element.rb

http://github.com/agross/netopenspace · Ruby · 325 lines · 258 code · 54 blank · 13 comment · 19 complexity · 948bcc18805d376391c324bceedff0ed MD5 · raw file

  1. # SOAP4R - RPC element definition.
  2. # Copyright (C) 2000, 2001, 2003, 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
  3. # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
  4. # redistribute it and/or modify it under the same terms of Ruby's license;
  5. # either the dual license version in 2003, or any later version.
  6. require 'soap/baseData'
  7. module SOAP
  8. # Add method definitions for RPC to common definition in element.rb
  9. class SOAPBody < SOAPStruct
  10. public
  11. def request
  12. root_node
  13. end
  14. def response
  15. root = root_node
  16. if !@is_fault
  17. if root.nil?
  18. nil
  19. elsif root.is_a?(SOAPBasetype)
  20. root
  21. else
  22. # Initial element is [retval].
  23. root[0]
  24. end
  25. else
  26. root
  27. end
  28. end
  29. def outparams
  30. root = root_node
  31. if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)
  32. op = root[1..-1]
  33. op = nil if op && op.empty?
  34. op
  35. else
  36. nil
  37. end
  38. end
  39. def fault
  40. if @is_fault
  41. self['fault']
  42. else
  43. nil
  44. end
  45. end
  46. def fault=(fault)
  47. @is_fault = true
  48. add_member('fault', fault)
  49. end
  50. end
  51. module RPC
  52. class RPCError < Error; end
  53. class MethodDefinitionError < RPCError; end
  54. class ParameterError < RPCError; end
  55. class SOAPMethod < SOAPStruct
  56. RETVAL = 'retval'
  57. IN = 'in'
  58. OUT = 'out'
  59. INOUT = 'inout'
  60. attr_reader :param_def
  61. attr_reader :inparam
  62. attr_reader :outparam
  63. attr_reader :retval_name
  64. attr_reader :retval_class_name
  65. def initialize(qname, param_def = nil)
  66. super(nil)
  67. @elename = qname
  68. @encodingstyle = nil
  69. @param_def = param_def
  70. @signature = []
  71. @inparam_names = []
  72. @inoutparam_names = []
  73. @outparam_names = []
  74. @inparam = {}
  75. @outparam = {}
  76. @retval_name = nil
  77. @retval_class_name = nil
  78. init_param(@param_def) if @param_def
  79. end
  80. def have_outparam?
  81. @outparam_names.size > 0
  82. end
  83. def input_params
  84. collect_params(IN, INOUT)
  85. end
  86. def output_params
  87. collect_params(OUT, INOUT)
  88. end
  89. def set_param(params)
  90. params.each do |param, data|
  91. @inparam[param] = data
  92. data.elename.name = param
  93. data.parent = self
  94. end
  95. end
  96. def set_outparam(params)
  97. params.each do |param, data|
  98. @outparam[param] = data
  99. data.elename.name = param
  100. end
  101. end
  102. def SOAPMethod.param_count(param_def, *type)
  103. count = 0
  104. param_def.each do |io_type, name, param_type|
  105. if type.include?(io_type)
  106. count += 1
  107. end
  108. end
  109. count
  110. end
  111. def SOAPMethod.derive_rpc_param_def(obj, name, *param)
  112. if param.size == 1 and param[0].is_a?(Array)
  113. return param[0]
  114. end
  115. if param.empty?
  116. method = obj.method(name)
  117. param_names = (1..method.arity.abs).collect { |i| "p#{i}" }
  118. else
  119. param_names = param
  120. end
  121. create_rpc_param_def(param_names)
  122. end
  123. def SOAPMethod.create_rpc_param_def(param_names)
  124. param_def = []
  125. param_names.each do |param_name|
  126. param_def.push([IN, param_name, nil])
  127. end
  128. param_def.push([RETVAL, 'return', nil])
  129. param_def
  130. end
  131. def SOAPMethod.create_doc_param_def(req_qnames, res_qnames)
  132. req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName)
  133. res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName)
  134. param_def = []
  135. req_qnames.each do |qname|
  136. param_def << [IN, qname.name, [nil, qname.namespace, qname.name]]
  137. end
  138. res_qnames.each do |qname|
  139. param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]]
  140. end
  141. param_def
  142. end
  143. private
  144. def collect_params(*type)
  145. names = []
  146. @signature.each do |io_type, name, param_type|
  147. names << name if type.include?(io_type)
  148. end
  149. names
  150. end
  151. def init_param(param_def)
  152. param_def.each do |io_type, name, param_type|
  153. case io_type
  154. when IN
  155. @signature.push([IN, name, param_type])
  156. @inparam_names.push(name)
  157. when OUT
  158. @signature.push([OUT, name, param_type])
  159. @outparam_names.push(name)
  160. when INOUT
  161. @signature.push([INOUT, name, param_type])
  162. @inoutparam_names.push(name)
  163. when RETVAL
  164. if @retval_name
  165. raise MethodDefinitionError.new('duplicated retval')
  166. end
  167. @retval_name = name
  168. @retval_class_name = nil
  169. if param_type
  170. if param_type[0].is_a?(String)
  171. @retval_class_name = Mapping.class_from_name(param_type[0])
  172. else
  173. @retval_class_name = param_type[0]
  174. end
  175. end
  176. else
  177. raise MethodDefinitionError.new("unknown type: #{io_type}")
  178. end
  179. end
  180. end
  181. end
  182. class SOAPMethodRequest < SOAPMethod
  183. attr_accessor :soapaction
  184. def SOAPMethodRequest.create_request(qname, *params)
  185. param_def = []
  186. param_value = []
  187. i = 0
  188. params.each do |param|
  189. param_name = "p#{i}"
  190. i += 1
  191. param_def << [IN, param_name, nil]
  192. param_value << [param_name, param]
  193. end
  194. param_def << [RETVAL, 'return', nil]
  195. o = new(qname, param_def)
  196. o.set_param(param_value)
  197. o
  198. end
  199. def initialize(qname, param_def = nil, soapaction = nil)
  200. check_elename(qname)
  201. super(qname, param_def)
  202. @soapaction = soapaction
  203. end
  204. def each
  205. input_params.each do |name|
  206. unless @inparam[name]
  207. raise ParameterError.new("parameter: #{name} was not given")
  208. end
  209. yield(name, @inparam[name])
  210. end
  211. end
  212. def dup
  213. req = self.class.new(@elename.dup, @param_def, @soapaction)
  214. req.encodingstyle = @encodingstyle
  215. req
  216. end
  217. def create_method_response(response_name = nil)
  218. response_name ||=
  219. XSD::QName.new(@elename.namespace, @elename.name + 'Response')
  220. SOAPMethodResponse.new(response_name, @param_def)
  221. end
  222. private
  223. def check_elename(qname)
  224. # NCName & ruby's method name
  225. unless /\A[\w_][\w\d_\-]*\z/ =~ qname.name
  226. raise MethodDefinitionError.new("element name '#{qname.name}' not allowed")
  227. end
  228. end
  229. end
  230. class SOAPMethodResponse < SOAPMethod
  231. def initialize(qname, param_def = nil)
  232. super(qname, param_def)
  233. @retval = nil
  234. end
  235. def retval=(retval)
  236. @retval = retval
  237. @retval.elename = @retval.elename.dup_name(@retval_name || 'return')
  238. retval.parent = self
  239. retval
  240. end
  241. def each
  242. if @retval_name and !@retval.is_a?(SOAPVoid)
  243. yield(@retval_name, @retval)
  244. end
  245. output_params.each do |name|
  246. unless @outparam[name]
  247. raise ParameterError.new("parameter: #{name} was not given")
  248. end
  249. yield(name, @outparam[name])
  250. end
  251. end
  252. end
  253. # To return(?) void explicitly.
  254. # def foo(input_var)
  255. # ...
  256. # return SOAP::RPC::SOAPVoid.new
  257. # end
  258. class SOAPVoid < XSD::XSDAnySimpleType
  259. include SOAPBasetype
  260. extend SOAPModuleUtils
  261. Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil)
  262. public
  263. def initialize()
  264. @elename = Name
  265. @id = nil
  266. @precedents = []
  267. @parent = nil
  268. end
  269. end
  270. end
  271. end