class SOAP::RPC::Proxy

Attributes

allow_unqualified_element[RW]
default_encodingstyle[RW]
filterchain[R]
generate_explicit_type[RW]
headerhandler[R]
literal_mapping_registry[RW]
mandatorycharset[RW]
mapping_registry[RW]
operation[R]
return_response_as_xml[RW]
soapaction[RW]
streamhandler[R]
use_default_namespace[RW]

Public Class Methods

new(endpoint_url, soapaction, options) click to toggle source
# File lib/soap/rpc/proxy.rb, line 47
def initialize(endpoint_url, soapaction, options)
  @endpoint_url = endpoint_url
  @soapaction = soapaction
  @options = options
  @protocol_option = options["protocol"] ||= ::SOAP::Property.new
  initialize_streamhandler(@protocol_option)
  @operation = {}
  @operation_by_qname = {}
  @operation_by_soapaction = {}
  @mandatorycharset = nil
  # TODO: set to false by default or drop thie option in 1.6.0
  @allow_unqualified_element = true
  @default_encodingstyle = nil
  @generate_explicit_type = nil
  @use_default_namespace = false
  @return_response_as_xml = false
  @headerhandler = Header::HandlerSet.new
  @filterchain = Filter::FilterChain.new
  @mapping_registry = nil
  @literal_mapping_registry = ::SOAP::Mapping::LiteralRegistry.new
end

Public Instance Methods

add_document_method(soapaction, name, param_def, opt = {})
add_document_operation(soapaction, name, param_def, opt = {}) click to toggle source
# File lib/soap/rpc/proxy.rb, line 101
def add_document_operation(soapaction, name, param_def, opt = {})
  ensure_styleuse_option(opt, :document, :literal)
  op = Operation.new(soapaction, param_def, opt)
  assign_operation(name, nil, soapaction, op)
end
Also aliased as: add_document_method
add_method(qname, soapaction, name, param_def, opt = {})

add_method is for shortcut of typical rpc/encoded method definition.

Alias for: add_rpc_operation
add_rpc_method(qname, soapaction, name, param_def, opt = {})
Alias for: add_rpc_operation
add_rpc_operation(qname, soapaction, name, param_def, opt = {}) click to toggle source
# File lib/soap/rpc/proxy.rb, line 94
def add_rpc_operation(qname, soapaction, name, param_def, opt = {})
  ensure_styleuse_option(opt, :rpc, :encoded)
  opt[:request_qname] = qname
  op = Operation.new(soapaction, param_def, opt)
  assign_operation(name, qname, soapaction, op)
end
Also aliased as: add_method, add_rpc_method
call(name, *params) click to toggle source
# File lib/soap/rpc/proxy.rb, line 122
def call(name, *params)
  # name must be used only for lookup
  op_info = lookup_operation(name)
  mapping_opt = create_mapping_opt
  req_header = create_request_header
  req_body = SOAPBody.new(
    op_info.request_body(params, @mapping_registry,
      @literal_mapping_registry, mapping_opt)
  )
  reqopt = create_encoding_opt(
    :soapaction => op_info.soapaction || @soapaction,
    :envelopenamespace => @options["soap.envelope.requestnamespace"],
    :default_encodingstyle =>
      @default_encodingstyle || op_info.request_default_encodingstyle,
    :use_default_namespace =>
      op_info.use_default_namespace || @use_default_namespace
  )
  resopt = create_encoding_opt(
    :envelopenamespace => @options["soap.envelope.responsenamespace"],
    :default_encodingstyle =>
      @default_encodingstyle || op_info.response_default_encodingstyle
  )
  if reqopt[:generate_explicit_type].nil?
    reqopt[:generate_explicit_type] = (op_info.request_use == :encoded)
  end
  if resopt[:generate_explicit_type].nil?
    resopt[:generate_explicit_type] = (op_info.response_use == :encoded)
  end
  env = route(req_header, req_body, reqopt, resopt)
  if op_info.response_use.nil?
    return nil
  end
  raise EmptyResponseError unless env
  receive_headers(env.header)
  begin
    check_fault(env.body)
  rescue ::SOAP::FaultError => e
    op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
  end
  if @return_response_as_xml
    resopt[:response_as_xml]
  else
    op_info.response_obj(env.body, @mapping_registry,
      @literal_mapping_registry, mapping_opt)
  end
end
check_fault(body) click to toggle source
# File lib/soap/rpc/proxy.rb, line 194
def check_fault(body)
  if body.fault
    raise SOAP::FaultError.new(body.fault)
  end
end
endpoint_url() click to toggle source
# File lib/soap/rpc/proxy.rb, line 73
def endpoint_url
  @endpoint_url
end
endpoint_url=(endpoint_url) click to toggle source
# File lib/soap/rpc/proxy.rb, line 77
def endpoint_url=(endpoint_url)
  @endpoint_url = endpoint_url
  reset_stream
end
inspect() click to toggle source
# File lib/soap/rpc/proxy.rb, line 69
def inspect
  "#<#{self.class}:#{@endpoint_url}>"
end
invoke(req_header, req_body, opt = nil) click to toggle source
# File lib/soap/rpc/proxy.rb, line 112
def invoke(req_header, req_body, opt = nil)
  opt ||= create_encoding_opt
  env = route(req_header, req_body, opt, opt)
  if @return_response_as_xml
    opt[:response_as_xml]
  else
    env
  end
end
reset_stream() click to toggle source
# File lib/soap/rpc/proxy.rb, line 82
def reset_stream
  @streamhandler.reset(@endpoint_url)
end
route(req_header, req_body, reqopt, resopt) click to toggle source
# File lib/soap/rpc/proxy.rb, line 169
def route(req_header, req_body, reqopt, resopt)
  req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body)
  unless reqopt[:envelopenamespace].nil?
    set_envelopenamespace(req_env, reqopt[:envelopenamespace])
  end
  reqopt[:external_content] = nil
  conn_data = marshal(req_env, reqopt)
  if ext = reqopt[:external_content]
    mime = MIMEMessage.new
    ext.each do |k, v|
      mime.add_attachment(v.data)
    end
    mime.add_part(conn_data.send_string + "\r\n")
    mime.close
    conn_data.send_string = mime.content_str
    conn_data.send_contenttype = mime.headers['content-type'].str
  end
  conn_data.soapaction = reqopt[:soapaction]
  conn_data = @streamhandler.send(@endpoint_url, conn_data)
  if conn_data.receive_string.empty?
    return nil
  end
  unmarshal(conn_data, resopt)
end
set_wiredump_file_base(wiredump_file_base) click to toggle source
# File lib/soap/rpc/proxy.rb, line 86
def set_wiredump_file_base(wiredump_file_base)
  @streamhandler.wiredump_file_base = wiredump_file_base
end
test_loopback_response() click to toggle source
# File lib/soap/rpc/proxy.rb, line 90
def test_loopback_response
  @streamhandler.test_loopback_response
end

Private Instance Methods

assign_operation(name, qname, soapaction, op) click to toggle source
# File lib/soap/rpc/proxy.rb, line 322
def assign_operation(name, qname, soapaction, op)
  assigned = false
  if name and !name.empty?
    @operation[name] = op
    assigned = true
  end
  if qname
    @operation_by_qname[qname] = op
    assigned = true
  end
  if soapaction and !soapaction.empty?
    @operation_by_soapaction[soapaction] = op
    assigned = true
  end
  unless assigned
    raise MethodDefinitionError.new("cannot assign operation")
  end
end
create_encoding_opt(hash = nil) click to toggle source
# File lib/soap/rpc/proxy.rb, line 302
def create_encoding_opt(hash = nil)
  opt = {}
  opt[:default_encodingstyle] = @default_encodingstyle
  opt[:allow_unqualified_element] = @allow_unqualified_element
  opt[:generate_explicit_type] = @generate_explicit_type
  opt[:no_indent] = @options["soap.envelope.no_indent"]
  opt[:use_numeric_character_reference] =
    @options["soap.envelope.use_numeric_character_reference"]
  opt.update(hash) if hash
  opt
end
create_mapping_opt(hash = nil) click to toggle source
# File lib/soap/rpc/proxy.rb, line 314
def create_mapping_opt(hash = nil)
  opt = {
    :external_ces => @options["soap.mapping.external_ces"]
  }
  opt.update(hash) if hash
  opt
end
create_request_header() click to toggle source
# File lib/soap/rpc/proxy.rb, line 245
def create_request_header
  header = ::SOAP::SOAPHeader.new
  items = @headerhandler.on_outbound(header)
  items.each do |item|
    header.add(item.elename.name, item)
  end
  header
end
ensure_styleuse_option(opt, style, use) click to toggle source
# File lib/soap/rpc/proxy.rb, line 202
def ensure_styleuse_option(opt, style, use)
  if opt[:request_style] || opt[:response_style] || opt[:request_use] || opt[:response_use]
    # do not edit
  else
    opt[:request_style] ||= style
    opt[:response_style] ||= style
    opt[:request_use] ||= use
    opt[:response_use] ||= use
  end
end
initialize_streamhandler(options) click to toggle source
# File lib/soap/rpc/proxy.rb, line 213
def initialize_streamhandler(options)
  value = options["streamhandler"]
  if value and !value.empty?
    factory = Property::Util.const_from_name(value)
  else
    factory = HTTPStreamHandler
  end
  @streamhandler = factory.create(options)
  options.add_hook("streamhandler") do |key, value|
    @streamhandler.reset
    if value.respond_to?(:create)
      factory = value
    elsif value and !value.to_str.empty?
      factory = Property::Util.const_from_name(value.to_str)
    else
      factory = HTTPStreamHandler
    end
    options.unlock(true)
    @streamhandler = factory.create(options)
  end
end
lookup_operation(name_or_qname_or_soapaction) click to toggle source
# File lib/soap/rpc/proxy.rb, line 341
def lookup_operation(name_or_qname_or_soapaction)
  if op = @operation[name_or_qname_or_soapaction]
    return op
  end
  if op = @operation_by_qname[name_or_qname_or_soapaction]
    return op
  end
  if op = @operation_by_soapaction[name_or_qname_or_soapaction]
    return op
  end
  raise MethodDefinitionError.new(
    "operation: #{name_or_qname_or_soapaction} not supported")
end
marshal(env, opt) click to toggle source
# File lib/soap/rpc/proxy.rb, line 258
def marshal(env, opt)
  @filterchain.each do |filter|
    env = filter.on_outbound(env, opt)
    break unless env
  end
  send_string = Processor.marshal(env, opt)
  StreamHandler::ConnectionData.new(send_string)
end
receive_headers(header) click to toggle source
# File lib/soap/rpc/proxy.rb, line 254
def receive_headers(header)
  @headerhandler.on_inbound(header) if header
end
set_envelopenamespace(env, namespace) click to toggle source
# File lib/soap/rpc/proxy.rb, line 235
def set_envelopenamespace(env, namespace)
  env.elename = XSD::QName.new(namespace, env.elename.name)
  if env.header
    env.header.elename = XSD::QName.new(namespace, env.header.elename.name)
  end
  if env.body
    env.body.elename = XSD::QName.new(namespace, env.body.elename.name)
  end
end
unmarshal(conn_data, opt) click to toggle source
# File lib/soap/rpc/proxy.rb, line 267
def unmarshal(conn_data, opt)
  contenttype = conn_data.receive_contenttype
  xml = nil
  if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
    opt[:external_content] = {}
    mime = MIMEMessage.parse("Content-Type: " + contenttype,
      conn_data.receive_string)
    mime.parts.each do |part|
      value = Attachment.new(part.content)
      value.contentid = part.contentid
      obj = SOAPAttachment.new(value)
      opt[:external_content][value.contentid] = obj if value.contentid
    end
    opt[:charset] = @mandatorycharset ||
      StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
    xml = mime.root.content
  else
    opt[:charset] = @mandatorycharset ||
      ::SOAP::StreamHandler.parse_media_type(contenttype)
    xml = conn_data.receive_string
  end
  @filterchain.reverse_each do |filter|
    xml = filter.on_inbound(xml, opt)
    break unless xml
  end
  env = Processor.unmarshal(xml, opt)
  if @return_response_as_xml
    opt[:response_as_xml] = xml
  end
  unless env.is_a?(::SOAP::SOAPEnvelope)
    raise ResponseFormatError.new("response is not a SOAP envelope: #{env}")
  end
  env
end