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

* added files

* lib/soap/attachment.rb
          * lib/soap/header
          * lib/soap/mimemessage.rb
          * lib/soap/rpc/httpserver.rb
          * lib/wsdl/soap/cgiStubCreator.rb
          * lib/wsdl/soap/classDefCreator.rb
          * lib/wsdl/soap/classDefCreatorSupport.rb
          * lib/wsdl/soap/clientSkeltonCreator.rb
          * lib/wsdl/soap/driverCreator.rb
          * lib/wsdl/soap/mappingRegistryCreator.rb
          * lib/wsdl/soap/methodDefCreator.rb
          * lib/wsdl/soap/servantSkeltonCreator.rb
          * lib/wsdl/soap/standaloneServerStubCreator.rb
          * lib/wsdl/xmlSchema/enumeration.rb
          * lib/wsdl/xmlSchema/simpleRestriction.rb
          * lib/wsdl/xmlSchema/simpleType.rb
          * lib/xsd/codegen
          * lib/xsd/codegen.rb
          * sample/soap/authheader
          * sample/soap/raa2.4
          * sample/soap/ssl
          * sample/soap/swa
          * sample/soap/whois.rb
          * sample/soap/calc/samplehttpd.conf
          * sample/soap/exchange/samplehttpd.conf
          * sample/soap/sampleStruct/samplehttpd.conf
          * sample/wsdl/raa2.4
          * sample/wsdl/googleSearch/samplehttpd.conf
          * test/openssl/_test_ssl.rb
          * test/soap/header
          * test/soap/ssl
          * test/soap/struct
          * test/soap/swa
          * test/soap/wsdlDriver
          * test/wsdl/multiplefault.wsdl
          * test/wsdl/simpletype
          * test/wsdl/test_multiplefault.rb

        * modified files
          * lib/soap/baseData.rb
          * lib/soap/element.rb
          * lib/soap/generator.rb
          * lib/soap/marshal.rb
          * lib/soap/netHttpClient.rb
          * lib/soap/parser.rb
          * lib/soap/processor.rb
          * lib/soap/property.rb
          * lib/soap/soap.rb
          * lib/soap/streamHandler.rb
          * lib/soap/wsdlDriver.rb
          * lib/soap/encodingstyle/handler.rb
          * lib/soap/encodingstyle/literalHandler.rb
          * lib/soap/encodingstyle/soapHandler.rb
          * lib/soap/mapping/factory.rb
          * lib/soap/mapping/mapping.rb
          * lib/soap/mapping/registry.rb
          * lib/soap/mapping/rubytypeFactory.rb
          * lib/soap/mapping/wsdlRegistry.rb
          * lib/soap/rpc/cgistub.rb
          * lib/soap/rpc/driver.rb
          * lib/soap/rpc/element.rb
          * lib/soap/rpc/proxy.rb
          * lib/soap/rpc/router.rb
          * lib/soap/rpc/soaplet.rb
          * lib/soap/rpc/standaloneServer.rb
          * lib/wsdl/data.rb
          * lib/wsdl/definitions.rb
          * lib/wsdl/operation.rb
          * lib/wsdl/parser.rb
          * lib/wsdl/soap/definitions.rb
          * lib/wsdl/xmlSchema/complexContent.rb
          * lib/wsdl/xmlSchema/complexType.rb
          * lib/wsdl/xmlSchema/data.rb
          * lib/wsdl/xmlSchema/parser.rb
          * lib/wsdl/xmlSchema/schema.rb
          * lib/xsd/datatypes.rb
          * lib/xsd/qname.rb
          * sample/soap/calc/httpd.rb
          * sample/soap/exchange/httpd.rb
          * sample/soap/sampleStruct/httpd.rb
          * sample/soap/sampleStruct/server.rb
          * sample/wsdl/amazon/AmazonSearch.rb
          * sample/wsdl/amazon/AmazonSearchDriver.rb
          * sample/wsdl/googleSearch/httpd.rb
          * test/soap/test_basetype.rb
          * test/soap/test_property.rb
          * test/soap/test_streamhandler.rb
          * test/soap/calc/test_calc.rb
          * test/soap/calc/test_calc2.rb
          * test/soap/calc/test_calc_cgi.rb
          * test/soap/helloworld/test_helloworld.rb
          * test/wsdl/test_emptycomplextype.rb
          * test/wsdl/axisArray/test_axisarray.rb
          * test/wsdl/datetime/test_datetime.rb
          * test/wsdl/raa/test_raa.rb
          * test/xsd/test_xmlschemaparser.rb
          * test/xsd/test_xsd.rb

        * summary
          * add SOAP Header mustUnderstand support.

          * add HTTP client SSL configuration and Cookies support (works
            completely with http-access2).

          * add header handler for handling sending/receiving SOAP Header.

          * map Ruby's anonymous Struct to common SOAP Struct in SOAP Object
            Model.  it caused error.

          * add WSDL simpleType support to restrict lexical value space.

          * add SOAP with Attachment support.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nahi 2004-07-03 15:29:32 +00:00
parent df2066555d
commit ab31bf0d4d
60 changed files with 2262 additions and 3170 deletions

116
ChangeLog
View file

@ -1,3 +1,119 @@
Sun Jul 4 00:24:40 2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
* added files
* lib/soap/attachment.rb
* lib/soap/header
* lib/soap/mimemessage.rb
* lib/soap/rpc/httpserver.rb
* lib/wsdl/soap/cgiStubCreator.rb
* lib/wsdl/soap/classDefCreator.rb
* lib/wsdl/soap/classDefCreatorSupport.rb
* lib/wsdl/soap/clientSkeltonCreator.rb
* lib/wsdl/soap/driverCreator.rb
* lib/wsdl/soap/mappingRegistryCreator.rb
* lib/wsdl/soap/methodDefCreator.rb
* lib/wsdl/soap/servantSkeltonCreator.rb
* lib/wsdl/soap/standaloneServerStubCreator.rb
* lib/wsdl/xmlSchema/enumeration.rb
* lib/wsdl/xmlSchema/simpleRestriction.rb
* lib/wsdl/xmlSchema/simpleType.rb
* lib/xsd/codegen
* lib/xsd/codegen.rb
* sample/soap/authheader
* sample/soap/raa2.4
* sample/soap/ssl
* sample/soap/swa
* sample/soap/whois.rb
* sample/soap/calc/samplehttpd.conf
* sample/soap/exchange/samplehttpd.conf
* sample/soap/sampleStruct/samplehttpd.conf
* sample/wsdl/raa2.4
* sample/wsdl/googleSearch/samplehttpd.conf
* test/openssl/_test_ssl.rb
* test/soap/header
* test/soap/ssl
* test/soap/struct
* test/soap/swa
* test/soap/wsdlDriver
* test/wsdl/multiplefault.wsdl
* test/wsdl/simpletype
* test/wsdl/test_multiplefault.rb
* modified files
* lib/soap/baseData.rb
* lib/soap/element.rb
* lib/soap/generator.rb
* lib/soap/marshal.rb
* lib/soap/netHttpClient.rb
* lib/soap/parser.rb
* lib/soap/processor.rb
* lib/soap/property.rb
* lib/soap/soap.rb
* lib/soap/streamHandler.rb
* lib/soap/wsdlDriver.rb
* lib/soap/encodingstyle/handler.rb
* lib/soap/encodingstyle/literalHandler.rb
* lib/soap/encodingstyle/soapHandler.rb
* lib/soap/mapping/factory.rb
* lib/soap/mapping/mapping.rb
* lib/soap/mapping/registry.rb
* lib/soap/mapping/rubytypeFactory.rb
* lib/soap/mapping/wsdlRegistry.rb
* lib/soap/rpc/cgistub.rb
* lib/soap/rpc/driver.rb
* lib/soap/rpc/element.rb
* lib/soap/rpc/proxy.rb
* lib/soap/rpc/router.rb
* lib/soap/rpc/soaplet.rb
* lib/soap/rpc/standaloneServer.rb
* lib/wsdl/data.rb
* lib/wsdl/definitions.rb
* lib/wsdl/operation.rb
* lib/wsdl/parser.rb
* lib/wsdl/soap/definitions.rb
* lib/wsdl/xmlSchema/complexContent.rb
* lib/wsdl/xmlSchema/complexType.rb
* lib/wsdl/xmlSchema/data.rb
* lib/wsdl/xmlSchema/parser.rb
* lib/wsdl/xmlSchema/schema.rb
* lib/xsd/datatypes.rb
* lib/xsd/qname.rb
* sample/soap/calc/httpd.rb
* sample/soap/exchange/httpd.rb
* sample/soap/sampleStruct/httpd.rb
* sample/soap/sampleStruct/server.rb
* sample/wsdl/amazon/AmazonSearch.rb
* sample/wsdl/amazon/AmazonSearchDriver.rb
* sample/wsdl/googleSearch/httpd.rb
* test/soap/test_basetype.rb
* test/soap/test_property.rb
* test/soap/test_streamhandler.rb
* test/soap/calc/test_calc.rb
* test/soap/calc/test_calc2.rb
* test/soap/calc/test_calc_cgi.rb
* test/soap/helloworld/test_helloworld.rb
* test/wsdl/test_emptycomplextype.rb
* test/wsdl/axisArray/test_axisarray.rb
* test/wsdl/datetime/test_datetime.rb
* test/wsdl/raa/test_raa.rb
* test/xsd/test_xmlschemaparser.rb
* test/xsd/test_xsd.rb
* summary
* add SOAP Header mustUnderstand support.
* add HTTP client SSL configuration and Cookies support (works
completely with http-access2).
* add header handler for handling sending/receiving SOAP Header.
* map Ruby's anonymous Struct to common SOAP Struct in SOAP Object
Model. it caused error.
* add WSDL simpleType support to restrict lexical value space.
* add SOAP with Attachment support.
Sat Jul 3 17:19:44 2004 WATANABE Hirofumi <eban@ruby-lang.org> Sat Jul 3 17:19:44 2004 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/tk/lib/tkextlib/tkDND.rb: fix syntax error. * ext/tk/lib/tkextlib/tkDND.rb: fix syntax error.

View file

@ -1,5 +1,5 @@
# soap/baseData.rb: SOAP4R - Base type library # soap/baseData.rb: SOAP4R - Base type library
# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2000, 2001, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -30,20 +30,10 @@ end
### ###
## Marker of SOAP/DM types. ## for SOAP type(base and compound)
# #
module SOAPType; end module SOAPType
###
## Mix-in module for SOAP base type instances.
#
module SOAPBasetype
include SOAPType
include SOAP
attr_accessor :encodingstyle attr_accessor :encodingstyle
attr_accessor :elename attr_accessor :elename
attr_accessor :id attr_accessor :id
attr_reader :precedents attr_reader :precedents
@ -51,46 +41,10 @@ module SOAPBasetype
attr_accessor :parent attr_accessor :parent
attr_accessor :position attr_accessor :position
attr_reader :extraattr attr_reader :extraattr
public
def initialize(*vars)
super(*vars)
@encodingstyle = nil
@elename = XSD::QName.new
@id = nil
@precedents = []
@parent = nil
@position = nil
@extraattr = {}
end
end
###
## Mix-in module for SOAP compound type instances.
#
module SOAPCompoundtype
include SOAPType
include SOAP
attr_accessor :encodingstyle
attr_accessor :elename
attr_accessor :id
attr_reader :precedents
attr_accessor :root
attr_accessor :parent
attr_accessor :position
attr_reader :extraattr
attr_accessor :definedtype attr_accessor :definedtype
public def initialize(*arg)
super(*arg)
def initialize(type)
super()
@type = type
@encodingstyle = nil @encodingstyle = nil
@elename = XSD::QName.new @elename = XSD::QName.new
@id = nil @id = nil
@ -101,6 +55,40 @@ public
@definedtype = nil @definedtype = nil
@extraattr = {} @extraattr = {}
end end
def rootnode
node = self
while node = node.parent
break if SOAPEnvelope === node
end
node
end
end
###
## for SOAP base type
#
module SOAPBasetype
include SOAPType
include SOAP
def initialize(*arg)
super(*arg)
end
end
###
## for SOAP compound type
#
module SOAPCompoundtype
include SOAPType
include SOAP
def initialize(*arg)
super(*arg)
end
end end
@ -114,20 +102,14 @@ class SOAPReference < XSD::NSDBase
public public
attr_accessor :refid attr_accessor :refid
attr_accessor :elename
# Override the definition in SOAPBasetype. # Override the definition in SOAPBasetype.
def initialize(refid = nil) def initialize(obj = nil)
super() super()
@type = XSD::QName.new @type = XSD::QName.new
@encodingstyle = nil @refid = nil
@elename = XSD::QName.new
@id = nil
@precedents = []
@root = false
@parent = nil
@refid = refid
@obj = nil @obj = nil
__setobj__(obj) if obj
end end
def __getobj__ def __getobj__
@ -136,7 +118,7 @@ public
def __setobj__(obj) def __setobj__(obj)
@obj = obj @obj = obj
@refid = SOAPReference.create_refid(@obj) @refid = @obj.id || SOAPReference.create_refid(@obj)
@obj.id = @refid unless @obj.id @obj.id = @refid unless @obj.id
@obj.precedents << self @obj.precedents << self
# Copies NSDBase information # Copies NSDBase information
@ -159,17 +141,54 @@ public
end end
end end
def self.decode(elename, refid) def refidstr
'#' + @refid
end
def self.create_refid(obj)
'id' + obj.__id__.to_s
end
def self.decode(elename, refidstr)
if /\A#(.*)\z/ =~ refidstr
refid = $1
elsif /\Acid:(.*)\z/ =~ refidstr
refid = $1
else
raise ArgumentError.new("illegal refid #{refidstr}")
end
d = super(elename) d = super(elename)
d.refid = refid d.refid = refid
d d
end end
end
def self.create_refid(obj)
'id' << obj.__id__.to_s class SOAPExternalReference < XSD::NSDBase
include SOAPBasetype
extend SOAPModuleUtils
def initialize
super()
@type = XSD::QName.new
end
def referred
rootnode.external_content[external_contentid] = self
end
def refidstr
'cid:' + external_contentid
end
private
def external_contentid
raise NotImplementedError.new
end end
end end
class SOAPNil < XSD::XSDNil class SOAPNil < XSD::XSDNil
include SOAPBasetype include SOAPBasetype
extend SOAPModuleUtils extend SOAPModuleUtils
@ -326,7 +345,8 @@ class SOAPStruct < XSD::NSDBase
public public
def initialize(type = nil) def initialize(type = nil)
super(type || XSD::QName.new) super()
@type = type || XSD::QName.new
@array = [] @array = []
@data = [] @data = []
end end
@ -362,6 +382,7 @@ public
def []=(idx, data) def []=(idx, data)
if @array.include?(idx) if @array.include?(idx)
data.parent = self if data.respond_to?(:parent=)
@data[@array.index(idx)] = data @data[@array.index(idx)] = data
else else
add(idx, data) add(idx, data)
@ -401,31 +422,42 @@ private
@array.push(name) @array.push(name)
value.elename = value.elename.dup_name(name) value.elename = value.elename.dup_name(name)
@data.push(value) @data.push(value)
value.parent = self if value.respond_to?(:parent=)
value
end end
end end
# SOAPElement is not typed so it does not derive NSDBase. # SOAPElement is not typed so it is not derived from NSDBase.
class SOAPElement class SOAPElement
include Enumerable include Enumerable
attr_accessor :encodingstyle attr_accessor :encodingstyle
attr_accessor :extraattr
attr_accessor :elename
attr_accessor :id
attr_reader :precedents attr_reader :precedents
attr_accessor :root
attr_accessor :parent
attr_accessor :position
attr_accessor :extraattr
attr_accessor :qualified attr_accessor :qualified
attr_accessor :elename
def initialize(elename, text = nil) def initialize(elename, text = nil)
if !elename.is_a?(XSD::QName) if !elename.is_a?(XSD::QName)
elename = XSD::QName.new(nil, elename) elename = XSD::QName.new(nil, elename)
end end
@encodingstyle = LiteralNamespace @encodingstyle = LiteralNamespace
@extraattr = {} @elename = elename
@id = nil
@precedents = [] @precedents = []
@root = false
@parent = nil
@position = nil
@extraattr = {}
@qualified = false @qualified = false
@elename = elename
@array = [] @array = []
@data = [] @data = []
@ -450,6 +482,7 @@ class SOAPElement
def []=(idx, data) def []=(idx, data)
if @array.include?(idx) if @array.include?(idx)
data.parent = self if data.respond_to?(:parent=)
@data[@array.index(idx)] = data @data[@array.index(idx)] = data
else else
add(data) add(data)
@ -470,7 +503,7 @@ class SOAPElement
else else
hash = {} hash = {}
each do |k, v| each do |k, v|
hash[k] = v.to_obj hash[k] = v.is_a?(SOAPElement) ? v.to_obj : v.to_s
end end
hash hash
end end
@ -483,8 +516,7 @@ class SOAPElement
end end
def self.decode(elename) def self.decode(elename)
o = SOAPElement.new o = SOAPElement.new(elename)
o.elename = elename
o o
end end
@ -493,7 +525,7 @@ class SOAPElement
if hash_or_string.is_a?(Hash) if hash_or_string.is_a?(Hash)
hash_or_string.each do |k, v| hash_or_string.each do |k, v|
child = self.from_obj(v) child = self.from_obj(v)
child.elename = XSD::QName.new(nil, k) child.elename = k.is_a?(XSD::QName) ? k : XSD::QName.new(nil, k.to_s)
o.add(child) o.add(child)
end end
else else
@ -508,6 +540,8 @@ private
add_accessor(name) add_accessor(name)
@array.push(name) @array.push(name)
@data.push(value) @data.push(value)
value.parent = self if value.respond_to?(:parent=)
value
end end
def add_accessor(name) def add_accessor(name)
@ -550,7 +584,8 @@ public
attr_reader :arytype attr_reader :arytype
def initialize(type = nil, rank = 1, arytype = nil) def initialize(type = nil, rank = 1, arytype = nil)
super(type || XSD::QName.new) super()
@type = type || XSD::QName.new
@rank = rank @rank = rank
@data = Array.new @data = Array.new
@sparse = false @sparse = false
@ -609,6 +644,7 @@ public
end end
@offset = idxary @offset = idxary
value.parent = self if value.respond_to?(:parent=)
offsetnext offsetnext
end end

View file

@ -1,5 +1,5 @@
# SOAP4R - SOAP elements library # SOAP4R - SOAP elements library
# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2000, 2001, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -71,6 +71,10 @@ public
self.faultactor.elename = EleFaultActorName if self.faultactor self.faultactor.elename = EleFaultActorName if self.faultactor
self.detail.elename = EleFaultDetailName if self.detail self.detail.elename = EleFaultDetailName if self.detail
end end
faultcode.parent = self if faultcode
faultstring.parent = self if faultstring
faultactor.parent = self if faultactor
detail.parent = self if detail
end end
def encode(generator, ns, attrs = {}) def encode(generator, ns, attrs = {})
@ -91,8 +95,6 @@ end
class SOAPBody < SOAPStruct class SOAPBody < SOAPStruct
include SOAPEnvelopeElement include SOAPEnvelopeElement
public
def initialize(data = nil, is_fault = false) def initialize(data = nil, is_fault = false)
super(nil) super(nil)
@elename = EleBodyName @elename = EleBodyName
@ -138,38 +140,39 @@ class SOAPHeaderItem < XSD::NSDBase
public public
attr_accessor :content attr_accessor :element
attr_accessor :mustunderstand attr_accessor :mustunderstand
attr_accessor :encodingstyle attr_accessor :encodingstyle
def initialize(content, mustunderstand = true, encodingstyle = nil) def initialize(element, mustunderstand = true, encodingstyle = nil)
super(nil) super()
@content = content @type = nil
@element = element
@mustunderstand = mustunderstand @mustunderstand = mustunderstand
@encodingstyle = encodingstyle || LiteralNamespace @encodingstyle = encodingstyle
element.parent = self if element
end end
def encode(generator, ns, attrs = {}) def encode(generator, ns, attrs = {})
attrs.each do |key, value| attrs.each do |key, value|
@content.attr[key] = value @element.extraattr[key] = value
end end
@content.attr[ns.name(EnvelopeNamespace, AttrMustUnderstand)] = @element.extraattr[ns.name(AttrMustUnderstandName)] =
(@mustunderstand ? '1' : '0') (@mustunderstand ? '1' : '0')
if @encodingstyle if @encodingstyle
@content.attr[ns.name(EnvelopeNamespace, AttrEncodingStyle)] = @element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle
@encodingstyle
end end
@content.encodingstyle = @encodingstyle if !@content.encodingstyle @element.encodingstyle = @encodingstyle if !@element.encodingstyle
yield(@content, true) yield(@element, true)
end end
end end
class SOAPHeader < SOAPArray class SOAPHeader < SOAPStruct
include SOAPEnvelopeElement include SOAPEnvelopeElement
def initialize() def initialize
super(nil, 1) # rank == 1 super(nil)
@elename = EleHeaderName @elename = EleHeaderName
@encodingstyle = nil @encodingstyle = nil
end end
@ -183,9 +186,17 @@ class SOAPHeader < SOAPArray
generator.encode_tag_end(name, true) generator.encode_tag_end(name, true)
end end
def add(name, value)
mu = (value.extraattr[AttrMustUnderstandName] == '1')
encstyle = value.extraattr[AttrEncodingStyleName]
item = SOAPHeaderItem.new(value, mu, encstyle)
super(name, item)
end
def length def length
@data.length @data.length
end end
alias size length
end end
@ -193,15 +204,30 @@ class SOAPEnvelope < XSD::NSDBase
include SOAPEnvelopeElement include SOAPEnvelopeElement
include SOAPCompoundtype include SOAPCompoundtype
attr_accessor :header attr_reader :header
attr_accessor :body attr_reader :body
attr_reader :external_content
def initialize(header = nil, body = nil) def initialize(header = nil, body = nil)
super(nil) super()
@type = nil
@elename = EleEnvelopeName @elename = EleEnvelopeName
@encodingstyle = nil @encodingstyle = nil
@header = header @header = header
@body = body @body = body
@external_content = {}
header.parent = self if header
body.parent = self if body
end
def header=(header)
header.parent = self
@header = header
end
def body=(body)
body.parent = self
@body = body
end end
def encode(generator, ns, attrs = {}) def encode(generator, ns, attrs = {})
@ -215,6 +241,10 @@ class SOAPEnvelope < XSD::NSDBase
generator.encode_tag_end(name, true) generator.encode_tag_end(name, true)
end end
def to_ary
[header, body]
end
end end

View file

@ -44,8 +44,8 @@ class Handler
attr_reader :charset attr_reader :charset
attr_accessor :generate_explicit_type attr_accessor :generate_explicit_type
def decode_typemap=(complextypes) def decode_typemap=(definedtypes)
@decode_typemap = complextypes @decode_typemap = definedtypes
end end
def initialize(charset) def initialize(charset)

View file

@ -1,5 +1,5 @@
# SOAP4R - XML Literal EncodingStyle handler library # SOAP4R - XML Literal EncodingStyle handler library
# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2001, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -41,14 +41,18 @@ class LiteralHandler < Handler
generator.encode_rawstring(data.to_s) generator.encode_rawstring(data.to_s)
when XSD::XSDString when XSD::XSDString
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
generator.encode_string(@charset ? XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s) str = data.to_s
str = XSD::Charset.encoding_to_xml(str, @charset) if @charset
generator.encode_string(str)
when XSD::XSDAnySimpleType when XSD::XSDAnySimpleType
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
generator.encode_string(data.to_s) generator.encode_string(data.to_s)
when SOAPStruct when SOAPStruct
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
data.each do |key, value| data.each do |key, value|
value.elename.namespace = data.elename.namespace if !value.elename.namespace if !value.elename.namespace
value.elename.namespace = data.elename.namespace
end
yield(value, true) yield(value, true)
end end
when SOAPArray when SOAPArray
@ -61,8 +65,6 @@ class LiteralHandler < Handler
generator.encode_tag(name, attrs.update(data.extraattr)) generator.encode_tag(name, attrs.update(data.extraattr))
generator.encode_rawstring(data.text) if data.text generator.encode_rawstring(data.text) if data.text
data.each do |key, value| data.each do |key, value|
value.elename.namespace = data.elename.namespace if !value.elename.namespace
#yield(value, data.qualified)
yield(value, qualified) yield(value, qualified)
end end
else else
@ -76,7 +78,8 @@ class LiteralHandler < Handler
else else
data.elename.name data.elename.name
end end
generator.encode_tag_end(name) cr = data.is_a?(SOAPElement) && !data.text
generator.encode_tag_end(name, cr)
end end
@ -92,15 +95,17 @@ class LiteralHandler < Handler
end end
class SOAPUnknown < SOAPTemporalObject class SOAPUnknown < SOAPTemporalObject
def initialize(handler, elename) def initialize(handler, elename, extraattr)
super() super()
@handler = handler @handler = handler
@elename = elename @elename = elename
@extraattr = extraattr
end end
def as_struct def as_element
o = SOAPStruct.decode(@elename, XSD::AnyTypeName) o = SOAPElement.decode(@elename)
o.parent = @parent o.parent = @parent
o.extraattr.update(@extraattr)
@handler.decode_parent(@parent, o) @handler.decode_parent(@parent, o)
o o
end end
@ -108,6 +113,7 @@ class LiteralHandler < Handler
def as_string def as_string
o = SOAPString.decode(@elename) o = SOAPString.decode(@elename)
o.parent = @parent o.parent = @parent
o.extraattr.update(@extraattr)
@handler.decode_parent(@parent, o) @handler.decode_parent(@parent, o)
o o
end end
@ -115,6 +121,7 @@ class LiteralHandler < Handler
def as_nil def as_nil
o = SOAPNil.decode(@elename) o = SOAPNil.decode(@elename)
o.parent = @parent o.parent = @parent
o.extraattr.update(@extraattr)
@handler.decode_parent(@parent, o) @handler.decode_parent(@parent, o)
o o
end end
@ -123,7 +130,7 @@ class LiteralHandler < Handler
def decode_tag(ns, elename, attrs, parent) def decode_tag(ns, elename, attrs, parent)
# ToDo: check if @textbuf is empty... # ToDo: check if @textbuf is empty...
@textbuf = '' @textbuf = ''
o = SOAPUnknown.new(self, elename) o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs))
o.parent = parent o.parent = parent
o o
end end
@ -132,7 +139,7 @@ class LiteralHandler < Handler
o = node.node o = node.node
if o.is_a?(SOAPUnknown) if o.is_a?(SOAPUnknown)
newnode = if /\A\s*\z/ =~ @textbuf newnode = if /\A\s*\z/ =~ @textbuf
o.as_struct o.as_element
else else
o.as_string o.as_string
end end
@ -149,6 +156,15 @@ class LiteralHandler < Handler
@textbuf << text @textbuf << text
end end
def decode_attrs(ns, attrs)
extraattr = {}
attrs.each do |key, value|
qname = ns.parse(key)
extraattr[qname] = value
end
extraattr
end
def decode_prologue def decode_prologue
end end
@ -158,13 +174,18 @@ class LiteralHandler < Handler
def decode_parent(parent, node) def decode_parent(parent, node)
case parent.node case parent.node
when SOAPUnknown when SOAPUnknown
newparent = parent.node.as_struct newparent = parent.node.as_element
node.parent = newparent node.parent = newparent
parent.replace_node(newparent) parent.replace_node(newparent)
decode_parent(parent, node) decode_parent(parent, node)
when SOAPElement
parent.node.add(node)
node.parent = parent.node
when SOAPStruct when SOAPStruct
parent.node.add(node.name, node) parent.node.add(node.elename.name, node)
node.parent = parent.node
when SOAPArray when SOAPArray
if node.position if node.position
@ -173,13 +194,14 @@ class LiteralHandler < Handler
else else
parent.node.add(node) parent.node.add(node)
end end
node.parent = parent.node
when SOAPBasetype when SOAPBasetype
raise EncodingStyleError.new("SOAP base type must not have a child.") raise EncodingStyleError.new("SOAP base type must not have a child.")
else else
# SOAPUnknown does not have parent. # SOAPUnknown does not have parent.
# raise EncodingStyleError.new("Illegal parent: #{ parent }.") raise EncodingStyleError.new("Illegal parent: #{ parent }.")
end end
end end

View file

@ -33,7 +33,7 @@ class SOAPHandler < Handler
attrs = encode_attrs(generator, ns, data, parent) attrs = encode_attrs(generator, ns, data, parent)
if parent && parent.is_a?(SOAPArray) && parent.position if parent && parent.is_a?(SOAPArray) && parent.position
attrs[ns.name(AttrPositionName)] = '[' << parent.position.join(',') << ']' attrs[ns.name(AttrPositionName)] = "[#{ parent.position.join(',') }]"
end end
name = nil name = nil
@ -46,14 +46,19 @@ class SOAPHandler < Handler
case data case data
when SOAPReference when SOAPReference
attrs['href'] = '#' << data.refid attrs['href'] = data.refidstr
generator.encode_tag(name, attrs)
when SOAPExternalReference
data.referred
attrs['href'] = data.refidstr
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
when SOAPRawString when SOAPRawString
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
generator.encode_rawstring(data.to_s) generator.encode_rawstring(data.to_s)
when XSD::XSDString when XSD::XSDString
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
generator.encode_string(@charset ? XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s) generator.encode_string(@charset ?
XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
when XSD::XSDAnySimpleType when XSD::XSDAnySimpleType
generator.encode_tag(name, attrs) generator.encode_tag(name, attrs)
generator.encode_string(data.to_s) generator.encode_string(data.to_s)
@ -202,16 +207,12 @@ class SOAPHandler < Handler
node.replace_node(newnode) node.replace_node(newnode)
o = node.node o = node.node
end end
if o.is_a?(SOAPCompoundtype)
o.definedtype = nil
end
decode_textbuf(o) decode_textbuf(o)
@textbuf = '' # unlink definedtype
o.definedtype = nil
end end
def decode_text(ns, text) def decode_text(ns, text)
# @textbuf is set at decode_tag_end.
@textbuf << text @textbuf << text
end end
@ -235,11 +236,9 @@ class SOAPHandler < Handler
end end
parent.replace_node(newparent) parent.replace_node(newparent)
decode_parent(parent, node) decode_parent(parent, node)
when SOAPStruct when SOAPStruct
parent.node.add(node.elename.name, node) parent.node.add(node.elename.name, node)
node.parent = parent.node node.parent = parent.node
when SOAPArray when SOAPArray
if node.position if node.position
parent.node[*(decode_arypos(node.position))] = node parent.node[*(decode_arypos(node.position))] = node
@ -248,10 +247,8 @@ class SOAPHandler < Handler
parent.node.add(node) parent.node.add(node)
end end
node.parent = parent.node node.parent = parent.node
when SOAPBasetype when SOAPBasetype
raise EncodingStyleError.new("SOAP base type must not have a child.") raise EncodingStyleError.new("SOAP base type must not have a child.")
else else
raise EncodingStyleError.new("Illegal parent: #{ parent.node }.") raise EncodingStyleError.new("Illegal parent: #{ parent.node }.")
end end
@ -269,7 +266,7 @@ private
def create_arytype(ns, data) def create_arytype(ns, data)
XSD::QName.new(data.arytype.namespace, XSD::QName.new(data.arytype.namespace,
content_typename(data.arytype.name) << '[' << data.size.join(',') << ']') content_typename(data.arytype.name) + "[#{ data.size.join(',') }]")
end end
def encode_attrs(generator, ns, data, parent) def encode_attrs(generator, ns, data, parent)
@ -320,10 +317,9 @@ private
def encode_attr_value(generator, ns, qname, value) def encode_attr_value(generator, ns, qname, value)
if value.is_a?(SOAPType) if value.is_a?(SOAPType)
refid = SOAPReference.create_refid(value) ref = SOAPReference.new(value)
value.id = refid
generator.add_reftarget(qname.name, value) generator.add_reftarget(qname.name, value)
'#' + refid ref.refidstr
else else
value.to_s value.to_s
end end
@ -349,8 +345,7 @@ private
typename = ns.parse(typestr) typename = ns.parse(typestr)
typedef = @decode_typemap[typename] typedef = @decode_typemap[typename]
if typedef if typedef
return decode_defined_compoundtype(elename, typename, typedef, return decode_definedtype(elename, typename, typedef, arytypestr)
arytypestr)
end end
end end
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
@ -372,21 +367,42 @@ private
definedtype_name = parenttype.child_type(elename) definedtype_name = parenttype.child_type(elename)
if definedtype_name and (klass = TypeMap[definedtype_name]) if definedtype_name and (klass = TypeMap[definedtype_name])
return klass.decode(elename) return decode_basetype(klass, elename)
elsif definedtype_name == XSD::AnyTypeName elsif definedtype_name == XSD::AnyTypeName
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
extraattr) extraattr)
end end
typedef = definedtype_name ? @decode_typemap[definedtype_name] : if definedtype_name
parenttype.child_defined_complextype(elename) typedef = @decode_typemap[definedtype_name]
decode_defined_compoundtype(elename, definedtype_name, typedef, arytypestr) else
typedef = parenttype.child_defined_complextype(elename)
end
decode_definedtype(elename, definedtype_name, typedef, arytypestr)
end end
def decode_defined_compoundtype(elename, typename, typedef, arytypestr) def decode_definedtype(elename, typename, typedef, arytypestr)
unless typedef unless typedef
raise EncodingStyleError.new("Unknown type '#{ typename }'.") raise EncodingStyleError.new("Unknown type '#{ typename }'.")
end end
if typedef.is_a?(::WSDL::XMLSchema::SimpleType)
decode_defined_simpletype(elename, typename, typedef, arytypestr)
else
decode_defined_complextype(elename, typename, typedef, arytypestr)
end
end
def decode_basetype(klass, elename)
klass.decode(elename)
end
def decode_defined_simpletype(elename, typename, typedef, arytypestr)
o = decode_basetype(TypeMap[typedef.base], elename)
o.definedtype = typedef
o
end
def decode_defined_complextype(elename, typename, typedef, arytypestr)
case typedef.compoundtype case typedef.compoundtype
when :TYPE_STRUCT when :TYPE_STRUCT
o = SOAPStruct.decode(elename, typename) o = SOAPStruct.decode(elename, typename)
@ -406,7 +422,7 @@ private
o.definedtype = typedef o.definedtype = typedef
return o return o
end end
return nil nil
end end
def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr) def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr)
@ -431,7 +447,7 @@ private
end end
if (klass = TypeMap[type]) if (klass = TypeMap[type])
node = klass.decode(elename) node = decode_basetype(klass, elename)
node.extraattr.update(extraattr) node.extraattr.update(extraattr)
return node return node
end end
@ -446,10 +462,12 @@ private
node.set_encoded(@textbuf) node.set_encoded(@textbuf)
when XSD::XSDString when XSD::XSDString
if @charset if @charset
node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset)) @textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset)
else
node.set(@textbuf)
end end
if node.definedtype
node.definedtype.check_lexical_format(@textbuf)
end
node.set(@textbuf)
when SOAPNil when SOAPNil
# Nothing to do. # Nothing to do.
when SOAPBasetype when SOAPBasetype
@ -457,6 +475,7 @@ private
else else
# Nothing to do... # Nothing to do...
end end
@textbuf = ''
end end
NilLiteralMap = { NilLiteralMap = {
@ -526,7 +545,7 @@ private
def decode_attr_value(ns, qname, value) def decode_attr_value(ns, qname, value)
if /\A#/ =~ value if /\A#/ =~ value
o = SOAPReference.new(value) o = SOAPReference.decode(nil, value)
@refpool << o @refpool << o
o o
else else
@ -544,16 +563,18 @@ private
while !@refpool.empty? && count > 0 while !@refpool.empty? && count > 0
@refpool = @refpool.find_all { |ref| @refpool = @refpool.find_all { |ref|
o = @idpool.find { |item| o = @idpool.find { |item|
'#' + item.id == ref.refid item.id == ref.refid
} }
unless o
raise EncodingStyleError.new("Unresolved reference: #{ ref.refid }.")
end
if o.is_a?(SOAPReference) if o.is_a?(SOAPReference)
true true # link of link.
else elsif o
ref.__setobj__(o) ref.__setobj__(o)
false false
elsif o = ref.rootnode.external_content[ref.refid]
ref.__setobj__(o)
false
else
raise EncodingStyleError.new("Unresolved reference: #{ ref.refid }.")
end end
} }
count -= 1 count -= 1

View file

@ -68,9 +68,8 @@ public
if @reftarget && !obj.precedents.empty? if @reftarget && !obj.precedents.empty?
add_reftarget(obj.elename.name, obj) add_reftarget(obj.elename.name, obj)
ref = SOAPReference.new ref = SOAPReference.new(obj)
ref.elename.name = obj.elename.name ref.elename.name = obj.elename.name
ref.__setobj__(obj)
obj.precedents.clear # Avoid cyclic delay. obj.precedents.clear # Avoid cyclic delay.
obj.encodingstyle = parent.encodingstyle obj.encodingstyle = parent.encodingstyle
# SOAPReference is encoded here. # SOAPReference is encoded here.
@ -91,9 +90,9 @@ public
raise FormatEncodeError.new("Element name not defined: #{ obj }.") raise FormatEncodeError.new("Element name not defined: #{ obj }.")
end end
handler.encode_data(self, ns, qualified, obj, parent) do |child, child_q| handler.encode_data(self, ns, qualified, obj, parent) do |child, nextq|
indent_backup, @indent = @indent, @indent + ' ' indent_backup, @indent = @indent, @indent + ' '
encode_data(ns.clone_ns, child_q, child, obj) encode_data(ns.clone_ns, nextq, child, obj)
@indent = indent_backup @indent = indent_backup
end end
handler.encode_data_end(self, ns, qualified, obj, parent) handler.encode_data_end(self, ns, qualified, obj, parent)
@ -110,9 +109,9 @@ public
attrs = {} attrs = {}
if obj.is_a?(SOAPBody) if obj.is_a?(SOAPBody)
@reftarget = obj @reftarget = obj
obj.encode(self, ns, attrs) do |child, child_q| obj.encode(self, ns, attrs) do |child, nextq|
indent_backup, @indent = @indent, @indent + ' ' indent_backup, @indent = @indent, @indent + ' '
encode_data(ns.clone_ns, child_q, child, obj) encode_data(ns.clone_ns, nextq, child, obj)
@indent = indent_backup @indent = indent_backup
end end
@reftarget = nil @reftarget = nil
@ -125,9 +124,9 @@ public
SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag) SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)
end end
end end
obj.encode(self, ns, attrs) do |child, child_q| obj.encode(self, ns, attrs) do |child, nextq|
indent_backup, @indent = @indent, @indent + ' ' indent_backup, @indent = @indent, @indent + ' '
encode_data(ns.clone_ns, child_q, child, obj) encode_data(ns.clone_ns, nextq, child, obj)
@indent = indent_backup @indent = indent_backup
end end
end end

View file

@ -70,6 +70,7 @@ class Factory
end end
def setiv2soap(node, obj, map) def setiv2soap(node, obj, map)
# should we sort instance_variables?
obj.instance_variables.each do |var| obj.instance_variables.each do |var|
name = var.sub(/^@/, '') name = var.sub(/^@/, '')
node.add(Mapping.name2elename(name), node.add(Mapping.name2elename(name),

View file

@ -68,24 +68,26 @@ module Mapping
md_ary md_ary
end end
def self.fault2exception(e, registry = nil) def self.fault2exception(fault, registry = nil)
registry ||= Mapping::DefaultRegistry registry ||= Mapping::DefaultRegistry
detail = if e.detail detail = if fault.detail
soap2obj(e.detail, registry) || "" soap2obj(fault.detail, registry) || ""
else else
"" ""
end end
if detail.is_a?(Mapping::SOAPException) if detail.is_a?(Mapping::SOAPException)
begin begin
remote_backtrace = detail.to_e.backtrace e = detail.to_e
raise detail.to_e remote_backtrace = e.backtrace
rescue Exception => e2 e.set_backtrace(nil)
e2.set_backtrace(remote_backtrace + e2.backtrace) raise e # ruby sets current caller as local backtrace of e => e2.
rescue Exception => e
e.set_backtrace(remote_backtrace + e.backtrace[1..-1])
raise raise
end end
else else
e.detail = detail fault.detail = detail
e.set_backtrace( fault.set_backtrace(
if detail.is_a?(Array) if detail.is_a?(Array)
detail detail
else else
@ -98,9 +100,7 @@ module Mapping
def self._obj2soap(obj, registry, type = nil) def self._obj2soap(obj, registry, type = nil)
if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__]
soap_obj = SOAPReference.new SOAPReference.new(referent)
soap_obj.__setobj__(referent)
soap_obj
else else
registry.obj2soap(obj.class, obj, type) registry.obj2soap(obj.class, obj, type)
end end

View file

@ -44,14 +44,15 @@ class SOAPException; include Marshallable
if @cause.is_a?(::Exception) if @cause.is_a?(::Exception)
@cause.extend(::SOAP::Mapping::MappedException) @cause.extend(::SOAP::Mapping::MappedException)
return @cause return @cause
elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace)
e = RuntimeError.new(@cause.message)
e.set_backtrace(@cause.backtrace)
return e
end end
klass = Mapping.class_from_name( klass = Mapping.class_from_name(
Mapping.elename2name(@excn_type_name.to_s)) Mapping.elename2name(@excn_type_name.to_s))
if klass.nil? if klass.nil? or not klass <= ::Exception
raise RuntimeError.new(@cause.message) return RuntimeError.new(@cause.inspect)
end
unless klass <= ::Exception
raise NameError.new
end end
obj = klass.new(@cause.message) obj = klass.new(@cause.message)
obj.extend(::SOAP::Mapping::MappedException) obj.extend(::SOAP::Mapping::MappedException)
@ -62,50 +63,78 @@ end
# For anyType object: SOAP::Mapping::Object not ::Object # For anyType object: SOAP::Mapping::Object not ::Object
class Object; include Marshallable class Object; include Marshallable
def set_property(name, value) def initialize
var_name = name @__members = []
begin @__value_type = {}
instance_eval <<-EOS
def #{ var_name }
@#{ var_name }
end
def #{ var_name }=(value)
@#{ var_name } = value
end
EOS
self.send(var_name + '=', value)
rescue SyntaxError
var_name = safe_name(var_name)
retry
end
var_name
end
def members
instance_variables.collect { |str| str[1..-1] }
end end
def [](name) def [](name)
if self.respond_to?(name) if @__members.include?(name)
self.send(name) self.__send__(name)
else else
self.send(safe_name(name)) self.__send__(Object.safe_name(name))
end end
end end
def []=(name, value) def []=(name, value)
if self.respond_to?(name) if @__members.include?(name)
self.send(name + '=', value) self.__send__(name + '=', value)
else else
self.send(safe_name(name) + '=', value) self.__send__(Object.safe_name(name) + '=', value)
end end
end end
def __set_property(name, value)
var_name = name
unless @__members.include?(name)
var_name = __define_attr_accessor(var_name)
end
__set_property_value(var_name, value)
var_name
end
def __members
@__members
end
private private
def safe_name(name) def __set_property_value(name, value)
org = self.__send__(name)
case @__value_type[name]
when :single
self.__send__(name + '=', [org, value])
@__value_type[name] = :multi
when :multi
org << value
else
self.__send__(name + '=', value)
@__value_type[name] = :single
end
value
end
def __define_attr_accessor(name)
var_name = name
begin
instance_eval <<-EOS
def #{ var_name }
@#{ var_name }
end
def #{ var_name }=(value)
@#{ var_name } = value
end
EOS
rescue SyntaxError
var_name = Object.safe_name(var_name)
retry
end
@__members << var_name
var_name
end
def Object.safe_name(name)
require 'md5' require 'md5'
"var_" << MD5.new(name).hexdigest "var_" << MD5.new(name).hexdigest
end end
@ -309,7 +338,7 @@ class Registry
def add(obj_class, soap_class, factory, info = nil) def add(obj_class, soap_class, factory, info = nil)
@map.add(obj_class, soap_class, factory, info) @map.add(obj_class, soap_class, factory, info)
end end
alias :set :add alias set add
# This mapping registry ignores type hint. # This mapping registry ignores type hint.
def obj2soap(klass, obj, type_qname = nil) def obj2soap(klass, obj, type_qname = nil)

View file

@ -38,7 +38,7 @@ class RubytypeFactory < Factory
def obj2soap(soap_class, obj, info, map) def obj2soap(soap_class, obj, info, map)
param = nil param = nil
case obj case obj
when String when ::String
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -47,7 +47,7 @@ class RubytypeFactory < Factory
param.extraattr[RubyTypeName] = obj.class.name param.extraattr[RubyTypeName] = obj.class.name
end end
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Time when ::Time
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -56,7 +56,7 @@ class RubytypeFactory < Factory
param.extraattr[RubyTypeName] = obj.class.name param.extraattr[RubyTypeName] = obj.class.name
end end
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Array when ::Array
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -65,19 +65,19 @@ class RubytypeFactory < Factory
param.extraattr[RubyTypeName] = obj.class.name param.extraattr[RubyTypeName] = obj.class.name
end end
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when NilClass when ::NilClass
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
param = @basetype_factory.obj2soap(SOAPNil, obj, info, map) param = @basetype_factory.obj2soap(SOAPNil, obj, info, map)
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when FalseClass, TrueClass when ::FalseClass, ::TrueClass
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map) param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map)
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Integer when ::Integer
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -85,7 +85,7 @@ class RubytypeFactory < Factory
param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map) param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map)
param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map) param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map)
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Float when ::Float
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -94,7 +94,7 @@ class RubytypeFactory < Factory
param.extraattr[RubyTypeName] = obj.class.name param.extraattr[RubyTypeName] = obj.class.name
end end
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Hash when ::Hash
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -114,7 +114,7 @@ class RubytypeFactory < Factory
end end
param.add('default', Mapping._obj2soap(obj.default, map)) param.add('default', Mapping._obj2soap(obj.default, map))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Regexp when ::Regexp
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -150,7 +150,7 @@ class RubytypeFactory < Factory
end end
param.add('options', SOAPInt.new(options)) param.add('options', SOAPInt.new(options))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Range when ::Range
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -163,29 +163,29 @@ class RubytypeFactory < Factory
param.add('end', Mapping._obj2soap(obj.end, map)) param.add('end', Mapping._obj2soap(obj.end, map))
param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?)) param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Class when ::Class
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
if obj.to_s[0] == ?# if obj.to_s[0] == ?#
raise TypeError.new("Can't dump anonymous class #{ obj }.") raise TypeError.new("can't dump anonymous class #{ obj }")
end end
param = SOAPStruct.new(TYPE_CLASS) param = SOAPStruct.new(TYPE_CLASS)
mark_marshalled_obj(obj, param) mark_marshalled_obj(obj, param)
param.add('name', SOAPString.new(obj.name)) param.add('name', SOAPString.new(obj.name))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Module when ::Module
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
if obj.to_s[0] == ?# if obj.to_s[0] == ?#
raise TypeError.new("Can't dump anonymous module #{ obj }.") raise TypeError.new("can't dump anonymous module #{ obj }")
end end
param = SOAPStruct.new(TYPE_MODULE) param = SOAPStruct.new(TYPE_MODULE)
mark_marshalled_obj(obj, param) mark_marshalled_obj(obj, param)
param.add('name', SOAPString.new(obj.name)) param.add('name', SOAPString.new(obj.name))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Symbol when ::Symbol
unless @allow_original_mapping unless @allow_original_mapping
return nil return nil
end end
@ -193,28 +193,37 @@ class RubytypeFactory < Factory
mark_marshalled_obj(obj, param) mark_marshalled_obj(obj, param)
param.add('id', SOAPString.new(obj.id2name)) param.add('id', SOAPString.new(obj.id2name))
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Struct when ::Struct
unless @allow_original_mapping unless @allow_original_mapping
return nil # treat it as an user defined class. [ruby-talk:104980]
#param = unknownobj2soap(soap_class, obj, info, map)
param = SOAPStruct.new(XSD::AnyTypeName)
mark_marshalled_obj(obj, param)
obj.members.each do |member|
param.add(Mapping.name2elename(member),
Mapping._obj2soap(obj[member], map))
end
else
param = SOAPStruct.new(TYPE_STRUCT)
mark_marshalled_obj(obj, param)
param.add('type', ele_type = SOAPString.new(obj.class.to_s))
ele_member = SOAPStruct.new
obj.members.each do |member|
ele_member.add(Mapping.name2elename(member),
Mapping._obj2soap(obj[member], map))
end
param.add('member', ele_member)
addiv2soapattr(param, obj, map)
end end
param = SOAPStruct.new(TYPE_STRUCT) when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat,
mark_marshalled_obj(obj, param) ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup
param.add('type', ele_type = SOAPString.new(obj.class.to_s)) # from 1.8: Process::Status, UnboundMethod
ele_member = SOAPStruct.new
obj.members.each do |member|
ele_member.add(Mapping.name2elename(member),
Mapping._obj2soap(obj[member], map))
end
param.add('member', ele_member)
addiv2soapattr(param, obj, map)
when IO, Binding, Continuation, Data, Dir, File::Stat, MatchData, Method,
Proc, Thread, ThreadGroup # from 1.8: Process::Status, UnboundMethod
return nil return nil
when ::SOAP::Mapping::Object when ::SOAP::Mapping::Object
param = SOAPStruct.new(XSD::AnyTypeName) param = SOAPStruct.new(XSD::AnyTypeName)
mark_marshalled_obj(obj, param) mark_marshalled_obj(obj, param)
addiv2soapattr(param, obj, map) addiv2soapattr(param, obj, map)
when Exception when ::Exception
typestr = Mapping.name2elename(obj.class.to_s) typestr = Mapping.name2elename(obj.class.to_s)
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr)) param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))
mark_marshalled_obj(obj, param) mark_marshalled_obj(obj, param)
@ -249,7 +258,7 @@ private
def unknownobj2soap(soap_class, obj, info, map) def unknownobj2soap(soap_class, obj, info, map)
if obj.class.name.empty? if obj.class.name.empty?
raise TypeError.new("Can't dump anonymous class #{ obj }.") raise TypeError.new("can't dump anonymous class #{ obj }")
end end
singleton_class = class << obj; self; end singleton_class = class << obj; self; end
if !singleton_methods_true(obj).empty? or if !singleton_methods_true(obj).empty? or
@ -369,7 +378,7 @@ private
obj = klass.new obj = klass.new
mark_unmarshalled_obj(node, obj) mark_unmarshalled_obj(node, obj)
node.each do |name, value| node.each do |name, value|
obj.set_property(name, Mapping._soap2obj(value, map)) obj.__set_property(name, Mapping._soap2obj(value, map))
end end
return true, obj return true, obj
else else

View file

@ -18,10 +18,10 @@ module Mapping
class WSDLRegistry class WSDLRegistry
include TraverseSupport include TraverseSupport
attr_reader :complextypes attr_reader :definedtypes
def initialize(complextypes, config = {}) def initialize(definedtypes, config = {})
@complextypes = complextypes @definedtypes = definedtypes
@config = config @config = config
@excn_handler_obj2soap = nil @excn_handler_obj2soap = nil
# For mapping AnyType element. # For mapping AnyType element.
@ -37,27 +37,20 @@ class WSDLRegistry
soap_obj = SOAPNil.new soap_obj = SOAPNil.new
elsif obj.is_a?(XSD::NSDBase) elsif obj.is_a?(XSD::NSDBase)
soap_obj = soap2soap(obj, type_qname) soap_obj = soap2soap(obj, type_qname)
elsif (type = @complextypes[type_qname]) elsif type = @definedtypes[type_qname]
case type.compoundtype soap_obj = obj2type(obj, type)
when :TYPE_STRUCT
soap_obj = struct2soap(obj, type_qname, type)
when :TYPE_ARRAY
soap_obj = array2soap(obj, type_qname, type)
end
elsif (type = TypeMap[type_qname]) elsif (type = TypeMap[type_qname])
soap_obj = base2soap(obj, type) soap_obj = base2soap(obj, type)
elsif type_qname == XSD::AnyTypeName elsif type_qname == XSD::AnyTypeName
soap_obj = @rubytype_factory.obj2soap(nil, obj, nil, nil) soap_obj = @rubytype_factory.obj2soap(nil, obj, nil, nil)
end end
return soap_obj if soap_obj return soap_obj if soap_obj
if @excn_handler_obj2soap if @excn_handler_obj2soap
soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
Mapping._obj2soap(yield_obj, self) Mapping._obj2soap(yield_obj, self)
} }
end end
return soap_obj if soap_obj return soap_obj if soap_obj
raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.") raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.")
end end
@ -74,12 +67,12 @@ private
def soap2soap(obj, type_qname) def soap2soap(obj, type_qname)
if obj.is_a?(SOAPBasetype) if obj.is_a?(SOAPBasetype)
obj obj
elsif obj.is_a?(SOAPStruct) && (type = @complextypes[type_qname]) elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname])
soap_obj = obj soap_obj = obj
mark_marshalled_obj(obj, soap_obj) mark_marshalled_obj(obj, soap_obj)
elements2soap(obj, soap_obj, type.content.elements) elements2soap(obj, soap_obj, type.content.elements)
soap_obj soap_obj
elsif obj.is_a?(SOAPArray) && (type = @complextypes[type_qname]) elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname])
soap_obj = obj soap_obj = obj
contenttype = type.child_type contenttype = type.child_type
mark_marshalled_obj(obj, soap_obj) mark_marshalled_obj(obj, soap_obj)
@ -92,6 +85,33 @@ private
end end
end end
def obj2type(obj, type)
if type.is_a?(::WSDL::XMLSchema::SimpleType)
simple2soap(obj, type)
else
complex2soap(obj, type)
end
end
def simple2soap(obj, type)
o = base2soap(obj, TypeMap[type.base])
if type.restriction.enumeration.empty?
STDERR.puts("#{type.name}: simpleType which is not enum type not supported.")
return o
end
type.check_lexical_format(obj)
o
end
def complex2soap(obj, type)
case type.compoundtype
when :TYPE_STRUCT
struct2soap(obj, type.name, type)
when :TYPE_ARRAY
array2soap(obj, type.name, type)
end
end
def base2soap(obj, type) def base2soap(obj, type)
soap_obj = nil soap_obj = nil
if type <= XSD::XSDString if type <= XSD::XSDString

View file

@ -37,15 +37,16 @@ module Marshal
soap_obj = Mapping.obj2soap(obj, mapping_registry) soap_obj = Mapping.obj2soap(obj, mapping_registry)
body = SOAPBody.new body = SOAPBody.new
body.add(elename, soap_obj) body.add(elename, soap_obj)
SOAP::Processor.marshal(nil, body, {}, io) env = SOAPEnvelope.new(nil, body)
SOAP::Processor.marshal(env, {}, io)
end end
def unmarshal(stream, mapping_registry = MarshalMappingRegistry) def unmarshal(stream, mapping_registry = MarshalMappingRegistry)
header, body = SOAP::Processor.unmarshal(stream) env = SOAP::Processor.unmarshal(stream)
if body.nil? if env.nil?
raise ArgumentError.new("Illegal SOAP marshal format.") raise ArgumentError.new("Illegal SOAP marshal format.")
end end
Mapping.soap2obj(body.root_node, mapping_registry) Mapping.soap2obj(env.body.root_node, mapping_registry)
end end
end end
end end

View file

@ -35,6 +35,10 @@ class NetHttpClient
@no_proxy = nil @no_proxy = nil
end end
def test_loopback_response
raise NotImplementedError.new("not supported for now")
end
def proxy=(proxy_str) def proxy=(proxy_str)
if proxy_str.nil? if proxy_str.nil?
@proxy = nil @proxy = nil
@ -54,7 +58,11 @@ class NetHttpClient
end end
def set_cookie_store(filename) def set_cookie_store(filename)
# ignored. raise NotImplementedError.new
end
def save_cookie_store(filename)
raise NotImplementedError.new
end end
def reset(url) def reset(url)
@ -70,8 +78,8 @@ class NetHttpClient
extra = header.dup extra = header.dup
extra['User-Agent'] = @agent if @agent extra['User-Agent'] = @agent if @agent
res = start(url) { |http| res = start(url) { |http|
http.post(url.request_uri, req_body, extra) http.post(url.request_uri, req_body, extra)
} }
Response.new(res) Response.new(res)
end end

View file

@ -65,6 +65,7 @@ public
attr_accessor :allow_unqualified_element attr_accessor :allow_unqualified_element
def initialize(opt = {}) def initialize(opt = {})
@opt = opt
@parser = XSD::XMLParser.create_parser(self, opt) @parser = XSD::XMLParser.create_parser(self, opt)
@parsestack = nil @parsestack = nil
@lastnode = nil @lastnode = nil
@ -116,7 +117,13 @@ public
encodingstyle = find_encodingstyle(ns, attrs) encodingstyle = find_encodingstyle(ns, attrs)
# Children's encodingstyle is derived from its parent. # Children's encodingstyle is derived from its parent.
encodingstyle ||= parent_encodingstyle || @default_encodingstyle if encodingstyle.nil?
if parent.node.is_a?(SOAPHeader)
encodingstyle = LiteralNamespace
else
encodingstyle = parent_encodingstyle || @default_encodingstyle
end
end
node = decode_tag(ns, name, attrs, parent, encodingstyle) node = decode_tag(ns, name, attrs, parent, encodingstyle)
@ -201,6 +208,11 @@ private
o = nil o = nil
if ele.name == EleEnvelope if ele.name == EleEnvelope
o = SOAPEnvelope.new o = SOAPEnvelope.new
if ext = @opt[:external_content]
ext.each do |k, v|
o.external_content[k] = v
end
end
elsif ele.name == EleHeader elsif ele.name == EleHeader
unless parent.node.is_a?(SOAPEnvelope) unless parent.node.is_a?(SOAPEnvelope)
raise FormatDecodeError.new("Header should be a child of Envelope.") raise FormatDecodeError.new("Header should be a child of Envelope.")
@ -220,7 +232,6 @@ private
o = SOAPFault.new o = SOAPFault.new
parent.node.fault = o parent.node.fault = o
end end
o.parent = parent if o
o o
end end

View file

@ -25,20 +25,18 @@ module Processor
class << self class << self
public public
def marshal(header, body, opt = {}, io = nil) def marshal(env, opt = {}, io = nil)
env = SOAPEnvelope.new(header, body)
generator = create_generator(opt) generator = create_generator(opt)
generator.generate(env, io) marshalled_str = generator.generate(env, io)
unless env.external_content.empty?
opt[:external_content] = env.external_content
end
marshalled_str
end end
def unmarshal(stream, opt = {}) def unmarshal(stream, opt = {})
parser = create_parser(opt) parser = create_parser(opt)
env = parser.parse(stream) parser.parse(stream)
if env
return env.header, env.body
else
return nil, nil
end
end end
def default_parser_option=(rhs) def default_parser_option=(rhs)

View file

@ -34,22 +34,24 @@ module SOAP
class Property class Property
include Enumerable include Enumerable
module Util
def const_from_name(fqname)
fqname.split("::").inject(Kernel) { |klass, name| klass.const_get(name) }
end
module_function :const_from_name
def require_from_name(fqname)
require File.join(fqname.split("::").collect { |ele| ele.downcase })
end
module_function :require_from_name
end
def self.load(stream) def self.load(stream)
new.load(stream) new.load(stream)
end end
def self.open(filename)
File.open(filename) { |f| load(f) }
end
# find property from $:.
def self.loadproperty(propname) def self.loadproperty(propname)
$:.each do |path| new.loadproperty(propname)
if File.file?(file = File.join(path, propname))
return open(file)
end
end
nil
end end
def initialize def initialize
@ -87,6 +89,17 @@ class Property
self self
end end
# find property from $:.
def loadproperty(propname)
return loadpropertyfile(propname) if File.file?(propname)
$:.each do |path|
if File.file?(file = File.join(path, propname))
return loadpropertyfile(file)
end
end
nil
end
# name: a Symbol, String or an Array # name: a Symbol, String or an Array
def [](name) def [](name)
referent(name_to_a(name)) referent(name_to_a(name))
@ -95,10 +108,10 @@ class Property
# name: a Symbol, String or an Array # name: a Symbol, String or an Array
# value: an Object # value: an Object
def []=(name, value) def []=(name, value)
hooks = assign(name_to_a(name), value) name_pair = name_to_a(name).freeze
normalized_name = normalize_name(name) hooks = assign(name_pair, value)
hooks.each do |hook| hooks.each do |hook|
hook.call(normalized_name, value) hook.call(name_pair, value)
end end
value value
end end
@ -109,13 +122,15 @@ class Property
self[generate_new_key] = value self[generate_new_key] = value
end end
# name: a Symbol, String or an Array. nil means hook to the root # name: a Symbol, String or an Array; nil means hook to the root
# cascade: true/false; for cascading hook of sub key
# hook: block which will be called with 2 args, name and value # hook: block which will be called with 2 args, name and value
def add_hook(name = nil, &hook) def add_hook(name = nil, cascade = false, &hook)
if name.nil? if name == nil or name == true or name == false
assign_self_hook(&hook) cascade = name
assign_self_hook(cascade, &hook)
else else
assign_hook(name_to_a(name), &hook) assign_hook(name_to_a(name), cascade, &hook)
end end
end end
@ -192,14 +207,18 @@ protected
@store[key] = value @store[key] = value
end end
def local_hook(key) def local_hook(key, direct)
@self_hook + (@hook[key] || NO_HOOK) hooks = []
(@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade|
hooks << hook if direct or cascade
end
hooks
end end
def local_assign_hook(key, &hook) def local_assign_hook(key, cascade, &hook)
check_lock(key) check_lock(key)
@store[key] ||= nil @store[key] ||= nil
(@hook[key] ||= []) << hook (@hook[key] ||= []) << [hook, cascade]
end end
private private
@ -217,23 +236,23 @@ private
hook = NO_HOOK hook = NO_HOOK
ary[0..-2].each do |name| ary[0..-2].each do |name|
key = to_key(name) key = to_key(name)
hook += ref.local_hook(key) hook += ref.local_hook(key, false)
ref = ref.deref_key(key) ref = ref.deref_key(key)
end end
last_key = to_key(ary.last) last_key = to_key(ary.last)
ref.local_assign(last_key, value) ref.local_assign(last_key, value)
hook + ref.local_hook(last_key) hook + ref.local_hook(last_key, true)
end end
def assign_hook(ary, &hook) def assign_hook(ary, cascade, &hook)
ary[0..-2].inject(self) { |ref, name| ary[0..-2].inject(self) { |ref, name|
ref.deref_key(to_key(name)) ref.deref_key(to_key(name))
}.local_assign_hook(to_key(ary.last), &hook) }.local_assign_hook(to_key(ary.last), cascade, &hook)
end end
def assign_self_hook(&hook) def assign_self_hook(cascade, &hook)
check_lock(nil) check_lock(nil)
@self_hook << hook @self_hook << [hook, cascade]
end end
def each_key def each_key
@ -267,10 +286,6 @@ private
end end
end end
def normalize_name(name)
name_to_a(name).collect { |key| to_key(key) }.join('.')
end
def to_key(name) def to_key(name)
name.to_s.downcase name.to_s.downcase
end end
@ -286,6 +301,13 @@ private
def key_max def key_max
(@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i
end end
def loadpropertyfile(file)
puts "find property at #{file}" if $DEBUG
File.open(file) do |f|
load(f)
end
end
end end

View file

@ -1,5 +1,5 @@
# SOAP4R - CGI stub library # SOAP4R - CGI stub library
# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2001, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -40,7 +40,6 @@ class CGIStub < Logger::Application
@method = ENV['REQUEST_METHOD'] @method = ENV['REQUEST_METHOD']
@size = ENV['CONTENT_LENGTH'].to_i || 0 @size = ENV['CONTENT_LENGTH'].to_i || 0
@contenttype = ENV['CONTENT_TYPE'] @contenttype = ENV['CONTENT_TYPE']
@charset = nil
@soapaction = ENV['HTTP_SOAPAction'] @soapaction = ENV['HTTP_SOAPAction']
@source = stream @source = stream
@body = nil @body = nil
@ -48,7 +47,6 @@ class CGIStub < Logger::Application
def init def init
validate validate
@charset = StreamHandler.parse_media_type(@contenttype)
@body = @source.read(@size) @body = @source.read(@size)
self self
end end
@ -61,8 +59,8 @@ class CGIStub < Logger::Application
@soapaction @soapaction
end end
def charset def contenttype
@charset @contenttype
end end
def to_s def to_s
@ -96,15 +94,21 @@ class CGIStub < Logger::Application
on_init on_init
end end
def add_servant(obj, namespace = @default_namespace, soapaction = nil) def add_rpc_servant(obj, namespace = @default_namespace, soapaction = nil)
RPC.defined_methods(obj).each do |name| RPC.defined_methods(obj).each do |name|
qname = XSD::QName.new(namespace, name) qname = XSD::QName.new(namespace, name)
param_size = obj.method(name).arity.abs param_size = obj.method(name).arity.abs
params = (1..param_size).collect { |i| "p#{ i }" } params = (1..param_size).collect { |i| "p#{i}" }
param_def = SOAP::RPC::SOAPMethod.create_param_def(params) param_def = SOAP::RPC::SOAPMethod.create_param_def(params)
@router.add_method(obj, qname, soapaction, name, param_def) @router.add_method(obj, qname, soapaction, name, param_def)
end end
end end
alias add_servant add_rpc_servant
def add_rpc_headerhandler(obj)
@router.headerhandler << obj
end
alias add_headerhandler add_rpc_headerhandler
def on_init def on_init
# Override this method in derived class to call 'add_method' to add methods. # Override this method in derived class to call 'add_method' to add methods.
@ -142,8 +146,8 @@ class CGIStub < Logger::Application
@router.add_method(receiver, qname, nil, name, param_def) @router.add_method(receiver, qname, nil, name, param_def)
end end
def route(request_string, charset) def route(conn_data)
@router.route(request_string, charset) @router.route(conn_data)
end end
def create_fault_response(e) def create_fault_response(e)
@ -157,32 +161,30 @@ private
httpversion = WEBrick::HTTPVersion.new('1.0') httpversion = WEBrick::HTTPVersion.new('1.0')
@response = WEBrick::HTTPResponse.new({:HTTPVersion => httpversion}) @response = WEBrick::HTTPResponse.new({:HTTPVersion => httpversion})
conn_data = nil
begin begin
log(INFO) { "Received a request from '#{ @remote_user }@#{ @remote_host }'." } log(INFO) { "Received a request from '#{ @remote_user }@#{ @remote_host }'." }
# SOAP request parsing. # SOAP request parsing.
@request = SOAPRequest.new.init @request = SOAPRequest.new.init
@response['Status'] = 200 @response['Status'] = 200
req_charset = @request.charset conn_data = ::SOAP::StreamHandler::ConnectionData.new
req_string = @request.dump conn_data.receive_string = @request.dump
log(DEBUG) { "XML Request: #{req_string}" } conn_data.receive_contenttype = @request.contenttype
res_string, is_fault = route(req_string, req_charset) log(DEBUG) { "XML Request: #{conn_data.receive_string}" }
log(DEBUG) { "XML Response: #{res_string}" } conn_data = route(conn_data)
log(DEBUG) { "XML Response: #{conn_data.send_string}" }
@response['Cache-Control'] = 'private' if conn_data.is_fault
if req_charset
@response['content-type'] = "#{@mediatype}; charset=\"#{req_charset}\""
else
@response['content-type'] = @mediatype
end
if is_fault
@response['Status'] = 500 @response['Status'] = 500
end end
@response.body = res_string
rescue Exception
res_string = create_fault_response($!)
@response['Cache-Control'] = 'private' @response['Cache-Control'] = 'private'
@response['content-type'] = @mediatype @response.body = conn_data.send_string
@response['content-type'] = conn_data.send_contenttype
rescue Exception
conn_data = create_fault_response($!)
@response['Cache-Control'] = 'private'
@response['Status'] = 500 @response['Status'] = 500
@response.body = conn_data.send_string
@response['content-type'] = conn_data.send_contenttype || @mediatype
ensure ensure
buf = '' buf = ''
@response.send_response(buf) @response.send_response(buf)

View file

@ -1,5 +1,5 @@
# SOAP4R - SOAP RPC driver # SOAP4R - SOAP RPC driver
# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2000, 2001, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -13,6 +13,7 @@ require 'soap/rpc/proxy'
require 'soap/rpc/element' require 'soap/rpc/element'
require 'soap/streamHandler' require 'soap/streamHandler'
require 'soap/property' require 'soap/property'
require 'soap/header/handlerset'
module SOAP module SOAP
@ -41,6 +42,8 @@ class Driver
end end
__attr_proxy :options __attr_proxy :options
__attr_proxy :headerhandler
__attr_proxy :test_loopback_response
__attr_proxy :endpoint_url, true __attr_proxy :endpoint_url, true
__attr_proxy :mapping_registry, true __attr_proxy :mapping_registry, true
__attr_proxy :soapaction, true __attr_proxy :soapaction, true
@ -84,6 +87,12 @@ class Driver
@proxy = @servant.proxy @proxy = @servant.proxy
end end
def loadproperty(propertyname)
unless options.loadproperty(propertyname)
raise LoadError.new("No such property to load -- #{propertyname}")
end
end
def inspect def inspect
"#<#{self.class}:#{@servant.streamhandler.inspect}>" "#<#{self.class}:#{@servant.streamhandler.inspect}>"
end end
@ -130,6 +139,7 @@ private
class Servant__ class Servant__
attr_reader :options attr_reader :options
attr_reader :streamhandler attr_reader :streamhandler
attr_reader :headerhandler
attr_reader :proxy attr_reader :proxy
def initialize(host, endpoint_url, namespace) def initialize(host, endpoint_url, namespace)
@ -141,6 +151,7 @@ private
@options = setup_options @options = setup_options
@streamhandler = HTTPPostStreamHandler.new(endpoint_url, @streamhandler = HTTPPostStreamHandler.new(endpoint_url,
@options["protocol.http"] ||= ::SOAP::Property.new) @options["protocol.http"] ||= ::SOAP::Property.new)
@headerhandler = Header::HandlerSet.new
@proxy = Proxy.new(@streamhandler, @soapaction) @proxy = Proxy.new(@streamhandler, @soapaction)
@proxy.allow_unqualified_element = true @proxy.allow_unqualified_element = true
end end
@ -178,27 +189,37 @@ private
@proxy.default_encodingstyle = encodingstyle @proxy.default_encodingstyle = encodingstyle
end end
def test_loopback_response
@streamhandler.test_loopback_response
end
def invoke(headers, body) def invoke(headers, body)
set_wiredump_file_base(body.elename.name) set_wiredump_file_base(body.elename.name)
@proxy.invoke(headers, body) env = @proxy.invoke(headers, body)
if env.nil?
return nil, nil
else
return env.header, env.body
end
end end
def call(name, *params) def call(name, *params)
set_wiredump_file_base(name) set_wiredump_file_base(name)
# Convert parameters: params array => SOAPArray => members array # Convert parameters: params array => SOAPArray => members array
params = Mapping.obj2soap(params, @mapping_registry).to_a params = Mapping.obj2soap(params, @mapping_registry).to_a
header, body = @proxy.call(nil, name, *params) env = @proxy.call(call_headers, name, *params)
raise EmptyResponseError.new("Empty response.") unless body raise EmptyResponseError.new("Empty response.") unless env
receive_headers(env.header)
begin begin
@proxy.check_fault(body) @proxy.check_fault(env.body)
rescue SOAP::FaultError => e rescue SOAP::FaultError => e
Mapping.fault2exception(e) Mapping.fault2exception(e)
end end
ret = body.response ? ret = env.body.response ?
Mapping.soap2obj(body.response, @mapping_registry) : nil Mapping.soap2obj(env.body.response, @mapping_registry) : nil
if body.outparams if env.body.outparams
outparams = body.outparams.collect { |outparam| outparams = env.body.outparams.collect { |outparam|
Mapping.soap2obj(outparam) Mapping.soap2obj(outparam)
} }
return [ret].concat(outparams) return [ret].concat(outparams)
@ -227,10 +248,28 @@ private
@servant.call(#{ name.dump }#{ callparam }) @servant.call(#{ name.dump }#{ callparam })
end end
EOS EOS
@host.method(name)
end end
private private
def call_headers
headers = @headerhandler.on_outbound
if headers.empty?
nil
else
h = ::SOAP::SOAPHeader.new
headers.each do |header|
h.add(header.elename.name, header)
end
h
end
end
def receive_headers(headers)
@headerhandler.on_inbound(headers) if headers
end
def set_wiredump_file_base(name) def set_wiredump_file_base(name)
if @wiredump_file_base if @wiredump_file_base
@streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }" @streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }"

View file

@ -43,7 +43,7 @@ class SOAPBody < SOAPStruct
end end
def void? def void?
root_node.nil? # || root_node.is_a?(SOAPNil) root_node.nil?
end end
def fault def fault
@ -113,6 +113,7 @@ class SOAPMethod < SOAPStruct
params.each do |param, data| params.each do |param, data|
@inparam[param] = data @inparam[param] = data
data.elename.name = param data.elename.name = param
data.parent = self
end end
end end
@ -226,6 +227,8 @@ class SOAPMethodResponse < SOAPMethod
def retval=(retval) def retval=(retval)
@retval = retval @retval = retval
@retval.elename = @retval.elename.dup_name(@retval_name || 'return') @retval.elename = @retval.elename.dup_name(@retval_name || 'return')
retval.parent = self
retval
end end
def each def each

View file

@ -1,5 +1,5 @@
# SOAP4R - RPC Proxy library. # SOAP4R - RPC Proxy library.
# Copyright (C) 2000, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2000, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -12,6 +12,7 @@ require 'soap/mapping'
require 'soap/rpc/rpc' require 'soap/rpc/rpc'
require 'soap/rpc/element' require 'soap/rpc/element'
require 'soap/streamHandler' require 'soap/streamHandler'
require 'soap/mimemessage'
module SOAP module SOAP
@ -79,7 +80,6 @@ public
raise SOAP::RPC::MethodDefinitionError.new( raise SOAP::RPC::MethodDefinitionError.new(
"Method: #{ name } not defined.") "Method: #{ name } not defined.")
end end
Request.new(method, values) Request.new(method, values)
end end
@ -91,21 +91,30 @@ public
req_body = SOAPBody.new(req_body) req_body = SOAPBody.new(req_body)
end end
opt = create_options opt = create_options
send_string = Processor.marshal(req_header, req_body, opt) opt[:external_content] = nil
data = @streamhandler.send(send_string, soapaction) req_env = SOAPEnvelope.new(req_header, req_body)
if data.receive_string.empty? send_string = Processor.marshal(req_env, opt)
conn_data = StreamHandler::ConnectionData.new(send_string)
if ext = opt[: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 = @streamhandler.send(conn_data, soapaction)
if conn_data.receive_string.empty?
return nil, nil return nil, nil
end end
opt = create_options unmarshal(conn_data, opt)
opt[:charset] = @mandatorycharset ||
StreamHandler.parse_media_type(data.receive_contenttype)
res_header, res_body = Processor.unmarshal(data.receive_string, opt)
return res_header, res_body
end end
def call(headers, name, *values) def call(req_header, name, *values)
req = create_request(name, *values) req = create_request(name, *values)
return invoke(headers, req.method, req.method.soapaction || @soapaction) invoke(req_header, req.method, req.method.soapaction || @soapaction)
end end
def check_fault(body) def check_fault(body)
@ -116,6 +125,29 @@ public
private private
def unmarshal(conn_data, opt)
contenttype = conn_data.receive_contenttype
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)
env = Processor.unmarshal(mime.root.content, opt)
else
opt[:charset] = @mandatorycharset ||
::SOAP::StreamHandler.parse_media_type(contenttype)
env = Processor.unmarshal(conn_data.receive_string, opt)
end
env
end
def create_header(headers) def create_header(headers)
header = SOAPHeader.new() header = SOAPHeader.new()
headers.each do |content, mustunderstand, encodingstyle| headers.each do |content, mustunderstand, encodingstyle|

View file

@ -11,6 +11,9 @@ require 'soap/processor'
require 'soap/mapping' require 'soap/mapping'
require 'soap/rpc/rpc' require 'soap/rpc/rpc'
require 'soap/rpc/element' require 'soap/rpc/element'
require 'soap/streamHandler'
require 'soap/mimemessage'
require 'soap/header/handlerset'
module SOAP module SOAP
@ -24,6 +27,7 @@ class Router
attr_accessor :allow_unqualified_element attr_accessor :allow_unqualified_element
attr_accessor :default_encodingstyle attr_accessor :default_encodingstyle
attr_accessor :mapping_registry attr_accessor :mapping_registry
attr_reader :headerhandler
def initialize(actor) def initialize(actor)
@actor = actor @actor = actor
@ -33,6 +37,7 @@ class Router
@allow_unqualified_element = false @allow_unqualified_element = false
@default_encodingstyle = nil @default_encodingstyle = nil
@mapping_registry = nil @mapping_registry = nil
@headerhandler = Header::HandlerSet.new
end end
def add_method(receiver, qname, soapaction, name, param_def) def add_method(receiver, qname, soapaction, name, param_def)
@ -42,47 +47,112 @@ class Router
@method[fqname] = RPC::SOAPMethodRequest.new(qname, param_def, soapaction) @method[fqname] = RPC::SOAPMethodRequest.new(qname, param_def, soapaction)
end end
def add_header_handler def route(conn_data)
raise NotImplementedError.new soap_response = nil
end
# Routing...
def route(soap_string, charset = nil)
opt = options
opt[:charset] = charset
is_fault = false
begin begin
header, body = Processor.unmarshal(soap_string, opt) env = unmarshal(conn_data)
# So far, header is omitted... if env.nil?
soap_request = body.request raise ArgumentError.new("Illegal SOAP marshal format.")
end
receive_headers(env.header)
soap_request = env.body.request
unless soap_request.is_a?(SOAPStruct) unless soap_request.is_a?(SOAPStruct)
raise RPCRoutingError.new("Not an RPC style.") raise RPCRoutingError.new("Not an RPC style.")
end end
soap_response = dispatch(soap_request) soap_response = dispatch(soap_request)
rescue Exception rescue Exception
soap_response = fault($!) soap_response = fault($!)
is_fault = true conn_data.is_fault = true
end end
header = SOAPHeader.new opt = options
opt[:external_content] = nil
header = call_headers
body = SOAPBody.new(soap_response) body = SOAPBody.new(soap_response)
response_string = Processor.marshal(header, body, opt) env = SOAPEnvelope.new(header, body)
response_string = Processor.marshal(env, opt)
return response_string, is_fault conn_data.send_string = response_string
if ext = opt[: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
end end
# Create fault response string. # Create fault response string.
def create_fault_response(e, charset = nil) def create_fault_response(e, charset = nil)
header = SOAPHeader.new header = SOAPHeader.new
soap_response = fault(e) body = SOAPBody.new(fault(e))
body = SOAPBody.new(soap_response) env = SOAPEnvelope.new(header, body)
opt = options opt = options
opt[:external_content] = nil
opt[:charset] = charset opt[:charset] = charset
Processor.marshal(header, body, opt) response_string = Processor.marshal(env, opt)
conn_data = StreamHandler::ConnectionData.new(response_string)
conn_data.is_fault = true
if ext = opt[: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
end end
private private
def call_headers
headers = @headerhandler.on_outbound
if headers.empty?
nil
else
h = ::SOAP::SOAPHeader.new
headers.each do |header|
h.add(header.elename.name, header)
end
h
end
end
def receive_headers(headers)
@headerhandler.on_inbound(headers) if headers
end
def unmarshal(conn_data)
opt = options
contenttype = conn_data.receive_contenttype
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] =
StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
env = Processor.unmarshal(mime.root.content, opt)
else
opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)
env = Processor.unmarshal(conn_data.receive_string, opt)
end
charset = opt[:charset]
conn_data.send_contenttype = "text/xml; charset=\"#{charset}\""
env
end
# Create new response. # Create new response.
def create_response(qname, result) def create_response(qname, result)
name = fqname(qname) name = fqname(qname)

View file

@ -1,5 +1,5 @@
# SOAP4R - SOAP handler servlet for WEBrick # SOAP4R - SOAP handler servlet for WEBrick
# Copyright (C) 2001, 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2001, 2002, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -22,20 +22,28 @@ public
def initialize def initialize
@router_map = {} @router_map = {}
@app_scope_router = ::SOAP::RPC::Router.new(self.class.name) @app_scope_router = ::SOAP::RPC::Router.new(self.class.name)
@headerhandlerfactory = []
@app_scope_headerhandler = nil
end end
# Add servant klass whose object has request scope. A servant object is # Add servant factory whose object has request scope. A servant object is
# instantiated for each request. # instanciated for each request.
# #
# Bare in mind that servant klasses are distinguished by HTTP SOAPAction # Bear in mind that servant factories are distinguished by HTTP SOAPAction
# header in request. Client which calls request-scoped servant must have a # header in request. Client which calls request-scoped servant must have a
# SOAPAction header which is a namespace of the servant klass. # SOAPAction header which is a namespace of the servant factory.
# I mean, use Driver#add_method_with_soapaction instead of Driver#add_method # I mean, use Driver#add_method_with_soapaction instead of Driver#add_method
# at client side. # at client side.
# #
def add_rpc_request_servant(klass, namespace, mapping_registry = nil) # A factory must respond to :create.
router = RequestRouter.new(klass, namespace, mapping_registry) #
add_router(namespace, router) def add_rpc_request_servant(factory, namespace, mapping_registry = nil)
unless factory.respond_to?(:create)
raise TypeError.new("factory must respond to 'create'")
end
router = setup_request_router(namespace)
router.factory = factory
router.mapping_registry = mapping_registry
end end
# Add servant object which has application scope. # Add servant object which has application scope.
@ -46,6 +54,17 @@ public
end end
alias add_servant add_rpc_servant alias add_servant add_rpc_servant
def add_rpc_request_headerhandler(factory)
unless factory.respond_to?(:create)
raise TypeError.new("factory must respond to 'create'")
end
@headerhandlerfactory << factory
end
def add_rpc_headerhandler(obj)
@app_scope_headerhandler = obj
end
alias add_headerhandler add_rpc_headerhandler
### ###
## Servlet interfaces for WEBrick. ## Servlet interfaces for WEBrick.
@ -67,42 +86,43 @@ public
def do_POST(req, res) def do_POST(req, res)
namespace = parse_soapaction(req.meta_vars['HTTP_SOAPACTION']) namespace = parse_soapaction(req.meta_vars['HTTP_SOAPACTION'])
router = lookup_router(namespace) router = lookup_router(namespace)
with_headerhandler(router) do |router|
is_fault = false begin
conn_data = ::SOAP::StreamHandler::ConnectionData.new
charset = ::SOAP::StreamHandler.parse_media_type(req['content-type']) conn_data.receive_string = req.body
begin conn_data.receive_contenttype = req['content-type']
response_stream, is_fault = router.route(req.body, charset) conn_data = router.route(conn_data)
rescue Exception => e if conn_data.is_fault
response_stream = router.create_fault_response(e) res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR
is_fault = true end
res.body = conn_data.send_string
res['content-type'] = conn_data.send_contenttype
rescue Exception => e
conn_data = router.create_fault_response(e)
res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR
res.body = conn_data.send_string
res['content-type'] = conn_data.send_contenttype || "text/xml"
end
end end
res.body = response_stream if res.body.is_a?(IO)
res['content-type'] = "text/xml; charset=\"#{charset}\""
if response_stream.is_a?(IO)
res.chunked = true res.chunked = true
end end
if is_fault
res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR
end
end end
private private
class RequestRouter < ::SOAP::RPC::Router class RequestRouter < ::SOAP::RPC::Router
def initialize(klass, namespace, mapping_registry = nil) attr_accessor :factory
def initialize(namespace = nil)
super(namespace) super(namespace)
if mapping_registry
self.mapping_registry = mapping_registry
end
@klass = klass
@namespace = namespace @namespace = namespace
@factory = nil
end end
def route(soap_string) def route(soap_string)
obj = @klass.new obj = @factory.create
namespace = self.actor namespace = self.actor
router = ::SOAP::RPC::Router.new(@namespace) router = ::SOAP::RPC::Router.new(@namespace)
SOAPlet.add_servant_to_router(router, obj, namespace) SOAPlet.add_servant_to_router(router, obj, namespace)
@ -110,6 +130,12 @@ private
end end
end end
def setup_request_router(namespace)
router = @router_map[namespace] || RequestRouter.new(namespace)
add_router(namespace, router)
router
end
def add_router(namespace, router) def add_router(namespace, router)
@router_map[namespace] = router @router_map[namespace] = router
end end
@ -132,11 +158,29 @@ private
end end
end end
def with_headerhandler(router)
if @app_scope_headerhandler and
!router.headerhandler.include?(@app_scope_headerhandler)
router.headerhandler.add(@app_scope_headerhandler)
end
handlers = @headerhandlerfactory.collect { |f| f.create }
begin
handlers.each { |h| router.headerhandler.add(h) }
yield(router)
ensure
handlers.each { |h| router.headerhandler.delete(h) }
end
end
class << self class << self
public public
def add_servant_to_router(router, obj, namespace) def add_servant_to_router(router, obj, namespace)
::SOAP::RPC.defined_methods(obj).each do |name| ::SOAP::RPC.defined_methods(obj).each do |name|
add_servant_method_to_router(router, obj, namespace, name) begin
add_servant_method_to_router(router, obj, namespace, name)
rescue SOAP::RPC::MethodDefinitionError => e
p e if $DEBUG
end
end end
end end
@ -145,7 +189,7 @@ private
soapaction = nil soapaction = nil
method = obj.method(name) method = obj.method(name)
param_def = ::SOAP::RPC::SOAPMethod.create_param_def( param_def = ::SOAP::RPC::SOAPMethod.create_param_def(
(1..method.arity.abs).collect { |i| "p#{ i }" }) (1..method.arity.abs).collect { |i| "p#{ i }" })
router.add_method(obj, qname, soapaction, name, param_def) router.add_method(obj, qname, soapaction, name, param_def)
end end
end end

View file

@ -6,111 +6,35 @@
# either the dual license version in 2003, or any later version. # either the dual license version in 2003, or any later version.
require 'logger' require 'soap/rpc/httpserver'
require 'soap/rpc/soaplet'
require 'soap/streamHandler'
# require 'webrick'
require 'webrick/compat.rb'
require 'webrick/version.rb'
require 'webrick/config.rb'
require 'webrick/log.rb'
require 'webrick/server.rb'
require 'webrick/utils.rb'
require 'webrick/accesslog'
# require 'webrick/htmlutils.rb'
require 'webrick/httputils.rb'
# require 'webrick/cookie.rb'
require 'webrick/httpversion.rb'
require 'webrick/httpstatus.rb'
require 'webrick/httprequest.rb'
require 'webrick/httpresponse.rb'
require 'webrick/httpserver.rb'
# require 'webrick/httpservlet.rb'
# require 'webrick/httpauth.rb'
module SOAP module SOAP
module RPC module RPC
class StandaloneServer < Logger::Application class StandaloneServer < HTTPServer
attr_reader :server def initialize(appname, default_namespace, host = "0.0.0.0", port = 8080)
@appname = appname
def initialize(app_name, namespace, host = "0.0.0.0", port = 8080) @default_namespace = default_namespace
super(app_name)
self.level = Logger::Severity::INFO
@namespace = namespace
@host = host @host = host
@port = port @port = port
@server = nil super(create_config)
@soaplet = ::SOAP::RPC::SOAPlet.new
on_init
end end
def on_init
# define extra methods in derived class.
end
def status
if @server
@server.status
else
nil
end
end
def shutdown
@server.shutdown
end
def add_rpc_request_servant(klass, namespace = @namespace, mapping_registry = nil)
@soaplet.add_rpc_request_servant(klass, namespace, mapping_registry)
end
def add_rpc_servant(obj, namespace = @namespace)
@soaplet.add_rpc_servant(obj, namespace)
end
alias add_servant add_rpc_servant alias add_servant add_rpc_servant
alias add_headerhandler add_rpc_headerhandler
def mapping_registry
@soaplet.app_scope_router.mapping_registry
end
def mapping_registry=(mapping_registry)
@soaplet.app_scope_router.mapping_registry = mapping_registry
end
def add_method(obj, name, *param)
add_method_as(obj, name, name, *param)
end
def add_method_as(obj, name, name_as, *param)
qname = XSD::QName.new(@namespace, name_as)
soapaction = nil
method = obj.method(name)
param_def = if param.size == 1 and param[0].is_a?(Array)
param[0]
elsif param.empty?
::SOAP::RPC::SOAPMethod.create_param_def(
(1..method.arity.abs).collect { |i| "p#{ i }" })
else
SOAP::RPC::SOAPMethod.create_param_def(param)
end
@soaplet.app_scope_router.add_method(obj, qname, soapaction, name, param_def)
end
private private
def run def create_config
@server = WEBrick::HTTPServer.new( {
:BindAddress => @host, :BindAddress => @host,
:Logger => @log, :Port => @port,
:AccessLog => [], :AccessLog => [],
:Port => @port :SOAPDefaultNamespace => @default_namespace,
) :SOAPHTTPServerApplicationName => @appname,
@server.mount('/', @soaplet) }
@server.start
end end
end end

View file

@ -1,5 +1,5 @@
# soap/soap.rb: SOAP4R - Base definitions. # soap/soap.rb: SOAP4R - Base definitions.
# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2000-2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -48,6 +48,7 @@ EleFaultStringName = XSD::QName.new(nil, EleFaultString)
EleFaultActorName = XSD::QName.new(nil, EleFaultActor) EleFaultActorName = XSD::QName.new(nil, EleFaultActor)
EleFaultCodeName = XSD::QName.new(nil, EleFaultCode) EleFaultCodeName = XSD::QName.new(nil, EleFaultCode)
EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail) EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail)
AttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand)
AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle) AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle)
AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot) AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot)
AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType) AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType)
@ -75,6 +76,8 @@ class ArrayStoreError < Error; end
class RPCRoutingError < Error; end class RPCRoutingError < Error; end
class UnhandledMustUnderstandHeaderError < Error; end
class FaultError < Error class FaultError < Error
attr_reader :faultcode attr_reader :faultcode
attr_reader :faultstring attr_reader :faultstring

View file

@ -33,21 +33,14 @@ class StreamHandler
attr_accessor :send_contenttype attr_accessor :send_contenttype
attr_accessor :receive_string attr_accessor :receive_string
attr_accessor :receive_contenttype attr_accessor :receive_contenttype
attr_accessor :is_fault
def initialize def initialize(send_string = nil)
@send_string = nil @send_string = send_string
@send_contenttype = nil @send_contenttype = nil
@receive_string = nil @receive_string = nil
@receive_contenttype = nil @receive_contenttype = nil
@bag = {} @is_fault = false
end
def [](idx)
@bag[idx]
end
def []=(idx, value)
@bag[idx] = value
end end
end end
@ -59,7 +52,7 @@ class StreamHandler
def self.parse_media_type(str) def self.parse_media_type(str)
if /^#{ MediaType }(?:\s*;\s*charset=([^"]+|"[^"]+"))?$/i !~ str if /^#{ MediaType }(?:\s*;\s*charset=([^"]+|"[^"]+"))?$/i !~ str
raise StreamError.new("Illegal media type."); return nil
end end
charset = $1 charset = $1
charset.gsub!(/"/, '') if charset charset.gsub!(/"/, '') if charset
@ -90,18 +83,24 @@ public
@options = options @options = options
set_options set_options
@client.debug_dev = @wiredump_dev @client.debug_dev = @wiredump_dev
@cookie_store = nil
end
def test_loopback_response
@client.test_loopback_response
end end
def inspect def inspect
"#<#{self.class}:#{endpoint_url}>" "#<#{self.class}:#{endpoint_url}>"
end end
def send(soap_string, soapaction = nil, charset = @charset) def send(conn_data, soapaction = nil, charset = @charset)
send_post(soap_string, soapaction, charset) send_post(conn_data, soapaction, charset)
end end
def reset def reset
@client.reset(@endpoint_url) @client.reset(@endpoint_url)
@client.save_cookie_store if @cookie_store
end end
private private
@ -125,10 +124,6 @@ private
@options.add_hook("cookie_store_file") do |key, value| @options.add_hook("cookie_store_file") do |key, value|
set_cookie_store_file(value) set_cookie_store_file(value)
end 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) @charset = @options["charset"] || XSD::Charset.charset_label($KCODE)
@options.add_hook("charset") do |key, value| @options.add_hook("charset") do |key, value|
@charset = value @charset = value
@ -138,12 +133,18 @@ private
@wiredump_dev = value @wiredump_dev = value
@client.debug_dev = @wiredump_dev @client.debug_dev = @wiredump_dev
end end
ssl_config = @options["ssl_config"] ||= ::SOAP::Property.new
set_ssl_config(ssl_config)
ssl_config.add_hook(true) do |key, value|
set_ssl_config(ssl_config)
end
basic_auth = @options["basic_auth"] ||= ::SOAP::Property.new basic_auth = @options["basic_auth"] ||= ::SOAP::Property.new
set_basic_auth(basic_auth) set_basic_auth(basic_auth)
basic_auth.add_hook do |key, value| basic_auth.add_hook do |key, value|
set_basic_auth(basic_auth) set_basic_auth(basic_auth)
end end
@options.lock(true) @options.lock(true)
ssl_config.unlock
basic_auth.unlock basic_auth.unlock
end end
@ -154,34 +155,82 @@ private
end end
def set_cookie_store_file(value) def set_cookie_store_file(value)
return unless value @cookie_store = value
raise NotImplementedError.new @client.set_cookie_store(@cookie_store) if @cookie_store
end end
def set_ssl_config(value) def set_ssl_config(ssl_config)
return unless value ssl_config.each do |key, value|
raise NotImplementedError.new cfg = @client.ssl_config
case key
when 'client_cert'
cfg.client_cert = cert_from_file(value)
when 'client_key'
cfg.client_key = key_from_file(value)
when 'client_ca'
cfg.client_ca = value
when 'ca_path'
cfg.set_trust_ca(value)
when 'ca_file'
cfg.set_trust_ca(value)
when 'crl'
cfg.set_crl(value)
when 'verify_mode'
cfg.verify_mode = ssl_config_int(value)
when 'verify_depth'
cfg.verify_depth = ssl_config_int(value)
when 'options'
cfg.options = value
when 'ciphers'
cfg.ciphers = value
when 'verify_callback'
cfg.verify_callback = value
when 'cert_store'
cfg.cert_store = value
else
raise ArgumentError.new("unknown ssl_config property #{key}")
end
end
end end
def send_post(soap_string, soapaction, charset) def ssl_config_int(value)
data = ConnectionData.new if value.nil? or value.empty?
data.send_string = soap_string nil
data.send_contenttype = StreamHandler.create_media_type(charset) else
begin
Integer(value)
rescue ArgumentError
::SOAP::Property::Util.const_from_name(value)
end
end
end
def cert_from_file(filename)
OpenSSL::X509::Certificate.new(File.open(filename) { |f| f.read })
end
def key_from_file(filename)
OpenSSL::PKey::RSA.new(File.open(filename) { |f| f.read })
end
def send_post(conn_data, soapaction, charset)
conn_data.send_contenttype ||= StreamHandler.create_media_type(charset)
if @wiredump_file_base if @wiredump_file_base
filename = @wiredump_file_base + '_request.xml' filename = @wiredump_file_base + '_request.xml'
f = File.open(filename, "w") f = File.open(filename, "w")
f << soap_string f << conn_data.send_string
f.close f.close
end end
extra = {} extra = {}
extra['Content-Type'] = data.send_contenttype extra['Content-Type'] = conn_data.send_contenttype
extra['SOAPAction'] = "\"#{ soapaction }\"" extra['SOAPAction'] = "\"#{ soapaction }\""
send_string = conn_data.send_string
@wiredump_dev << "Wire dump:\n\n" if @wiredump_dev @wiredump_dev << "Wire dump:\n\n" if @wiredump_dev
begin begin
res = @client.post(@endpoint_url, soap_string, extra) res = @client.post(@endpoint_url, send_string, extra)
rescue rescue
@client.reset(@endpoint_url) @client.reset(@endpoint_url)
raise raise
@ -206,10 +255,9 @@ private
raise HTTPStreamError.new("#{ res.status }: #{ res.reason }") raise HTTPStreamError.new("#{ res.status }: #{ res.reason }")
end end
data.receive_string = receive_string conn_data.receive_string = receive_string
data.receive_contenttype = res.contenttype conn_data.receive_contenttype = res.contenttype
conn_data
return data
end end
CRLF = "\r\n" CRLF = "\r\n"

View file

@ -12,11 +12,13 @@ require 'xsd/qname'
require 'soap/element' require 'soap/element'
require 'soap/baseData' require 'soap/baseData'
require 'soap/streamHandler' require 'soap/streamHandler'
require 'soap/mimemessage'
require 'soap/mapping' require 'soap/mapping'
require 'soap/mapping/wsdlRegistry' require 'soap/mapping/wsdlRegistry'
require 'soap/rpc/rpc' require 'soap/rpc/rpc'
require 'soap/rpc/element' require 'soap/rpc/element'
require 'soap/processor' require 'soap/processor'
require 'soap/header/handlerset'
require 'logger' require 'logger'
@ -91,6 +93,8 @@ class WSDLDriver
end end
__attr_proxy :options __attr_proxy :options
__attr_proxy :headerhandler
__attr_proxy :test_loopback_response
__attr_proxy :endpoint_url, true __attr_proxy :endpoint_url, true
__attr_proxy :mapping_registry, true # for RPC unmarshal __attr_proxy :mapping_registry, true # for RPC unmarshal
__attr_proxy :wsdl_mapping_registry, true # for RPC marshal __attr_proxy :wsdl_mapping_registry, true # for RPC marshal
@ -151,6 +155,7 @@ class WSDLDriver
attr_reader :options attr_reader :options
attr_reader :streamhandler attr_reader :streamhandler
attr_reader :headerhandler
attr_reader :port attr_reader :port
attr_accessor :mapping_registry attr_accessor :mapping_registry
@ -175,7 +180,7 @@ class WSDLDriver
@mandatorycharset = nil @mandatorycharset = nil
@wsdl_elements = @wsdl.collect_elements @wsdl_elements = @wsdl.collect_elements
@wsdl_types = @wsdl.collect_complextypes @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes
@rpc_decode_typemap = @wsdl_types + @rpc_decode_typemap = @wsdl_types +
@wsdl.soap_rpc_complextypes(port.find_binding) @wsdl.soap_rpc_complextypes(port.find_binding)
@wsdl_mapping_registry = Mapping::WSDLRegistry.new(@rpc_decode_typemap) @wsdl_mapping_registry = Mapping::WSDLRegistry.new(@rpc_decode_typemap)
@ -183,6 +188,7 @@ class WSDLDriver
endpoint_url = @port.soap_address.location endpoint_url = @port.soap_address.location
@streamhandler = HTTPPostStreamHandler.new(endpoint_url, @streamhandler = HTTPPostStreamHandler.new(endpoint_url,
@options["protocol.http"] ||= Property.new) @options["protocol.http"] ||= Property.new)
@headerhandler = Header::HandlerSet.new
# Convert a map which key is QName, to a Hash which key is String. # Convert a map which key is QName, to a Hash which key is String.
@operations = {} @operations = {}
@port.inputoperation_map.each do |op_name, op_info| @port.inputoperation_map.each do |op_name, op_info|
@ -200,14 +206,19 @@ class WSDLDriver
@streamhandler.reset @streamhandler.reset
end end
def test_loopback_response
@streamhandler.test_loopback_response
end
def rpc_send(method_name, *params) def rpc_send(method_name, *params)
log(INFO) { "call: calling method '#{ method_name }'." } log(INFO) { "call: calling method '#{ method_name }'." }
log(DEBUG) { "call: parameters '#{ params.inspect }'." } log(DEBUG) { "call: parameters '#{ params.inspect }'." }
op_info = @operations[method_name] op_info = @operations[method_name]
method = create_method_struct(op_info, params) method = create_method_struct(op_info, params)
req_header = nil req_header = call_headers
req_body = SOAPBody.new(method) req_body = SOAPBody.new(method)
req_env = SOAPEnvelope.new(req_header, req_body)
if @wiredump_file_base if @wiredump_file_base
@streamhandler.wiredump_file_base = @streamhandler.wiredump_file_base =
@ -217,19 +228,20 @@ class WSDLDriver
begin begin
opt = create_options opt = create_options
opt[:decode_typemap] = @rpc_decode_typemap opt[:decode_typemap] = @rpc_decode_typemap
res_header, res_body = invoke(req_header, req_body, op_info, opt) res_env = invoke(req_env, op_info, opt)
if res_body.fault receive_headers(res_env.header)
raise SOAP::FaultError.new(res_body.fault) if res_env.body.fault
raise ::SOAP::FaultError.new(res_env.body.fault)
end end
rescue SOAP::FaultError => e rescue ::SOAP::FaultError => e
Mapping.fault2exception(e) Mapping.fault2exception(e)
end end
ret = res_body.response ? ret = res_env.body.response ?
Mapping.soap2obj(res_body.response, @mapping_registry) : nil Mapping.soap2obj(res_env.body.response, @mapping_registry) : nil
if res_body.outparams if res_env.body.outparams
outparams = res_body.outparams.collect { |outparam| outparams = res_env.body.outparams.collect { |outparam|
Mapping.soap2obj(outparam) Mapping.soap2obj(outparam)
} }
return [ret].concat(outparams) return [ret].concat(outparams)
@ -245,18 +257,36 @@ class WSDLDriver
op_info = @operations[name] op_info = @operations[name]
req_header = header_from_obj(header_obj, op_info) req_header = header_from_obj(header_obj, op_info)
req_body = body_from_obj(body_obj, op_info) req_body = body_from_obj(body_obj, op_info)
req_env = SOAPEnvelope.new(req_header, req_body)
opt = create_options opt = create_options
res_header, res_body = invoke(req_header, req_body, op_info, opt) res_env = invoke(req_env, op_info, opt)
if res_body.fault if res_env.body.fault
raise SOAP::FaultError.new(res_body.fault) raise ::SOAP::FaultError.new(res_env.body.fault)
end end
res_body_obj = res_body.response ? res_body_obj = res_env.body.response ?
Mapping.soap2obj(res_body.response, @mapping_registry) : nil Mapping.soap2obj(res_env.body.response, @mapping_registry) : nil
return res_header, res_body_obj return res_env.header, res_body_obj
end end
private private
def call_headers
headers = @headerhandler.on_outbound
if headers.empty?
nil
else
h = ::SOAP::SOAPHeader.new
headers.each do |header|
h.add(header.elename.name, header)
end
h
end
end
def receive_headers(headers)
@headerhandler.on_inbound(headers) if headers
end
def create_method_struct(op_info, params) def create_method_struct(op_info, params)
parts_names = op_info.bodyparts.collect { |part| part.name } parts_names = op_info.bodyparts.collect { |part| part.name }
obj = create_method_obj(parts_names, params) obj = create_method_obj(parts_names, params)
@ -283,18 +313,50 @@ class WSDLDriver
o o
end end
def invoke(req_header, req_body, op_info, opt) def invoke(req_env, op_info, opt)
send_string = Processor.marshal(req_header, req_body, opt) opt[:external_content] = nil
send_string = Processor.marshal(req_env, opt)
log(DEBUG) { "invoke: sending string #{ send_string }" } log(DEBUG) { "invoke: sending string #{ send_string }" }
data = @streamhandler.send(send_string, op_info.soapaction) conn_data = StreamHandler::ConnectionData.new(send_string)
log(DEBUG) { "invoke: received string #{ data.receive_string }" } if ext = opt[:external_content]
if data.receive_string.empty? 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 = @streamhandler.send(conn_data, op_info.soapaction)
log(DEBUG) { "invoke: received string #{ conn_data.receive_string }" }
if conn_data.receive_string.empty?
return nil, nil return nil, nil
end end
opt[:charset] = @mandatorycharset || unmarshal(conn_data, opt)
StreamHandler.parse_media_type(data.receive_contenttype) end
res_header, res_body = Processor.unmarshal(data.receive_string, opt)
return res_header, res_body def unmarshal(conn_data, opt)
contenttype = conn_data.receive_contenttype
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)
env = Processor.unmarshal(mime.root.content, opt)
else
opt[:charset] = @mandatorycharset ||
::SOAP::StreamHandler.parse_media_type(contenttype)
env = Processor.unmarshal(conn_data.receive_string, opt)
end
env
end end
def header_from_obj(obj, op_info) def header_from_obj(obj, op_info)
@ -314,9 +376,9 @@ class WSDLDriver
else else
header = SOAPHeader.new() header = SOAPHeader.new()
op_info.headerparts.each do |part| op_info.headerparts.each do |part|
child = obj[part.elename.name] child = Mapper.find_attribute(obj, part.name)
ele = headeritem_from_obj(child, part.element || part.eletype) ele = headeritem_from_obj(child, part.element || part.eletype)
header.add(ele) header.add(part.name, ele)
end end
header header
end end
@ -348,7 +410,7 @@ class WSDLDriver
else else
body = SOAPBody.new body = SOAPBody.new
op_info.bodyparts.each do |part| op_info.bodyparts.each do |part|
child = obj[part.elename.name] child = Mapper.find_attribute(obj, part.name)
ele = bodyitem_from_obj(child, part.element || part.type) ele = bodyitem_from_obj(child, part.element || part.type)
body.add(ele.elename.name, ele) body.add(ele.elename.name, ele)
end end
@ -426,6 +488,7 @@ class WSDLDriver
opt opt
end end
class MappingError < StandardError; end
class Mapper class Mapper
def initialize(elements, types) def initialize(elements, types)
@elements = elements @elements = elements
@ -438,7 +501,7 @@ class WSDLDriver
elsif type = @types[name] elsif type = @types[name]
obj2type(obj, type) obj2type(obj, type)
else else
raise RuntimeError.new("Cannot find name #{name} in schema.") raise MappingError.new("Cannot find name #{name} in schema.")
end end
end end
@ -446,6 +509,16 @@ class WSDLDriver
raise NotImplementedError.new raise NotImplementedError.new
end end
def Mapper.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
private private
def _obj2ele(obj, ele) def _obj2ele(obj, ele)
@ -456,25 +529,47 @@ class WSDLDriver
elsif type = TypeMap[ele.type] elsif type = TypeMap[ele.type]
o = base2soap(obj, type) o = base2soap(obj, type)
else else
raise RuntimeError.new("Cannot find type #{ele.type}.") raise MappingError.new("Cannot find type #{ele.type}.")
end end
o.elename = ele.name o.elename = ele.name
elsif ele.local_complextype elsif ele.local_complextype
o = SOAPElement.new(ele.name) o = SOAPElement.new(ele.name)
ele.local_complextype.each_element do |child_name, child_ele| ele.local_complextype.each_element do |child_ele|
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele)) o.add(_obj2ele(Mapper.find_attribute(obj, child_ele.name.name),
child_ele))
end end
else else
raise RuntimeError.new("Illegal schema?") raise MappingError.new("Illegal schema?")
end end
o o
end end
def obj2type(obj, type) def obj2type(obj, type)
o = SOAPElement.new(type.name) if type.is_a?(::WSDL::XMLSchema::SimpleType)
type.each_element do |child_name, child_ele| simple2soap(obj, type)
o.add(_obj2ele(find_attribute(obj, child_name.name), child_ele)) else
end complex2soap(obj, type)
end
end
def simple2soap(obj, type)
o = base2soap(obj, TypeMap[type.base])
if type.restriction.enumeration.empty?
STDERR.puts("#{type.name}: simpleType which is not enum type not supported.")
return o
end
if type.restriction.enumeration.include?(o)
raise MappingError.new("#{o} is not allowed for #{type.name}")
end
o
end
def complex2soap(obj, type)
o = SOAPElement.new(type.name)
type.each_element do |child_ele|
o.add(_obj2ele(Mapper.find_attribute(obj, child_ele.name.name),
child_ele))
end
o o
end end
@ -486,22 +581,13 @@ class WSDLDriver
soap_obj = nil soap_obj = nil
if type <= XSD::XSDString if type <= XSD::XSDString
soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj) XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) :
obj)
else else
soap_obj = type.new(obj) soap_obj = type.new(obj)
end end
soap_obj soap_obj
end 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 end
end end

View file

@ -6,6 +6,7 @@
# either the dual license version in 2003, or any later version. # either the dual license version in 2003, or any later version.
require 'xsd/qname'
require 'wsdl/documentation' require 'wsdl/documentation'
require 'wsdl/definitions' require 'wsdl/definitions'
require 'wsdl/types' require 'wsdl/types'

View file

@ -43,8 +43,7 @@ class Definitions < Info
end end
def inspect def inspect
name = @name || '(unnamed)' sprintf("#<%s:0x%x %s>", self.class.name, __id__, @name || '(unnamed)')
"#<#{self.class}:#{name}>"
end end
def targetnamespace=(targetnamespace) def targetnamespace=(targetnamespace)
@ -58,7 +57,7 @@ class Definitions < Info
result = XSD::NamedElements.new result = XSD::NamedElements.new
if @types if @types
@types.schemas.each do |schema| @types.schemas.each do |schema|
result.concat(schema.elements) result.concat(schema.collect_elements)
end end
end end
@imports.each do |import| @imports.each do |import|
@ -71,7 +70,7 @@ class Definitions < Info
result = @anontypes.dup result = @anontypes.dup
if @types if @types
@types.schemas.each do |schema| @types.schemas.each do |schema|
result.concat(schema.complextypes) result.concat(schema.collect_complextypes)
end end
end end
@imports.each do |import| @imports.each do |import|
@ -80,6 +79,20 @@ class Definitions < Info
result result
end end
def collect_simpletypes
result = XSD::NamedElements.new
if @types
@types.schemas.each do |schema|
result.concat(schema.collect_simpletypes)
end
end
@imports.each do |import|
result.concat(import.content.collect_simpletypes)
end
result
end
# ToDo: simpletype must be accepted...
def add_type(complextype) def add_type(complextype)
@anontypes << complextype @anontypes << complextype
end end

View file

@ -119,7 +119,7 @@ private
return parts.dup return parts.dup
end end
if parts.length != result.length if parts.length != result.length
raise RuntimeError.new("Incomplete parameter order list.") raise RuntimeError.new("Incomplete prarmeterOrder list.")
end end
result result
end end

View file

@ -119,7 +119,8 @@ private
STDERR.puts("Unknown element #{ element }.") STDERR.puts("Unknown element #{ element }.")
o = Documentation.new # which accepts any element. o = Documentation.new # which accepts any element.
end end
o.parent = parent # node could be a pseudo element. pseudo element has its own parent.
o.parent = parent if o.parent.nil?
end end
attrs.each do |key, value| attrs.each do |key, value|
attr = unless /:/ =~ key attr = unless /:/ =~ key

View file

@ -75,8 +75,36 @@ class Definitions < Info
types + self.class.soap_rpc_complextypes types + self.class.soap_rpc_complextypes
end end
def collect_faulttypes
result = []
collect_fault_messages.each do |message|
parts = message(message).parts
if parts.size != 1
raise RuntimeError.new("Expecting fault message to have only 1 part.")
end
if result.index(parts[0].type).nil?
result << parts[0].type
end
end
result
end
private private
def collect_fault_messages
result = []
porttypes.each do |porttype|
porttype.operations.each do |operation|
operation.fault.each do |fault|
if result.index(fault.message).nil?
result << fault.message
end
end
end
end
result
end
def rpc_operation_complextypes(binding) def rpc_operation_complextypes(binding)
types = XSD::NamedElements.new types = XSD::NamedElements.new
binding.operations.each do |op_bind| binding.operations.each do |op_bind|

View file

@ -28,6 +28,10 @@ class ComplexContent < Info
@attributes = XSD::NamedElements.new @attributes = XSD::NamedElements.new
end end
def targetnamespace
parent.targetnamespace
end
def parse_element(element) def parse_element(element)
case element case element
when RestrictionName, ExtensionName when RestrictionName, ExtensionName

View file

@ -8,6 +8,7 @@
require 'wsdl/info' require 'wsdl/info'
require 'wsdl/xmlSchema/content' require 'wsdl/xmlSchema/content'
require 'wsdl/xmlSchema/element'
require 'xsd/namedelements' require 'xsd/namedelements'
@ -37,10 +38,15 @@ class ComplexType < Info
parent.targetnamespace parent.targetnamespace
end end
AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName)
def each_element def each_element
if @content if @content
@content.elements.each do |element| @content.elements.each do |element|
yield(element.name, element) if element.is_a?(Any)
yield(AnyAsElement)
else
yield(element)
end
end end
end end
end end
@ -48,7 +54,11 @@ class ComplexType < Info
def find_element(name) def find_element(name)
if @content if @content
@content.elements.each do |element| @content.elements.each do |element|
return element if name == element.name if element.is_a?(Any)
return AnyAsElement if name == AnyAsElement.name
else
return element if name == element.name
end
end end
end end
nil nil
@ -57,7 +67,11 @@ class ComplexType < Info
def find_element_by_name(name) def find_element_by_name(name)
if @content if @content
@content.elements.each do |element| @content.elements.each do |element|
return element if name == element.name.name if element.is_a?(Any)
return AnyAsElement if name == AnyAsElement.name.name
else
return element if name == element.name.name
end
end end
end end
nil nil

View file

@ -6,8 +6,11 @@
# either the dual license version in 2003, or any later version. # either the dual license version in 2003, or any later version.
require 'xsd/datatypes'
require 'wsdl/xmlSchema/schema' require 'wsdl/xmlSchema/schema'
require 'wsdl/xmlSchema/import' require 'wsdl/xmlSchema/import'
require 'wsdl/xmlSchema/simpleType'
require 'wsdl/xmlSchema/simpleRestriction'
require 'wsdl/xmlSchema/complexType' require 'wsdl/xmlSchema/complexType'
require 'wsdl/xmlSchema/complexContent' require 'wsdl/xmlSchema/complexContent'
require 'wsdl/xmlSchema/any' require 'wsdl/xmlSchema/any'
@ -17,7 +20,7 @@ require 'wsdl/xmlSchema/choice'
require 'wsdl/xmlSchema/sequence' require 'wsdl/xmlSchema/sequence'
require 'wsdl/xmlSchema/attribute' require 'wsdl/xmlSchema/attribute'
require 'wsdl/xmlSchema/unique' require 'wsdl/xmlSchema/unique'
require 'wsdl/xmlSchema/enumeration'
module WSDL module WSDL
module XMLSchema module XMLSchema
@ -30,6 +33,7 @@ ChoiceName = XSD::QName.new(XSD::Namespace, 'choice')
ComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent') ComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent')
ComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType') ComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType')
ElementName = XSD::QName.new(XSD::Namespace, 'element') ElementName = XSD::QName.new(XSD::Namespace, 'element')
EnumerationName = XSD::QName.new(XSD::Namespace, 'enumeration')
ExtensionName = XSD::QName.new(XSD::Namespace, 'extension') ExtensionName = XSD::QName.new(XSD::Namespace, 'extension')
ImportName = XSD::QName.new(XSD::Namespace, 'import') ImportName = XSD::QName.new(XSD::Namespace, 'import')
RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction') RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction')
@ -57,6 +61,7 @@ SchemaLocationAttrName = XSD::QName.new(nil, 'schemaLocation')
TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace') TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')
TypeAttrName = XSD::QName.new(nil, 'type') TypeAttrName = XSD::QName.new(nil, 'type')
UseAttrName = XSD::QName.new(nil, 'use') UseAttrName = XSD::QName.new(nil, 'use')
ValueAttrName = XSD::QName.new(nil, 'value')
end end

View file

@ -116,7 +116,8 @@ private
unless o unless o
raise UnknownElementError.new("Unknown element #{ element }.") raise UnknownElementError.new("Unknown element #{ element }.")
end end
o.parent = parent # node could be a pseudo element. pseudo element has its own parent.
o.parent = parent if o.parent.nil?
end end
attrs.each do |key, value| attrs.each do |key, value|
attr = unless /:/ =~ key attr = unless /:/ =~ key

View file

@ -17,6 +17,7 @@ module XMLSchema
class Schema < Info class Schema < Info
attr_reader :targetnamespace # required attr_reader :targetnamespace # required
attr_reader :complextypes attr_reader :complextypes
attr_reader :simpletypes
attr_reader :elements attr_reader :elements
attr_reader :attributes attr_reader :attributes
attr_reader :imports attr_reader :imports
@ -27,6 +28,7 @@ class Schema < Info
super super
@targetnamespace = nil @targetnamespace = nil
@complextypes = XSD::NamedElements.new @complextypes = XSD::NamedElements.new
@simpletypes = XSD::NamedElements.new
@elements = XSD::NamedElements.new @elements = XSD::NamedElements.new
@attributes = XSD::NamedElements.new @attributes = XSD::NamedElements.new
@imports = [] @imports = []
@ -44,8 +46,9 @@ class Schema < Info
@complextypes << o @complextypes << o
o o
when SimpleTypeName when SimpleTypeName
STDERR.puts("Restriction of basetype with simpleType definition is ignored for now.") o = SimpleType.new
nil @simpletypes << o
o
when ElementName when ElementName
o = Element.new o = Element.new
@elements << o @elements << o
@ -83,6 +86,12 @@ class Schema < Info
result result
end end
def collect_simpletypes
result = XSD::NamedElements.new
result.concat(@simpletypes)
result
end
def self.parse_element(element) def self.parse_element(element)
if element == SchemaName if element == SchemaName
Schema.new Schema.new

View file

@ -103,6 +103,12 @@ class XSDAnySimpleType < NSDBase
set(value) if value set(value) if value
end end
# true or raise
def check_lexical_format(value)
screen_data(value)
true
end
# set accepts a string which follows lexical space (ex. String: "+123"), or # set accepts a string which follows lexical space (ex. String: "+123"), or
# an object which follows canonical space (ex. Integer: 123). # an object which follows canonical space (ex. Integer: 123).
def set(value) def set(value)
@ -111,7 +117,7 @@ class XSDAnySimpleType < NSDBase
@data = nil @data = nil
else else
@is_nil = false @is_nil = false
_set(value) _set(screen_data(value))
end end
end end
@ -126,6 +132,11 @@ class XSDAnySimpleType < NSDBase
private private
# raises ValueSpaceError if check failed
def screen_data(value)
value
end
def _set(value) def _set(value)
@data = value @data = value
end end
@ -144,12 +155,6 @@ class XSDNil < XSDAnySimpleType
@type = Type @type = Type
set(value) set(value)
end end
private
def _set(value)
@data = value
end
end end
@ -167,11 +172,11 @@ class XSDString < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
unless XSD::Charset.is_ces(value, XSD::Charset.encoding) unless XSD::Charset.is_ces(value, XSD::Charset.encoding)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
@data = value value
end end
end end
@ -186,18 +191,18 @@ class XSDBoolean < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
if value.is_a?(String) if value.is_a?(String)
str = value.strip str = value.strip
if str == 'true' || str == '1' if str == 'true' || str == '1'
@data = true true
elsif str == 'false' || str == '0' elsif str == 'false' || str == '0'
@data = false false
else else
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
else else
@data = value ? true : false value ? true : false
end end
end end
end end
@ -220,38 +225,39 @@ class XSDDecimal < XSDAnySimpleType
private private
def _set(d) def screen_data(d)
if d.is_a?(String) if d.is_a?(String)
# Integer("00012") => 10 in Ruby. # Integer("00012") => 10 in Ruby.
d.sub!(/^([+\-]?)0*(?=\d)/, "\\1") d.sub!(/^([+\-]?)0*(?=\d)/, "\\1")
end end
set_str(d) screen_data_str(d)
end end
def set_str(str) def screen_data_str(str)
/^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip /^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
sign = $1 || '+'
@sign = $1 || '+'
int_part = $2 int_part = $2
frac_part = $3 frac_part = $3
int_part = '0' if int_part.empty? int_part = '0' if int_part.empty?
frac_part = frac_part ? frac_part.sub(/0+$/, '') : '' frac_part = frac_part ? frac_part.sub(/0+$/, '') : ''
@point = - frac_part.size point = - frac_part.size
@number = int_part + frac_part number = int_part + frac_part
# normalize # normalize
if @sign == '+' if sign == '+'
@sign = '' sign = ''
elsif @sign == '-' elsif sign == '-'
if @number == '0' if number == '0'
@sign = '' sign = ''
end end
end end
[sign, point, number]
end
def _set(pair)
@sign, @point, @number = pair
@data = _to_s @data = _to_s
@data.freeze @data.freeze
end end
@ -272,7 +278,7 @@ module FloatConstants
NEGATIVE_INF = -1.0/0.0 NEGATIVE_INF = -1.0/0.0
POSITIVE_ZERO = +1.0/POSITIVE_INF POSITIVE_ZERO = +1.0/POSITIVE_INF
NEGATIVE_ZERO = -1.0/POSITIVE_INF NEGATIVE_ZERO = -1.0/POSITIVE_INF
MIN_POSITIVE_SINGLE = 2 ** -149 MIN_POSITIVE_SINGLE = 2.0 ** -149
end end
class XSDFloat < XSDAnySimpleType class XSDFloat < XSDAnySimpleType
@ -287,20 +293,18 @@ class XSDFloat < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
# "NaN".to_f => 0 in some environment. libc? # "NaN".to_f => 0 in some environment. libc?
if value.is_a?(Float) if value.is_a?(Float)
@data = narrow32bit(value) return narrow32bit(value)
return
end end
str = value.to_s.strip str = value.to_s.strip
if str == 'NaN' if str == 'NaN'
@data = NaN NaN
elsif str == 'INF' elsif str == 'INF'
@data = POSITIVE_INF POSITIVE_INF
elsif str == '-INF' elsif str == '-INF'
@data = NEGATIVE_INF NEGATIVE_INF
else else
if /^[+\-\.\deE]+$/ !~ str if /^[+\-\.\deE]+$/ !~ str
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
@ -308,7 +312,7 @@ private
# Float("-1.4E") might fail on some system. # Float("-1.4E") might fail on some system.
str << '0' if /e$/i =~ str str << '0' if /e$/i =~ str
begin begin
@data = narrow32bit(Float(str)) return narrow32bit(Float(str))
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
@ -357,28 +361,26 @@ class XSDDouble < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
# "NaN".to_f => 0 in some environment. libc? # "NaN".to_f => 0 in some environment. libc?
if value.is_a?(Float) if value.is_a?(Float)
@data = value return value
return
end end
str = value.to_s.strip str = value.to_s.strip
if str == 'NaN' if str == 'NaN'
@data = NaN NaN
elsif str == 'INF' elsif str == 'INF'
@data = POSITIVE_INF POSITIVE_INF
elsif str == '-INF' elsif str == '-INF'
@data = NEGATIVE_INF NEGATIVE_INF
else else
begin begin
@data = Float(str) return Float(str)
rescue ArgumentError rescue ArgumentError
# '1.4e' cannot be parsed on some architecture. # '1.4e' cannot be parsed on some architecture.
if /e\z/i =~ str if /e\z/i =~ str
begin begin
@data = Float(str + '0') return Float(str + '0')
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
@ -429,24 +431,27 @@ class XSDDuration < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
/^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip /^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8))) if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8)))
# Should we allow 'PT5S' here? # Should we allow 'PT5S' here?
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
sign = $1
year = $2.to_i
month = $3.to_i
day = $4.to_i
hour = $6.to_i
min = $7.to_i
sec = $8 ? XSDDecimal.new($8) : 0
[sign, year, month, day, hour, min, sec]
end
@sign = $1 def _set(ary)
@year = $2.to_i @sign, @year, @month, @day, @hour, @min, @sec = ary
@month = $3.to_i
@day = $4.to_i
@hour = $6.to_i
@min = $7.to_i
@sec = $8 ? XSDDecimal.new($8) : 0
@data = _to_s @data = _to_s
@data.freeze @data.freeze
end end
@ -524,18 +529,18 @@ module XSDDateTimeImpl
end end
end end
def _set(t) def screen_data(t)
set_datetime_init(t)
if (t.is_a?(Date)) if (t.is_a?(Date))
@data = t t
elsif (t.is_a?(Time)) elsif (t.is_a?(Time))
sec, min, hour, mday, month, year = t.to_a[0..5] sec, min, hour, mday, month, year = t.to_a[0..5]
diffday = t.usec.to_r / 1000000 / SecInDay diffday = t.usec.to_r / 1000000 / SecInDay
of = t.utc_offset.to_r / SecInDay of = t.utc_offset.to_r / SecInDay
@data = DateTime.civil(year, month, mday, hour, min, sec, of) data = DateTime.civil(year, month, mday, hour, min, sec, of)
@data += diffday data += diffday
data
else else
set_str(t) screen_data_str(t)
end end
end end
@ -557,11 +562,7 @@ class XSDDateTime < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
@secfrac = nil
end
def set_str(t)
/^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip /^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
@ -569,7 +570,6 @@ private
if $1 == '0000' if $1 == '0000'
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
year = $1.to_i year = $1.to_i
if year < 0 if year < 0
year += 1 year += 1
@ -581,22 +581,18 @@ private
sec = $6.to_i sec = $6.to_i
secfrac = $7 secfrac = $7
zonestr = $8 zonestr = $8
data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))
@data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))
@secfrac = secfrac
if secfrac if secfrac
diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
# jd = @data.jd data += diffday
# day_fraction = @data.day_fraction + diffday
# @data = DateTime.new0(DateTime.jd_to_rjd(jd, day_fraction,
# @data.offset), @data.offset)
#
# Thanks to Funaba-san, above code can be simply written as below.
@data += diffday
# FYI: new0 and jd_to_rjd are not necessary to use if you don't have # FYI: new0 and jd_to_rjd are not necessary to use if you don't have
# exceptional reason. # exceptional reason.
end end
[data, secfrac]
end
def _set(pair)
@data, @secfrac = pair
end end
def _to_s def _to_s
@ -607,7 +603,8 @@ private
if @secfrac if @secfrac
s << ".#{ @secfrac }" s << ".#{ @secfrac }"
else else
s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') s << sprintf("%.16f",
(@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
end end
end end
add_tz(s) add_tz(s)
@ -627,29 +624,26 @@ class XSDTime < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
@secfrac = nil
end
def set_str(t)
/^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip /^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
hour = $1.to_i hour = $1.to_i
min = $2.to_i min = $2.to_i
sec = $3.to_i sec = $3.to_i
secfrac = $4 secfrac = $4
zonestr = $5 zonestr = $5
data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))
@data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))
@secfrac = secfrac
if secfrac if secfrac
diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
@data += diffday data += diffday
end end
[data, secfrac]
end
def _set(pair)
@data, @secfrac = pair
end end
def _to_s def _to_s
@ -658,7 +652,8 @@ private
if @secfrac if @secfrac
s << ".#{ @secfrac }" s << ".#{ @secfrac }"
else else
s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') s << sprintf("%.16f",
(@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
end end
end end
add_tz(s) add_tz(s)
@ -677,15 +672,11 @@ class XSDDate < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip /^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
year = $1.to_i year = $1.to_i
if year < 0 if year < 0
year += 1 year += 1
@ -693,8 +684,7 @@ private
mon = $2.to_i mon = $2.to_i
mday = $3.to_i mday = $3.to_i
zonestr = $4 zonestr = $4
DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -716,23 +706,18 @@ class XSDGYearMonth < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip /^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
year = $1.to_i year = $1.to_i
if year < 0 if year < 0
year += 1 year += 1
end end
mon = $2.to_i mon = $2.to_i
zonestr = $3 zonestr = $3
DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -754,22 +739,17 @@ class XSDGYear < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip /^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
year = $1.to_i year = $1.to_i
if year < 0 if year < 0
year += 1 year += 1
end end
zonestr = $2 zonestr = $2
DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -791,20 +771,15 @@ class XSDGMonthDay < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip /^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
mon = $1.to_i mon = $1.to_i
mday = $2.to_i mday = $2.to_i
zonestr = $3 zonestr = $3
DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -825,19 +800,14 @@ class XSDGDay < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
mday = $1.to_i mday = $1.to_i
zonestr = $2 zonestr = $2
DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -858,19 +828,14 @@ class XSDGMonth < XSDAnySimpleType
private private
def set_datetime_init(t) def screen_data_str(t)
end
def set_str(t)
/^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end end
mon = $1.to_i mon = $1.to_i
zonestr = $2 zonestr = $2
DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))
@data = DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))
end end
def _to_s def _to_s
@ -903,9 +868,8 @@ class XSDHexBinary < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
@data = value.unpack("H*")[0] value.unpack("H*")[0].tr('a-f', 'A-F')
@data.tr!('a-f', 'A-F')
end end
end end
@ -933,8 +897,8 @@ class XSDBase64Binary < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
@data = [value].pack("m").strip [value].pack("m").strip
end end
end end
@ -949,9 +913,9 @@ class XSDAnyURI < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
begin begin
@data = URI.parse(value.to_s.strip) URI.parse(value.to_s.strip)
rescue URI::InvalidURIError rescue URI::InvalidURIError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
@ -969,14 +933,18 @@ class XSDQName < XSDAnySimpleType
private private
def _set(value) def screen_data(value)
/^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip /^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip
unless Regexp.last_match unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
prefix = $1
localpart = $2
[prefix, localpart]
end
@prefix = $1 def _set(pair)
@localpart = $2 @prefix, @localpart = pair
@data = _to_s @data = _to_s
@data.freeze @data.freeze
end end
@ -1005,7 +973,7 @@ class XSDNormalizedString < XSDString
private private
def _set(value) def screen_data(value)
if /[\t\r\n]/ =~ value if /[\t\r\n]/ =~ value
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end end
@ -1024,12 +992,17 @@ class XSDInteger < XSDDecimal
private private
def set_str(str) def screen_data_str(str)
begin begin
@data = Integer(str) data = Integer(str)
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
data
end
def _set(value)
@data = value
end end
def _to_s() def _to_s()
@ -1048,15 +1021,20 @@ class XSDLong < XSDInteger
private private
def set_str(str) def screen_data_str(str)
begin begin
@data = Integer(str) data = Integer(str)
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
unless validate(@data) unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
data
end
def _set(value)
@data = value
end end
MaxInclusive = +9223372036854775807 MaxInclusive = +9223372036854775807
@ -1077,15 +1055,20 @@ class XSDInt < XSDLong
private private
def set_str(str) def screen_data_str(str)
begin begin
@data = Integer(str) data = Integer(str)
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
unless validate(@data) unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
data
end
def _set(value)
@data = value
end end
MaxInclusive = +2147483647 MaxInclusive = +2147483647
@ -1106,15 +1089,20 @@ class XSDShort < XSDInt
private private
def set_str(str) def screen_data_str(str)
begin begin
@data = Integer(str) data = Integer(str)
rescue ArgumentError rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
unless validate(@data) unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end end
data
end
def _set(value)
@data = value
end end
MaxInclusive = +32767 MaxInclusive = +32767

View file

@ -1,5 +1,5 @@
# XSD4R - XML QName definition. # XSD4R - XML QName definition.
# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. # Copyright (C) 2002, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can # 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; # redistribute it and/or modify it under the same terms of Ruby's license;
@ -19,7 +19,7 @@ class QName
end end
def dup_name(name) def dup_name(name)
self.class.new(@namespace, name) ::XSD::QName.new(@namespace, name)
end end
def match(rhs) def match(rhs)
@ -55,6 +55,11 @@ class QName
"{#{ namespace }}#{ name }" "{#{ namespace }}#{ name }"
end end
def inspect
sprintf("#<%s:0x%x %s>", self.class.name, __id__,
"{#{ namespace }}#{ name }")
end
NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/ NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/
def parse(str) def parse(str)
NormalizedNameRegexp =~ str NormalizedNameRegexp =~ str

View file

@ -1,14 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'webrick' require 'webrick'
require 'getopts' require 'soap/property'
getopts "", 'r:', 'p:8808' docroot = "."
port = 8808
if opt = SOAP::Property.loadproperty("samplehttpd.conf")
docroot = opt["docroot"]
port = Integer(opt["port"])
end
s = WEBrick::HTTPServer.new( s = WEBrick::HTTPServer.new(
:BindAddress => "0.0.0.0", :BindAddress => "0.0.0.0",
:Port => $OPT_p.to_i, :Port => port,
:DocumentRoot => $OPT_r || ".", :DocumentRoot => docroot,
:CGIPathEnv => ENV['PATH'] :CGIPathEnv => ENV['PATH']
) )
trap(:INT){ s.shutdown } trap(:INT){ s.shutdown }

View file

@ -1,14 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'webrick' require 'webrick'
require 'getopts' require 'soap/property'
getopts "", 'r:', 'p:8808' docroot = "."
port = 8808
if opt = SOAP::Property.loadproperty("samplehttpd.conf")
docroot = opt["docroot"]
port = Integer(opt["port"])
end
s = WEBrick::HTTPServer.new( s = WEBrick::HTTPServer.new(
:BindAddress => "0.0.0.0", :BindAddress => "0.0.0.0",
:Port => $OPT_p.to_i, :Port => port,
:DocumentRoot => $OPT_r || ".", :DocumentRoot => docroot,
:CGIPathEnv => ENV['PATH'] :CGIPathEnv => ENV['PATH']
) )
trap(:INT){ s.shutdown } trap(:INT){ s.shutdown }

View file

@ -1,14 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'webrick' require 'webrick'
require 'getopts' require 'soap/property'
getopts "", 'r:', 'p:8808' docroot = "."
port = 8808
if opt = SOAP::Property.loadproperty("samplehttpd.conf")
docroot = opt["docroot"]
port = Integer(opt["port"])
end
s = WEBrick::HTTPServer.new( s = WEBrick::HTTPServer.new(
:BindAddress => "0.0.0.0", :BindAddress => "0.0.0.0",
:Port => $OPT_p.to_i, :Port => port,
:DocumentRoot => $OPT_r || ".", :DocumentRoot => docroot,
:CGIPathEnv => ENV['PATH'] :CGIPathEnv => ENV['PATH']
) )
trap(:INT){ s.shutdown } trap(:INT){ s.shutdown }

View file

@ -12,5 +12,9 @@ class SampleStructServer < SOAP::RPC::StandaloneServer
end end
if $0 == __FILE__ if $0 == __FILE__
status = SampleStructServer.new('SampleStructServer', SampleStructServiceNamespace, '0.0.0.0', 7000).start server = SampleStructServer.new('SampleStructServer', SampleStructServiceNamespace, '0.0.0.0', 7000)
trap(:INT) do
server.shutdown
end
server.start
end end

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,8 @@ require 'AmazonSearch.rb'
require 'soap/rpc/driver' require 'soap/rpc/driver'
class AmazonSearchPort < SOAP::RPC::Driver class AmazonSearchPort < ::SOAP::RPC::Driver
DefaultEndpointUrl = "http://soap.amazon.com/onca/soap3"
MappingRegistry = ::SOAP::Mapping::Registry.new MappingRegistry = ::SOAP::Mapping::Registry.new
MappingRegistry.set( MappingRegistry.set(
@ -331,166 +332,190 @@ class AmazonSearchPort < SOAP::RPC::Driver
) )
Methods = [ Methods = [
["KeywordSearchRequest", "keywordSearchRequest", [ ["KeywordSearchRequest", "keywordSearchRequest",
["in", "KeywordSearchRequest", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "KeywordRequest"]], ["in", "KeywordSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "KeywordRequest"]],
["retval", "return", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], "http://soap.amazon.com", "http://soap.amazon.com"
["TextStreamSearchRequest", "textStreamSearchRequest", [ ],
["in", "TextStreamSearchRequest", ["TextStreamSearchRequest", "textStreamSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "TextStreamRequest"]], [
["retval", "return", ["in", "TextStreamSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "TextStreamRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["PowerSearchRequest", "powerSearchRequest", [ "http://soap.amazon.com", "http://soap.amazon.com"
["in", "PowerSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "PowerRequest"]], ["PowerSearchRequest", "powerSearchRequest",
["retval", "return", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["in", "PowerSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "PowerRequest"]],
"http://soap.amazon.com", "http://soap.amazon.com"], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["BrowseNodeSearchRequest", "browseNodeSearchRequest", [ ],
["in", "BrowseNodeSearchRequest", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "BrowseNodeRequest"]], ],
["retval", "return", ["BrowseNodeSearchRequest", "browseNodeSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], [
"http://soap.amazon.com", "http://soap.amazon.com"], ["in", "BrowseNodeSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "BrowseNodeRequest"]],
["AsinSearchRequest", "asinSearchRequest", [ ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["in", "AsinSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "AsinRequest"]], "http://soap.amazon.com", "http://soap.amazon.com"
["retval", "return", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["AsinSearchRequest", "asinSearchRequest",
"http://soap.amazon.com", "http://soap.amazon.com"], [
["BlendedSearchRequest", "blendedSearchRequest", [ ["in", "AsinSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "AsinRequest"]],
["in", "BlendedSearchRequest", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "BlendedRequest"]], ],
["retval", "return", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPArray, "http://soap.amazon.com", "ProductLine"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], ["BlendedSearchRequest", "blendedSearchRequest",
["UpcSearchRequest", "upcSearchRequest", [ [
["in", "UpcSearchRequest", ["in", "BlendedSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "BlendedRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "UpcRequest"]], ["retval", "return", [::SOAP::SOAPArray, "http://soap.amazon.com", "ProductLine"]]
["retval", "return", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], "http://soap.amazon.com", "http://soap.amazon.com"
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["SkuSearchRequest", "skuSearchRequest", [ ["UpcSearchRequest", "upcSearchRequest",
["in", "SkuSearchRequest", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SkuRequest"]], ["in", "UpcSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "UpcRequest"]],
["retval", "return", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], "http://soap.amazon.com", "http://soap.amazon.com"
["AuthorSearchRequest", "authorSearchRequest", [ ],
["in", "AuthorSearchRequest", ["SkuSearchRequest", "skuSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "AuthorRequest"]], [
["retval", "return", ["in", "SkuSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SkuRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["ArtistSearchRequest", "artistSearchRequest", [ "http://soap.amazon.com", "http://soap.amazon.com"
["in", "ArtistSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ArtistRequest"]], ["AuthorSearchRequest", "authorSearchRequest",
["retval", "return", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["in", "AuthorSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "AuthorRequest"]],
"http://soap.amazon.com", "http://soap.amazon.com"], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["ActorSearchRequest", "actorSearchRequest", [ ],
["in", "ActorSearchRequest", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ActorRequest"]], ],
["retval", "return", ["ArtistSearchRequest", "artistSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], [
"http://soap.amazon.com", "http://soap.amazon.com"], ["in", "ArtistSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ArtistRequest"]],
["ManufacturerSearchRequest", "manufacturerSearchRequest", [ ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["in", "ManufacturerSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ManufacturerRequest"]], "http://soap.amazon.com", "http://soap.amazon.com"
["retval", "return", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ["ActorSearchRequest", "actorSearchRequest",
"http://soap.amazon.com", "http://soap.amazon.com"], [
["DirectorSearchRequest", "directorSearchRequest", [ ["in", "ActorSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ActorRequest"]],
["in", "DirectorSearchRequest", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "DirectorRequest"]], ],
["retval", "return", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], ["ManufacturerSearchRequest", "manufacturerSearchRequest",
["ListManiaSearchRequest", "listManiaSearchRequest", [ [
["in", "ListManiaSearchRequest", ["in", "ManufacturerSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ManufacturerRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ListManiaRequest"]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["retval", "return", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], "http://soap.amazon.com", "http://soap.amazon.com"
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["WishlistSearchRequest", "wishlistSearchRequest", [ ["DirectorSearchRequest", "directorSearchRequest",
["in", "WishlistSearchRequest", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "WishlistRequest"]], ["in", "DirectorSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "DirectorRequest"]],
["retval", "return", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], "http://soap.amazon.com", "http://soap.amazon.com"
["ExchangeSearchRequest", "exchangeSearchRequest", [ ],
["in", "ExchangeSearchRequest", ["ListManiaSearchRequest", "listManiaSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ExchangeRequest"]], [
["retval", "return", ["in", "ListManiaSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ListManiaRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ListingProductDetails"]]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["MarketplaceSearchRequest", "marketplaceSearchRequest", [ "http://soap.amazon.com", "http://soap.amazon.com"
["in", "MarketplaceSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "MarketplaceRequest"]], ["WishlistSearchRequest", "wishlistSearchRequest",
["retval", "return", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "MarketplaceSearch"]]], ["in", "WishlistSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "WishlistRequest"]],
"http://soap.amazon.com", "http://soap.amazon.com"], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
["SellerProfileSearchRequest", "sellerProfileSearchRequest", [ ],
["in", "SellerProfileSearchRequest", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerProfileRequest"]], ],
["retval", "return", ["ExchangeSearchRequest", "exchangeSearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerProfile"]]], [
"http://soap.amazon.com", "http://soap.amazon.com"], ["in", "ExchangeSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ExchangeRequest"]],
["SellerSearchRequest", "sellerSearchRequest", [ ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ListingProductDetails"]]
["in", "SellerSearchRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerRequest"]], "http://soap.amazon.com", "http://soap.amazon.com"
["retval", "return", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerSearch"]]], ["MarketplaceSearchRequest", "marketplaceSearchRequest",
"http://soap.amazon.com", "http://soap.amazon.com"], [
["SimilaritySearchRequest", "similaritySearchRequest", [ ["in", "MarketplaceSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "MarketplaceRequest"]],
["in", "SimilaritySearchRequest", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "MarketplaceSearch"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "SimilarityRequest"]], ],
["retval", "return", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], ["SellerProfileSearchRequest", "sellerProfileSearchRequest",
["GetShoppingCartRequest", "getShoppingCartRequest", [ [
["in", "GetShoppingCartRequest", ["in", "SellerProfileSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerProfileRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "GetShoppingCartRequest"]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerProfile"]]
["retval", "ShoppingCart", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]], "http://soap.amazon.com", "http://soap.amazon.com"
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["ClearShoppingCartRequest", "clearShoppingCartRequest", [ ["SellerSearchRequest", "sellerSearchRequest",
["in", "ClearShoppingCartRequest", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ClearShoppingCartRequest"]], ["in", "SellerSearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerRequest"]],
["retval", "ShoppingCart", ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SellerSearch"]]
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]], ],
"http://soap.amazon.com", "http://soap.amazon.com"], "http://soap.amazon.com", "http://soap.amazon.com"
["AddShoppingCartItemsRequest", "addShoppingCartItemsRequest", [ ],
["in", "AddShoppingCartItemsRequest", ["SimilaritySearchRequest", "similaritySearchRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "AddShoppingCartItemsRequest"]], [
["retval", "ShoppingCart", ["in", "SimilaritySearchRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "SimilarityRequest"]],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]], ["retval", "return", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ProductInfo"]]
"http://soap.amazon.com", "http://soap.amazon.com"], ],
["RemoveShoppingCartItemsRequest", "removeShoppingCartItemsRequest", [ "http://soap.amazon.com", "http://soap.amazon.com"
["in", "RemoveShoppingCartItemsRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "RemoveShoppingCartItemsRequest"]], ["GetShoppingCartRequest", "getShoppingCartRequest",
["retval", "ShoppingCart", [
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]], ["in", "GetShoppingCartRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "GetShoppingCartRequest"]],
"http://soap.amazon.com", "http://soap.amazon.com"], ["retval", "ShoppingCart", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]
["ModifyShoppingCartItemsRequest", "modifyShoppingCartItemsRequest", [ ],
["in", "ModifyShoppingCartItemsRequest", "http://soap.amazon.com", "http://soap.amazon.com"
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ModifyShoppingCartItemsRequest"]], ],
["retval", "ShoppingCart", ["ClearShoppingCartRequest", "clearShoppingCartRequest",
[::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]], [
"http://soap.amazon.com", "http://soap.amazon.com"], ["in", "ClearShoppingCartRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ClearShoppingCartRequest"]],
["GetTransactionDetailsRequest", "getTransactionDetailsRequest", [ ["retval", "ShoppingCart", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]
["in", "GetTransactionDetailsRequest", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "GetTransactionDetailsRequest"]], "http://soap.amazon.com", "http://soap.amazon.com"
["retval", "GetTransactionDetailsResponse", ],
[::SOAP::SOAPStruct, "http://soap.amazon.com", "GetTransactionDetailsResponse"]]], ["AddShoppingCartItemsRequest", "addShoppingCartItemsRequest",
"http://soap.amazon.com", "http://soap.amazon.com"] [
["in", "AddShoppingCartItemsRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "AddShoppingCartItemsRequest"]],
["retval", "ShoppingCart", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]
],
"http://soap.amazon.com", "http://soap.amazon.com"
],
["RemoveShoppingCartItemsRequest", "removeShoppingCartItemsRequest",
[
["in", "RemoveShoppingCartItemsRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "RemoveShoppingCartItemsRequest"]],
["retval", "ShoppingCart", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]
],
"http://soap.amazon.com", "http://soap.amazon.com"
],
["ModifyShoppingCartItemsRequest", "modifyShoppingCartItemsRequest",
[
["in", "ModifyShoppingCartItemsRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ModifyShoppingCartItemsRequest"]],
["retval", "ShoppingCart", [::SOAP::SOAPStruct, "http://soap.amazon.com", "ShoppingCart"]]
],
"http://soap.amazon.com", "http://soap.amazon.com"
],
["GetTransactionDetailsRequest", "getTransactionDetailsRequest",
[
["in", "GetTransactionDetailsRequest", [::SOAP::SOAPStruct, "http://soap.amazon.com", "GetTransactionDetailsRequest"]],
["retval", "GetTransactionDetailsResponse", [::SOAP::SOAPStruct, "http://soap.amazon.com", "GetTransactionDetailsResponse"]]
],
"http://soap.amazon.com", "http://soap.amazon.com"
]
] ]
DefaultEndpointUrl = "http://soap.amazon.com/onca/soap3"
def initialize(endpoint_url = nil) def initialize(endpoint_url = nil)
endpoint_url ||= DefaultEndpointUrl endpoint_url ||= DefaultEndpointUrl
super(endpoint_url, nil) super(endpoint_url, nil)

View file

@ -1,14 +1,19 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'webrick' require 'webrick'
require 'getopts' require 'soap/property'
getopts "", 'r:', 'p:8808' docroot = "."
port = 8808
if opt = SOAP::Property.loadproperty("samplehttpd.conf")
docroot = opt["docroot"]
port = Integer(opt["port"])
end
s = WEBrick::HTTPServer.new( s = WEBrick::HTTPServer.new(
:BindAddress => "0.0.0.0", :BindAddress => "0.0.0.0",
:Port => $OPT_p.to_i, :Port => port,
:DocumentRoot => $OPT_r || ".", :DocumentRoot => docroot,
:CGIPathEnv => ENV['PATH'] :CGIPathEnv => ENV['PATH']
) )
trap(:INT){ s.shutdown } trap(:INT){ s.shutdown }

View file

@ -1,10 +1,6 @@
require 'test/unit' require 'test/unit'
require 'soap/rpc/driver' require 'soap/rpc/driver'
dir = File.dirname(__FILE__)
$:.push(dir)
require 'server.rb' require 'server.rb'
$:.delete(dir)
module SOAP module SOAP

View file

@ -1,10 +1,6 @@
require 'test/unit' require 'test/unit'
require 'soap/rpc/driver' require 'soap/rpc/driver'
dir = File.dirname(__FILE__)
$:.push(dir)
require 'server2.rb' require 'server2.rb'
$:.delete(dir)
module SOAP module SOAP
@ -30,6 +26,7 @@ class TestCalc2 < Test::Unit::TestCase
end end
@endpoint = "http://localhost:#{Port}/" @endpoint = "http://localhost:#{Port}/"
@var = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService') @var = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService')
@var.wiredump_dev = STDERR if $DEBUG
@var.add_method('set', 'newValue') @var.add_method('set', 'newValue')
@var.add_method('get') @var.add_method('get')
@var.add_method_as('+', 'add', 'rhs') @var.add_method_as('+', 'add', 'rhs')

View file

@ -44,6 +44,7 @@ class TestCalcCGI < Test::Unit::TestCase
end end
@endpoint = "http://localhost:#{Port}/server.cgi" @endpoint = "http://localhost:#{Port}/server.cgi"
@calc = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService') @calc = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService')
@calc.wiredump_dev = STDERR if $DEBUG
@calc.add_method('add', 'lhs', 'rhs') @calc.add_method('add', 'lhs', 'rhs')
@calc.add_method('sub', 'lhs', 'rhs') @calc.add_method('sub', 'lhs', 'rhs')
@calc.add_method('multi', 'lhs', 'rhs') @calc.add_method('multi', 'lhs', 'rhs')

View file

@ -1,10 +1,6 @@
require 'test/unit' require 'test/unit'
require 'soap/rpc/driver' require 'soap/rpc/driver'
dir = File.dirname(__FILE__)
$:.push(dir)
require 'hw_s.rb' require 'hw_s.rb'
$:.delete(dir)
module SOAP module SOAP

View file

@ -156,8 +156,8 @@ class TestSOAP < Test::Unit::TestCase
targets = [ targets = [
3.14159265358979, 3.14159265358979,
12.34e36, 12.34e36,
1.4e-45, 1.402e-45,
-1.4e-45, -1.402e-45,
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, SOAP::SOAPFloat.new(f).data) assert_equal(f, SOAP::SOAPFloat.new(f).data)
@ -166,8 +166,8 @@ class TestSOAP < Test::Unit::TestCase
targets = [ targets = [
"+3.141592654", "+3.141592654",
"+1.234e+37", "+1.234e+37",
"+1.4e-45", "+1.402e-45",
"-1.4e-45", "-1.402e-45",
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, SOAP::SOAPFloat.new(f).to_s) assert_equal(f, SOAP::SOAPFloat.new(f).to_s)
@ -178,13 +178,13 @@ class TestSOAP < Test::Unit::TestCase
[-2, "-2"], # ditto [-2, "-2"], # ditto
[3.14159265358979, "+3.141592654"], [3.14159265358979, "+3.141592654"],
[12.34e36, "+1.234e+37"], [12.34e36, "+1.234e+37"],
[1.4e-45, "+1.4e-45"], [1.402e-45, "+1.402e-45"],
[-1.4e-45, "-1.4e-45"], [-1.402e-45, "-1.402e-45"],
["1.4e", "+1.4"], ["1.402e", "+1.402"],
["12.34E36", "+1.234e+37"], ["12.34E36", "+1.234e+37"],
["1.4E-45", "+1.4e-45"], ["1.402E-45", "+1.402e-45"],
["-1.4E-45", "-1.4e-45"], ["-1.402E-45", "-1.402e-45"],
["1.4E", "+1.4"], ["1.402E", "+1.402"],
] ]
targets.each do |f, str| targets.each do |f, str|
assert_equal(str, SOAP::SOAPFloat.new(f).to_s) assert_equal(str, SOAP::SOAPFloat.new(f).to_s)
@ -221,8 +221,8 @@ class TestSOAP < Test::Unit::TestCase
targets = [ targets = [
3.14159265358979, 3.14159265358979,
12.34e36, 12.34e36,
1.4e-45, 1.402e-45,
-1.4e-45, -1.402e-45,
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, SOAP::SOAPDouble.new(f).data) assert_equal(f, SOAP::SOAPDouble.new(f).data)
@ -231,8 +231,8 @@ class TestSOAP < Test::Unit::TestCase
targets = [ targets = [
"+3.14159265358979", "+3.14159265358979",
"+1.234e+37", "+1.234e+37",
"+1.4e-45", "+1.402e-45",
"-1.4e-45", "-1.402e-45",
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, SOAP::SOAPDouble.new(f).to_s) assert_equal(f, SOAP::SOAPDouble.new(f).to_s)
@ -243,13 +243,13 @@ class TestSOAP < Test::Unit::TestCase
[-2, "-2"], # ditto. [-2, "-2"], # ditto.
[3.14159265358979, "+3.14159265358979"], [3.14159265358979, "+3.14159265358979"],
[12.34e36, "+1.234e+37"], [12.34e36, "+1.234e+37"],
[1.4e-45, "+1.4e-45"], [1.402e-45, "+1.402e-45"],
[-1.4e-45, "-1.4e-45"], [-1.402e-45, "-1.402e-45"],
["1.4e", "+1.4"], ["1.402e", "+1.402"],
["12.34E36", "+1.234e+37"], ["12.34E36", "+1.234e+37"],
["1.4E-45", "+1.4e-45"], ["1.402E-45", "+1.402e-45"],
["-1.4E-45", "-1.4e-45"], ["-1.402E-45", "-1.402e-45"],
["1.4E", "+1.4"], ["1.402E", "+1.402"],
] ]
targets.each do |f, str| targets.each do |f, str|
assert_equal(str, SOAP::SOAPDouble.new(f).to_s) assert_equal(str, SOAP::SOAPDouble.new(f).to_s)

View file

@ -59,7 +59,7 @@ __EOP__
prop = Property.new prop = Property.new
hooked = false hooked = false
prop.add_hook("foo.bar.baz") do |name, value| prop.add_hook("foo.bar.baz") do |name, value|
assert_equal("foo.bar.baz", name) assert_equal(["foo", "bar", "baz"], name)
assert_equal("123", value) assert_equal("123", value)
hooked = true hooked = true
end end
@ -126,11 +126,24 @@ __EOP__
end end
end end
def test_hook_name
tag = Object.new
tested = false
@prop.add_hook("foo.bar") do |key, value|
assert_raise(TypeError) do
key << "baz"
end
tested = true
end
@prop["foo.bar"] = tag
assert(tested)
end
def test_value_hook def test_value_hook
tag = Object.new tag = Object.new
tested = false tested = false
@prop.add_hook("FOO.BAR.BAZ") do |key, value| @prop.add_hook("FOO.BAR.BAZ") do |key, value|
assert_equal("foo.bar.baz", key) assert_equal(["Foo", "baR", "baZ"], key)
assert_equal(tag, value) assert_equal(tag, value)
tested = true tested = true
end end
@ -141,32 +154,65 @@ __EOP__
assert_equal(1, @prop["foo.bar"]) assert_equal(1, @prop["foo.bar"])
end end
def test_key_hook def test_key_hook_no_cascade
tag = Object.new tag = Object.new
tested = 0 tested = 0
@prop.add_hook("foo") do |key, value| @prop.add_hook do |key, value|
assert_equal("foo.bar.baz.qux", key) assert(false)
assert_equal(tag, value)
tested += 1
end end
@prop.add_hook("foo.bar") do |key, value| @prop.add_hook(false) do |key, value|
assert_equal("foo.bar.baz.qux", key) assert(false)
assert_equal(tag, value) end
tested += 1 @prop.add_hook("foo") do |key, value|
assert(false)
end
@prop.add_hook("foo.bar", false) do |key, value|
assert(false)
end end
@prop.add_hook("foo.bar.baz") do |key, value| @prop.add_hook("foo.bar.baz") do |key, value|
assert_equal("foo.bar.baz.qux", key) assert(false)
assert_equal(tag, value)
tested += 1
end end
@prop.add_hook("foo.bar.baz.qux") do |key, value| @prop.add_hook("foo.bar.baz.qux", false) do |key, value|
assert_equal("foo.bar.baz.qux", key) assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value) assert_equal(tag, value)
tested += 1 tested += 1
end end
@prop["foo.bar.baz.qux"] = tag @prop["foo.bar.baz.qux"] = tag
assert_equal(tag, @prop["foo.bar.baz.qux"]) assert_equal(tag, @prop["foo.bar.baz.qux"])
assert_equal(4, tested) assert_equal(1, tested)
end
def test_key_hook_cascade
tag = Object.new
tested = 0
@prop.add_hook(true) do |key, value|
assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value)
tested += 1
end
@prop.add_hook("foo", true) do |key, value|
assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value)
tested += 1
end
@prop.add_hook("foo.bar", true) do |key, value|
assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value)
tested += 1
end
@prop.add_hook("foo.bar.baz", true) do |key, value|
assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value)
tested += 1
end
@prop.add_hook("foo.bar.baz.qux", true) do |key, value|
assert_equal(["foo", "bar", "baz", "qux"], key)
assert_equal(tag, value)
tested += 1
end
@prop["foo.bar.baz.qux"] = tag
assert_equal(tag, @prop["foo.bar.baz.qux"])
assert_equal(5, tested)
end end
def test_keys def test_keys
@ -310,7 +356,7 @@ __EOP__
def test_hook_then_lock def test_hook_then_lock
tested = false tested = false
@prop.add_hook("a.b.c") do |name, value| @prop.add_hook("a.b.c") do |name, value|
assert_equal("a.b.c", name) assert_equal(["a", "b", "c"], name)
tested = true tested = true
end end
@prop["a.b"].lock @prop["a.b"].lock

View file

@ -142,9 +142,16 @@ __EOX__
end end
def test_basic_auth def test_basic_auth
# soap4r + basic_auth is not officially supported in ruby/1.8.1 even though unless Object.const_defined?('HTTPAccess2')
# soap4r + basic_auth + http-access2 should run fine. STDERR.puts("basic_auth is not supported under soap4r + net/http for now.")
return return
end
str = ""
@client.wiredump_dev = str
@client.options["protocol.http.basic_auth"] << [@url, "foo", "bar"]
assert_nil(@client.do_server_proc)
r, h = parse_req_header(str)
assert_equal("Basic Zm9vOmJhcg==", h["authorization"])
end end
def test_proxy def test_proxy

View file

@ -3,6 +3,7 @@ require 'soap/processor'
require 'soap/mapping' require 'soap/mapping'
require 'soap/rpc/element' require 'soap/rpc/element'
require 'wsdl/importer' require 'wsdl/importer'
require 'itemList.rb'
module WSDL module WSDL
@ -10,10 +11,6 @@ module WSDL
class TestAxisArray < Test::Unit::TestCase class TestAxisArray < Test::Unit::TestCase
def setup def setup
dir = File.dirname(File.expand_path(__FILE__))
$:.push(dir)
require 'itemList.rb'
$:.delete(dir)
@xml =<<__EOX__ @xml =<<__EOX__
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

View file

@ -1,5 +1,6 @@
require 'test/unit' require 'test/unit'
require 'soap/wsdlDriver' require 'soap/wsdlDriver'
require 'DatetimeService.rb'
module WSDL module WSDL
@ -17,9 +18,6 @@ class TestDatetime < Test::Unit::TestCase
end end
def setup_server def setup_server
$:.push(DIR)
require File.join(DIR, 'DatetimeService.rb')
$:.delete(DIR)
@server = DatetimePortTypeApp.new('Datetime server', nil, '0.0.0.0', Port) @server = DatetimePortTypeApp.new('Datetime server', nil, '0.0.0.0', Port)
@server.level = Logger::Severity::ERROR @server.level = Logger::Severity::ERROR
@t = Thread.new { @t = Thread.new {

View file

@ -1,5 +1,8 @@
require 'test/unit' require 'test/unit'
require 'soap/wsdlDriver' require 'soap/wsdlDriver'
require 'RAA.rb'
require 'RAAServant.rb'
require 'RAAService.rb'
module WSDL module WSDL
@ -17,11 +20,6 @@ class TestRAA < Test::Unit::TestCase
end end
def setup_server def setup_server
$:.push(DIR)
require File.join(DIR, 'RAA.rb')
require File.join(DIR, 'RAAServant.rb')
require File.join(DIR, 'RAAService.rb')
$:.delete(DIR)
@server = App.new('RAA server', nil, '0.0.0.0', Port) @server = App.new('RAA server', nil, '0.0.0.0', Port)
@server.level = Logger::Severity::ERROR @server.level = Logger::Severity::ERROR
@t = Thread.new { @t = Thread.new {

View file

@ -7,12 +7,12 @@ module WSDL
class TestWSDL < Test::Unit::TestCase class TestWSDL < Test::Unit::TestCase
def setup def setup
@file = File.join(File.dirname(__FILE__), 'emptycomplextype.wsdl') @file = File.join(File.dirname(File.expand_path(__FILE__)), 'emptycomplextype.wsdl')
end end
def test_wsdl def test_wsdl
@wsdl = WSDL::Parser.new.parse(File.open(@file) { |f| f.read }) @wsdl = WSDL::Parser.new.parse(File.open(@file) { |f| f.read })
assert_equal("#<WSDL::Definitions:{urn:jp.gr.jin.rrr.example.emptycomplextype}emptycomplextype>", @wsdl.inspect) assert(/\{urn:jp.gr.jin.rrr.example.emptycomplextype\}emptycomplextype/ =~ @wsdl.inspect)
end end
end end

View file

@ -7,7 +7,7 @@ module XSD
class TestXMLSchemaParser < Test::Unit::TestCase class TestXMLSchemaParser < Test::Unit::TestCase
def setup def setup
@file = File.join(File.dirname(__FILE__), 'xmlschema.xml') @file = File.join(File.dirname(File.expand_path(__FILE__)), 'xmlschema.xml')
end end
def test_wsdl def test_wsdl

View file

@ -189,8 +189,8 @@ class TestXSD < Test::Unit::TestCase
targets = [ targets = [
3.14159265358979, 3.14159265358979,
12.34e36, 12.34e36,
1.4e-45, 1.402e-45,
-1.4e-45, -1.402e-45,
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, XSD::XSDFloat.new(f).data) assert_equal(f, XSD::XSDFloat.new(f).data)
@ -199,8 +199,8 @@ class TestXSD < Test::Unit::TestCase
targets = [ targets = [
"+3.141592654", "+3.141592654",
"+1.234e+37", "+1.234e+37",
"+1.4e-45", "+1.402e-45",
"-1.4e-45", "-1.402e-45",
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, XSD::XSDFloat.new(f).to_s) assert_equal(f, XSD::XSDFloat.new(f).to_s)
@ -211,13 +211,13 @@ class TestXSD < Test::Unit::TestCase
[-2, "-2"], # ditto [-2, "-2"], # ditto
[3.14159265358979, "+3.141592654"], [3.14159265358979, "+3.141592654"],
[12.34e36, "+1.234e+37"], [12.34e36, "+1.234e+37"],
[1.4e-45, "+1.4e-45"], [1.402e-45, "+1.402e-45"],
[-1.4e-45, "-1.4e-45"], [-1.402e-45, "-1.402e-45"],
["1.4e", "+1.4"], ["1.402e", "+1.402"],
["12.34E36", "+1.234e+37"], ["12.34E36", "+1.234e+37"],
["1.4E-45", "+1.4e-45"], ["1.402E-45", "+1.402e-45"],
["-1.4E-45", "-1.4e-45"], ["-1.402E-45", "-1.402e-45"],
["1.4E", "+1.4"], ["1.402E", "+1.402"],
] ]
targets.each do |f, str| targets.each do |f, str|
assert_equal(str, XSD::XSDFloat.new(f).to_s) assert_equal(str, XSD::XSDFloat.new(f).to_s)
@ -254,8 +254,8 @@ class TestXSD < Test::Unit::TestCase
targets = [ targets = [
3.14159265358979, 3.14159265358979,
12.34e36, 12.34e36,
1.4e-45, 1.402e-45,
-1.4e-45, -1.402e-45,
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, XSD::XSDDouble.new(f).data) assert_equal(f, XSD::XSDDouble.new(f).data)
@ -264,8 +264,8 @@ class TestXSD < Test::Unit::TestCase
targets = [ targets = [
"+3.14159265358979", "+3.14159265358979",
"+1.234e+37", "+1.234e+37",
"+1.4e-45", "+1.402e-45",
"-1.4e-45", "-1.402e-45",
] ]
targets.each do |f| targets.each do |f|
assert_equal(f, XSD::XSDDouble.new(f).to_s) assert_equal(f, XSD::XSDDouble.new(f).to_s)
@ -276,13 +276,13 @@ class TestXSD < Test::Unit::TestCase
[-2, "-2"], # ditto. [-2, "-2"], # ditto.
[3.14159265358979, "+3.14159265358979"], [3.14159265358979, "+3.14159265358979"],
[12.34e36, "+1.234e+37"], [12.34e36, "+1.234e+37"],
[1.4e-45, "+1.4e-45"], [1.402e-45, "+1.402e-45"],
[-1.4e-45, "-1.4e-45"], [-1.402e-45, "-1.402e-45"],
["1.4e", "+1.4"], ["1.402e", "+1.402"],
["12.34E36", "+1.234e+37"], ["12.34E36", "+1.234e+37"],
["1.4E-45", "+1.4e-45"], ["1.402E-45", "+1.402e-45"],
["-1.4E-45", "-1.4e-45"], ["-1.402E-45", "-1.402e-45"],
["1.4E", "+1.4"], ["1.402E", "+1.402"],
] ]
targets.each do |f, str| targets.each do |f, str|
assert_equal(str, XSD::XSDDouble.new(f).to_s) assert_equal(str, XSD::XSDDouble.new(f).to_s)

View file

@ -1,14 +1,14 @@
#define RUBY_VERSION "1.8.2" #define RUBY_VERSION "1.8.2"
#define RUBY_RELEASE_DATE "2004-07-03" #define RUBY_RELEASE_DATE "2004-07-04"
#define RUBY_VERSION_CODE 182 #define RUBY_VERSION_CODE 182
#define RUBY_RELEASE_CODE 20040703 #define RUBY_RELEASE_CODE 20040704
#define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8 #define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 2 #define RUBY_VERSION_TEENY 2
#define RUBY_RELEASE_YEAR 2004 #define RUBY_RELEASE_YEAR 2004
#define RUBY_RELEASE_MONTH 7 #define RUBY_RELEASE_MONTH 7
#define RUBY_RELEASE_DAY 3 #define RUBY_RELEASE_DAY 4
RUBY_EXTERN const char ruby_version[]; RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[]; RUBY_EXTERN const char ruby_release_date[];