Class SOAP::RPC::Router
In: lib/soap/rpc/router.rb
Parent: Object

Methods

Included Modules

SOAP

Classes and Modules

Class SOAP::RPC::Router::ApplicationScopeOperation
Class SOAP::RPC::Router::Operation
Class SOAP::RPC::Router::RequestScopeOperation

Attributes

actor  [R] 
external_ces  [RW] 
generate_explicit_type  [RW] 
literal_mapping_registry  [RW] 
mapping_registry  [RW] 

Public Class methods

[Source]

    # File lib/soap/rpc/router.rb, line 33
33:   def initialize(actor)
34:     @actor = actor
35:     @mapping_registry = nil
36:     @headerhandler = Header::HandlerSet.new
37:     @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new
38:     @generate_explicit_type = true
39:     @external_ces = nil
40:     @operation_by_soapaction = {}
41:     @operation_by_qname = {}
42:     @headerhandlerfactory = []
43:   end

Public Instance methods

add_document_method(receiver, soapaction, name, param_def, opt = {})

[Source]

     # File lib/soap/rpc/router.rb, line 119
119:   def add_document_operation(receiver, soapaction, name, param_def, opt = {})
120:     #
121:     # adopt workaround for doc/lit wrapper method
122:     # (you should consider to simply use rpc/lit service)
123:     #
124:     #unless soapaction
125:     #  raise RPCRoutingError.new("soapaction is a must for document method")
126:     #end
127:     ensure_styleuse_option(opt, :document, :literal)
128:     op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
129:       opt)
130:     if opt[:request_style] != :document
131:       raise RPCRoutingError.new("illegal request_style given")
132:     end
133:     assign_operation(soapaction, first_input_part_qname(param_def), op)
134:   end

[Source]

     # File lib/soap/rpc/router.rb, line 137
137:   def add_document_request_operation(factory, soapaction, name, param_def, opt = {})
138:     #
139:     # adopt workaround for doc/lit wrapper method
140:     # (you should consider to simply use rpc/lit service)
141:     #
142:     #unless soapaction
143:     #  raise RPCRoutingError.new("soapaction is a must for document method")
144:     #end
145:     ensure_styleuse_option(opt, :document, :literal)
146:     op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt)
147:     if opt[:request_style] != :document
148:       raise RPCRoutingError.new("illegal request_style given")
149:     end
150:     assign_operation(soapaction, first_input_part_qname(param_def), op)
151:   end

[Source]

    # File lib/soap/rpc/router.rb, line 55
55:   def add_headerhandler(handler)
56:     @headerhandler.add(handler)
57:   end
add_method(receiver, qname, soapaction, name, param_def, opt = {})

Alias for add_rpc_operation

header handler interface

[Source]

    # File lib/soap/rpc/router.rb, line 48
48:   def add_request_headerhandler(factory)
49:     unless factory.respond_to?(:create)
50:       raise TypeError.new("factory must respond to 'create'")
51:     end
52:     @headerhandlerfactory << factory
53:   end
add_rpc_method(receiver, qname, soapaction, name, param_def, opt = {})

Alias for add_rpc_operation

operation definition interface

[Source]

     # File lib/soap/rpc/router.rb, line 96
 96:   def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
 97:     ensure_styleuse_option(opt, :rpc, :encoded)
 98:     opt[:request_qname] = qname
 99:     op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
100:       opt)
101:     if opt[:request_style] != :rpc
102:       raise RPCRoutingError.new("illegal request_style given")
103:     end
104:     assign_operation(soapaction, qname, op)
105:   end

[Source]

     # File lib/soap/rpc/router.rb, line 109
109:   def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})
110:     ensure_styleuse_option(opt, :rpc, :encoded)
111:     opt[:request_qname] = qname
112:     op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt)
113:     if opt[:request_style] != :rpc
114:       raise RPCRoutingError.new("illegal request_style given")
115:     end
116:     assign_operation(soapaction, qname, op)
117:   end

servant definition interface

[Source]

    # File lib/soap/rpc/router.rb, line 62
62:   def add_rpc_request_servant(factory, namespace)
63:     unless factory.respond_to?(:create)
64:       raise TypeError.new("factory must respond to 'create'")
65:     end
66:     obj = factory.create        # a dummy instance for introspection
67:     ::SOAP::RPC.defined_methods(obj).each do |name|
68:       begin
69:         qname = XSD::QName.new(namespace, name)
70:         param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
71:         opt = create_styleuse_option(:rpc, :encoded)
72:         add_rpc_request_operation(factory, qname, nil, name, param_def, opt)
73:       rescue SOAP::RPC::MethodDefinitionError => e
74:         p e if $DEBUG
75:       end
76:     end
77:   end

[Source]

    # File lib/soap/rpc/router.rb, line 79
79:   def add_rpc_servant(obj, namespace)
80:     ::SOAP::RPC.defined_methods(obj).each do |name|
81:       begin
82:         qname = XSD::QName.new(namespace, name)
83:         param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
84:         opt = create_styleuse_option(:rpc, :encoded)
85:         add_rpc_operation(obj, qname, nil, name, param_def, opt)
86:       rescue SOAP::RPC::MethodDefinitionError => e
87:         p e if $DEBUG
88:       end
89:     end
90:   end
add_servant(obj, namespace)

Alias for add_rpc_servant

Create fault response string.

[Source]

     # File lib/soap/rpc/router.rb, line 183
183:   def create_fault_response(e)
184:     env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e)))
185:     opt = {}
186:     opt[:external_content] = nil
187:     response_string = Processor.marshal(env, opt)
188:     conn_data = StreamHandler::ConnectionData.new(response_string)
189:     conn_data.is_fault = true
190:     if ext = opt[:external_content]
191:       mimeize(conn_data, ext)
192:     end
193:     conn_data
194:   end

[Source]

     # File lib/soap/rpc/router.rb, line 153
153:   def route(conn_data)
154:     # we cannot set request_default_encodingsyle before parsing the content.
155:     env = unmarshal(conn_data)
156:     if env.nil?
157:       raise ArgumentError.new("illegal SOAP marshal format")
158:     end
159:     op = lookup_operation(conn_data.soapaction, env.body)
160:     headerhandler = @headerhandler.dup
161:     @headerhandlerfactory.each do |f|
162:       headerhandler.add(f.create)
163:     end
164:     receive_headers(headerhandler, env.header)
165:     soap_response = default_encodingstyle = nil
166:     begin
167:       soap_response =
168:         op.call(env.body, @mapping_registry, @literal_mapping_registry,
169:           create_mapping_opt)
170:       default_encodingstyle = op.response_default_encodingstyle
171:     rescue Exception
172:       soap_response = fault($!)
173:       default_encodingstyle = nil
174:     end
175:     conn_data.is_fault = true if soap_response.is_a?(SOAPFault)
176:     header = call_headers(headerhandler)
177:     body = SOAPBody.new(soap_response)
178:     env = SOAPEnvelope.new(header, body)
179:     marshal(conn_data, env, default_encodingstyle)
180:   end

Private Instance methods

[Source]

     # File lib/soap/rpc/router.rb, line 222
222:   def assign_operation(soapaction, qname, op)
223:     assigned = false
224:     if soapaction and !soapaction.empty?
225:       @operation_by_soapaction[soapaction] = op
226:       assigned = true
227:     end
228:     if qname
229:       @operation_by_qname[qname] = op
230:       assigned = true
231:     end
232:     unless assigned
233:       raise RPCRoutingError.new("cannot assign operation")
234:     end
235:   end

[Source]

     # File lib/soap/rpc/router.rb, line 253
253:   def call_headers(headerhandler)
254:     headers = headerhandler.on_outbound
255:     if headers.empty?
256:       nil
257:     else
258:       h = ::SOAP::SOAPHeader.new
259:       headers.each do |header|
260:         h.add(header.elename.name, header)
261:       end
262:       h
263:     end
264:   end

[Source]

     # File lib/soap/rpc/router.rb, line 330
330:   def create_mapping_opt
331:     { :external_ces => @external_ces }
332:   end

[Source]

     # File lib/soap/rpc/router.rb, line 208
208:   def create_styleuse_option(style, use)
209:     opt = {}
210:     opt[:request_style] = opt[:response_style] = style
211:     opt[:request_use] = opt[:response_use] = use
212:     opt
213:   end

[Source]

     # File lib/soap/rpc/router.rb, line 215
215:   def ensure_styleuse_option(opt, style, use)
216:     opt[:request_style] ||= style
217:     opt[:response_style] ||= style
218:     opt[:request_use] ||= use
219:     opt[:response_use] ||= use
220:   end

Create fault response.

[Source]

     # File lib/soap/rpc/router.rb, line 321
321:   def fault(e)
322:     detail = Mapping::SOAPException.new(e)
323:     SOAPFault.new(
324:       SOAPString.new('Server'),
325:       SOAPString.new(e.to_s),
326:       SOAPString.new(@actor),
327:       Mapping.obj2soap(detail, @mapping_registry))
328:   end

[Source]

     # File lib/soap/rpc/router.rb, line 198
198:   def first_input_part_qname(param_def)
199:     param_def.each do |inout, paramname, typeinfo|
200:       if inout == SOAPMethod::IN
201:         klass, nsdef, namedef = typeinfo
202:         return XSD::QName.new(nsdef, namedef)
203:       end
204:     end
205:     nil
206:   end

[Source]

     # File lib/soap/rpc/router.rb, line 237
237:   def lookup_operation(soapaction, body)
238:     if op = @operation_by_soapaction[soapaction]
239:       return op
240:     end
241:     qname = body.root_node.elename
242:     if op = @operation_by_qname[qname]
243:       return op
244:     end
245:     if soapaction
246:       raise RPCRoutingError.new(
247:         "operation: #{soapaction} #{qname} not supported")
248:     else
249:       raise RPCRoutingError.new("operation: #{qname} not supported")
250:     end
251:   end

[Source]

     # File lib/soap/rpc/router.rb, line 295
295:   def marshal(conn_data, env, default_encodingstyle = nil)
296:     opt = {}
297:     opt[:external_content] = nil
298:     opt[:default_encodingstyle] = default_encodingstyle
299:     opt[:generate_explicit_type] = @generate_explicit_type
300:     response_string = Processor.marshal(env, opt)
301:     conn_data.send_string = response_string
302:     if ext = opt[:external_content]
303:       mimeize(conn_data, ext)
304:     end
305:     conn_data
306:   end

[Source]

     # File lib/soap/rpc/router.rb, line 308
308:   def mimeize(conn_data, ext)
309:     mime = MIMEMessage.new
310:     ext.each do |k, v|
311:       mime.add_attachment(v.data)
312:     end
313:     mime.add_part(conn_data.send_string + "\r\n")
314:     mime.close
315:     conn_data.send_string = mime.content_str
316:     conn_data.send_contenttype = mime.headers['content-type'].str
317:     conn_data
318:   end

[Source]

     # File lib/soap/rpc/router.rb, line 266
266:   def receive_headers(headerhandler, headers)
267:     headerhandler.on_inbound(headers) if headers
268:   end

[Source]

     # File lib/soap/rpc/router.rb, line 270
270:   def unmarshal(conn_data)
271:     opt = {}
272:     contenttype = conn_data.receive_contenttype
273:     if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
274:       opt[:external_content] = {}
275:       mime = MIMEMessage.parse("Content-Type: " + contenttype,
276:         conn_data.receive_string)
277:       mime.parts.each do |part|
278:         value = Attachment.new(part.content)
279:         value.contentid = part.contentid
280:         obj = SOAPAttachment.new(value)
281:         opt[:external_content][value.contentid] = obj if value.contentid
282:       end
283:       opt[:charset] =
284:         StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
285:       env = Processor.unmarshal(mime.root.content, opt)
286:     else
287:       opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)
288:       env = Processor.unmarshal(conn_data.receive_string, opt)
289:     end
290:     charset = opt[:charset]
291:     conn_data.send_contenttype = "text/xml; charset=\"#{charset}\""
292:     env
293:   end

[Validate]