Parent

Included Modules

Files

Class Index [+]

Quicksearch

SOAP::RPC::Router

Attributes

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

Public Class Methods

new(actor) click to toggle source
    # File lib/soap/rpc/router.rb, line 37
37:   def initialize(actor)
38:     @actor = actor
39:     @mapping_registry = nil
40:     @headerhandler = Header::HandlerSet.new
41:     @literal_mapping_registry = ::SOAP::Mapping::LiteralRegistry.new
42:     @generate_explicit_type = true
43:     @use_default_namespace = false
44:     @external_ces = nil
45:     @operation_by_soapaction = {}
46:     @operation_by_qname = {}
47:     @headerhandlerfactory = []
48:     @filterchain = Filter::FilterChain.new
49:   end

Public Instance Methods

add_document_method(receiver, soapaction, name, param_def, opt = {}) click to toggle source
add_document_operation(receiver, soapaction, name, param_def, opt = {}) click to toggle source
     # File lib/soap/rpc/router.rb, line 125
125:   def add_document_operation(receiver, soapaction, name, param_def, opt = {})
126:     #
127:     # adopt workaround for doc/lit wrapper method
128:     # (you should consider to simply use rpc/lit service)
129:     #
130:     #unless soapaction
131:     #  raise RPCRoutingError.new("soapaction is a must for document method")
132:     #end
133:     ensure_styleuse_option(opt, :document, :literal)
134:     op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
135:       opt)
136:     if opt[:request_style] != :document
137:       raise RPCRoutingError.new("illegal request_style given")
138:     end
139:     assign_operation(soapaction, first_input_part_qname(param_def), op)
140:   end
Also aliased as: add_document_method
add_document_request_operation(factory, soapaction, name, param_def, opt = {}) click to toggle source
     # File lib/soap/rpc/router.rb, line 143
143:   def add_document_request_operation(factory, soapaction, name, param_def, opt = {})
144:     #
145:     # adopt workaround for doc/lit wrapper method
146:     # (you should consider to simply use rpc/lit service)
147:     #
148:     #unless soapaction
149:     #  raise RPCRoutingError.new("soapaction is a must for document method")
150:     #end
151:     ensure_styleuse_option(opt, :document, :literal)
152:     op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt)
153:     if opt[:request_style] != :document
154:       raise RPCRoutingError.new("illegal request_style given")
155:     end
156:     assign_operation(soapaction, first_input_part_qname(param_def), op)
157:   end
add_headerhandler(handler) click to toggle source
    # File lib/soap/rpc/router.rb, line 61
61:   def add_headerhandler(handler)
62:     @headerhandler.add(handler)
63:   end
add_method(receiver, qname, soapaction, name, param_def, opt = {}) click to toggle source
Alias for: add_rpc_operation
add_request_headerhandler(factory) click to toggle source

header handler interface

    # File lib/soap/rpc/router.rb, line 54
54:   def add_request_headerhandler(factory)
55:     unless factory.respond_to?(:create)
56:       raise TypeError.new("factory must respond to 'create'")
57:     end
58:     @headerhandlerfactory << factory
59:   end
add_rpc_method(receiver, qname, soapaction, name, param_def, opt = {}) click to toggle source
Alias for: add_rpc_operation
add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {}) click to toggle source

operation definition interface

     # File lib/soap/rpc/router.rb, line 102
102:   def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
103:     ensure_styleuse_option(opt, :rpc, :encoded)
104:     opt[:request_qname] = qname
105:     op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,
106:       opt)
107:     if opt[:request_style] != :rpc
108:       raise RPCRoutingError.new("illegal request_style given")
109:     end
110:     assign_operation(soapaction, qname, op)
111:   end
Also aliased as: add_method, add_rpc_method
add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {}) click to toggle source
     # File lib/soap/rpc/router.rb, line 115
115:   def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})
116:     ensure_styleuse_option(opt, :rpc, :encoded)
117:     opt[:request_qname] = qname
118:     op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt)
119:     if opt[:request_style] != :rpc
120:       raise RPCRoutingError.new("illegal request_style given")
121:     end
122:     assign_operation(soapaction, qname, op)
123:   end
add_rpc_request_servant(factory, namespace) click to toggle source

servant definition interface

    # File lib/soap/rpc/router.rb, line 68
68:   def add_rpc_request_servant(factory, namespace)
69:     unless factory.respond_to?(:create)
70:       raise TypeError.new("factory must respond to 'create'")
71:     end
72:     obj = factory.create        # a dummy instance for introspection
73:     ::SOAP::RPC.defined_methods(obj).each do |name|
74:       begin
75:         qname = XSD::QName.new(namespace, name)
76:         param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
77:         opt = create_styleuse_option(:rpc, :encoded)
78:         add_rpc_request_operation(factory, qname, nil, name, param_def, opt)
79:       rescue SOAP::RPC::MethodDefinitionError => e
80:         p e if $DEBUG
81:       end
82:     end
83:   end
add_rpc_servant(obj, namespace) click to toggle source
    # File lib/soap/rpc/router.rb, line 85
85:   def add_rpc_servant(obj, namespace)
86:     ::SOAP::RPC.defined_methods(obj).each do |name|
87:       begin
88:         qname = XSD::QName.new(namespace, name)
89:         param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)
90:         opt = create_styleuse_option(:rpc, :encoded)
91:         add_rpc_operation(obj, qname, nil, name, param_def, opt)
92:       rescue SOAP::RPC::MethodDefinitionError => e
93:         p e if $DEBUG
94:       end
95:     end
96:   end
Also aliased as: add_servant
add_servant(obj, namespace) click to toggle source
Alias for: add_rpc_servant
create_fault_response(e) click to toggle source

Create fault response string.

     # File lib/soap/rpc/router.rb, line 200
200:   def create_fault_response(e)
201:     env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e, nil), true))
202:     opt = {}
203:     opt[:external_content] = nil
204:     @filterchain.reverse_each do |filter|
205:       env = filter.on_outbound(env, opt)
206:       break unless env
207:     end
208:     response_string = Processor.marshal(env, opt)
209:     conn_data = StreamHandler::ConnectionData.new(response_string)
210:     conn_data.is_fault = true
211:     if ext = opt[:external_content]
212:       mimeize(conn_data, ext)
213:     end
214:     conn_data
215:   end
route(conn_data) click to toggle source
     # File lib/soap/rpc/router.rb, line 159
159:   def route(conn_data)
160:     # we cannot set request_default_encodingsyle before parsing the content.
161:     env = unmarshal(conn_data)
162:     if env.nil?
163:       raise ArgumentError.new("illegal SOAP marshal format")
164:     end
165:     op = lookup_operation(conn_data.soapaction, env.body)
166:     headerhandler = @headerhandler.dup
167:     @headerhandlerfactory.each do |f|
168:       headerhandler.add(f.create)
169:     end
170:     soap_response = default_encodingstyle = nil
171:     begin
172:       receive_headers(headerhandler, env.header)
173:       soap_response =
174:         op.call(env.body, @mapping_registry, @literal_mapping_registry,
175:           create_mapping_opt)
176:       conn_data.is_fault = true if soap_response.is_a?(SOAPFault)
177:       default_encodingstyle = op.response_default_encodingstyle
178:     rescue Exception => e
179:       # If a wsdl fault was raised by service, the fault declaration details
180:       # is kept in wsdl_fault. Otherwise (exception is a program fault)
181:       # wsdl_fault is nil
182:       wsdl_fault_details = op.faults && op.faults[e.class.name]
183:       soap_response = fault(e, wsdl_fault_details)
184:       conn_data.is_fault = true
185:       default_encodingstyle = nil
186:     end
187:     header = call_headers(headerhandler)
188:     if op.response_use.nil?
189:       conn_data.send_string = ''
190:       conn_data.is_nocontent = true
191:       conn_data
192:     else
193:       body = SOAPBody.new(soap_response, conn_data.is_fault)
194:       env = SOAPEnvelope.new(header, body)
195:       marshal(conn_data, env, default_encodingstyle)
196:     end
197:   end

Private Instance Methods

assign_operation(soapaction, qname, op) click to toggle source
     # File lib/soap/rpc/router.rb, line 247
247:   def assign_operation(soapaction, qname, op)
248:     assigned = false
249:     if soapaction and !soapaction.empty?
250:       @operation_by_soapaction[soapaction] = op
251:       assigned = true
252:     end
253:     if qname
254:       @operation_by_qname[qname] = op
255:       assigned = true
256:     end
257:     unless assigned
258:       raise RPCRoutingError.new("cannot assign operation")
259:     end
260:   end
call_headers(headerhandler) click to toggle source
     # File lib/soap/rpc/router.rb, line 278
278:   def call_headers(headerhandler)
279:     header = ::SOAP::SOAPHeader.new
280:     items = headerhandler.on_outbound(header)
281:     items.each do |item|
282:       header.add(item.elename.name, item)
283:     end
284:     header
285:   end
create_mapping_opt() click to toggle source
     # File lib/soap/rpc/router.rb, line 394
394:   def create_mapping_opt
395:     { :external_ces => @external_ces }
396:   end
create_styleuse_option(style, use) click to toggle source
     # File lib/soap/rpc/router.rb, line 229
229:   def create_styleuse_option(style, use)
230:     opt = {}
231:     opt[:request_style] = opt[:response_style] = style
232:     opt[:request_use] = opt[:response_use] = use
233:     opt
234:   end
ensure_styleuse_option(opt, style, use) click to toggle source
     # File lib/soap/rpc/router.rb, line 236
236:   def ensure_styleuse_option(opt, style, use)
237:     if opt[:request_style] || opt[:response_style] || opt[:request_use] || opt[:response_use]
238:       # do not edit
239:     else
240:       opt[:request_style] ||= style
241:       opt[:response_style] ||= style
242:       opt[:request_use] ||= use
243:       opt[:response_use] ||= use
244:     end
245:   end
fault(e, wsdl_fault_details) click to toggle source

Create fault response.

     # File lib/soap/rpc/router.rb, line 353
353:   def fault(e, wsdl_fault_details)
354:     if e.is_a?(UnhandledMustUnderstandHeaderError)
355:       faultcode = FaultCode::MustUnderstand
356:     else
357:       faultcode = FaultCode::Server
358:     end
359: 
360:     # If the exception represents a WSDL fault, the fault element should
361:     # be added as the SOAP fault <detail> element. If the exception is a
362:     # normal program exception, it is wrapped inside a custom SOAP4R
363:     # SOAP exception element.
364:     detail = nil
365:     begin
366:       if (wsdl_fault_details)
367:         registry = wsdl_fault_details[:use] == "literal" ?
368:           @literal_mapping_registry : @mapping_registry
369:         faultQName = XSD::QName.new(
370:           wsdl_fault_details[:ns], wsdl_fault_details[:name]
371:         )
372:         detail = Mapping.obj2soap(e, registry, faultQName)
373:         # wrap fault element (SOAPFault swallows top-level element)
374:         wrapper = SOAP::SOAPElement.new(faultQName)
375:         wrapper.add(detail)
376:         detail = wrapper
377:       else
378:         # Exception is a normal program exception. Wrap it.
379:         detail = Mapping.obj2soap(Mapping::SOAPException.new(e),
380:                                   @mapping_registry)
381:         detail.elename ||= XSD::QName::EMPTY # for literal mappingregstry
382:       end
383:     rescue
384:       detail = SOAPString.new("failed to serialize detail object: #{$!}")
385:     end
386: 
387:     SOAPFault.new(
388:       SOAPElement.new(nil, faultcode),
389:       SOAPString.new(e.to_s),
390:       SOAPString.new(@actor),
391:       detail)
392:   end
first_input_part_qname(param_def) click to toggle source
     # File lib/soap/rpc/router.rb, line 219
219:   def first_input_part_qname(param_def)
220:     param_def.each do |inout, paramname, typeinfo|
221:       if inout == SOAPMethod::IN
222:         klass, nsdef, namedef = typeinfo
223:         return XSD::QName.new(nsdef, namedef)
224:       end
225:     end
226:     nil
227:   end
lookup_operation(soapaction, body) click to toggle source
     # File lib/soap/rpc/router.rb, line 262
262:   def lookup_operation(soapaction, body)
263:     if op = @operation_by_soapaction[soapaction]
264:       return op
265:     end
266:     qname = body.root_node.elename
267:     if op = @operation_by_qname[qname]
268:       return op
269:     end
270:     if soapaction
271:       raise RPCRoutingError.new(
272:         "operation: #{soapaction} #{qname} not supported")
273:     else
274:       raise RPCRoutingError.new("operation: #{qname} not supported")
275:     end
276:   end
marshal(conn_data, env, default_encodingstyle = nil) click to toggle source
     # File lib/soap/rpc/router.rb, line 322
322:   def marshal(conn_data, env, default_encodingstyle = nil)
323:     opt = {}
324:     opt[:external_content] = nil
325:     opt[:default_encodingstyle] = default_encodingstyle
326:     opt[:generate_explicit_type] = @generate_explicit_type
327:     opt[:use_default_namespace] = @use_default_namespace
328:     @filterchain.reverse_each do |filter|
329:       env = filter.on_outbound(env, opt)
330:       break unless env
331:     end
332:     response_string = Processor.marshal(env, opt)
333:     conn_data.send_string = response_string
334:     if ext = opt[:external_content]
335:       mimeize(conn_data, ext)
336:     end
337:     conn_data
338:   end
mimeize(conn_data, ext) click to toggle source
     # File lib/soap/rpc/router.rb, line 340
340:   def mimeize(conn_data, ext)
341:     mime = MIMEMessage.new
342:     ext.each do |k, v|
343:       mime.add_attachment(v.data)
344:     end
345:     mime.add_part(conn_data.send_string + "\r\n")
346:     mime.close
347:     conn_data.send_string = mime.content_str
348:     conn_data.send_contenttype = mime.headers['content-type'].str
349:     conn_data
350:   end
receive_headers(headerhandler, header) click to toggle source
     # File lib/soap/rpc/router.rb, line 287
287:   def receive_headers(headerhandler, header)
288:     headerhandler.on_inbound(header) if header
289:   end
unmarshal(conn_data) click to toggle source
     # File lib/soap/rpc/router.rb, line 291
291:   def unmarshal(conn_data)
292:     xml = nil
293:     opt = {}
294:     contenttype = conn_data.receive_contenttype
295:     if /#{MIMEMessage::MultipartContentType}/ =~ contenttype
296:       opt[:external_content] = {}
297:       mime = MIMEMessage.parse("Content-Type: " + contenttype,
298:         conn_data.receive_string)
299:       mime.parts.each do |part|
300:         value = Attachment.new(part.content)
301:         value.contentid = part.contentid
302:         obj = SOAPAttachment.new(value)
303:         opt[:external_content][value.contentid] = obj if value.contentid
304:       end
305:       opt[:charset] =
306:         StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
307:       xml = mime.root.content
308:     else
309:       opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)
310:       xml = conn_data.receive_string
311:     end
312:     @filterchain.each do |filter|
313:       xml = filter.on_inbound(xml, opt)
314:       break unless xml
315:     end
316:     env = Processor.unmarshal(xml, opt)
317:     charset = opt[:charset]
318:     conn_data.send_contenttype = "text/xml; charset=\"#{charset}\""
319:     env
320:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.