summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-15 14:47:07 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-15 14:47:07 +0000
commitd168aaa9cb1fb14bd09f0c7c24d63a13af33248e (patch)
tree4cc1c58ec29d3d4af8ce0e7f31802447be125221 /lib
parentf592275211f19e520ec7e257db41899084533806 (diff)
downloadruby-d168aaa9cb1fb14bd09f0c7c24d63a13af33248e.tar.gz
ruby-d168aaa9cb1fb14bd09f0c7c24d63a13af33248e.tar.xz
ruby-d168aaa9cb1fb14bd09f0c7c24d63a13af33248e.zip
* lib/{soap,wsdl,xsd}, test/{soap,wsdl,xsd}: imported soap4r/1.5.5.
#nnn is a ticket number at http://dev.ctor.org/soap4r * SOAP * allow to configure an envelope namespace of SOAP request. (#124) TemporaryNamespace = 'http://www.w3.org/2003/05/soap-envelope' @client.options["soap.envelope.requestnamespace"] = TemporaryNamespace @client.options["soap.envelope.responsenamespace"] = TemporaryNamespace @client.do_proc(...) * let SOAP request XML indent space configuable. see "soap.envelope.no_indent" option. (#130) * let external CES configuable. ex. client["soap.mapping.external_ces"] = 'SJIS'. $KCODE is used by default. (#133) external CES ::= CES used in Ruby object of client and server internal CES ::= CES used in SOAP/OM * add iso-8859-1 external CES support. (#106) * fixed illegal 'qualified' handling of elements. it caused ASP.NET inteoperability problem. (#144) * added 'soap.envelope.use_numeric_character_reference' (boolean) option to let query XML use numeric character reference in XML, not plain UTF-8 character. !GoogleSearch server seems to not allow plain UTF-8 character since 2005-08-15 update. (#147) * SOAP::Header::SimpleHeader (de)serialization throws an exception on !SimpleHeader.on_(in|out)bound when header is a String. so we could not use a simple single element headerItem. fixed. thanks to emil. (#129) * out parameter of rpc operation did not work. (#132) * follow HTTP redirect only if using http-access2. (#125) (#145) * add a workaround for importing an WSDL whose path begins with drive letter. (#115) * WSDL * SOAP Data which is defined as a simpletype was not mapped correctly to Ruby obj when using wsdl2ruby.rb generated classdef file. (#123) * rpc/literal support. (#118) * re-implemented local element qualify/unqualify control. handles elementFormDefault and form in WSDL. (#119) * Array of an element which has simpleType causes a crash. (#128) * prarmeterOrder may not contain return part so it can be shorter than parts size. Thanks to Hugh. (#139) * Samples * added !BasicAuth client sample. (#117) * added Base64 client/server sample. * added Flickr SOAP interface client sample. (#122) * added !SalesForce client sample. (#135) * updated Thawte CA certificate for !GoogleAdWords sample. * updated a client script with the newer version made by Johan. thanks! * shortened long file names. (#120) * fixed typo in authheader sample. (#129) * updated deprecated method usage. (#138) git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@9171 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/soap/baseData.rb60
-rw-r--r--lib/soap/element.rb22
-rw-r--r--lib/soap/encodingstyle/aspDotNetHandler.rb34
-rw-r--r--lib/soap/encodingstyle/handler.rb8
-rw-r--r--lib/soap/encodingstyle/literalHandler.rb34
-rw-r--r--lib/soap/encodingstyle/soapHandler.rb27
-rw-r--r--lib/soap/generator.rb107
-rw-r--r--lib/soap/header/simplehandler.rb6
-rw-r--r--lib/soap/httpconfigloader.rb3
-rw-r--r--lib/soap/mapping/factory.rb10
-rw-r--r--lib/soap/mapping/registry.rb7
-rw-r--r--lib/soap/mapping/wsdlRegistry.rb155
-rw-r--r--lib/soap/mapping/wsdlencodedregistry.rb17
-rw-r--r--lib/soap/mapping/wsdlliteralregistry.rb90
-rw-r--r--lib/soap/mimemessage.rb4
-rw-r--r--lib/soap/parser.rb11
-rw-r--r--lib/soap/rpc/driver.rb2
-rw-r--r--lib/soap/rpc/element.rb18
-rw-r--r--lib/soap/rpc/proxy.rb154
-rw-r--r--lib/soap/rpc/router.rb104
-rw-r--r--lib/soap/rpc/soaplet.rb1
-rw-r--r--lib/soap/soap.rb33
-rw-r--r--lib/soap/streamHandler.rb47
-rw-r--r--lib/wsdl/operation.rb5
-rw-r--r--lib/wsdl/param.rb8
-rw-r--r--lib/wsdl/soap/body.rb6
-rw-r--r--lib/wsdl/soap/cgiStubCreator.rb10
-rw-r--r--lib/wsdl/soap/classDefCreator.rb54
-rw-r--r--lib/wsdl/soap/clientSkeltonCreator.rb4
-rw-r--r--lib/wsdl/soap/complexType.rb31
-rw-r--r--lib/wsdl/soap/driverCreator.rb22
-rw-r--r--lib/wsdl/soap/methodDefCreator.rb77
-rw-r--r--lib/wsdl/soap/standaloneServerStubCreator.rb10
-rw-r--r--lib/wsdl/xmlSchema/all.rb4
-rw-r--r--lib/wsdl/xmlSchema/attribute.rb15
-rw-r--r--lib/wsdl/xmlSchema/choice.rb4
-rw-r--r--lib/wsdl/xmlSchema/complexType.rb8
-rw-r--r--lib/wsdl/xmlSchema/element.rb36
-rw-r--r--lib/wsdl/xmlSchema/schema.rb5
-rw-r--r--lib/wsdl/xmlSchema/sequence.rb4
-rw-r--r--lib/xsd/charset.rb76
-rw-r--r--lib/xsd/codegen/gensupport.rb17
-rw-r--r--lib/xsd/datatypes.rb23
-rw-r--r--lib/xsd/ns.rb2
-rw-r--r--lib/xsd/qname.rb7
45 files changed, 799 insertions, 583 deletions
diff --git a/lib/soap/baseData.rb b/lib/soap/baseData.rb
index 6d0f628be..0e8b00d45 100644
--- a/lib/soap/baseData.rb
+++ b/lib/soap/baseData.rb
@@ -44,9 +44,9 @@ module SOAPType
attr_accessor :definedtype
def initialize(*arg)
- super(*arg)
+ super
@encodingstyle = nil
- @elename = XSD::QName.new
+ @elename = XSD::QName::EMPTY
@id = nil
@precedents = []
@root = false
@@ -82,7 +82,7 @@ module SOAPBasetype
include SOAP
def initialize(*arg)
- super(*arg)
+ super
end
end
@@ -95,7 +95,7 @@ module SOAPCompoundtype
include SOAP
def initialize(*arg)
- super(*arg)
+ super
end
end
@@ -114,7 +114,7 @@ public
# Override the definition in SOAPBasetype.
def initialize(obj = nil)
super()
- @type = XSD::QName.new
+ @type = XSD::QName::EMPTY
@refid = nil
@obj = nil
__setobj__(obj) if obj
@@ -178,7 +178,7 @@ class SOAPExternalReference < XSD::NSDBase
def initialize
super()
- @type = XSD::QName.new
+ @type = XSD::QName::EMPTY
end
def referred
@@ -399,7 +399,7 @@ public
def initialize(type = nil)
super()
- @type = type || XSD::QName.new
+ @type = type || XSD::QName::EMPTY
@array = []
@data = []
end
@@ -470,8 +470,10 @@ public
end
def each
- for i in 0..(@array.length - 1)
- yield(@array[i], @data[i])
+ idx = 0
+ while idx < @array.length
+ yield(@array[idx], @data[idx])
+ idx += 1
end
end
@@ -529,7 +531,7 @@ class SOAPElement
@position = nil
@extraattr = {}
- @qualified = false
+ @qualified = nil
@array = []
@data = []
@@ -598,8 +600,10 @@ class SOAPElement
end
def each
- for i in 0..(@array.length - 1)
- yield(@array[i], @data[i])
+ idx = 0
+ while idx < @array.length
+ yield(@array[idx], @data[idx])
+ idx += 1
end
end
@@ -737,27 +741,25 @@ public
" does not match rank: #{@rank}")
end
- for i in 0..(idxary.size - 1)
- if idxary[i] + 1 > @size[i]
- @size[i] = idxary[i] + 1
+ idx = 0
+ while idx < idxary.size
+ if idxary[idx] + 1 > @size[idx]
+ @size[idx] = idxary[idx] + 1
end
+ idx += 1
end
data = retrieve(idxary[0, idxary.size - 1])
data[idxary.last] = value
if value.is_a?(SOAPType)
- value.elename = value.elename.dup_name('item')
-
+ value.elename = ITEM_NAME
# Sync type
unless @type.name
@type = XSD::QName.new(value.type.namespace,
SOAPArray.create_arytype(value.type.name, @rank))
end
-
- unless value.type
- value.type = @type
- end
+ value.type ||= @type
end
@offset = idxary
@@ -787,7 +789,7 @@ public
deep_map(ele, &block)
else
new_obj = block.call(ele)
- new_obj.elename = new_obj.elename.dup_name('item')
+ new_obj.elename = ITEM_NAME
new_obj
end
end
@@ -815,13 +817,15 @@ public
def soap2array(ary)
traverse_data(@data) do |v, *position|
iteary = ary
- for rank in 1..(position.size - 1)
+ rank = 1
+ while rank < position.size
idx = position[rank - 1]
if iteary[idx].nil?
iteary = iteary[idx] = Array.new
else
iteary = iteary[idx]
end
+ rank += 1
end
if block_given?
iteary[position.last] = yield(v)
@@ -837,21 +841,26 @@ public
private
+ ITEM_NAME = XSD::QName.new(nil, 'item')
+
def retrieve(idxary)
data = @data
- for rank in 1..(idxary.size)
+ rank = 1
+ while rank <= idxary.size
idx = idxary[rank - 1]
if data[idx].nil?
data = data[idx] = Array.new
else
data = data[idx]
end
+ rank += 1
end
data
end
def traverse_data(data, rank = 1)
- for idx in 0..(ranksize(rank) - 1)
+ idx = 0
+ while idx < ranksize(rank)
if rank < @rank
traverse_data(data[idx], rank + 1) do |*v|
v[1, 0] = idx
@@ -860,6 +869,7 @@ private
else
yield(data[idx], idx)
end
+ idx += 1
end
end
diff --git a/lib/soap/element.rb b/lib/soap/element.rb
index 20d7c3bb2..cc58b5d34 100644
--- a/lib/soap/element.rb
+++ b/lib/soap/element.rb
@@ -83,10 +83,10 @@ public
attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace
name = ns.name(@elename)
generator.encode_tag(name, attrs)
- yield(self.faultcode, false)
- yield(self.faultstring, false)
- yield(self.faultactor, false)
- yield(self.detail, false) if self.detail
+ yield(self.faultcode)
+ yield(self.faultstring)
+ yield(self.faultactor)
+ yield(self.detail) if self.detail
generator.encode_tag_end(name, true)
end
end
@@ -115,10 +115,10 @@ class SOAPBody < SOAPStruct
name = ns.name(@elename)
generator.encode_tag(name, attrs)
if @is_fault
- yield(@data, true)
+ yield(@data)
else
@data.each do |data|
- yield(data, true)
+ yield(data)
end
end
generator.encode_tag_end(name, true)
@@ -171,7 +171,7 @@ public
@element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle
end
@element.encodingstyle = @encodingstyle if !@element.encodingstyle
- yield(@element, true)
+ yield(@element)
end
end
@@ -189,7 +189,7 @@ class SOAPHeader < SOAPStruct
name = ns.name(@elename)
generator.encode_tag(name, attrs)
@data.each do |data|
- yield(data, true)
+ yield(data)
end
generator.encode_tag_end(name, true)
end
@@ -239,12 +239,12 @@ class SOAPEnvelope < XSD::NSDBase
end
def encode(generator, ns, attrs = {})
- SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace, SOAPNamespaceTag)
+ SOAPGenerator.assign_ns(attrs, ns, elename.namespace, SOAPNamespaceTag)
name = ns.name(@elename)
generator.encode_tag(name, attrs)
- yield(@header, true) if @header and @header.length > 0
- yield(@body, true)
+ yield(@header) if @header and @header.length > 0
+ yield(@body)
generator.encode_tag_end(name, true)
end
diff --git a/lib/soap/encodingstyle/aspDotNetHandler.rb b/lib/soap/encodingstyle/aspDotNetHandler.rb
index e4b2028f8..fd7e0fa21 100644
--- a/lib/soap/encodingstyle/aspDotNetHandler.rb
+++ b/lib/soap/encodingstyle/aspDotNetHandler.rb
@@ -27,38 +27,36 @@ class ASPDotNetHandler < Handler
###
## encode interface.
#
- def encode_data(generator, ns, qualified, data, parent)
+ def encode_data(generator, ns, data, parent)
attrs = {}
- name = if qualified and data.elename.namespace
- SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
- ns.name(data.elename)
- else
- data.elename.name
- end
-
+ # ASPDotNetHandler is intended to be used for accessing an ASP.NET doc/lit
+ # service as an rpc/encoded service. in the situation, local elements
+ # should be qualified. propagate parent's namespace to children.
+ if data.elename.namespace.nil?
+ data.elename.namespace = parent.elename.namespace
+ end
+ name = generator.encode_name(ns, data, attrs)
case data
when SOAPRawString
generator.encode_tag(name, attrs)
generator.encode_rawstring(data.to_s)
when XSD::XSDString
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
generator.encode_tag(name, attrs)
generator.encode_string(data.to_s)
when SOAPStruct
generator.encode_tag(name, attrs)
data.each do |key, value|
- if !value.elename.namespace
- value.elename.namespace = data.elename.namespace
- end
- yield(value, true)
+ generator.encode_child(ns, value, data)
end
when SOAPArray
generator.encode_tag(name, attrs)
data.traverse do |child, *rank|
data.position = nil
- yield(child, true)
+ generator.encode_child(ns, child, data)
end
else
raise EncodingStyleError.new(
@@ -66,12 +64,8 @@ class ASPDotNetHandler < Handler
end
end
- def encode_data_end(generator, ns, qualified, data, parent)
- name = if qualified and data.elename.namespace
- ns.name(data.elename)
- else
- data.elename.name
- end
+ def encode_data_end(generator, ns, data, parent)
+ name = generator.encode_name_end(ns, data)
cr = data.is_a?(SOAPCompoundtype)
generator.encode_tag_end(name, cr)
end
diff --git a/lib/soap/encodingstyle/handler.rb b/lib/soap/encodingstyle/handler.rb
index 7bf65a2fd..c01541743 100644
--- a/lib/soap/encodingstyle/handler.rb
+++ b/lib/soap/encodingstyle/handler.rb
@@ -58,12 +58,12 @@ class Handler
## encode interface.
#
# Returns a XML instance as a string.
- def encode_data(generator, ns, qualified, data, parent)
- raise NotImplementError.new('Method encode_data must be defined in derived class.')
+ def encode_data(generator, ns, data, parent)
+ raise NotImplementError
end
- def encode_data_end(generator, ns, qualified, data, parent)
- raise NotImplementError.new('Method encode_data must be defined in derived class.')
+ def encode_data_end(generator, ns, data, parent)
+ raise NotImplementError
end
def encode_prologue
diff --git a/lib/soap/encodingstyle/literalHandler.rb b/lib/soap/encodingstyle/literalHandler.rb
index 9a494f929..59c720536 100644
--- a/lib/soap/encodingstyle/literalHandler.rb
+++ b/lib/soap/encodingstyle/literalHandler.rb
@@ -26,15 +26,11 @@ class LiteralHandler < Handler
###
## encode interface.
#
- def encode_data(generator, ns, qualified, data, parent)
+ def encode_data(generator, ns, data, parent)
attrs = {}
- name = if qualified and data.elename.namespace
- SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
- ns.name(data.elename)
- else
- data.elename.name
- end
+ name = generator.encode_name(ns, data, attrs)
data.extraattr.each do |k, v|
+ # ToDo: check generator.attributeformdefault here
if k.is_a?(XSD::QName)
if k.namespace
SOAPGenerator.assign_ns(attrs, ns, k.namespace)
@@ -45,7 +41,6 @@ class LiteralHandler < Handler
end
attrs[k] = v
end
-
case data
when SOAPRawString
generator.encode_tag(name, attrs)
@@ -61,22 +56,25 @@ class LiteralHandler < Handler
when SOAPStruct
generator.encode_tag(name, attrs)
data.each do |key, value|
- if !value.elename.namespace
- value.elename.namespace = data.elename.namespace
- end
- yield(value, true)
+ generator.encode_child(ns, value, data)
end
when SOAPArray
generator.encode_tag(name, attrs)
data.traverse do |child, *rank|
data.position = nil
- yield(child, true)
+ generator.encode_child(ns, child, data)
end
when SOAPElement
+ # passes 2 times for simplifying namespace definition
+ data.each do |key, value|
+ if value.elename.namespace
+ SOAPGenerator.assign_ns(attrs, ns, value.elename.namespace)
+ end
+ end
generator.encode_tag(name, attrs)
generator.encode_rawstring(data.text) if data.text
data.each do |key, value|
- yield(value, qualified)
+ generator.encode_child(ns, value, data)
end
else
raise EncodingStyleError.new(
@@ -84,12 +82,8 @@ class LiteralHandler < Handler
end
end
- def encode_data_end(generator, ns, qualified, data, parent)
- name = if qualified and data.elename.namespace
- ns.name(data.elename)
- else
- data.elename.name
- end
+ def encode_data_end(generator, ns, data, parent)
+ name = generator.encode_name_end(ns, data)
cr = (data.is_a?(SOAPCompoundtype) or
(data.is_a?(SOAPElement) and !data.text))
generator.encode_tag_end(name, cr)
diff --git a/lib/soap/encodingstyle/soapHandler.rb b/lib/soap/encodingstyle/soapHandler.rb
index f9152e0df..a52239262 100644
--- a/lib/soap/encodingstyle/soapHandler.rb
+++ b/lib/soap/encodingstyle/soapHandler.rb
@@ -29,21 +29,12 @@ class SOAPHandler < Handler
###
## encode interface.
#
- def encode_data(generator, ns, qualified, data, parent)
+ def encode_data(generator, ns, data, parent)
attrs = encode_attrs(generator, ns, data, parent)
-
if parent && parent.is_a?(SOAPArray) && parent.position
attrs[ns.name(AttrPositionName)] = "[#{parent.position.join(',')}]"
end
-
- name = nil
- if qualified and data.elename.namespace
- SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
- name = ns.name(data.elename)
- else
- name = data.elename.name
- end
-
+ name = generator.encode_name(ns, data, attrs)
case data
when SOAPReference
attrs['href'] = data.refidstr
@@ -65,13 +56,13 @@ class SOAPHandler < Handler
when SOAPStruct
generator.encode_tag(name, attrs)
data.each do |key, value|
- yield(value, false)
+ generator.encode_child(ns, value, data)
end
when SOAPArray
generator.encode_tag(name, attrs)
data.traverse do |child, *rank|
data.position = data.sparse ? rank : nil
- yield(child, false)
+ generator.encode_child(ns, child, data)
end
else
raise EncodingStyleError.new(
@@ -79,12 +70,8 @@ class SOAPHandler < Handler
end
end
- def encode_data_end(generator, ns, qualified, data, parent)
- name = if qualified and data.elename.namespace
- ns.name(data.elename)
- else
- data.elename.name
- end
+ def encode_data_end(generator, ns, data, parent)
+ name = generator.encode_name_end(ns, data)
cr = data.is_a?(SOAPCompoundtype)
generator.encode_tag_end(name, cr)
end
@@ -268,8 +255,8 @@ private
end
def encode_attrs(generator, ns, data, parent)
- return {} if data.is_a?(SOAPReference)
attrs = {}
+ return attrs if data.is_a?(SOAPReference)
if !parent || parent.encodingstyle != EncodingNamespace
if @generate_explicit_type
diff --git a/lib/soap/generator.rb b/lib/soap/generator.rb
index a44d1468b..f179555e1 100644
--- a/lib/soap/generator.rb
+++ b/lib/soap/generator.rb
@@ -1,5 +1,5 @@
# SOAP4R - SOAP XML Instance Generator library.
-# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
@@ -28,14 +28,19 @@ public
attr_accessor :charset
attr_accessor :default_encodingstyle
attr_accessor :generate_explicit_type
+ attr_accessor :use_numeric_character_reference
def initialize(opt = {})
@reftarget = nil
@handlers = {}
- @charset = opt[:charset] || XSD::Charset.encoding_label
+ @charset = opt[:charset] || XSD::Charset.xml_encoding_label
@default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
@generate_explicit_type =
opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true
+ @elementformdefault = opt[:elementformdefault]
+ @attributeformdefault = opt[:attributeformdefault]
+ @use_numeric_character_reference = opt[:use_numeric_character_reference]
+ @indentstr = opt[:no_indent] ? '' : ' '
@buf = @indent = @curr = nil
end
@@ -50,7 +55,7 @@ public
ns = XSD::NS.new
@buf << xmldecl
- encode_data(ns, true, obj, nil)
+ encode_data(ns, obj, nil)
@handlers.each do |uri, handler|
handler.encode_epilogue
@@ -60,42 +65,33 @@ public
@buf
end
- def encode_data(ns, qualified, obj, parent)
+ def encode_data(ns, obj, parent)
if obj.is_a?(SOAPEnvelopeElement)
- encode_element(ns, qualified, obj, parent)
+ encode_element(ns, obj, parent)
return
end
-
if @reftarget && !obj.precedents.empty?
add_reftarget(obj.elename.name, obj)
ref = SOAPReference.new(obj)
- ref.elename.name = obj.elename.name
+ ref.elename = ref.elename.dup_name(obj.elename.name)
obj.precedents.clear # Avoid cyclic delay.
obj.encodingstyle = parent.encodingstyle
# SOAPReference is encoded here.
obj = ref
end
-
encodingstyle = obj.encodingstyle
# Children's encodingstyle is derived from its parent.
encodingstyle ||= parent.encodingstyle if parent
obj.encodingstyle = encodingstyle
-
handler = find_handler(encodingstyle || @default_encodingstyle)
unless handler
raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
end
-
if !obj.elename.name
raise FormatEncodeError.new("Element name not defined: #{ obj }.")
end
-
- handler.encode_data(self, ns, qualified, obj, parent) do |child, nextq|
- indent_backup, @indent = @indent, @indent + ' '
- encode_data(ns.clone_ns, nextq, child, obj)
- @indent = indent_backup
- end
- handler.encode_data_end(self, ns, qualified, obj, parent)
+ handler.encode_data(self, ns, obj, parent)
+ handler.encode_data_end(self, ns, obj, parent)
end
def add_reftarget(name, node)
@@ -105,13 +101,19 @@ public
@reftarget.add(name, node)
end
- def encode_element(ns, qualified, obj, parent)
+ def encode_child(ns, child, parent)
+ indent_backup, @indent = @indent, @indent + @indentstr
+ encode_data(ns.clone_ns, child, parent)
+ @indent = indent_backup
+ end
+
+ def encode_element(ns, obj, parent)
attrs = {}
if obj.is_a?(SOAPBody)
@reftarget = obj
- obj.encode(self, ns, attrs) do |child, nextq|
- indent_backup, @indent = @indent, @indent + ' '
- encode_data(ns.clone_ns, nextq, child, obj)
+ obj.encode(self, ns, attrs) do |child|
+ indent_backup, @indent = @indent, @indent + @indentstr
+ encode_data(ns.clone_ns, child, obj)
@indent = indent_backup
end
@reftarget = nil
@@ -124,14 +126,35 @@ public
SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)
end
end
- obj.encode(self, ns, attrs) do |child, nextq|
- indent_backup, @indent = @indent, @indent + ' '
- encode_data(ns.clone_ns, nextq, child, obj)
+ obj.encode(self, ns, attrs) do |child|
+ indent_backup, @indent = @indent, @indent + @indentstr
+ encode_data(ns.clone_ns, child, obj)
@indent = indent_backup
end
end
end
+ def encode_name(ns, data, attrs)
+ if element_local?(data)
+ data.elename.name
+ else
+ if element_qualified?(data)
+ SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
+ else
+ SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
+ end
+ ns.name(data.elename)
+ end
+ end
+
+ def encode_name_end(ns, data)
+ if element_local?(data)
+ data.elename.name
+ else
+ ns.name(data.elename)
+ end
+ end
+
def encode_tag(elename, attrs = nil)
if !attrs or attrs.empty?
@buf << "\n#{ @indent }<#{ elename }>"
@@ -142,7 +165,7 @@ public
@buf << "\n#{ @indent }<#{ elename } " <<
attrs.collect { |key, value|
%Q[#{ key }="#{ value }"]
- }.join("\n#{ @indent } ") <<
+ }.join("\n#{ @indent }#{ @indentstr * 2 }") <<
'>'
end
end
@@ -169,11 +192,41 @@ public
}
EncodeCharRegexp = Regexp.new("[#{EncodeMap.keys.join}]")
def encode_string(str)
- @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
+ if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)
+ str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] }
+ @buf << str.unpack("U*").collect { |c|
+ if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)
+ c.chr
+ else
+ sprintf("&#x%x;", c)
+ end
+ }.join
+ else
+ @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
+ end
+ end
+
+ def element_local?(element)
+ element.elename.namespace.nil?
+ end
+
+ def element_qualified?(element)
+ if element.respond_to?(:qualified)
+ if element.qualified.nil?
+ @elementformdefault
+ else
+ element.qualified
+ end
+ else
+ @elementformdefault
+ end
end
def self.assign_ns(attrs, ns, namespace, tag = nil)
- if namespace and !ns.assigned?(namespace)
+ if namespace.nil?
+ raise FormatEncodeError.new("empty namespace")
+ end
+ unless ns.assigned?(namespace)
tag = ns.assign(namespace, tag)
if tag == ''
attr = 'xmlns'
diff --git a/lib/soap/header/simplehandler.rb b/lib/soap/header/simplehandler.rb
index 4c6b00ab9..7b206f77d 100644
--- a/lib/soap/header/simplehandler.rb
+++ b/lib/soap/header/simplehandler.rb
@@ -19,12 +19,12 @@ class SimpleHandler < SOAP::Header::Handler
super(elename)
end
- # Should return a Hash or nil.
+ # Should return a Hash, String or nil.
def on_simple_outbound
nil
end
- # Given header is a Hash or nil.
+ # Given header is a Hash, String or nil.
def on_simple_inbound(header, mustunderstand)
end
@@ -34,7 +34,7 @@ class SimpleHandler < SOAP::Header::Handler
end
def on_inbound(header, mustunderstand)
- h = header.to_obj
+ h = header.respond_to?(:to_obj) ? header.to_obj : header.data
on_simple_inbound(h, mustunderstand)
end
end
diff --git a/lib/soap/httpconfigloader.rb b/lib/soap/httpconfigloader.rb
index ebc17d8f9..cd7bca8a6 100644
--- a/lib/soap/httpconfigloader.rb
+++ b/lib/soap/httpconfigloader.rb
@@ -60,6 +60,9 @@ module_function
def set_ssl_config(client, ssl_config)
ssl_config.each do |key, value|
cfg = client.ssl_config
+ if cfg.nil?
+ raise NotImplementedError.new("SSL not supported")
+ end
case key
when 'client_cert'
cfg.client_cert = cert_from_file(value)
diff --git a/lib/soap/mapping/factory.rb b/lib/soap/mapping/factory.rb
index 13dffc2dd..978b303b3 100644
--- a/lib/soap/mapping/factory.rb
+++ b/lib/soap/mapping/factory.rb
@@ -87,10 +87,11 @@ class StringFactory_ < Factory
return nil
end
begin
- unless XSD::Charset.is_ces(obj, $KCODE)
- return nil
+ unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES])
+ return nil
end
- encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding)
+ encoded = XSD::Charset.encoding_conv(obj,
+ Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
soap_obj = soap_class.new(encoded)
rescue XSD::ValueSpaceError
return nil
@@ -101,7 +102,8 @@ class StringFactory_ < Factory
def soap2obj(obj_class, node, info, map)
obj = Mapping.create_empty_object(obj_class)
- decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE)
+ decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding,
+ Thread.current[:SOAPExternalCES])
obj.replace(decoded)
mark_unmarshalled_obj(node, obj)
return true, obj
diff --git a/lib/soap/mapping/registry.rb b/lib/soap/mapping/registry.rb
index e733f5c95..823e80666 100644
--- a/lib/soap/mapping/registry.rb
+++ b/lib/soap/mapping/registry.rb
@@ -49,8 +49,7 @@ class SOAPException; include Marshallable
e.set_backtrace(@cause.backtrace)
return e
end
- klass = Mapping.class_from_name(
- Mapping.elename2name(@excn_type_name.to_s))
+ klass = Mapping.class_from_name(Mapping.elename2name(@excn_type_name.to_s))
if klass.nil? or not klass <= ::Exception
return RuntimeError.new(@cause.inspect)
end
@@ -89,6 +88,10 @@ class Object; include Marshallable
@__xmlele.each do |k, v|
return v if k == qname
end
+ # fallback
+ @__xmlele.each do |k, v|
+ return v if k.name == qname.name
+ end
nil
end
diff --git a/lib/soap/mapping/wsdlRegistry.rb b/lib/soap/mapping/wsdlRegistry.rb
deleted file mode 100644
index 64f49f226..000000000
--- a/lib/soap/mapping/wsdlRegistry.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-# SOAP4R - WSDL mapping registry.
-# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
-
-# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
-# redistribute it and/or modify it under the same terms of Ruby's license;
-# either the dual license version in 2003, or any later version.
-
-
-require 'soap/baseData'
-require 'soap/mapping/mapping'
-require 'soap/mapping/typeMap'
-
-
-module SOAP
-module Mapping
-
-
-class WSDLRegistry
- include TraverseSupport
-
- attr_reader :definedtypes
-
- def initialize(definedtypes, config = {})
- @definedtypes = definedtypes
- @config = config
- @excn_handler_obj2soap = nil
- # For mapping AnyType element.
- @rubytype_factory = RubytypeFactory.new(
- :allow_untyped_struct => true,
- :allow_original_mapping => true
- )
- end
-
- def obj2soap(klass, obj, type_qname)
- soap_obj = nil
- if obj.nil?
- soap_obj = SOAPNil.new
- elsif obj.is_a?(XSD::NSDBase)
- soap_obj = soap2soap(obj, type_qname)
- elsif type = @definedtypes[type_qname]
- soap_obj = obj2type(obj, type)
- elsif (type = TypeMap[type_qname])
- soap_obj = base2soap(obj, type)
- elsif type_qname == XSD::AnyTypeName
- soap_obj = @rubytype_factory.obj2soap(nil, obj, nil, nil)
- end
- return soap_obj if soap_obj
- if @excn_handler_obj2soap
- soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
- Mapping._obj2soap(yield_obj, self)
- }
- end
- return soap_obj if soap_obj
- raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.")
- end
-
- def soap2obj(klass, node)
- raise RuntimeError.new("#{ self } is for obj2soap only.")
- end
-
- def excn_handler_obj2soap=(handler)
- @excn_handler_obj2soap = handler
- end
-
-private
-
- def soap2soap(obj, type_qname)
- if obj.is_a?(SOAPBasetype)
- obj
- elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname])
- soap_obj = obj
- mark_marshalled_obj(obj, soap_obj)
- elements2soap(obj, soap_obj, type.content.elements)
- soap_obj
- elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname])
- soap_obj = obj
- contenttype = type.child_type
- mark_marshalled_obj(obj, soap_obj)
- obj.replace do |ele|
- Mapping._obj2soap(ele, self, contenttype)
- end
- soap_obj
- else
- nil
- 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)
- soap_obj = nil
- if type <= XSD::XSDString
- soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
- XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj)
- mark_marshalled_obj(obj, soap_obj)
- else
- soap_obj = type.new(obj)
- end
- soap_obj
- end
-
- def struct2soap(obj, type_qname, type)
- soap_obj = SOAPStruct.new(type_qname)
- mark_marshalled_obj(obj, soap_obj)
- elements2soap(obj, soap_obj, type.content.elements)
- soap_obj
- end
-
- def array2soap(obj, type_qname, type)
- contenttype = type.child_type
- soap_obj = SOAPArray.new(ValueArrayName, 1, contenttype)
- mark_marshalled_obj(obj, soap_obj)
- obj.each do |item|
- soap_obj.add(Mapping._obj2soap(item, self, contenttype))
- end
- soap_obj
- end
-
- def elements2soap(obj, soap_obj, elements)
- elements.each do |element|
- name = element.name.name
- child_obj = obj.instance_eval("@#{ name }")
- soap_obj.add(name, Mapping._obj2soap(child_obj, self, element.type))
- end
- end
-end
-
-
-end
-end
diff --git a/lib/soap/mapping/wsdlencodedregistry.rb b/lib/soap/mapping/wsdlencodedregistry.rb
index 8d495668e..4efb60188 100644
--- a/lib/soap/mapping/wsdlencodedregistry.rb
+++ b/lib/soap/mapping/wsdlencodedregistry.rb
@@ -149,8 +149,9 @@ private
def base2soap(obj, type)
soap_obj = nil
if type <= XSD::XSDString
- soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
- XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj)
+ str = XSD::Charset.encoding_conv(obj.to_s,
+ Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
+ soap_obj = type.new(str)
mark_marshalled_obj(obj, soap_obj)
else
soap_obj = type.new(obj)
@@ -234,7 +235,9 @@ private
elements, as_array = schema_element_definition(obj.class)
vars = {}
node.each do |name, value|
- if class_name = elements[name]
+ item = elements.find { |k, v| k.name == name }
+ if item
+ elename, class_name = item
if klass = Mapping.class_from_name(class_name)
# klass must be a SOAPBasetype or a class
if klass.ancestors.include?(::SOAP::SOAPBasetype)
@@ -246,6 +249,14 @@ private
else
child = Mapping._soap2obj(value, self, klass)
end
+ elsif klass = Mapping.module_from_name(class_name)
+ # simpletype
+ if value.respond_to?(:data)
+ child = value.data
+ else
+ raise MappingError.new(
+ "cannot map to a module value: #{class_name}")
+ end
else
raise MappingError.new("unknown class: #{class_name}")
end
diff --git a/lib/soap/mapping/wsdlliteralregistry.rb b/lib/soap/mapping/wsdlliteralregistry.rb
index 59acf2f65..7bb8e1220 100644
--- a/lib/soap/mapping/wsdlliteralregistry.rb
+++ b/lib/soap/mapping/wsdlliteralregistry.rb
@@ -38,14 +38,14 @@ class WSDLLiteralRegistry < Registry
if ele = @definedelements[qname]
soap_obj = obj2elesoap(obj, ele)
elsif type = @definedtypes[qname]
- soap_obj = obj2typesoap(obj, type)
+ soap_obj = obj2typesoap(obj, type, true)
else
soap_obj = any2soap(obj, qname)
end
return soap_obj if soap_obj
if @excn_handler_obj2soap
soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
- Mapping._obj2soap(yield_obj, self)
+ Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT)
}
return soap_obj if soap_obj
end
@@ -54,9 +54,7 @@ class WSDLLiteralRegistry < Registry
# node should be a SOAPElement
def soap2obj(node, obj_class = nil)
- unless obj_class.nil?
- raise MappingError.new("must not reach here")
- end
+ # obj_class is given when rpc/literal service. but ignored for now.
begin
return any2obj(node)
rescue MappingError
@@ -64,45 +62,50 @@ class WSDLLiteralRegistry < Registry
if @excn_handler_soap2obj
begin
return @excn_handler_soap2obj.call(node) { |yield_node|
- Mapping._soap2obj(yield_node, self)
+ Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT)
}
rescue Exception
end
end
- raise MappingError.new("cannot map #{node.type.name} to Ruby object")
+ if node.respond_to?(:type)
+ raise MappingError.new("cannot map #{node.type.name} to Ruby object")
+ else
+ raise MappingError.new("cannot map #{node.elename.name} to Ruby object")
+ end
end
private
+ MAPPING_OPT = { :no_reference => true }
+
def obj2elesoap(obj, ele)
o = nil
+ qualified = (ele.elementform == 'qualified')
if ele.type
if type = @definedtypes[ele.type]
- o = obj2typesoap(obj, type)
+ o = obj2typesoap(obj, type, qualified)
elsif type = TypeMap[ele.type]
o = base2soap(obj, type)
else
raise MappingError.new("cannot find type #{ele.type}")
end
- o.elename = ele.name
elsif ele.local_complextype
- o = obj2typesoap(obj, ele.local_complextype)
- o.elename = ele.name
+ o = obj2typesoap(obj, ele.local_complextype, qualified)
add_attributes2soap(obj, o)
elsif ele.local_simpletype
- o = obj2typesoap(obj, ele.local_simpletype)
- o.elename = ele.name
+ o = obj2typesoap(obj, ele.local_simpletype, qualified)
else
raise MappingError.new('illegal schema?')
end
+ o.elename = ele.name
o
end
- def obj2typesoap(obj, type)
+ def obj2typesoap(obj, type, qualified)
if type.is_a?(::WSDL::XMLSchema::SimpleType)
simpleobj2soap(obj, type)
else
- complexobj2soap(obj, type)
+ complexobj2soap(obj, type, qualified)
end
end
@@ -113,15 +116,17 @@ private
o
end
- def complexobj2soap(obj, type)
+ def complexobj2soap(obj, type, qualified)
o = SOAPElement.new(type.name)
+ o.qualified = qualified
type.each_element do |child_ele|
child = Mapping.get_attribute(obj, child_ele.name.name)
if child.nil?
if child_ele.nillable
# ToDo: test
# add empty element
- o.add(obj2elesoap(nil))
+ child_soap = obj2elesoap(nil, child_ele)
+ o.add(child_soap)
elsif Integer(child_ele.minoccurs) == 0
# nothing to do
else
@@ -129,10 +134,12 @@ private
end
elsif child_ele.map_as_array?
child.each do |item|
- o.add(obj2elesoap(item, child_ele))
+ child_soap = obj2elesoap(item, child_ele)
+ o.add(child_soap)
end
else
- o.add(obj2elesoap(child, child_ele))
+ child_soap = obj2elesoap(child, child_ele)
+ o.add(child_soap)
end
end
o
@@ -153,7 +160,7 @@ private
# expected to be a basetype or an anyType.
# SOAPStruct, etc. is used instead of SOAPElement.
begin
- ele = Mapping.obj2soap(obj)
+ ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT)
ele.elename = qname
ele
rescue MappingError
@@ -170,6 +177,9 @@ private
def stubobj2soap(obj, qname)
ele = SOAPElement.new(qname)
+ ele.qualified =
+ (obj.class.class_variables.include?('@@schema_qualified') and
+ obj.class.class_eval('@@schema_qualified'))
add_elements2soap(obj, ele)
add_attributes2soap(obj, ele)
ele
@@ -196,15 +206,17 @@ private
elements, as_array = schema_element_definition(obj.class)
if elements
elements.each do |elename, type|
- child = Mapping.get_attribute(obj, elename)
- unless child.nil?
- name = XSD::QName.new(nil, elename)
- if as_array.include?(type)
+ if child = Mapping.get_attribute(obj, elename.name)
+ if as_array.include?(elename.name)
child.each do |item|
- ele.add(obj2soap(item, name))
+ ele.add(obj2soap(item, elename))
end
else
- ele.add(obj2soap(child, name))
+ ele.add(obj2soap(child, elename))
+ end
+ elsif obj.is_a?(::Array) and as_array.include?(elename.name)
+ obj.each do |item|
+ ele.add(obj2soap(item, elename))
end
end
end
@@ -225,8 +237,9 @@ private
def base2soap(obj, type)
soap_obj = nil
if type <= XSD::XSDString
- soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ?
- XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj)
+ str = XSD::Charset.encoding_conv(obj.to_s,
+ Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
+ soap_obj = type.new(str)
else
soap_obj = type.new(obj)
end
@@ -253,7 +266,7 @@ private
# SOAPArray for literal?
soapele2plainobj(node)
else
- obj = Mapping._soap2obj(node, Mapping::DefaultRegistry, obj_class)
+ obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT)
add_attributes2plainobj(node, obj)
obj
end
@@ -277,8 +290,11 @@ private
elements, as_array = schema_element_definition(obj.class)
vars = {}
node.each do |name, value|
- if class_name = elements[name]
+ item = elements.find { |k, v| k.name == name }
+ if item
+ elename, class_name = item
if klass = Mapping.class_from_name(class_name)
+ # klass must be a SOAPBasetype or a class
if klass.ancestors.include?(::SOAP::SOAPBasetype)
if value.respond_to?(:data)
child = klass.new(value.data).data
@@ -288,13 +304,21 @@ private
else
child = any2obj(value, klass)
end
+ elsif klass = Mapping.module_from_name(class_name)
+ # simpletype
+ if value.respond_to?(:data)
+ child = value.data
+ else
+ raise MappingError.new(
+ "cannot map to a module value: #{class_name}")
+ end
else
- raise MappingError.new("unknown class: #{class_name}")
+ raise MappingError.new("unknown class/module: #{class_name}")
end
else # untyped element is treated as anyType.
child = any2obj(value)
end
- if as_array.include?(class_name)
+ if as_array.include?(elename.name)
(vars[name] ||= []) << child
else
vars[name] = child
@@ -323,7 +347,7 @@ private
def add_elements2plainobj(node, obj)
node.each do |name, value|
- obj.__add_xmlele_value(XSD::QName.new(nil, name), any2obj(value))
+ obj.__add_xmlele_value(value.elename, any2obj(value))
end
end
diff --git a/lib/soap/mimemessage.rb b/lib/soap/mimemessage.rb
index 1197cebc8..acb4322e1 100644
--- a/lib/soap/mimemessage.rb
+++ b/lib/soap/mimemessage.rb
@@ -112,6 +112,7 @@ class MIMEMessage
@headers = Headers.new
@headers.add("Content-Transfer-Encoding", "8bit")
@body = nil
+ @contentid = nil
end
def self.parse(str)
@@ -147,6 +148,7 @@ class MIMEMessage
def initialize
@parts = []
@headers = Headers.new
+ @root = nil
end
def self.parse(head, str)
@@ -197,7 +199,7 @@ class MIMEMessage
def add_part(content)
part = Part.new
part.headers.add("Content-Type",
- "text/xml; charset=" + XSD::Charset.encoding_label)
+ "text/xml; charset=" + XSD::Charset.xml_encoding_label)
part.headers.add("Content-ID", Attachment.contentid(part))
part.body = content
@parts.unshift(part)
diff --git a/lib/soap/parser.rb b/lib/soap/parser.rb
index 14704a6d9..412fd4855 100644
--- a/lib/soap/parser.rb
+++ b/lib/soap/parser.rb
@@ -60,6 +60,7 @@ private
public
+ attr_accessor :envelopenamespace
attr_accessor :default_encodingstyle
attr_accessor :decode_typemap
attr_accessor :allow_unqualified_element
@@ -70,6 +71,7 @@ public
@parsestack = nil
@lastnode = nil
@handlers = {}
+ @envelopenamespace = opt[:envelopenamespace] || EnvelopeNamespace
@default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
@decode_typemap = opt[:decode_typemap] || nil
@allow_unqualified_element = opt[:allow_unqualified_element] || false
@@ -134,10 +136,7 @@ public
lastframe = @parsestack.last
if lastframe
# Need not to be cloned because character does not have attr.
- ns = lastframe.ns
- parent = lastframe.node
- encodingstyle = lastframe.encodingstyle
- decode_text(ns, text, encodingstyle)
+ decode_text(lastframe.ns, text, lastframe.encodingstyle)
else
# Ignore Text outside of SOAP Envelope.
p text if $DEBUG
@@ -157,7 +156,7 @@ private
def find_encodingstyle(ns, attrs)
attrs.each do |key, value|
- if (ns.compare(EnvelopeNamespace, AttrEncodingStyle, key))
+ if (ns.compare(@envelopenamespace, AttrEncodingStyle, key))
return value
end
end
@@ -168,7 +167,7 @@ private
ele = ns.parse(name)
# Envelope based parsing.
- if ((ele.namespace == EnvelopeNamespace) ||
+ if ((ele.namespace == @envelopenamespace) ||
(@allow_unqualified_element && ele.namespace.nil?))
o = decode_soap_envelope(ns, ele, attrs, parent)
return o if o
diff --git a/lib/soap/rpc/driver.rb b/lib/soap/rpc/driver.rb
index 096a54f01..0fb4e8248 100644
--- a/lib/soap/rpc/driver.rb
+++ b/lib/soap/rpc/driver.rb
@@ -205,7 +205,7 @@ private
opt.add_hook("protocol.wiredump_file_base") do |key, value|
@wiredump_file_base = value
end
- opt["protocol.http.charset"] ||= XSD::Charset.encoding_label
+ opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label
opt["protocol.http.proxy"] ||= Env::HTTP_PROXY
opt["protocol.http.no_proxy"] ||= Env::NO_PROXY
opt
diff --git a/lib/soap/rpc/element.rb b/lib/soap/rpc/element.rb
index e6cae2f7e..c224b03d0 100644
--- a/lib/soap/rpc/element.rb
+++ b/lib/soap/rpc/element.rb
@@ -20,21 +20,25 @@ class SOAPBody < SOAPStruct
end
def response
+ root = root_node
if !@is_fault
- if void?
+ if root.nil?
nil
+ elsif root.is_a?(SOAPBasetype)
+ root
else
# Initial element is [retval].
- root_node[0]
+ root[0]
end
else
- root_node
+ root
end
end
def outparams
- if !@is_fault and !void?
- op = root_node[1..-1]
+ root = root_node
+ if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)
+ op = root[1..-1]
op = nil if op && op.empty?
op
else
@@ -42,10 +46,6 @@ class SOAPBody < SOAPStruct
end
end
- def void?
- root_node.nil?
- end
-
def fault
if @is_fault
self['fault']
diff --git a/lib/soap/rpc/proxy.rb b/lib/soap/rpc/proxy.rb
index b9d80541a..7dfda6200 100644
--- a/lib/soap/rpc/proxy.rb
+++ b/lib/soap/rpc/proxy.rb
@@ -92,6 +92,14 @@ public
opt[:response_style] ||= :document
opt[:request_use] ||= :literal
opt[:response_use] ||= :literal
+ # default values of these values are unqualified in XML Schema.
+ # set true for backward compatibility.
+ unless opt.key?(:elementformdefault)
+ opt[:elementformdefault] = true
+ end
+ unless opt.key?(:attributeformdefault)
+ opt[:attributeformdefault] = true
+ end
@operation[name] = Operation.new(soapaction, param_def, opt)
end
@@ -101,7 +109,7 @@ public
alias add_document_method add_document_operation
def invoke(req_header, req_body, opt = nil)
- opt ||= create_options
+ opt ||= create_encoding_opt
route(req_header, req_body, opt, opt)
end
@@ -109,15 +117,27 @@ public
unless op_info = @operation[name]
raise MethodDefinitionError, "method: #{name} not defined"
end
+ mapping_opt = create_mapping_opt
req_header = create_request_header
req_body = SOAPBody.new(
- op_info.request_body(params, @mapping_registry, @literal_mapping_registry)
+ op_info.request_body(params, @mapping_registry,
+ @literal_mapping_registry, mapping_opt)
)
- reqopt = create_options({
+ reqopt = create_encoding_opt(
:soapaction => op_info.soapaction || @soapaction,
- :default_encodingstyle => op_info.request_default_encodingstyle})
- resopt = create_options({
- :default_encodingstyle => op_info.response_default_encodingstyle})
+ :envelopenamespace => @options["soap.envelope.requestnamespace"],
+ :default_encodingstyle =>
+ @default_encodingstyle || op_info.request_default_encodingstyle,
+ :elementformdefault => op_info.elementformdefault,
+ :attributeformdefault => op_info.attributeformdefault
+ )
+ resopt = create_encoding_opt(
+ :envelopenamespace => @options["soap.envelope.responsenamespace"],
+ :default_encodingstyle =>
+ @default_encodingstyle || op_info.response_default_encodingstyle,
+ :elementformdefault => op_info.elementformdefault,
+ :attributeformdefault => op_info.attributeformdefault
+ )
env = route(req_header, req_body, reqopt, resopt)
raise EmptyResponseError unless env
receive_headers(env.header)
@@ -126,11 +146,15 @@ public
rescue ::SOAP::FaultError => e
op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
end
- op_info.response_obj(env.body, @mapping_registry, @literal_mapping_registry)
+ op_info.response_obj(env.body, @mapping_registry,
+ @literal_mapping_registry, mapping_opt)
end
def route(req_header, req_body, reqopt, resopt)
- req_env = SOAPEnvelope.new(req_header, req_body)
+ req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body)
+ unless reqopt[:envelopenamespace].nil?
+ set_envelopenamespace(req_env, reqopt[:envelopenamespace])
+ end
reqopt[:external_content] = nil
conn_data = marshal(req_env, reqopt)
if ext = reqopt[:external_content]
@@ -159,6 +183,16 @@ public
private
+ def set_envelopenamespace(env, namespace)
+ env.elename = XSD::QName.new(namespace, env.elename.name)
+ if env.header
+ env.header.elename = XSD::QName.new(namespace, env.header.elename.name)
+ end
+ if env.body
+ env.body.elename = XSD::QName.new(namespace, env.body.elename.name)
+ end
+ end
+
def create_request_header
headers = @headerhandler.on_outbound
if headers.empty?
@@ -201,6 +235,10 @@ private
::SOAP::StreamHandler.parse_media_type(contenttype)
env = Processor.unmarshal(conn_data.receive_string, opt)
end
+ unless env.is_a?(::SOAP::SOAPEnvelope)
+ raise ResponseFormatError.new(
+ "response is not a SOAP envelope: #{conn_data.receive_string}")
+ end
env
end
@@ -212,11 +250,22 @@ private
header
end
- def create_options(hash = nil)
+ def create_encoding_opt(hash = nil)
opt = {}
opt[:default_encodingstyle] = @default_encodingstyle
opt[:allow_unqualified_element] = @allow_unqualified_element
opt[:generate_explicit_type] = @generate_explicit_type
+ opt[:no_indent] = @options["soap.envelope.no_indent"]
+ opt[:use_numeric_character_reference] =
+ @options["soap.envelope.use_numeric_character_reference"]
+ opt.update(hash) if hash
+ opt
+ end
+
+ def create_mapping_opt(hash = nil)
+ opt = {
+ :external_ces => @options["soap.mapping.external_ces"]
+ }
opt.update(hash) if hash
opt
end
@@ -227,6 +276,8 @@ private
attr_reader :response_style
attr_reader :request_use
attr_reader :response_use
+ attr_reader :elementformdefault
+ attr_reader :attributeformdefault
def initialize(soapaction, param_def, opt)
@soapaction = soapaction
@@ -234,6 +285,9 @@ private
@response_style = opt[:response_style]
@request_use = opt[:request_use]
@response_use = opt[:response_use]
+ # set nil(unqualified) by default
+ @elementformdefault = opt[:elementformdefault]
+ @attributeformdefault = opt[:attributeformdefault]
check_style(@request_style)
check_style(@response_style)
check_use(@request_use)
@@ -247,17 +301,22 @@ private
RPC::SOAPMethodRequest.new(@rpc_request_qname, param_def, @soapaction)
else
@doc_request_qnames = []
+ @doc_request_qualified = []
@doc_response_qnames = []
- param_def.each do |inout, paramname, typeinfo|
+ @doc_response_qualified = []
+ param_def.each do |inout, paramname, typeinfo, eleinfo|
klass_not_used, nsdef, namedef = typeinfo
+ qualified = eleinfo
if namedef.nil?
raise MethodDefinitionError.new("qname must be given")
end
case inout
when SOAPMethod::IN
@doc_request_qnames << XSD::QName.new(nsdef, namedef)
+ @doc_request_qualified << qualified
when SOAPMethod::OUT
@doc_response_qnames << XSD::QName.new(nsdef, namedef)
+ @doc_response_qualified << qualified
else
raise MethodDefinitionError.new(
"illegal inout definition for document style: #{inout}")
@@ -274,19 +333,19 @@ private
(@response_use == :encoded) ? EncodingNamespace : LiteralNamespace
end
- def request_body(values, mapping_registry, literal_mapping_registry)
+ def request_body(values, mapping_registry, literal_mapping_registry, opt)
if @request_style == :rpc
- request_rpc(values, mapping_registry, literal_mapping_registry)
+ request_rpc(values, mapping_registry, literal_mapping_registry, opt)
else
- request_doc(values, mapping_registry, literal_mapping_registry)
+ request_doc(values, mapping_registry, literal_mapping_registry, opt)
end
end
- def response_obj(body, mapping_registry, literal_mapping_registry)
+ def response_obj(body, mapping_registry, literal_mapping_registry, opt)
if @response_style == :rpc
- response_rpc(body, mapping_registry, literal_mapping_registry)
+ response_rpc(body, mapping_registry, literal_mapping_registry, opt)
else
- response_doc(body, mapping_registry, literal_mapping_registry)
+ response_doc(body, mapping_registry, literal_mapping_registry, opt)
end
end
@@ -312,86 +371,89 @@ private
end
end
- def request_rpc(values, mapping_registry, literal_mapping_registry)
+ def request_rpc(values, mapping_registry, literal_mapping_registry, opt)
if @request_use == :encoded
- request_rpc_enc(values, mapping_registry)
+ request_rpc_enc(values, mapping_registry, opt)
else
- request_rpc_lit(values, literal_mapping_registry)
+ request_rpc_lit(values, literal_mapping_registry, opt)
end
end
- def request_doc(values, mapping_registry, literal_mapping_registry)
+ def request_doc(values, mapping_registry, literal_mapping_registry, opt)
if @request_use == :encoded
- request_doc_enc(values, mapping_registry)
+ request_doc_enc(values, mapping_registry, opt)
else
- request_doc_lit(values, literal_mapping_registry)
+ request_doc_lit(values, literal_mapping_registry, opt)
end
end
- def request_rpc_enc(values, mapping_registry)
+ def request_rpc_enc(values, mapping_registry, opt)
method = @rpc_method_factory.dup
names = method.input_params
obj = create_request_obj(names, values)
- soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname)
+ soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname, opt)
method.set_param(soap)
method
end
- def request_rpc_lit(values, mapping_registry)
+ def request_rpc_lit(values, mapping_registry, opt)
method = @rpc_method_factory.dup
params = {}
idx = 0
method.input_params.each do |name|
params[name] = Mapping.obj2soap(values[idx], mapping_registry,
- XSD::QName.new(nil, name))
+ XSD::QName.new(nil, name), opt)
idx += 1
end
method.set_param(params)
method
end
- def request_doc_enc(values, mapping_registry)
+ def request_doc_enc(values, mapping_registry, opt)
(0...values.size).collect { |idx|
- ele = Mapping.obj2soap(values[idx], mapping_registry)
+ ele = Mapping.obj2soap(values[idx], mapping_registry, nil, opt)
ele.elename = @doc_request_qnames[idx]
ele
}
end
- def request_doc_lit(values, mapping_registry)
+ def request_doc_lit(values, mapping_registry, opt)
(0...values.size).collect { |idx|
ele = Mapping.obj2soap(values[idx], mapping_registry,
- @doc_request_qnames[idx])
+ @doc_request_qnames[idx], opt)
ele.encodingstyle = LiteralNamespace
+ if ele.respond_to?(:qualified)
+ ele.qualified = @doc_request_qualified[idx]
+ end
ele
}
end
- def response_rpc(body, mapping_registry, literal_mapping_registry)
+ def response_rpc(body, mapping_registry, literal_mapping_registry, opt)
if @response_use == :encoded
- response_rpc_enc(body, mapping_registry)
+ response_rpc_enc(body, mapping_registry, opt)
else
- response_rpc_lit(body, literal_mapping_registry)
+ response_rpc_lit(body, literal_mapping_registry, opt)
end
end
- def response_doc(body, mapping_registry, literal_mapping_registry)
+ def response_doc(body, mapping_registry, literal_mapping_registry, opt)
if @response_use == :encoded
- return *response_doc_enc(body, mapping_registry)
+ return *response_doc_enc(body, mapping_registry, opt)
else
- return *response_doc_lit(body, literal_mapping_registry)
+ return *response_doc_lit(body, literal_mapping_registry, opt)
end
end
- def response_rpc_enc(body, mapping_registry)
+ def response_rpc_enc(body, mapping_registry, opt)
ret = nil
if body.response
ret = Mapping.soap2obj(body.response, mapping_registry,
- @rpc_method_factory.retval_class_name)
+ @rpc_method_factory.retval_class_name, opt)
end
if body.outparams
outparams = body.outparams.collect { |outparam|
- Mapping.soap2obj(outparam, mapping_regisry)
+ Mapping.soap2obj(outparam, mapping_registry, nil, opt)
}
[ret].concat(outparams)
else
@@ -399,20 +461,20 @@ private
end
end
- def response_rpc_lit(body, mapping_registry)
+ def response_rpc_lit(body, mapping_registry, opt)
body.root_node.collect { |key, value|
Mapping.soap2obj(value, mapping_registry,
- @rpc_method_factory.retval_class_name)
+ @rpc_method_factory.retval_class_name, opt)
}
end
- def response_doc_enc(body, mapping_registry)
+ def response_doc_enc(body, mapping_registry, opt)
body.collect { |key, value|
- Mapping.soap2obj(value, mapping_registry)
+ Mapping.soap2obj(value, mapping_registry, nil, opt)
}
end
- def response_doc_lit(body, mapping_registry)
+ def response_doc_lit(body, mapping_registry, opt)
body.collect { |key, value|
Mapping.soap2obj(value, mapping_registry)
}
@@ -420,8 +482,10 @@ private
def create_request_obj(names, params)
o = Object.new
- for idx in 0 ... params.length
+ idx = 0
+ while idx < params.length
o.instance_variable_set('@' + names[idx], params[idx])
+ idx += 1
end
o
end
diff --git a/lib/soap/rpc/router.rb b/lib/soap/rpc/router.rb
index 1d11bc17d..71c6eb625 100644
--- a/lib/soap/rpc/router.rb
+++ b/lib/soap/rpc/router.rb
@@ -28,6 +28,7 @@ class Router
attr_accessor :mapping_registry
attr_accessor :literal_mapping_registry
attr_accessor :generate_explicit_type
+ attr_accessor :external_ces
def initialize(actor)
@actor = actor
@@ -35,6 +36,7 @@ class Router
@headerhandler = Header::HandlerSet.new
@literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new
@generate_explicit_type = true
+ @external_ces = nil
@operation_by_soapaction = {}
@operation_by_qname = {}
@headerhandlerfactory = []
@@ -163,7 +165,8 @@ class Router
soap_response = default_encodingstyle = nil
begin
soap_response =
- op.call(env.body, @mapping_registry, @literal_mapping_registry)
+ op.call(env.body, @mapping_registry, @literal_mapping_registry,
+ create_mapping_opt)
default_encodingstyle = op.response_default_encodingstyle
rescue Exception
soap_response = fault($!)
@@ -240,7 +243,8 @@ private
return op
end
if soapaction
- raise RPCRoutingError.new("operation: #{soapaction} not supported")
+ raise RPCRoutingError.new(
+ "operation: #{soapaction} #{qname} not supported")
else
raise RPCRoutingError.new("operation: #{qname} not supported")
end
@@ -323,6 +327,10 @@ private
Mapping.obj2soap(detail, @mapping_registry))
end
+ def create_mapping_opt
+ { :external_ces => @external_ces }
+ end
+
class Operation
attr_reader :name
attr_reader :soapaction
@@ -349,14 +357,19 @@ private
@rpc_response_qname = opt[:response_qname]
else
@doc_request_qnames = []
+ @doc_request_qualified = []
@doc_response_qnames = []
- param_def.each do |inout, paramname, typeinfo|
+ @doc_response_qualified = []
+ param_def.each do |inout, paramname, typeinfo, eleinfo|
klass, nsdef, namedef = typeinfo
+ qualified = eleinfo
case inout
when SOAPMethod::IN
@doc_request_qnames << XSD::QName.new(nsdef, namedef)
+ @doc_request_qualified << qualified
when SOAPMethod::OUT
@doc_response_qnames << XSD::QName.new(nsdef, namedef)
+ @doc_response_qualified << qualified
else
raise ArgumentError.new(
"illegal inout definition for document style: #{inout}")
@@ -373,18 +386,20 @@ private
(@response_use == :encoded) ? EncodingNamespace : LiteralNamespace
end
- def call(body, mapping_registry, literal_mapping_registry)
+ def call(body, mapping_registry, literal_mapping_registry, opt)
if @request_style == :rpc
- values = request_rpc(body, mapping_registry, literal_mapping_registry)
+ values = request_rpc(body, mapping_registry, literal_mapping_registry,
+ opt)
else
- values = request_document(body, mapping_registry, literal_mapping_registry)
+ values = request_document(body, mapping_registry,
+ literal_mapping_registry, opt)
end
result = receiver.method(@name.intern).call(*values)
return result if result.is_a?(SOAPFault)
if @response_style == :rpc
- response_rpc(result, mapping_registry, literal_mapping_registry)
+ response_rpc(result, mapping_registry, literal_mapping_registry, opt)
else
- response_doc(result, mapping_registry, literal_mapping_registry)
+ response_doc(result, mapping_registry, literal_mapping_registry, opt)
end
end
@@ -394,61 +409,61 @@ private
raise NotImplementedError.new('must be defined in derived class')
end
- def request_rpc(body, mapping_registry, literal_mapping_registry)
+ def request_rpc(body, mapping_registry, literal_mapping_registry, opt)
request = body.request
unless request.is_a?(SOAPStruct)
raise RPCRoutingError.new("not an RPC style")
end
if @request_use == :encoded
- request_rpc_enc(request, mapping_registry)
+ request_rpc_enc(request, mapping_registry, opt)
else
- request_rpc_lit(request, literal_mapping_registry)
+ request_rpc_lit(request, literal_mapping_registry, opt)
end
end
- def request_document(body, mapping_registry, literal_mapping_registry)
+ def request_document(body, mapping_registry, literal_mapping_registry, opt)
# ToDo: compare names with @doc_request_qnames
if @request_use == :encoded
- request_doc_enc(body, mapping_registry)
+ request_doc_enc(body, mapping_registry, opt)
else
- request_doc_lit(body, literal_mapping_registry)
+ request_doc_lit(body, literal_mapping_registry, opt)
end
end
- def request_rpc_enc(request, mapping_registry)
- param = Mapping.soap2obj(request, mapping_registry)
+ def request_rpc_enc(request, mapping_registry, opt)
+ param = Mapping.soap2obj(request, mapping_registry, nil, opt)
request.collect { |key, value|
param[key]
}
end
- def request_rpc_lit(request, mapping_registry)
+ def request_rpc_lit(request, mapping_registry, opt)
request.collect { |key, value|
- Mapping.soap2obj(value, mapping_registry)
+ Mapping.soap2obj(value, mapping_registry, nil, opt)
}
end
- def request_doc_enc(body, mapping_registry)
+ def request_doc_enc(body, mapping_registry, opt)
body.collect { |key, value|
- Mapping.soap2obj(value, mapping_registry)
+ Mapping.soap2obj(value, mapping_registry, nil, opt)
}
end
- def request_doc_lit(body, mapping_registry)
+ def request_doc_lit(body, mapping_registry, opt)
body.collect { |key, value|
- Mapping.soap2obj(value, mapping_registry)
+ Mapping.soap2obj(value, mapping_registry, nil, opt)
}
end
- def response_rpc(result, mapping_registry, literal_mapping_registry)
+ def response_rpc(result, mapping_registry, literal_mapping_registry, opt)
if @response_use == :encoded
- response_rpc_enc(result, mapping_registry)
+ response_rpc_enc(result, mapping_registry, opt)
else
- response_rpc_lit(result, literal_mapping_registry)
+ response_rpc_lit(result, literal_mapping_registry, opt)
end
end
- def response_doc(result, mapping_registry, literal_mapping_registry)
+ def response_doc(result, mapping_registry, literal_mapping_registry, opt)
if @doc_response_qnames.size == 1 and !result.is_a?(Array)
result = [result]
end
@@ -457,13 +472,13 @@ private
"but #{result.size} given"
end
if @response_use == :encoded
- response_doc_enc(result, mapping_registry)
+ response_doc_enc(result, mapping_registry, opt)
else
- response_doc_lit(result, literal_mapping_registry)
+ response_doc_lit(result, literal_mapping_registry, opt)
end
end
- def response_rpc_enc(result, mapping_registry)
+ def response_rpc_enc(result, mapping_registry, opt)
soap_response =
@rpc_method_factory.create_method_response(@rpc_response_qname)
if soap_response.have_outparam?
@@ -473,18 +488,21 @@ private
outparams = {}
i = 1
soap_response.output_params.each do |outparam|
- outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry)
+ outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,
+ nil, opt)
i += 1
end
soap_response.set_outparam(outparams)
- soap_response.retval = Mapping.obj2soap(result[0], mapping_registry)
+ soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,
+ nil, opt)
else
- soap_response.retval = Mapping.obj2soap(result, mapping_registry)
+ soap_response.retval = Mapping.obj2soap(result, mapping_registry, nil,
+ opt)
end
soap_response
end
- def response_rpc_lit(result, mapping_registry)
+ def response_rpc_lit(result, mapping_registry, opt)
soap_response =
@rpc_method_factory.create_method_response(@rpc_response_qname)
if soap_response.have_outparam?
@@ -495,30 +513,36 @@ private
i = 1
soap_response.output_params.each do |outparam|
outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,
- XSD::QName.new(nil, outparam))
+ XSD::QName.new(nil, outparam), opt)
i += 1
end
soap_response.set_outparam(outparams)
soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,
- XSD::QName.new(nil, soap_response.elename))
+ XSD::QName.new(nil, soap_response.elename), opt)
else
soap_response.retval = Mapping.obj2soap(result, mapping_registry,
- XSD::QName.new(nil, soap_response.elename))
+ XSD::QName.new(nil, soap_response.elename), opt)
end
soap_response
end
- def response_doc_enc(result, mapping_registry)
+ def response_doc_enc(result, mapping_registry, opt)
(0...result.size).collect { |idx|
- ele = Mapping.obj2soap(result[idx], mapping_registry)
+ ele = Mapping.obj2soap(result[idx], mapping_registry, nil, opt)
ele.elename = @doc_response_qnames[idx]
ele
}
end
- def response_doc_lit(result, mapping_registry)
+ def response_doc_lit(result, mapping_registry, opt)
(0...result.size).collect { |idx|
- mapping_registry.obj2soap(result[idx], @doc_response_qnames[idx])
+ ele = Mapping.obj2soap(result[idx], mapping_registry,
+ @doc_response_qnames[idx])
+ ele.encodingstyle = LiteralNamespace
+ if ele.respond_to?(:qualified)
+ ele.qualified = @doc_response_qualified[idx]
+ end
+ ele
}
end
diff --git a/lib/soap/rpc/soaplet.rb b/lib/soap/rpc/soaplet.rb
index 4d2538f0b..7cccdd3e3 100644
--- a/lib/soap/rpc/soaplet.rb
+++ b/lib/soap/rpc/soaplet.rb
@@ -84,6 +84,7 @@ public
begin
conn_data = ::SOAP::StreamHandler::ConnectionData.new
setup_req(conn_data, req)
+ @router.external_ces = @options[:external_ces]
conn_data = @router.route(conn_data)
setup_res(conn_data, req, res)
rescue Exception => e
diff --git a/lib/soap/soap.rb b/lib/soap/soap.rb
index 0072a8dcf..12e09eccf 100644
--- a/lib/soap/soap.rb
+++ b/lib/soap/soap.rb
@@ -13,7 +13,7 @@ require 'xsd/charset'
module SOAP
-VERSION = Version = '1.5.4'
+VERSION = Version = '1.5.5'
PropertyName = 'soap/property'
EnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/'
@@ -40,21 +40,21 @@ AttrOffset = 'offset'
AttrPosition = 'position'
ValueArray = 'Array'
-EleEnvelopeName = XSD::QName.new(EnvelopeNamespace, EleEnvelope)
-EleHeaderName = XSD::QName.new(EnvelopeNamespace, EleHeader)
-EleBodyName = XSD::QName.new(EnvelopeNamespace, EleBody)
-EleFaultName = XSD::QName.new(EnvelopeNamespace, EleFault)
-EleFaultStringName = XSD::QName.new(nil, EleFaultString)
-EleFaultActorName = XSD::QName.new(nil, EleFaultActor)
-EleFaultCodeName = XSD::QName.new(nil, EleFaultCode)
-EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail)
-AttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand)
-AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle)
-AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot)
-AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType)
-AttrOffsetName = XSD::QName.new(EncodingNamespace, AttrOffset)
-AttrPositionName = XSD::QName.new(EncodingNamespace, AttrPosition)
-ValueArrayName = XSD::QName.new(EncodingNamespace, ValueArray)
+EleEnvelopeName = XSD::QName.new(EnvelopeNamespace, EleEnvelope).freeze
+EleHeaderName = XSD::QName.new(EnvelopeNamespace, EleHeader).freeze
+EleBodyName = XSD::QName.new(EnvelopeNamespace, EleBody).freeze
+EleFaultName = XSD::QName.new(EnvelopeNamespace, EleFault).freeze
+EleFaultStringName = XSD::QName.new(nil, EleFaultString).freeze
+EleFaultActorName = XSD::QName.new(nil, EleFaultActor).freeze
+EleFaultCodeName = XSD::QName.new(nil, EleFaultCode).freeze
+EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail).freeze
+AttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand).freeze
+AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle).freeze
+AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot).freeze
+AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType).freeze
+AttrOffsetName = XSD::QName.new(EncodingNamespace, AttrOffset).freeze
+AttrPositionName = XSD::QName.new(EncodingNamespace, AttrPosition).freeze
+ValueArrayName = XSD::QName.new(EncodingNamespace, ValueArray).freeze
Base64Literal = 'base64'
@@ -76,6 +76,7 @@ class ArrayStoreError < Error; end
class RPCRoutingError < Error; end
class EmptyResponseError < Error; end
+class ResponseFormatError < Error; end
class UnhandledMustUnderstandHeaderError < Error; end
diff --git a/lib/soap/streamHandler.rb b/lib/soap/streamHandler.rb
index 3890ac263..672396ecc 100644
--- a/lib/soap/streamHandler.rb
+++ b/lib/soap/streamHandler.rb
@@ -20,18 +20,6 @@ module SOAP
class StreamHandler
- Client = begin
- require 'http-access2'
- if HTTPAccess2::VERSION < "2.0"
- raise LoadError.new("http-access/2.0 or later is required.")
- end
- HTTPAccess2::Client
- rescue LoadError
- warn("Loading http-access2 failed. Net/http is used.") if $DEBUG
- require 'soap/netHttpClient'
- SOAP::NetHttpClient
- end
-
RUBY_VERSION_STRING = "ruby #{ RUBY_VERSION } (#{ RUBY_RELEASE_DATE }) [#{ RUBY_PLATFORM }]"
class ConnectionData
@@ -70,12 +58,27 @@ end
class HTTPStreamHandler < StreamHandler
include SOAP
+ begin
+ require 'http-access2'
+ if HTTPAccess2::VERSION < "2.0"
+ raise LoadError.new("http-access/2.0 or later is required.")
+ end
+ Client = HTTPAccess2::Client
+ RETRYABLE = true
+ rescue LoadError
+ warn("Loading http-access2 failed. Net/http is used.") if $DEBUG
+ require 'soap/netHttpClient'
+ Client = SOAP::NetHttpClient
+ RETRYABLE = false
+ end
+
+
public
attr_reader :client
attr_accessor :wiredump_file_base
- NofRetry = 10 # [times]
+ MAX_RETRY_COUNT = 10 # [times]
def initialize(options)
super()
@@ -119,7 +122,7 @@ private
def set_options
HTTPConfigLoader.set_options(@client, @options)
- @charset = @options["charset"] || XSD::Charset.charset_label($KCODE)
+ @charset = @options["charset"] || XSD::Charset.xml_encoding_label
@options.add_hook("charset") do |key, value|
@charset = value
end
@@ -140,6 +143,7 @@ private
end
def set_cookie_store_file(value)
+ value = nil if value and value.empty?
@cookie_store = value
@client.set_cookie_store(@cookie_store) if @cookie_store
end
@@ -161,7 +165,20 @@ private
send_string = conn_data.send_string
@wiredump_dev << "Wire dump:\n\n" if @wiredump_dev
begin
- res = @client.post(endpoint_url, send_string, extra)
+ retry_count = 0
+ while true
+ res = @client.post(endpoint_url, send_string, extra)
+ if RETRYABLE and HTTP::Status.redirect?(res.status)
+ retry_count += 1
+ if retry_count >= MAX_RETRY_COUNT
+ raise HTTPStreamError.new("redirect count exceeded")
+ end
+ endpoint_url = res.header["location"][0]
+ puts "redirected to #{endpoint_url}" if $DEBUG
+ else
+ break
+ end
+ end
rescue
@client.reset(endpoint_url)
raise
diff --git a/lib/wsdl/operation.rb b/lib/wsdl/operation.rb
index 727bb9a56..fb7f4a80f 100644
--- a/lib/wsdl/operation.rb
+++ b/lib/wsdl/operation.rb
@@ -120,9 +120,8 @@ private
if result.length == 0
return parts.dup
end
- if parts.length != result.length
- raise RuntimeError.new("Incomplete prarmeterOrder list.")
- end
+ # result length can be shorter than parts's.
+ # return part must not be a part of the parameterOrder.
result
end
end
diff --git a/lib/wsdl/param.rb b/lib/wsdl/param.rb
index 08ba07ee9..b6836b7de 100644
--- a/lib/wsdl/param.rb
+++ b/lib/wsdl/param.rb
@@ -36,6 +36,14 @@ class Param < Info
root.message(@message) or raise RuntimeError.new("#{@message} not found")
end
+ def soapbody_use
+ if @soapbody
+ @soapbody.use || :literal
+ else
+ raise RuntimeError.new("soap:body not found")
+ end
+ end
+
def parse_element(element)
case element
when SOAPBodyName
diff --git a/lib/wsdl/soap/body.rb b/lib/wsdl/soap/body.rb
index 47e99f381..824f8121a 100644
--- a/lib/wsdl/soap/body.rb
+++ b/lib/wsdl/soap/body.rb
@@ -36,7 +36,11 @@ class Body < Info
when PartsAttrName
@parts = value.source
when UseAttrName
- @use = value.source
+ if ['literal', 'encoded'].include?(value.source)
+ @use = value.source.intern
+ else
+ raise RuntimeError.new("unknown use of soap:body: #{value.source}")
+ end
when EncodingStyleAttrName
@encodingstyle = value.source
when NamespaceAttrName
diff --git a/lib/wsdl/soap/cgiStubCreator.rb b/lib/wsdl/soap/cgiStubCreator.rb
index 0a76dc43a..2c4dff2f6 100644
--- a/lib/wsdl/soap/cgiStubCreator.rb
+++ b/lib/wsdl/soap/cgiStubCreator.rb
@@ -53,12 +53,12 @@ Methods = [
<<-EOD
super(*arg)
servant = #{class_name}.new
- #{class_name}::Methods.each do |name_as, name, param_def, soapaction, namespace, style|
- if style == :document
- @router.add_document_operation(servant, soapaction, name, param_def)
+ #{class_name}::Methods.each do |definitions|
+ opt = definitions.last
+ if opt[:request_style] == :document
+ @router.add_document_operation(servant, *definitions)
else
- qname = XSD::QName.new(namespace, name_as)
- @router.add_rpc_operation(servant, qname, soapaction, name, param_def)
+ @router.add_rpc_operation(servant, *definitions)
end
end
self.mapping_registry = #{class_name}::MappingRegistry
diff --git a/lib/wsdl/soap/classDefCreator.rb b/lib/wsdl/soap/classDefCreator.rb
index deda4f131..aeb67c061 100644
--- a/lib/wsdl/soap/classDefCreator.rb
+++ b/lib/wsdl/soap/classDefCreator.rb
@@ -57,7 +57,8 @@ private
def dump_element
@elements.collect { |ele|
if ele.local_complextype
- dump_classdef(ele.name, ele.local_complextype)
+ dump_classdef(ele.name, ele.local_complextype,
+ ele.elementform == 'qualified')
elsif ele.local_simpletype
dump_simpletypedef(ele.name, ele.local_simpletype)
else
@@ -117,7 +118,7 @@ private
c.dump
end
- def dump_classdef(qname, typedef)
+ def dump_classdef(qname, typedef, qualified = false)
if @faulttypes and @faulttypes.index(qname)
c = XSD::CodeGen::ClassDef.new(create_class_name(qname),
'::StandardError')
@@ -127,6 +128,7 @@ private
c.comment = "#{qname}"
c.def_classvar('schema_type', ndq(qname.name))
c.def_classvar('schema_ns', ndq(qname.namespace))
+ c.def_classvar('schema_qualified', dq('true')) if qualified
schema_element = []
init_lines = ''
params = []
@@ -158,7 +160,10 @@ private
else
params << "#{varname} = nil"
end
- eleqname = (varname == name) ? nil : element.name
+ # nil means @@schema_ns + varname
+ eleqname =
+ (varname == name && element.name.namespace == qname.namespace) ?
+ nil : element.name
schema_element << [varname, eleqname, type]
end
unless typedef.attributes.empty?
@@ -256,13 +261,50 @@ private
raise RuntimeError.new("cannot define name of #{attribute}")
end
+ DEFAULT_ITEM_NAME = XSD::QName.new(nil, 'item')
+
def dump_arraydef(complextype)
qname = complextype.name
c = XSD::CodeGen::ClassDef.new(create_class_name(qname), '::Array')
c.comment = "#{qname}"
- type = complextype.child_type
- c.def_classvar('schema_type', ndq(type.name))
- c.def_classvar('schema_ns', ndq(type.namespace))
+ child_type = complextype.child_type
+ c.def_classvar('schema_type', ndq(child_type.name))
+ c.def_classvar('schema_ns', ndq(child_type.namespace))
+ child_element = complextype.find_aryelement
+ schema_element = []
+ if child_type == XSD::AnyTypeName
+ type = nil
+ elsif child_element and (klass = element_basetype(child_element))
+ type = klass.name
+ elsif child_type
+ type = create_class_name(child_type)
+ else
+ type = nil
+ end
+ if child_element
+ if child_element.map_as_array?
+ type << '[]' if type
+ end
+ child_element_name = child_element.name
+ else
+ child_element_name = DEFAULT_ITEM_NAME
+ end
+ schema_element << [child_element_name.name, child_element_name, type]
+ c.def_classvar('schema_element',
+ '[' +
+ schema_element.collect { |varname, name, type|
+ '[' +
+ (
+ if name
+ varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'
+ else
+ varname.dump + ', ' + ndq(type)
+ end
+ ) +
+ ']'
+ }.join(', ') +
+ ']'
+ )
c.dump
end
end
diff --git a/lib/wsdl/soap/clientSkeltonCreator.rb b/lib/wsdl/soap/clientSkeltonCreator.rb
index 0b9e79c71..916f0d4dc 100644
--- a/lib/wsdl/soap/clientSkeltonCreator.rb
+++ b/lib/wsdl/soap/clientSkeltonCreator.rb
@@ -42,8 +42,8 @@ private
endpoint_url = ARGV.shift
obj = #{ drv_name }.new(endpoint_url)
-# Uncomment the below line to see SOAP wiredumps.
-# obj.wiredump_dev = STDERR
+# run ruby with -d to see SOAP wiredumps.
+obj.wiredump_dev = STDERR if $DEBUG
__EOD__
@definitions.porttype(name).operations.each do |operation|
diff --git a/lib/wsdl/soap/complexType.rb b/lib/wsdl/soap/complexType.rb
index bba50fd15..b2e13d056 100644
--- a/lib/wsdl/soap/complexType.rb
+++ b/lib/wsdl/soap/complexType.rb
@@ -106,18 +106,43 @@ class ComplexType < Info
end
end
if check_array_content(complexcontent.content)
- return complexcontent.content.elements[0].type
+ return element_simpletype(complexcontent.content.elements[0])
end
elsif check_array_content(content)
- return content.elements[0].type
+ return element_simpletype(content.elements[0])
end
raise RuntimeError.new("Assert: Unknown array definition.")
end
+ def find_aryelement
+ unless compoundtype == :TYPE_ARRAY
+ raise RuntimeError.new("Assert: not for array")
+ end
+ if complexcontent
+ if check_array_content(complexcontent.content)
+ return complexcontent.content.elements[0]
+ end
+ elsif check_array_content(content)
+ return content.elements[0]
+ end
+ nil # use default item name
+ end
+
private
+ def element_simpletype(element)
+ if element.type
+ element.type
+ elsif element.local_simpletype
+ element.local_simpletype.base
+ else
+ nil
+ end
+ end
+
def check_array_content(content)
- content.elements.size == 1 and content.elements[0].maxoccurs != '1'
+ content and content.elements.size == 1 and
+ content.elements[0].maxoccurs != '1'
end
def content_arytype
diff --git a/lib/wsdl/soap/driverCreator.rb b/lib/wsdl/soap/driverCreator.rb
index dd504210f..eba7c158a 100644
--- a/lib/wsdl/soap/driverCreator.rb
+++ b/lib/wsdl/soap/driverCreator.rb
@@ -69,18 +69,18 @@ Methods = [
end
c.def_privatemethod("init_methods") do
<<-EOD
- Methods.each do |name_as, name, params, soapaction, namespace, style|
- qname = XSD::QName.new(namespace, name_as)
- if style == :document
- @proxy.add_document_method(soapaction, name, params)
- add_document_method_interface(name, params)
+ Methods.each do |definitions|
+ opt = definitions.last
+ if opt[:request_style] == :document
+ add_document_operation(*definitions)
else
- @proxy.add_rpc_method(qname, soapaction, name, params)
- add_rpc_method_interface(name, params)
- end
- if name_as != name and name_as.capitalize == name.capitalize
- ::SOAP::Mapping.define_singleton_method(self, name_as) do |*arg|
- __send__(name, *arg)
+ add_rpc_operation(*definitions)
+ qname = definitions[0]
+ name = definitions[2]
+ if qname.name != name and qname.name.capitalize == name.capitalize
+ ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|
+ __send__(name, *arg)
+ end
end
end
end
diff --git a/lib/wsdl/soap/methodDefCreator.rb b/lib/wsdl/soap/methodDefCreator.rb
index f256b4245..f3ffadbe6 100644
--- a/lib/wsdl/soap/methodDefCreator.rb
+++ b/lib/wsdl/soap/methodDefCreator.rb
@@ -46,18 +46,18 @@ class MethodDefCreator
def collect_rpcparameter(operation)
result = operation.inputparts.collect { |part|
collect_type(part.type)
- param_set(::SOAP::RPC::SOAPMethod::IN, rpcdefinedtype(part), part.name)
+ param_set(::SOAP::RPC::SOAPMethod::IN, part.name, rpcdefinedtype(part))
}
outparts = operation.outputparts
if outparts.size > 0
retval = outparts[0]
collect_type(retval.type)
- result << param_set(::SOAP::RPC::SOAPMethod::RETVAL,
- rpcdefinedtype(retval), retval.name)
+ result << param_set(::SOAP::RPC::SOAPMethod::RETVAL, retval.name,
+ rpcdefinedtype(retval))
cdr(outparts).each { |part|
collect_type(part.type)
- result << param_set(::SOAP::RPC::SOAPMethod::OUT, rpcdefinedtype(part),
- part.name)
+ result << param_set(::SOAP::RPC::SOAPMethod::OUT, part.name,
+ rpcdefinedtype(part))
}
end
result
@@ -66,12 +66,12 @@ class MethodDefCreator
def collect_documentparameter(operation)
param = []
operation.inputparts.each do |input|
- param << param_set(::SOAP::RPC::SOAPMethod::IN,
- documentdefinedtype(input), input.name)
+ param << param_set(::SOAP::RPC::SOAPMethod::IN, input.name,
+ documentdefinedtype(input), elementqualified(input))
end
operation.outputparts.each do |output|
- param << param_set(::SOAP::RPC::SOAPMethod::OUT,
- documentdefinedtype(output), output.name)
+ param << param_set(::SOAP::RPC::SOAPMethod::OUT, output.name,
+ documentdefinedtype(output), elementqualified(output))
end
param
end
@@ -82,23 +82,38 @@ private
name = safemethodname(operation.name.name)
name_as = operation.name.name
style = binding.soapoperation_style
+ inputuse = binding.input.soapbody_use
+ outputuse = binding.output.soapbody_use
namespace = binding.input.soapbody.namespace
if style == :rpc
+ qname = XSD::QName.new(namespace, name_as)
paramstr = param2str(collect_rpcparameter(operation))
else
+ qname = nil
paramstr = param2str(collect_documentparameter(operation))
end
if paramstr.empty?
paramstr = '[]'
else
- paramstr = "[\n" << paramstr.gsub(/^/, ' ') << "\n ]"
+ paramstr = "[ " << paramstr.split(/\r?\n/).join("\n ") << " ]"
end
- return <<__EOD__
-[#{dq(name_as)}, #{dq(name)},
+ definitions = <<__EOD__
+#{ndq(binding.soapaction)},
+ #{dq(name)},
#{paramstr},
- #{ndq(binding.soapaction)}, #{ndq(namespace)}, #{sym(style.id2name)}
-]
+ { :request_style => #{sym(style.id2name)}, :request_use => #{sym(inputuse.id2name)},
+ :response_style => #{sym(style.id2name)}, :response_use => #{sym(outputuse.id2name)} }
__EOD__
+ if style == :rpc
+ return <<__EOD__
+[ #{qname.dump},
+ #{definitions}]
+__EOD__
+ else
+ return <<__EOD__
+[ #{definitions}]
+__EOD__
+ end
end
def rpcdefinedtype(part)
@@ -144,8 +159,22 @@ __EOD__
end
end
- def param_set(io_type, type, name)
- [io_type, type, name]
+ def elementqualified(part)
+ if mapped = basetype_mapped_class(part.type)
+ false
+ elsif definedtype = @simpletypes[part.type]
+ false
+ elsif definedtype = @elements[part.element]
+ definedtype.elementform == 'qualified'
+ elsif definedtype = @complextypes[part.type]
+ false
+ else
+ raise RuntimeError.new("part: #{part.name} cannot be resolved")
+ end
+ end
+
+ def param_set(io_type, name, type, ele = nil)
+ [io_type, name, type, ele]
end
def collect_type(type)
@@ -161,7 +190,12 @@ __EOD__
def param2str(params)
params.collect { |param|
- "[#{dq(param[0])}, #{dq(param[2])}, #{type2str(param[1])}]"
+ io, name, type, ele = param
+ unless ele.nil?
+ "[#{dq(io)}, #{dq(name)}, #{type2str(type)}, #{ele2str(ele)}]"
+ else
+ "[#{dq(io)}, #{dq(name)}, #{type2str(type)}]"
+ end
}.join(",\n")
end
@@ -173,6 +207,15 @@ __EOD__
end
end
+ def ele2str(ele)
+ qualified = ele
+ if qualified
+ "true"
+ else
+ "false"
+ end
+ end
+
def cdr(ary)
result = ary.dup
result.shift
diff --git a/lib/wsdl/soap/standaloneServerStubCreator.rb b/lib/wsdl/soap/standaloneServerStubCreator.rb
index 243ac1221..0b751b515 100644
--- a/lib/wsdl/soap/standaloneServerStubCreator.rb
+++ b/lib/wsdl/soap/standaloneServerStubCreator.rb
@@ -55,12 +55,12 @@ Methods = [
<<-EOD
super(*arg)
servant = #{class_name}.new
- #{class_name}::Methods.each do |name_as, name, param_def, soapaction, namespace, style|
- if style == :document
- @router.add_document_operation(servant, soapaction, name, param_def)
+ #{class_name}::Methods.each do |definitions|
+ opt = definitions.last
+ if opt[:request_style] == :document
+ @router.add_document_operation(servant, *definitions)
else
- qname = XSD::QName.new(namespace, name_as)
- @router.add_rpc_operation(servant, qname, soapaction, name, param_def)
+ @router.add_rpc_operation(servant, *definitions)
end
end
self.mapping_registry = #{class_name}::MappingRegistry
diff --git a/lib/wsdl/xmlSchema/all.rb b/lib/wsdl/xmlSchema/all.rb
index 1cb1ac16e..bb9566fea 100644
--- a/lib/wsdl/xmlSchema/all.rb
+++ b/lib/wsdl/xmlSchema/all.rb
@@ -29,6 +29,10 @@ class All < Info
parent.targetnamespace
end
+ def elementformdefault
+ parent.elementformdefault
+ end
+
def <<(element)
@elements << element
end
diff --git a/lib/wsdl/xmlSchema/attribute.rb b/lib/wsdl/xmlSchema/attribute.rb
index c82bd13bd..f9048661a 100644
--- a/lib/wsdl/xmlSchema/attribute.rb
+++ b/lib/wsdl/xmlSchema/attribute.rb
@@ -18,9 +18,8 @@ class Attribute < Info
if RUBY_VERSION > "1.7.0"
def attr_reader_ref(symbol)
name = symbol.to_s
- iv = "@#{name}"
define_method(name) {
- instance_variable_get(iv) ||
+ instance_variable_get("@#{name}") ||
(refelement ? refelement.__send__(name) : nil)
}
end
@@ -94,7 +93,11 @@ class Attribute < Info
when FormAttrName
@form = value.source
when NameAttrName
- @name = XSD::QName.new(targetnamespace, value.source)
+ if directelement?
+ @name = XSD::QName.new(targetnamespace, value.source)
+ else
+ @name = XSD::QName.new(nil, value.source)
+ end
when TypeAttrName
@type = value
when DefaultAttrName
@@ -111,6 +114,12 @@ class Attribute < Info
nil
end
end
+
+private
+
+ def directelement?
+ parent.is_a?(Schema)
+ end
end
diff --git a/lib/wsdl/xmlSchema/choice.rb b/lib/wsdl/xmlSchema/choice.rb
index 435fd48e4..f6d27fa38 100644
--- a/lib/wsdl/xmlSchema/choice.rb
+++ b/lib/wsdl/xmlSchema/choice.rb
@@ -29,6 +29,10 @@ class Choice < Info
parent.targetnamespace
end
+ def elementformdefault
+ parent.elementformdefault
+ end
+
def <<(element)
@elements << element
end
diff --git a/lib/wsdl/xmlSchema/complexType.rb b/lib/wsdl/xmlSchema/complexType.rb
index 0d9c622c7..dc9ec954f 100644
--- a/lib/wsdl/xmlSchema/complexType.rb
+++ b/lib/wsdl/xmlSchema/complexType.rb
@@ -37,7 +37,13 @@ class ComplexType < Info
end
def targetnamespace
- parent.is_a?(WSDL::XMLSchema::Element) ? nil : parent.targetnamespace
+ # inner elements can be qualified
+ # parent.is_a?(WSDL::XMLSchema::Element) ? nil : parent.targetnamespace
+ parent.targetnamespace
+ end
+
+ def elementformdefault
+ parent.elementformdefault
end
AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName)
diff --git a/lib/wsdl/xmlSchema/element.rb b/lib/wsdl/xmlSchema/element.rb
index 4a144cd52..fffb6485d 100644
--- a/lib/wsdl/xmlSchema/element.rb
+++ b/lib/wsdl/xmlSchema/element.rb
@@ -18,9 +18,8 @@ class Element < Info
if RUBY_VERSION > "1.7.0"
def attr_reader_ref(symbol)
name = symbol.to_s
- iv = "@#{name}"
define_method(name) {
- instance_variable_get(iv) ||
+ instance_variable_get("@#{name}") ||
(refelement ? refelement.__send__(name) : nil)
}
end
@@ -37,6 +36,7 @@ class Element < Info
end
attr_writer :name # required
+ attr_writer :form
attr_writer :type
attr_writer :local_simpletype
attr_writer :local_complextype
@@ -46,6 +46,7 @@ class Element < Info
attr_writer :nillable
attr_reader_ref :name
+ attr_reader_ref :form
attr_reader_ref :type
attr_reader_ref :local_simpletype
attr_reader_ref :local_complextype
@@ -59,6 +60,7 @@ class Element < Info
def initialize(name = nil, type = nil)
super()
@name = name
+ @form = nil
@type = type
@local_simpletype = @local_complextype = nil
@constraint = nil
@@ -70,18 +72,21 @@ class Element < Info
end
def refelement
- @refelement ||= root.collect_elements[@ref]
+ @refelement ||= (@ref ? root.collect_elements[@ref] : nil)
end
def targetnamespace
parent.targetnamespace
end
- def elementform
- # ToDo: must be overwritten.
+ def elementformdefault
parent.elementformdefault
end
+ def elementform
+ self.form.nil? ? parent.elementformdefault : self.form
+ end
+
def parse_element(element)
case element
when SimpleTypeName
@@ -102,7 +107,14 @@ class Element < Info
def parse_attr(attr, value)
case attr
when NameAttrName
- @name = XSD::QName.new(targetnamespace, value.source)
+ # namespace may be nil
+ if directelement? or elementform == 'qualified'
+ @name = XSD::QName.new(targetnamespace, value.source)
+ else
+ @name = XSD::QName.new(nil, value.source)
+ end
+ when FormAttrName
+ @form = value.source
when TypeAttrName
@type = value
when RefAttrName
@@ -110,14 +122,16 @@ class Element < Info
when MaxOccursAttrName
if parent.is_a?(All)
if value.source != '1'
- raise Parser::AttrConstraintError.new("cannot parse #{value} for #{attr}")
+ raise Parser::AttrConstraintError.new(
+ "cannot parse #{value} for #{attr}")
end
end
@maxoccurs = value.source
when MinOccursAttrName
if parent.is_a?(All)
unless ['0', '1'].include?(value.source)
- raise Parser::AttrConstraintError.new("cannot parse #{value} for #{attr}")
+ raise Parser::AttrConstraintError.new(
+ "cannot parse #{value} for #{attr}")
end
end
@minoccurs = value.source
@@ -127,6 +141,12 @@ class Element < Info
nil
end
end
+
+private
+
+ def directelement?
+ parent.is_a?(Schema)
+ end
end
diff --git a/lib/wsdl/xmlSchema/schema.rb b/lib/wsdl/xmlSchema/schema.rb
index 43447f9fb..ec97d07aa 100644
--- a/lib/wsdl/xmlSchema/schema.rb
+++ b/lib/wsdl/xmlSchema/schema.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema schema definition for WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003-2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
@@ -34,7 +34,8 @@ class Schema < Info
@elements = XSD::NamedElements.new
@attributes = XSD::NamedElements.new
@imports = []
- @elementformdefault = "qualified"
+ @attributeformdefault = "unqualified"
+ @elementformdefault = "unqualified"
@importedschema = {}
@location = nil
@root = self
diff --git a/lib/wsdl/xmlSchema/sequence.rb b/lib/wsdl/xmlSchema/sequence.rb
index bffb6a009..823fa3b7f 100644
--- a/lib/wsdl/xmlSchema/sequence.rb
+++ b/lib/wsdl/xmlSchema/sequence.rb
@@ -29,6 +29,10 @@ class Sequence < Info
parent.targetnamespace
end
+ def elementformdefault
+ parent.elementformdefault
+ end
+
def <<(element)
@elements << element
end
diff --git a/lib/xsd/charset.rb b/lib/xsd/charset.rb
index ccd22a774..15d5500fc 100644
--- a/lib/xsd/charset.rb
+++ b/lib/xsd/charset.rb
@@ -1,5 +1,5 @@
# XSD4R - Charset handling library.
-# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
@@ -10,7 +10,7 @@ module XSD
module Charset
- @encoding = $KCODE
+ @internal_encoding = $KCODE
class XSDError < StandardError; end
class CharsetError < XSDError; end
@@ -24,27 +24,40 @@ public
#
EncodingConvertMap = {}
def Charset.init
+ EncodingConvertMap[['UTF8', 'X_ISO8859_1']] =
+ Proc.new { |str| str.unpack('U*').pack('C*') }
+ EncodingConvertMap[['X_ISO8859_1', 'UTF8']] =
+ Proc.new { |str| str.unpack('C*').pack('U*') }
begin
require 'xsd/iconvcharset'
- @encoding = 'UTF8'
- sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' : 'shift_jis'
- EncodingConvertMap[['UTF8', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) }
- EncodingConvertMap[['EUC' , 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) }
- EncodingConvertMap[['EUC' , 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) }
- EncodingConvertMap[['UTF8', 'SJIS']] = Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) }
- EncodingConvertMap[['SJIS', 'UTF8']] = Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) }
- EncodingConvertMap[['SJIS', 'EUC' ]] = Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) }
+ @internal_encoding = 'UTF8'
+ sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' :
+ 'shift_jis'
+ EncodingConvertMap[['UTF8', 'EUC' ]] =
+ Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) }
+ EncodingConvertMap[['EUC' , 'UTF8']] =
+ Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) }
+ EncodingConvertMap[['EUC' , 'SJIS']] =
+ Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) }
+ EncodingConvertMap[['UTF8', 'SJIS']] =
+ Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) }
+ EncodingConvertMap[['SJIS', 'UTF8']] =
+ Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) }
+ EncodingConvertMap[['SJIS', 'EUC' ]] =
+ Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) }
rescue LoadError
begin
require 'nkf'
- EncodingConvertMap[['EUC' , 'SJIS']] = Proc.new { |str| NKF.nkf('-sXm0', str) }
- EncodingConvertMap[['SJIS', 'EUC' ]] = Proc.new { |str| NKF.nkf('-eXm0', str) }
+ EncodingConvertMap[['EUC' , 'SJIS']] =
+ Proc.new { |str| NKF.nkf('-sXm0', str) }
+ EncodingConvertMap[['SJIS', 'EUC' ]] =
+ Proc.new { |str| NKF.nkf('-eXm0', str) }
rescue LoadError
end
begin
require 'uconv'
- @encoding = 'UTF8'
+ @internal_encoding = 'UTF8'
EncodingConvertMap[['UTF8', 'EUC' ]] = Uconv.method(:u8toeuc)
EncodingConvertMap[['UTF8', 'SJIS']] = Uconv.method(:u8tosjis)
EncodingConvertMap[['EUC' , 'UTF8']] = Uconv.method(:euctou8)
@@ -60,6 +73,8 @@ public
'EUC' => 'euc-jp',
'SJIS' => 'shift_jis',
'UTF8' => 'utf-8',
+ 'X_ISO_8859_1' => 'iso-8859-1',
+ 'X_UNKNOWN' => nil,
}
@@ -67,24 +82,24 @@ public
## handlers
#
def Charset.encoding
- @encoding
+ @internal_encoding
end
def Charset.encoding=(encoding)
warn("xsd charset is set to #{encoding}") if $DEBUG
- @encoding = encoding
+ @internal_encoding = encoding
end
- def Charset.encoding_label
- charset_label(@encoding)
+ def Charset.xml_encoding_label
+ charset_label(@internal_encoding)
end
def Charset.encoding_to_xml(str, charset)
- encoding_conv(str, @encoding, charset_str(charset))
+ encoding_conv(str, @internal_encoding, charset_str(charset))
end
def Charset.encoding_from_xml(str, charset)
- encoding_conv(str, charset_str(charset), @encoding)
+ encoding_conv(str, charset_str(charset), @internal_encoding)
end
def Charset.encoding_conv(str, enc_from, enc_to)
@@ -94,7 +109,7 @@ public
converter.call(str)
else
raise CharsetConversionError.new(
- "Converter not found: #{ enc_from } -> #{ enc_to }")
+ "Converter not found: #{enc_from} -> #{enc_to}")
end
end
@@ -104,26 +119,26 @@ public
def Charset.charset_str(label)
if CharsetMap.respond_to?(:key)
- CharsetMap.key(label.downcase)
+ CharsetMap.key(label.downcase) || 'X_UNKNOWN'
else
- CharsetMap.index(label.downcase)
+ CharsetMap.index(label.downcase) || 'X_UNKNOWN'
end
end
# us_ascii = '[\x00-\x7F]'
us_ascii = '[\x9\xa\xd\x20-\x7F]' # XML 1.0 restricted.
- USASCIIRegexp = Regexp.new("\\A#{ us_ascii }*\\z", nil, "NONE")
+ USASCIIRegexp = Regexp.new("\\A#{us_ascii}*\\z", nil, "NONE")
twobytes_euc = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'
threebytes_euc = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'
- character_euc = "(?:#{ us_ascii }|#{ twobytes_euc }|#{ threebytes_euc })"
- EUCRegexp = Regexp.new("\\A#{ character_euc }*\\z", nil, "NONE")
+ character_euc = "(?:#{us_ascii}|#{twobytes_euc}|#{threebytes_euc})"
+ EUCRegexp = Regexp.new("\\A#{character_euc}*\\z", nil, "NONE")
# onebyte_sjis = '[\x00-\x7F\xA1-\xDF]'
onebyte_sjis = '[\x9\xa\xd\x20-\x7F\xA1-\xDF]' # XML 1.0 restricted.
twobytes_sjis = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'
- character_sjis = "(?:#{ onebyte_sjis }|#{ twobytes_sjis })"
- SJISRegexp = Regexp.new("\\A#{ character_sjis }*\\z", nil, "NONE")
+ character_sjis = "(?:#{onebyte_sjis}|#{twobytes_sjis})"
+ SJISRegexp = Regexp.new("\\A#{character_sjis}*\\z", nil, "NONE")
# 0xxxxxxx
# 110yyyyy 10xxxxxx
@@ -132,8 +147,9 @@ public
threebytes_utf8 = '(?:[\xE0-\xEF][\x80-\xBF][\x80-\xBF])'
# 11110uuu 10uuuzzz 10yyyyyy 10xxxxxx
fourbytes_utf8 = '(?:[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])'
- character_utf8 = "(?:#{ us_ascii }|#{ twobytes_utf8 }|#{ threebytes_utf8 }|#{ fourbytes_utf8 })"
- UTF8Regexp = Regexp.new("\\A#{ character_utf8 }*\\z", nil, "NONE")
+ character_utf8 =
+ "(?:#{us_ascii}|#{twobytes_utf8}|#{threebytes_utf8}|#{fourbytes_utf8})"
+ UTF8Regexp = Regexp.new("\\A#{character_utf8}*\\z", nil, "NONE")
def Charset.is_us_ascii(str)
USASCIIRegexp =~ str
@@ -162,7 +178,7 @@ public
when 'SJIS'
is_sjis(str)
else
- raise UnknownCharsetError.new("Unknown charset: #{ code }")
+ raise UnknownCharsetError.new("Unknown charset: #{code}")
end
end
end
diff --git a/lib/xsd/codegen/gensupport.rb b/lib/xsd/codegen/gensupport.rb
index 854534154..1e85d3668 100644
--- a/lib/xsd/codegen/gensupport.rb
+++ b/lib/xsd/codegen/gensupport.rb
@@ -1,5 +1,5 @@
# XSD4R - Code generation support
-# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2004, 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
@@ -10,7 +10,8 @@ module XSD
module CodeGen
# from the file 'keywords' in 1.9.
-KEYWORD = %w(
+KEYWORD = {}
+%w(
__LINE__
__FILE__
BEGIN
@@ -51,7 +52,7 @@ until
when
while
yield
-)
+).each { |k| KEYWORD[k] = nil }
module GenSupport
def capitalize(target)
@@ -96,12 +97,12 @@ module GenSupport
module_function :safemethodname?
def safevarname(name)
- safename = name.scan(/[a-zA-Z0-9_]+/).join('_')
- safename = uncapitalize(safename)
+ safename = uncapitalize(name.scan(/[a-zA-Z0-9_]+/).join('_'))
if /^[a-z]/ !~ safename or keyword?(safename)
- safename = "v_#{safename}"
+ "v_#{safename}"
+ else
+ safename
end
- safename
end
module_function :safevarname
@@ -111,7 +112,7 @@ module GenSupport
module_function :safevarname?
def keyword?(word)
- KEYWORD.include?(word)
+ KEYWORD.key?(word)
end
module_function :keyword?
diff --git a/lib/xsd/datatypes.rb b/lib/xsd/datatypes.rb
index d0fc44d69..bbe6c8578 100644
--- a/lib/xsd/datatypes.rb
+++ b/lib/xsd/datatypes.rb
@@ -560,23 +560,20 @@ module XSDDateTimeImpl
def screen_data(t)
# convert t to a DateTime as an internal representation.
- if t.is_a?(DateTime)
+ if t.respond_to?(:to_datetime) # 1.9 or later
+ t.to_datetime
+ elsif t.is_a?(DateTime)
t
elsif t.is_a?(Date)
- if t.respond_to?(:to_datetime) # from 1.9
- t.to_datetime
- else
- t = screen_data_str(t)
- t <<= 12 if t.year < 0
- t
- end
+ t = screen_data_str(t)
+ t <<= 12 if t.year < 0
+ t
elsif t.is_a?(Time)
- sec, min, hour, mday, month, year = t.to_a[0..5]
- diffday = t.usec.to_r / 1000000 / SecInDay
+ jd = DateTime.civil_to_jd(t.year, t.mon, t.mday, DateTime::ITALY)
+ fr = DateTime.time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
+ t.usec.to_r / 1000000 / SecInDay
of = t.utc_offset.to_r / SecInDay
- data = DateTime.civil(year, month, mday, hour, min, sec, of)
- data += diffday
- data
+ DateTime.new0(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)
else
screen_data_str(t)
end
diff --git a/lib/xsd/ns.rb b/lib/xsd/ns.rb
index b63a8a5cd..53eeae713 100644
--- a/lib/xsd/ns.rb
+++ b/lib/xsd/ns.rb
@@ -72,7 +72,7 @@ public
if (name.namespace == @default_namespace)
name.name
elsif @ns2tag.key?(name.namespace)
- @ns2tag[name.namespace] + ':' << name.name
+ "#{@ns2tag[name.namespace]}:#{name.name}"
else
raise FormatError.new("namespace: #{name.namespace} not defined yet")
end
diff --git a/lib/xsd/qname.rb b/lib/xsd/qname.rb
index 18b002764..bb9763a69 100644
--- a/lib/xsd/qname.rb
+++ b/lib/xsd/qname.rb
@@ -31,9 +31,6 @@ class QName
end
def match(rhs)
- unless self.class === rhs
- return false
- end
if rhs.namespace and (rhs.namespace != @namespace)
return false
end
@@ -44,7 +41,7 @@ class QName
end
def ==(rhs)
- (self.class === rhs && @namespace == rhs.namespace && @name == rhs.name)
+ !rhs.nil? and @namespace == rhs.namespace and @name == rhs.name
end
def ===(rhs)
@@ -73,6 +70,8 @@ class QName
NormalizedNameRegexp =~ str
self.new($1, $2)
end
+
+ EMPTY = QName.new.freeze
end