1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/soap/soap.rb: add SOAP::Env module for environment repository

such as HTTP_PROXY.

        * lib/soap/property.rb: property implementation.

        * lib/soap/streamHandler.rb, lib/soap/wsdlDriver.rb,
          lib/soap/rpc/driver.rb: use soap/property.rb.

        * lib/wsdl/importer.rb, lib/soap/wsdlDriver.rb, lib/soap/rpc/driver.rb:
          use SOAP::Env.

        * lib/soap/netHttpClient.rb: add basic_auth, ssl_config, and cookie
          management interface, but ignored for now.

        * lib/xsd/charset.rb: add XSD::Charset.encoding= interface to set
          wiredump charset explicitly.  it was fixed to 'utf-8' when iconv or
          uconv module was found.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5104 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nahi 2003-12-04 04:05:51 +00:00
parent b28a2a1ad6
commit 20fa0df5cd
12 changed files with 735 additions and 320 deletions

View file

@ -1,3 +1,23 @@
Thu Dec 4 13:04:44 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
* lib/soap/soap.rb: add SOAP::Env module for environment repository
such as HTTP_PROXY.
* lib/soap/property.rb: property implementation.
* lib/soap/streamHandler.rb, lib/soap/wsdlDriver.rb,
lib/soap/rpc/driver.rb: use soap/property.rb.
* lib/wsdl/importer.rb, lib/soap/wsdlDriver.rb, lib/soap/rpc/driver.rb:
use SOAP::Env.
* lib/soap/netHttpClient.rb: add basic_auth, ssl_config, and cookie
management interface, but ignored for now.
* lib/xsd/charset.rb: add XSD::Charset.encoding= interface to set
wiredump charset explicitly. it was fixed to 'utf-8' when iconv or
uconv module was found.
Thu Dec 4 10:43:58 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/dl/sym.c (rb_dlsym_guardcall): __declspec(noinline) is VC7

View file

@ -349,6 +349,7 @@ lib/soap/marshal.rb
lib/soap/netHttpClient.rb
lib/soap/parser.rb
lib/soap/processor.rb
lib/soap/property.rb
lib/soap/rpc/cgistub.rb
lib/soap/rpc/driver.rb
lib/soap/rpc/element.rb

View file

@ -24,39 +24,31 @@ class NetHttpClient
attr_accessor :proxy
attr_accessor :no_proxy
attr_accessor :debug_dev
attr_reader :session_manager
class SessionManager
attr_accessor :connect_timeout
attr_accessor :send_timeout
attr_accessor :receive_timeout
end
class Response
attr_reader :content
attr_reader :status
attr_reader :reason
attr_reader :contenttype
def initialize(res)
@status = res.code.to_i
@reason = res.message
@contenttype = res['content-type']
@content = res.body
end
end
attr_accessor :ssl_config # ignored for now.
attr_accessor :protocol_version # ignored for now.
def initialize(proxy = nil, agent = nil)
@proxy = proxy ? URI.parse(proxy) : nil
@agent = agent
@debug_dev = nil
@session_manager = SessionManager.new
name = 'no_proxy'
@no_proxy = ENV[name] || ENV[name.upcase]
@no_proxy = nil
end
def set_basic_auth(uri, user_id, passwd)
# ignored for now.
end
def set_cookie_store(filename)
# ignored for now.
end
def reset(url)
# ignored.
# ignored for now.
end
def reset_all
# ignored for now.
end
def post(url, req_body, header = {})
@ -134,6 +126,26 @@ private
false
end
end
class SessionManager
attr_accessor :connect_timeout
attr_accessor :send_timeout
attr_accessor :receive_timeout
end
class Response
attr_reader :content
attr_reader :status
attr_reader :reason
attr_reader :contenttype
def initialize(res)
@status = res.code.to_i
@reason = res.message
@contenttype = res['content-type']
@content = res.body
end
end
end

232
lib/soap/property.rb Normal file
View file

@ -0,0 +1,232 @@
# soap/property.rb: SOAP4R - Property implementation.
# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.
module SOAP
class Property
include Enumerable
def initialize
@store = Hash.new
@hook = Hash.new
@self_hook = Array.new
@locked = false
end
# name: a Symbol, String or an Array
def [](name)
referent(name_to_a(name))
end
# name: a Symbol, String or an Array
# value: an Object
def []=(name, value)
hooks = assign(name_to_a(name), value)
normalized_name = normalize_name(name)
hooks.each do |hook|
hook.call(normalized_name, value)
end
value
end
# value: an Object
# key is generated by property
def <<(value)
self[generate_new_key] = value
end
# name: a Symbol, String or an Array. nil means hook to the root.
# hook: block which will be called with 2 args, name and value
def add_hook(name = nil, &hook)
if name.nil?
assign_self_hook(hook)
else
assign_hook(name_to_a(name), hook)
end
end
def each
@store.each do |key, value|
yield(key, value)
end
end
def empty?
@store.empty?
end
def keys
@store.keys
end
def values
@store.values
end
def lock(cascade = false)
if cascade
each_key do |key|
key.lock(cascade)
end
end
@locked = true
self
end
def unlock(cascade = false)
@locked = false
if cascade
each_key do |key|
key.unlock(cascade)
end
end
self
end
def locked?
@locked
end
protected
def referent(ary)
key, rest = location_pair(ary)
if rest.empty?
local_referent(key)
else
deref_key(key).referent(rest)
end
end
def assign(ary, value)
key, rest = location_pair(ary)
if rest.empty?
local_assign(key, value)
local_hook(key)
else
local_hook(key) + deref_key(key).assign(rest, value)
end
end
def assign_hook(ary, hook)
key, rest = location_pair(ary)
if rest.empty?
local_assign_hook(key, hook)
else
deref_key(key).assign_hook(rest, hook)
end
end
def assign_self_hook(hook)
check_lock(nil)
@self_hook << hook
end
private
def each_key
self.each do |key, value|
if propkey?(value)
yield(value)
end
end
end
def deref_key(key)
check_lock(key)
ref = @store[key] ||= self.class.new
unless propkey?(ref)
raise ArgumentError.new("key `#{key}' already defined as a value")
end
ref
end
def local_referent(key)
check_lock(key)
if propkey?(@store[key]) and @store[key].locked?
raise TypeError.new("cannot split any key from locked property")
end
@store[key]
end
def local_assign(key, value)
check_lock(key)
if @locked
if propkey?(value)
raise TypeError.new("cannot add any key to locked property")
elsif propkey?(@store[key])
raise TypeError.new("cannot override any key in locked property")
end
end
@store[key] = value
end
def local_assign_hook(key, hook)
check_lock(key)
@store[key] ||= nil
(@hook[key] ||= []) << hook
end
NO_HOOK = [].freeze
def local_hook(key)
@self_hook + (@hook[key] || NO_HOOK)
end
def check_lock(key)
if @locked and (key.nil? or !@store.key?(key))
raise TypeError.new("cannot add any key to locked property")
end
end
def propkey?(value)
value.is_a?(::SOAP::Property)
end
def name_to_a(name)
case name
when Symbol
[name]
when String
name.split(/\./)
when Array
name
else
raise ArgumentError.new("Unknown name #{name}(#{name.class})")
end
end
def location_pair(ary)
name, *rest = *ary
key = to_key(name)
return key, rest
end
def normalize_name(name)
name_to_a(name).collect { |key| to_key(key) }.join('.')
end
def to_key(name)
name.to_s.downcase.intern
end
def generate_new_key
if @store.empty?
"0"
else
(key_max + 1).to_s
end
end
def key_max
(@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i
end
end
end

View file

@ -12,6 +12,7 @@ require 'soap/rpc/rpc'
require 'soap/rpc/proxy'
require 'soap/rpc/element'
require 'soap/streamHandler'
require 'soap/property'
module SOAP
@ -19,91 +20,86 @@ module RPC
class Driver
public
class EmptyResponseError < Error; end
attr_accessor :mapping_registry
attr_accessor :soapaction
attr_reader :wiredump_dev
attr_reader :wiredump_file_base
attr_reader :streamhandler
def initialize(endpoint_url, namespace, soapaction = nil)
@namespace = namespace
@mapping_registry = nil # for unmarshal
@soapaction = soapaction
@wiredump_dev = nil
@wiredump_file_base = nil
name = 'http_proxy'
@httpproxy = ENV[name] || ENV[name.upcase]
@streamhandler = HTTPPostStreamHandler.new(endpoint_url, @httpproxy,
XSD::Charset.encoding_label)
@proxy = Proxy.new(@streamhandler, @soapaction)
@proxy.allow_unqualified_element = true
class << self
def __attr_proxy(symbol, assignable = false)
name = symbol.to_s
module_eval <<-EOD
def #{name}
@servant.#{name}
end
EOD
if assignable
module_eval <<-EOD
def #{name}=(rhs)
@servant.#{name} = rhs
end
EOD
end
end
end
def inspect
"#<#{self.class}:#{@streamhandler.inspect}>"
end
def endpoint_url
@streamhandler.endpoint_url
end
def endpoint_url=(endpoint_url)
@streamhandler.endpoint_url = endpoint_url
@streamhandler.reset
end
def wiredump_dev=(dev)
@wiredump_dev = dev
@streamhandler.wiredump_dev = @wiredump_dev
@streamhandler.reset
end
def wiredump_file_base=(base)
@wiredump_file_base = base
end
__attr_proxy :options
__attr_proxy :endpoint_url, true
__attr_proxy :mapping_registry, true
__attr_proxy :soapaction, true
__attr_proxy :default_encodingstyle, true
def httpproxy
@httpproxy
@servant.options["protocol.http.proxy"]
end
def httpproxy=(httpproxy)
@httpproxy = httpproxy
@streamhandler.proxy = @httpproxy
@streamhandler.reset
@servant.options["protocol.http.proxy"] = httpproxy
end
def wiredump_dev
@servant.options["protocol.http.wiredump_dev"]
end
def wiredump_dev=(wiredump_dev)
@servant.options["protocol.http.wiredump_dev"] = wiredump_dev
end
def mandatorycharset
@proxy.mandatorycharset
@servant.options["protocol.mandatorycharset"]
end
def mandatorycharset=(mandatorycharset)
@proxy.mandatorycharset = mandatorycharset
@servant.options["protocol.mandatorycharset"] = mandatorycharset
end
def default_encodingstyle
@proxy.default_encodingstyle
def wiredump_file_base
@servant.options["protocol.wiredump_file_base"]
end
def default_encodingstyle=(encodingstyle)
@proxy.default_encodingstyle = encodingstyle
def wiredump_file_base=(wiredump_file_base)
@servant.options["protocol.wiredump_file_base"] = wiredump_file_base
end
def initialize(endpoint_url, namespace, soapaction = nil)
@servant = Servant__.new(self, endpoint_url, namespace)
@servant.soapaction = soapaction
@proxy = @servant.proxy
if env_httpproxy = ::SOAP::Env::HTTP_PROXY
@servant.options["protocol.http.proxy"] = env_httpproxy
end
if env_no_proxy = ::SOAP::Env::NO_PROXY
@servant.options["protocol.http.no_proxy"] = env_no_proxy
end
end
###
## Method definition interfaces.
#
# params: [[param_def...]] or [paramname, paramname, ...]
# param_def: See proxy.rb. Sorry.
def inspect
"#<#{self.class}:#{@servant.streamhandler.inspect}>"
end
def add_method(name, *params)
add_method_with_soapaction_as(name, name, @soapaction, *params)
add_method_with_soapaction_as(name, name, @servant.soapaction, *params)
end
def add_method_as(name, name_as, *params)
add_method_with_soapaction_as(name, name_as, @soapaction, *params)
add_method_with_soapaction_as(name, name_as, @servant.soapaction, *params)
end
def add_method_with_soapaction(name, soapaction, *params)
@ -116,72 +112,147 @@ public
else
SOAPMethod.create_param_def(params)
end
qname = XSD::QName.new(@namespace, name_as)
@proxy.add_method(qname, soapaction, name, param_def)
add_rpc_method_interface(name, param_def)
end
###
## Driving interface.
#
def invoke(headers, body)
if @wiredump_file_base
@streamhandler.wiredump_file_base =
@wiredump_file_base + '_' << body.elename.name
end
@proxy.invoke(headers, body)
end
def call(name, *params)
# Convert parameters: params array => SOAPArray => members array
params = Mapping.obj2soap(params, @mapping_registry).to_a
if @wiredump_file_base
@streamhandler.wiredump_file_base = @wiredump_file_base + '_' << name
end
# Then, call @proxy.call like the following.
header, body = @proxy.call(nil, name, *params)
unless body
raise EmptyResponseError.new("Empty response.")
end
begin
@proxy.check_fault(body)
rescue SOAP::FaultError => e
Mapping.fault2exception(e)
end
ret = body.response ? Mapping.soap2obj(body.response, @mapping_registry) : nil
if body.outparams
outparams = body.outparams.collect { |outparam| Mapping.soap2obj(outparam) }
return [ret].concat(outparams)
else
return ret
end
@servant.add_method(name_as, soapaction, name, param_def)
end
def reset_stream
@streamhandler.reset
@servant.streamhandler.reset
end
def invoke(headers, body)
@servant.invoke(headers, body)
end
def call(name, *params)
@servant.call(name, *params)
end
private
def add_rpc_method_interface(name, param_def)
param_names = []
i = 0
@proxy.method[name].each_param_name(RPC::SOAPMethod::IN,
RPC::SOAPMethod::INOUT) do |param_name|
i += 1
param_names << "arg#{ i }"
@servant.add_rpc_method_interface(name, param_def)
end
class Servant__
attr_reader :options
attr_reader :streamhandler
attr_reader :proxy
def initialize(host, endpoint_url, namespace)
@host = host
@namespace = namespace
@mapping_registry = nil
@soapaction = nil
@wiredump_file_base = nil
@options = ::SOAP::Property.new
set_options
@streamhandler = HTTPPostStreamHandler.new(endpoint_url,
@options["protocol.http"] ||= ::SOAP::Property.new)
@proxy = Proxy.new(@streamhandler, @soapaction)
@proxy.allow_unqualified_element = true
end
callparam = (param_names.collect { |pname| ", " + pname }).join
self.instance_eval <<-EOS
def #{ name }(#{ param_names.join(", ") })
call("#{ name }"#{ callparam })
def endpoint_url
@streamhandler.endpoint_url
end
def endpoint_url=(endpoint_url)
@streamhandler.endpoint_url = endpoint_url
@streamhandler.reset
end
def mapping_registry
@mapping_registry
end
def mapping_registry=(mapping_registry)
@mapping_registry = mapping_registry
end
def soapaction
@soapaction
end
def soapaction=(soapaction)
@soapaction = soapaction
end
def default_encodingstyle
@proxy.default_encodingstyle
end
def default_encodingstyle=(encodingstyle)
@proxy.default_encodingstyle = encodingstyle
end
def invoke(headers, body)
set_wiredump_file_base(body.elename.name)
@proxy.invoke(headers, body)
end
def call(name, *params)
set_wiredump_file_base(name)
# Convert parameters: params array => SOAPArray => members array
params = Mapping.obj2soap(params, @mapping_registry).to_a
header, body = @proxy.call(nil, name, *params)
raise EmptyResponseError.new("Empty response.") unless body
begin
@proxy.check_fault(body)
rescue SOAP::FaultError => e
Mapping.fault2exception(e)
end
EOS
ret = body.response ?
Mapping.soap2obj(body.response, @mapping_registry) : nil
if body.outparams
outparams = body.outparams.collect { |outparam|
Mapping.soap2obj(outparam)
}
return [ret].concat(outparams)
else
return ret
end
end
def add_method(name_as, soapaction, name, param_def)
qname = XSD::QName.new(@namespace, name_as)
@proxy.add_method(qname, soapaction, name, param_def)
add_rpc_method_interface(name, param_def)
end
def add_rpc_method_interface(name, param_def)
param_names = []
i = 0
@proxy.method[name].each_param_name(RPC::SOAPMethod::IN,
RPC::SOAPMethod::INOUT) do |param_name|
i += 1
param_names << "arg#{ i }"
end
callparam = (param_names.collect { |pname| ", " + pname }).join
@host.instance_eval <<-EOS
def #{ name }(#{ param_names.join(", ") })
@servant.call(#{ name.dump }#{ callparam })
end
EOS
end
private
def set_wiredump_file_base(name)
if @wiredump_file_base
@streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }"
end
end
def set_options
@options.add_hook("protocol.mandatorycharset") do |key, value|
@proxy.mandatorycharset = value
end
@options.add_hook("protocol.wiredump_file_base") do |key, value|
@wiredump_file_base = value
end
@options["protocol.http.charset"] = XSD::Charset.encoding_label
end
end
end

View file

@ -13,7 +13,7 @@ require 'xsd/charset'
module SOAP
Version = '1.5.1'
Version = '1.5.2'
EnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/'
EncodingNamespace = 'http://schemas.xmlsoap.org/soap/encoding/'
@ -90,12 +90,22 @@ class FaultError < Error
def to_s
str = nil
if @faultstring && @faultstring.respond_to?('data')
if @faultstring and @faultstring.respond_to?('data')
str = @faultstring.data
end
str || '(No faultstring)'
end
end
module Env
def self.getenv(name)
ENV[name.downcase] || ENV[name]
end
use_proxy = getenv('soap_use_proxy') == 'on'
HTTP_PROXY = use_proxy ? getenv('http_proxy') : nil
NO_PROXY = use_proxy ? getenv('no_proxy') : nil
end
end

View file

@ -7,6 +7,7 @@
require 'soap/soap'
require 'soap/property'
module SOAP
@ -76,31 +77,25 @@ class HTTPPostStreamHandler < StreamHandler
public
attr_accessor :wiredump_dev
attr_accessor :wiredump_file_base
attr_accessor :charset
attr_reader :client
attr_accessor :wiredump_file_base
NofRetry = 10 # [times]
def initialize(endpoint_url, proxy = nil, charset = nil)
def initialize(endpoint_url, options)
super(endpoint_url)
@proxy = proxy || ENV['http_proxy'] || ENV['HTTP_PROXY']
@charset = charset || XSD::Charset.charset_label($KCODE)
@wiredump_dev = nil # Set an IO to get wiredump.
@client = Client.new(nil, "SOAP4R/#{ Version }")
@wiredump_file_base = nil
@client = Client.new(@proxy, "SOAP4R/#{ Version }")
@charset = @wiredump_dev = nil
@options = options
set_options
@client.debug_dev = @wiredump_dev
end
def inspect
"#<#{self.class}:#{endpoint_url}>"
end
def proxy=(proxy)
@proxy = proxy
@client.proxy = @proxy
end
def send(soap_string, soapaction = nil, charset = @charset)
send_post(soap_string, soapaction, charset)
end
@ -111,18 +106,66 @@ public
private
def set_options
@client.proxy = @options["proxy"]
@options.add_hook("proxy") do |key, value|
@client.proxy = value
end
@client.no_proxy = @options["no_proxy"]
@options.add_hook("no_proxy") do |key, value|
@client.no_proxy = value
end
@client.protocol_version = @options["protocol_version"]
@options.add_hook("protocol_version") do |key, value|
@client.protocol_version = value
end
set_cookie_store_file(@options["cookie_store_file"])
@options.add_hook("cookie_store_file") do |key, value|
set_cookie_store_file(value)
end
set_ssl_config(@options["ssl_config"])
@options.add_hook("ssl_config") do |key, value|
set_ssl_config(@options["ssl_config"])
end
@charset = @options["charset"] || XSD::Charset.charset_label($KCODE)
@options.add_hook("charset") do |key, value|
@charset = value
end
@wiredump_dev = @options["wiredump_dev"]
@options.add_hook("wiredump_dev") do |key, value|
@wiredump_dev = value
@client.debug_dev = @wiredump_dev
end
basic_auth = @options["basic_auth"] ||= ::SOAP::Property.new
set_basic_auth(basic_auth)
basic_auth.add_hook do |key, value|
set_basic_auth(basic_auth)
end
@options.lock(true)
basic_auth.unlock
end
def set_basic_auth(basic_auth)
basic_auth.values.each do |url, userid, passwd|
@client.set_basic_auth(url, userid, passwd)
end
end
def set_cookie_store_file(value)
return unless value
raise NotImplementedError.new
end
def set_ssl_config(value)
return unless value
raise NotImplementedError.new
end
def send_post(soap_string, soapaction, charset)
data = ConnectionData.new
data.send_string = soap_string
data.send_contenttype = StreamHandler.create_media_type(charset)
wiredump_dev = if @wiredump_dev && @wiredump_dev.respond_to?("<<")
@wiredump_dev
else
nil
end
@client.debug_dev = wiredump_dev
if @wiredump_file_base
filename = @wiredump_file_base + '_request.xml'
f = File.open(filename, "w")
@ -134,14 +177,14 @@ private
extra['Content-Type'] = data.send_contenttype
extra['SOAPAction'] = "\"#{ soapaction }\""
wiredump_dev << "Wire dump:\n\n" if wiredump_dev
@wiredump_dev << "Wire dump:\n\n" if @wiredump_dev
begin
res = @client.post(@endpoint_url, soap_string, extra)
rescue
@client.reset(@endpoint_url)
raise
end
wiredump_dev << "\n\n" if wiredump_dev
@wiredump_dev << "\n\n" if @wiredump_dev
receive_string = res.content

View file

@ -37,7 +37,7 @@ class WSDLDriverFactory
"#<#{self.class}:#{@wsdl.name}>"
end
def create_driver(servicename = nil, portname = nil, opt = {})
def create_driver(servicename = nil, portname = nil)
service = if servicename
@wsdl.service(XSD::QName.new(@wsdl.targetnamespace, servicename))
else
@ -57,7 +57,7 @@ class WSDLDriverFactory
if port.soap_address.nil?
raise FactoryError.new("soap:address element not found in WSDL.")
end
WSDLDriver.new(@wsdl, port, @logdev, opt)
WSDLDriver.new(@wsdl, port, @logdev)
end
# Backward compatibility.
@ -90,22 +90,62 @@ class WSDLDriver
end
end
__attr_proxy :opt
__attr_proxy :logdev, true
__attr_proxy :options
__attr_proxy :endpoint_url, true
__attr_proxy :mapping_registry, true # for RPC unmarshal
__attr_proxy :wsdl_mapping_registry, true # for RPC marshal
__attr_proxy :endpoint_url, true
__attr_proxy :wiredump_dev, true
__attr_proxy :wiredump_file_base, true
__attr_proxy :httpproxy, true
__attr_proxy :mandatorycharset, true # force using charset
__attr_proxy :default_encodingstyle, true
__attr_proxy :allow_unqualified_element, true
__attr_proxy :generate_explicit_type, true
def httpproxy
@servant.options["protocol.http.proxy"]
end
def httpproxy=(httpproxy)
@servant.options["protocol.http.proxy"] = httpproxy
end
def wiredump_dev
@servant.options["protocol.http.wiredump_dev"]
end
def wiredump_dev=(wiredump_dev)
@servant.options["protocol.http.wiredump_dev"] = wiredump_dev
end
def mandatorycharset
@servant.options["protocol.mandatorycharset"]
end
def mandatorycharset=(mandatorycharset)
@servant.options["protocol.mandatorycharset"] = mandatorycharset
end
def wiredump_file_base
@servant.options["protocol.wiredump_file_base"]
end
def wiredump_file_base=(wiredump_file_base)
@servant.options["protocol.wiredump_file_base"] = wiredump_file_base
end
def initialize(wsdl, port, logdev)
@servant = Servant__.new(self, wsdl, port, logdev)
if env_httpproxy = ::SOAP::Env::HTTP_PROXY
@servant.options["protocol.http.proxy"] = env_httpproxy
end
if env_httpproxy = ::SOAP::Env::NO_PROXY
@servant.options["protocol.http.no_proxy"] = env_httpproxy
end
end
def inspect
"#<#{self.class}:#{@servant.port.name}>"
end
def reset_stream
@servant.reset_stream
@servant.streamhandler.reset
end
# Backward compatibility.
@ -115,124 +155,43 @@ class WSDLDriver
include Logger::Severity
include SOAP
attr_reader :wsdl
attr_reader :options
attr_reader :streamhandler
attr_reader :port
attr_reader :opt
attr_accessor :logdev
attr_accessor :mapping_registry
attr_accessor :wsdl_mapping_registry
attr_reader :wiredump_dev
attr_reader :wiredump_file_base
attr_reader :httpproxy
attr_accessor :mandatorycharset
attr_accessor :default_encodingstyle
attr_accessor :allow_unqualified_element
attr_accessor :generate_explicit_type
class Mapper
def initialize(elements, types)
@elements = elements
@types = types
end
def obj2ele(obj, name)
if ele = @elements[name]
_obj2ele(obj, ele)
elsif type = @types[name]
obj2type(obj, type)
else
raise RuntimeError.new("Cannot find name #{name} in schema.")
end
end
def ele2obj(ele, *arg)
raise NotImplementedError.new
end
private
def _obj2ele(obj, ele)
o = nil
if ele.type
if type = @types[ele.type]
o = obj2type(obj, type)
elsif type = TypeMap[ele.type]
o = base2soap(obj, type)
else
raise RuntimeError.new("Cannot find type #{ele.type}.")
end
o.elename = ele.name
elsif ele.local_complextype
o = SOAPElement.new(ele.name)
ele.local_complextype.each_element do |child_name, child_ele|
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele))
end
else
raise RuntimeError.new("Illegal schema?")
end
o
end
def obj2type(obj, type)
o = SOAPElement.new(type.name)
type.each_element do |child_name, child_ele|
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele))
end
o
end
def _ele2obj(ele)
raise NotImplementedError.new
end
def base2soap(obj, type)
soap_obj = nil
if type <= XSD::XSDString
soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj)
else
soap_obj = type.new(obj)
end
soap_obj
end
def find_attribute(obj, attr_name)
if obj.respond_to?(attr_name)
obj.__send__(attr_name)
elsif obj.is_a?(Hash)
obj[attr_name] || obj[attr_name.intern]
else
obj.instance_eval("@#{ attr_name }")
end
end
end
def initialize(host, wsdl, port, logdev, opt)
def initialize(host, wsdl, port, logdev)
@host = host
@wsdl = wsdl
@port = port
@logdev = logdev
@opt = opt.dup
@options = ::SOAP::Property.new
set_options
@mapping_registry = nil # for rpc unmarshal
@wsdl_mapping_registry = nil # for rpc marshal
@wiredump_dev = nil
@default_encodingstyle = EncodingNamespace
@allow_unqualified_element = true
@generate_explicit_type = false
@wiredump_file_base = nil
@mandatorycharset = nil
@wsdl_elements = @wsdl.collect_elements
@wsdl_types = @wsdl.collect_complextypes
@rpc_decode_typemap = @wsdl_types + @wsdl.soap_rpc_complextypes(port.find_binding)
@rpc_decode_typemap = @wsdl_types +
@wsdl.soap_rpc_complextypes(port.find_binding)
@wsdl_mapping_registry = Mapping::WSDLRegistry.new(@rpc_decode_typemap)
@doc_mapper = Mapper.new(@wsdl_elements, @wsdl_types)
@default_encodingstyle = EncodingNamespace
@allow_unqualified_element = true
@generate_explicit_type = false
create_streamhandler(@port.soap_address.location,
ENV['http_proxy'] || ENV['HTTP_PROXY'])
@operations = {}
endpoint_url = @port.soap_address.location
@streamhandler = HTTPPostStreamHandler.new(endpoint_url,
@options["protocol.http"] ||= ::SOAP::Property.new)
# Convert a map which key is QName, to a Hash which key is String.
@operations = {}
@port.inputoperation_map.each do |op_name, op_info|
@operations[op_name.name] = op_info
add_method_interface(op_info)
@ -246,27 +205,6 @@ class WSDLDriver
def endpoint_url=(endpoint_url)
@streamhandler.endpoint_url = endpoint_url
@streamhandler.reset
log(DEBUG) { "endpoint_url=: set endpoint_url #{ endpoint_url }." }
end
def wiredump_dev=(dev)
@wiredump_dev = dev
@streamhandler.wiredump_dev = @wiredump_dev
@streamhandler.reset
end
def wiredump_file_base=(base)
@wiredump_file_base = base
end
def httpproxy=(httpproxy)
@streamhandler.proxy = httpproxy
@streamhandler.reset
log(DEBUG) { "httpproxy=: set httpproxy #{ httpproxy }." }
end
def reset_stream
@streamhandler.reset
end
def rpc_send(method_name, *params)
@ -330,12 +268,6 @@ class WSDLDriver
private
def create_streamhandler(endpoint_url, httpproxy)
@streamhandler = HTTPPostStreamHandler.new(endpoint_url, httpproxy,
XSD::Charset.encoding_label)
@streamhandler.wiredump_dev = @wiredump_dev
end
def create_method_obj(names, params)
o = Object.new
for idx in 0 ... params.length
@ -450,16 +382,16 @@ class WSDLDriver
def add_rpc_method_interface(name, parts_names)
i = 0
param_names = parts_names.collect { |orgname| i += 1; "arg#{ i }" }
callparam_str = (param_names.collect { |pname| ", " + pname }).join
callparam = (param_names.collect { |pname| ", " + pname }).join
@host.instance_eval <<-EOS
def #{ name }(#{ param_names.join(", ") })
@servant.rpc_send(#{ name.dump }#{ callparam_str })
@servant.rpc_send(#{ name.dump }#{ callparam })
end
EOS
end
def create_options
opt = @opt.dup
opt = {}
opt[:default_encodingstyle] = @default_encodingstyle
opt[:allow_unqualified_element] = @allow_unqualified_element
opt[:generate_explicit_type] = @generate_explicit_type
@ -469,14 +401,94 @@ class WSDLDriver
def log(sev)
@logdev.add(sev, nil, self.class) { yield } if @logdev
end
end
def initialize(wsdl, port, logdev, opt)
@servant = Servant__.new(self, wsdl, port, logdev, opt)
end
def set_options
@options.add_hook("protocol.mandatorycharset") do |key, value|
@mandatorycharset = value
end
@options.add_hook("protocol.wiredump_file_base") do |key, value|
@wiredump_file_base = value
end
@options["protocol.http.charset"] = XSD::Charset.encoding_label
end
def inspect
"#<#{self.class}:#{@servant.port.name}>"
class Mapper
def initialize(elements, types)
@elements = elements
@types = types
end
def obj2ele(obj, name)
if ele = @elements[name]
_obj2ele(obj, ele)
elsif type = @types[name]
obj2type(obj, type)
else
raise RuntimeError.new("Cannot find name #{name} in schema.")
end
end
def ele2obj(ele, *arg)
raise NotImplementedError.new
end
private
def _obj2ele(obj, ele)
o = nil
if ele.type
if type = @types[ele.type]
o = obj2type(obj, type)
elsif type = TypeMap[ele.type]
o = base2soap(obj, type)
else
raise RuntimeError.new("Cannot find type #{ele.type}.")
end
o.elename = ele.name
elsif ele.local_complextype
o = SOAPElement.new(ele.name)
ele.local_complextype.each_element do |child_name, child_ele|
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele))
end
else
raise RuntimeError.new("Illegal schema?")
end
o
end
def obj2type(obj, type)
o = SOAPElement.new(type.name)
type.each_element do |child_name, child_ele|
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele))
end
o
end
def _ele2obj(ele)
raise NotImplementedError.new
end
def base2soap(obj, type)
soap_obj = nil
if type <= XSD::XSDString
soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj)
else
soap_obj = type.new(obj)
end
soap_obj
end
def find_attribute(obj, attr_name)
if obj.respond_to?(attr_name)
obj.__send__(attr_name)
elsif obj.is_a?(Hash)
obj[attr_name] || obj[attr_name.intern]
else
obj.instance_eval("@#{ attr_name }")
end
end
end
end
end

View file

@ -8,6 +8,7 @@
require 'wsdl/info'
require 'wsdl/parser'
require 'soap/soap'
module WSDL
@ -27,8 +28,14 @@ class Importer
if FileTest.exist?(location)
content = File.open(location).read
else
proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
content = web_client.new(proxy, "WSDL4R").get_content(location)
client = web_client.new(nil, "WSDL4R")
if env_httpproxy = ::SOAP::Env::HTTP_PROXY
client.proxy = env_httpproxy
end
if env_no_proxy = ::SOAP::Env::NO_PROXY
client.no_proxy = env_no_proxy
end
content = client.get_content(location)
end
opt = {} # charset?
begin

View file

@ -27,18 +27,13 @@ public
begin
require 'xsd/iconvcharset'
@encoding = 'UTF8'
sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' : 'shift_jis'
EncodingConvertMap[['UTF8', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) }
EncodingConvertMap[['EUC' , 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) }
EncodingConvertMap[['EUC' , 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv("shift_jis", "euc-jp", str) }
if /(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM
EncodingConvertMap[['UTF8', 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv("cp932", "utf-8", str) }
EncodingConvertMap[['SJIS', 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", "cp932", str) }
EncodingConvertMap[['SJIS', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "cp932", str) }
else
EncodingConvertMap[['UTF8', 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv("shift_jis", "utf-8", str) }
EncodingConvertMap[['SJIS', 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", "shift_jis", str) }
EncodingConvertMap[['SJIS', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "shift_jis", str) }
end
EncodingConvertMap[['EUC' , 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) }
EncodingConvertMap[['UTF8', 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) }
EncodingConvertMap[['SJIS', 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) }
EncodingConvertMap[['SJIS', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) }
rescue LoadError
begin
require 'nkf'
@ -75,6 +70,11 @@ public
@encoding
end
def Charset.encoding=(encoding)
STDERR.puts("xsd charset is set to #{encoding}") if $DEBUG
@encoding = encoding
end
def Charset.encoding_label
charset_label(@encoding)
end

View file

@ -369,7 +369,7 @@ module MarshalTestLib
class MyTime < Time; def initialize(v, *args) super(*args); @v = v; end end
def test_time
# once there was a bug caused by usec overflow. try a little harder.
100.times do
10.times do
t = Time.now
marshal_equal(t, t.usec.to_s)
end

View file

@ -58,8 +58,15 @@ class TestDatetime < Test::Unit::TestCase
end
def test_datetime
d = DateTime.now
assert_equal(d + 1, @client.now(d))
d1 = DateTime.now
d2 = @client.now(d1)
assert_equal(d2.year, d1.year)
assert_equal(d2.month, d1.month)
assert_equal(d2.day, d1.day + 1)
assert_equal(d2.hour, d1.hour)
assert_equal(d2.min, d1.min)
assert_equal(d2.sec, d1.sec)
assert_equal(d2.sec, d1.sec)
end
def test_time