Welcome to the "trac"-ing site of soap4r!
[soap4r] [httpclient] [openpgp4u] [pkcs1] [logger] [csv] [vtr]

root/trunk/lib/soap/rpc/driver.rb

Revision 2000, 6.0 kB (checked in by nahi, 1 year ago)
  • removed backward compatibility definitions for soap4r-1.4.X. closes #445.
    • removed SOAPlet#{app_scope_router,add_servant} -> use methods in HTTPServer instead.
    • removed SOAP::WSDLDriver#generateEncodeType -> use SOAP::WSDLDriver#generate_explicit_type
    • removed SOAP::SOAPGenerator -> use SOAP::Generator instead.
    • removed compatibility method definitions for ruby-1.6.X.
  • rpc/encoded service + detail element without xsi:type attribute caused NameError? since 1.5.6. (#435)
  • extract attr_proxy definition. added soap/attrproxy.rb and wsdl/xmlSchema/ref.rb.
  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 # SOAP4R - SOAP RPC driver
2 # Copyright (C) 2000-2007  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
3
4 # This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
5 # redistribute it and/or modify it under the same terms of Ruby's license;
6 # either the dual license version in 2003, or any later version.
7
8
9 require 'soap/soap'
10 require 'soap/attrproxy'
11 require 'soap/mapping'
12 require 'soap/rpc/rpc'
13 require 'soap/rpc/proxy'
14 require 'soap/rpc/element'
15 require 'soap/streamHandler'
16 require 'soap/property'
17 require 'soap/header/handlerset'
18
19
20 module SOAP
21 module RPC
22
23
24 class Driver
25   include AttrProxy
26
27   attr_proxy :endpoint_url, true
28   attr_proxy :mapping_registry, true
29   attr_proxy :literal_mapping_registry, true
30   attr_proxy :allow_unqualified_element, true
31   attr_proxy :default_encodingstyle, true
32   attr_proxy :generate_explicit_type, true
33   attr_proxy :use_default_namespace, true
34   attr_proxy :return_response_as_xml, true
35   attr_proxy :headerhandler
36   attr_proxy :filterchain
37   attr_proxy :streamhandler
38   attr_proxy :test_loopback_response
39   attr_proxy :reset_stream
40
41   attr_reader :proxy
42   attr_reader :options
43   attr_accessor :soapaction
44
45   def inspect
46     "#<#{self.class}:#{@proxy.inspect}>"
47   end
48
49   def httpproxy
50     options["protocol.http.proxy"]
51   end
52
53   def httpproxy=(httpproxy)
54     options["protocol.http.proxy"] = httpproxy
55   end
56
57   def wiredump_dev
58     options["protocol.http.wiredump_dev"]
59   end
60
61   def wiredump_dev=(wiredump_dev)
62     options["protocol.http.wiredump_dev"] = wiredump_dev
63   end
64
65   def mandatorycharset
66     options["protocol.mandatorycharset"]
67   end
68
69   def mandatorycharset=(mandatorycharset)
70     options["protocol.mandatorycharset"] = mandatorycharset
71   end
72
73   def wiredump_file_base
74     options["protocol.wiredump_file_base"]
75   end
76
77   def wiredump_file_base=(wiredump_file_base)
78     options["protocol.wiredump_file_base"] = wiredump_file_base
79   end
80
81   def initialize(endpoint_url, namespace = nil, soapaction = nil)
82     @namespace = namespace
83     @soapaction = soapaction
84     @options = setup_options
85     @wiredump_file_base = nil
86     @proxy = Proxy.new(endpoint_url, @soapaction, @options)
87   end
88
89   def loadproperty(propertyname)
90     unless options.loadproperty(propertyname)
91       raise LoadError.new("No such property to load -- #{propertyname}")
92     end
93   end
94
95   def add_rpc_method(name, *params)
96     add_rpc_method_with_soapaction_as(name, name, @soapaction, *params)
97   end
98
99   def add_rpc_method_as(name, name_as, *params)
100     add_rpc_method_with_soapaction_as(name, name_as, @soapaction, *params)
101   end
102
103   def add_rpc_method_with_soapaction(name, soapaction, *params)
104     add_rpc_method_with_soapaction_as(name, name, soapaction, *params)
105   end
106
107   def add_rpc_method_with_soapaction_as(name, name_as, soapaction, *params)
108     param_def = SOAPMethod.create_rpc_param_def(params)
109     qname = XSD::QName.new(@namespace, name_as)
110     @proxy.add_rpc_method(qname, soapaction, name, param_def)
111     add_rpc_method_interface(name, param_def)
112   end
113
114   # add_method is for shortcut of typical rpc/encoded method definition.
115   alias add_method add_rpc_method
116   alias add_method_as add_rpc_method_as
117   alias add_method_with_soapaction add_rpc_method_with_soapaction
118   alias add_method_with_soapaction_as add_rpc_method_with_soapaction_as
119
120   def add_document_method(name, soapaction, req_qname, res_qname)
121     param_def = SOAPMethod.create_doc_param_def(req_qname, res_qname)
122     @proxy.add_document_method(soapaction, name, param_def)
123     add_document_method_interface(name, param_def)
124   end
125
126   def add_rpc_operation(qname, soapaction, name, param_def, opt = {})
127     @proxy.add_rpc_operation(qname, soapaction, name, param_def, opt)
128     add_rpc_method_interface(name, param_def)
129   end
130
131   def add_document_operation(soapaction, name, param_def, opt = {})
132     @proxy.add_document_operation(soapaction, name, param_def, opt)
133     add_document_method_interface(name, param_def)
134   end
135
136   def invoke(headers, body)
137     if headers and !headers.is_a?(SOAPHeader)
138       headers = create_header(headers)
139     end
140     set_wiredump_file_base(body.elename.name)
141     env = @proxy.invoke(headers, body)
142     if env.nil?
143       return nil, nil
144     else
145       return env.header, env.body
146     end
147   end
148
149   def call(name, *params)
150     set_wiredump_file_base(name)
151     @proxy.call(name, *params)
152   end
153
154 private
155
156   def attrproxy
157     @proxy
158   end
159
160   def set_wiredump_file_base(name)
161     if @wiredump_file_base
162       @proxy.set_wiredump_file_base("#{@wiredump_file_base}_#{name}")
163     end
164   end
165
166   def create_header(headers)
167     header = SOAPHeader.new()
168     headers.each do |content, mustunderstand, encodingstyle|
169       header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))
170     end
171     header
172   end
173
174   def setup_options
175     if opt = Property.loadproperty(::SOAP::PropertyName)
176       opt = opt["client"]
177     end
178     opt ||= Property.new
179     opt.add_hook("protocol.mandatorycharset") do |key, value|
180       @proxy.mandatorycharset = value
181     end
182     opt.add_hook("protocol.wiredump_file_base") do |key, value|
183       @wiredump_file_base = value
184     end
185     opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label
186     opt["protocol.http.proxy"] ||= Env::HTTP_PROXY
187     opt["protocol.http.no_proxy"] ||= Env::NO_PROXY
188     opt
189   end
190
191   def add_rpc_method_interface(name, param_def)
192     param_count = RPC::SOAPMethod.param_count(param_def,
193       RPC::SOAPMethod::IN, RPC::SOAPMethod::INOUT)
194     add_method_interface(name, param_count)
195   end
196
197   def add_document_method_interface(name, param_def)
198     param_count = RPC::SOAPMethod.param_count(param_def, RPC::SOAPMethod::IN)
199     add_method_interface(name, param_count)
200   end
201
202   # Mapping.define_singleton_method calls define_method with proc and it
203   # exhausts much memory for each singleton Object.  just instance_eval instead
204   # of it.
205   def add_method_interface(name, param_count)
206     instance_eval <<-EOS
207       def #{name}(*arg)
208         unless arg.size == #{param_count}
209           raise ArgumentError.new(
210             "wrong number of arguments (\#{arg.size} for #{param_count})")
211         end
212         call(#{name.dump}, *arg)
213       end
214     EOS
215     self.method(name)
216   end
217 end
218
219
220 end
221 end
Note: See TracBrowser for help on using the browser.