mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/soap/baseData.rb: Introduce SOAPType as the common ancestor of
SOAPBasetype and SOAPCompoundtype. * lib/soap/generator.rb, lib/soap/element.rb, lib/soap/encodingstyle/*: Encoding methods signature change. Pass SOAPGenerator as a parameter. * lib/soap/mapping/*, test/soap/marshal/test_marshal.rb: Refactoring for better marshalling/unmarshalling support. Now I think SOAP marshaller supports all kind of object graph which is supported by Ruby's original marshaller. Of course there could be bugs as always. Find it. :-) * lib/soap/rpc/standaloneServer.rb: Set severity threshould to INFO. DEBUG is too noisy. * lib/xsd/datatypes.rb: DateTime#of is obsoleted. Use DateTime#offset. * test/wsdl/emptycomplextype.wsdl, test/xsd/xmlschema.xml: Avoid useless warning. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4760 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0b841783b5
commit
9cba39a1a1
21 changed files with 716 additions and 402 deletions
|
@ -40,10 +40,17 @@ public
|
|||
end
|
||||
|
||||
|
||||
###
|
||||
## Marker of SOAP/DM types.
|
||||
#
|
||||
module SOAPType; end
|
||||
|
||||
|
||||
###
|
||||
## Mix-in module for SOAP base type instances.
|
||||
#
|
||||
module SOAPBasetype
|
||||
include SOAPType
|
||||
include SOAP
|
||||
|
||||
attr_accessor :encodingstyle
|
||||
|
@ -75,6 +82,7 @@ end
|
|||
## Mix-in module for SOAP compound type instances.
|
||||
#
|
||||
module SOAPCompoundtype
|
||||
include SOAPType
|
||||
include SOAP
|
||||
|
||||
attr_accessor :encodingstyle
|
||||
|
@ -168,7 +176,7 @@ public
|
|||
d
|
||||
end
|
||||
|
||||
def SOAPReference.create_refid(obj)
|
||||
def self.create_refid(obj)
|
||||
'id' << obj.__id__.to_s
|
||||
end
|
||||
end
|
||||
|
@ -597,7 +605,7 @@ public
|
|||
data = retrieve(idxary[0, idxary.size - 1])
|
||||
data[idxary.last] = value
|
||||
|
||||
if value.is_a?(SOAPBasetype) || value.is_a?(SOAPCompoundtype)
|
||||
if value.is_a?(SOAPType)
|
||||
value.elename = value.elename.dup_name('item')
|
||||
|
||||
# Sync type
|
||||
|
|
|
@ -84,17 +84,17 @@ public
|
|||
end
|
||||
end
|
||||
|
||||
def encode(buf, ns, attrs = {}, indent = '')
|
||||
def encode(generator, ns, attrs = {})
|
||||
SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)
|
||||
SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)
|
||||
attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace
|
||||
name = ns.name(@elename)
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
yield(self.faultcode, false)
|
||||
yield(self.faultstring, false)
|
||||
yield(self.faultactor, false)
|
||||
yield(self.detail, false) if self.detail
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, true)
|
||||
generator.encode_tag_end(name, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -112,9 +112,9 @@ public
|
|||
@is_fault = is_fault
|
||||
end
|
||||
|
||||
def encode(buf, ns, attrs = {}, indent = '')
|
||||
def encode(generator, ns, attrs = {})
|
||||
name = ns.name(@elename)
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
if @is_fault
|
||||
yield(@data, true)
|
||||
else
|
||||
|
@ -122,7 +122,7 @@ public
|
|||
yield(data, true)
|
||||
end
|
||||
end
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, true)
|
||||
generator.encode_tag_end(name, true)
|
||||
end
|
||||
|
||||
def root_node
|
||||
|
@ -160,7 +160,7 @@ public
|
|||
@encodingstyle = encodingstyle || LiteralNamespace
|
||||
end
|
||||
|
||||
def encode(buf, ns, attrs = {}, indent = '')
|
||||
def encode(generator, ns, attrs = {})
|
||||
attrs.each do |key, value|
|
||||
@content.attr[key] = value
|
||||
end
|
||||
|
@ -185,13 +185,13 @@ class SOAPHeader < SOAPArray
|
|||
@encodingstyle = nil
|
||||
end
|
||||
|
||||
def encode(buf, ns, attrs = {}, indent = '')
|
||||
def encode(generator, ns, attrs = {})
|
||||
name = ns.name(@elename)
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
@data.each do |data|
|
||||
yield(data, true)
|
||||
end
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, true)
|
||||
generator.encode_tag_end(name, true)
|
||||
end
|
||||
|
||||
def length
|
||||
|
@ -215,16 +215,16 @@ class SOAPEnvelope < XSD::NSDBase
|
|||
@body = body
|
||||
end
|
||||
|
||||
def encode(buf, ns, attrs = {}, indent = '')
|
||||
def encode(generator, ns, attrs = {})
|
||||
SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace,
|
||||
SOAPNamespaceTag)
|
||||
name = ns.name(@elename)
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
|
||||
yield(@header, true) if @header and @header.length > 0
|
||||
yield(@body, true)
|
||||
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, true)
|
||||
generator.encode_tag_end(name, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class ASPDotNetHandler < Handler
|
|||
###
|
||||
## encode interface.
|
||||
#
|
||||
def encode_data(buf, ns, qualified, data, parent, indent = '')
|
||||
def encode_data(generator, ns, qualified, data, parent)
|
||||
attrs = {}
|
||||
name = if qualified and data.elename.namespace
|
||||
SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
|
||||
|
@ -49,17 +49,16 @@ class ASPDotNetHandler < Handler
|
|||
|
||||
case data
|
||||
when SOAPRawString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << data.to_s
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_rawstring(data.to_s)
|
||||
when XSD::XSDString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(@charset ?
|
||||
XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(@charset ? XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
when XSD::XSDAnySimpleType
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(data.to_s)
|
||||
when SOAPStruct
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.each do |key, value|
|
||||
if !value.elename.namespace
|
||||
value.elename.namespace = data.elename.namespace
|
||||
|
@ -67,7 +66,7 @@ class ASPDotNetHandler < Handler
|
|||
yield(value, true)
|
||||
end
|
||||
when SOAPArray
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.traverse do |child, *rank|
|
||||
data.position = nil
|
||||
yield(child, true)
|
||||
|
@ -78,14 +77,14 @@ yle.")
|
|||
end
|
||||
end
|
||||
|
||||
def encode_data_end(buf, ns, qualified, data, parent, indent = "")
|
||||
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
|
||||
cr = data.is_a?(SOAPCompoundtype)
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, cr)
|
||||
generator.encode_tag_end(name, cr)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ class Handler
|
|||
## encode interface.
|
||||
#
|
||||
# Returns a XML instance as a string.
|
||||
def encode_data(buf, ns, qualified, data, parent, indent)
|
||||
def encode_data(generator, ns, qualified, data, parent)
|
||||
raise NotImplementError.new('Method encode_data must be defined in derived class.')
|
||||
end
|
||||
|
||||
def encode_data_end(buf, ns, qualified, data, parent, indent)
|
||||
def encode_data_end(generator, ns, qualified, data, parent)
|
||||
raise NotImplementError.new('Method encode_data must be defined in derived class.')
|
||||
end
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class LiteralHandler < Handler
|
|||
###
|
||||
## encode interface.
|
||||
#
|
||||
def encode_data(buf, ns, qualified, data, parent, indent = '')
|
||||
def encode_data(generator, ns, qualified, data, parent)
|
||||
attrs = {}
|
||||
name = if qualified and data.elename.namespace
|
||||
SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
|
||||
|
@ -48,31 +48,29 @@ class LiteralHandler < Handler
|
|||
|
||||
case data
|
||||
when SOAPRawString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << data.to_s
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_rawstring(data.to_s)
|
||||
when XSD::XSDString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(@charset ?
|
||||
XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(@charset ? XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
when XSD::XSDAnySimpleType
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(data.to_s)
|
||||
when SOAPStruct
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.each do |key, value|
|
||||
value.elename.namespace = data.elename.namespace if !value.elename.namespace
|
||||
yield(value, true)
|
||||
end
|
||||
when SOAPArray
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.traverse do |child, *rank|
|
||||
data.position = nil
|
||||
yield(child, true)
|
||||
end
|
||||
when SOAPElement
|
||||
SOAPGenerator.encode_tag(buf, name, attrs.update(data.extraattr),
|
||||
indent)
|
||||
buf << data.text if data.text
|
||||
generator.encode_tag(name, attrs.update(data.extraattr))
|
||||
generator.encode_rawstring(data.text) if data.text
|
||||
data.each do |key, value|
|
||||
value.elename.namespace = data.elename.namespace if !value.elename.namespace
|
||||
#yield(value, data.qualified)
|
||||
|
@ -83,13 +81,13 @@ class LiteralHandler < Handler
|
|||
end
|
||||
end
|
||||
|
||||
def encode_data_end(buf, ns, qualified, data, parent, indent)
|
||||
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
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent)
|
||||
generator.encode_tag_end(name)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ class SOAPHandler < Handler
|
|||
###
|
||||
## encode interface.
|
||||
#
|
||||
def encode_data(buf, ns, qualified, data, parent, indent = '')
|
||||
attrs = encode_attrs(ns, qualified, data, parent)
|
||||
def encode_data(generator, ns, qualified, data, parent)
|
||||
attrs = encode_attrs(generator, ns, data, parent)
|
||||
|
||||
if parent && parent.is_a?(SOAPArray) && parent.position
|
||||
attrs[ns.name(AttrPositionName)] = '[' << parent.position.join(',') << ']'
|
||||
|
@ -55,32 +55,26 @@ class SOAPHandler < Handler
|
|||
name = data.elename.name
|
||||
end
|
||||
|
||||
if data.respond_to?(:encode)
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
return data.encode(buf, ns, attrs, indent)
|
||||
end
|
||||
|
||||
case data
|
||||
when SOAPReference
|
||||
attrs['href'] = '#' << data.refid
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
when SOAPRawString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << data.to_s
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_rawstring(data.to_s)
|
||||
when XSD::XSDString
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(@charset ?
|
||||
XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(@charset ? XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
||||
when XSD::XSDAnySimpleType
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
buf << SOAPGenerator.encode_str(data.to_s)
|
||||
generator.encode_tag(name, attrs)
|
||||
generator.encode_string(data.to_s)
|
||||
when SOAPStruct
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.each do |key, value|
|
||||
yield(value, false)
|
||||
end
|
||||
when SOAPArray
|
||||
SOAPGenerator.encode_tag(buf, name, attrs, indent)
|
||||
generator.encode_tag(name, attrs)
|
||||
data.traverse do |child, *rank|
|
||||
data.position = data.sparse ? rank : nil
|
||||
yield(child, false)
|
||||
|
@ -91,14 +85,14 @@ class SOAPHandler < Handler
|
|||
end
|
||||
end
|
||||
|
||||
def encode_data_end(buf, ns, qualified, data, parent, indent = '')
|
||||
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
|
||||
cr = data.is_a?(SOAPCompoundtype)
|
||||
SOAPGenerator.encode_tag_end(buf, name, indent, cr)
|
||||
generator.encode_tag_end(name, cr)
|
||||
end
|
||||
|
||||
|
||||
|
@ -292,7 +286,7 @@ private
|
|||
content_typename(data.arytype.name) << '[' << data.size.join(',') << ']')
|
||||
end
|
||||
|
||||
def encode_attrs(ns, qualified, data, parent)
|
||||
def encode_attrs(generator, ns, data, parent)
|
||||
return {} if data.is_a?(SOAPReference)
|
||||
attrs = {}
|
||||
|
||||
|
@ -330,7 +324,7 @@ private
|
|||
|
||||
data.extraattr.each do |key, value|
|
||||
SOAPGenerator.assign_ns(attrs, ns, key.namespace)
|
||||
attrs[ns.name(key)] = value # ns.name(value) ?
|
||||
attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value)
|
||||
end
|
||||
if data.id
|
||||
attrs['id'] = data.id
|
||||
|
@ -338,6 +332,17 @@ private
|
|||
attrs
|
||||
end
|
||||
|
||||
def encode_attr_value(generator, ns, qname, value)
|
||||
if value.is_a?(SOAPType)
|
||||
refid = SOAPReference.create_refid(value)
|
||||
value.id = refid
|
||||
generator.add_reftarget(qname.name, value)
|
||||
'#' + refid
|
||||
else
|
||||
value.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr)
|
||||
if parent.class == SOAPBody
|
||||
# Unqualified name is allowed here.
|
||||
|
@ -423,11 +428,13 @@ private
|
|||
end
|
||||
|
||||
if (klass = TypeMap[type])
|
||||
klass.decode(elename)
|
||||
else
|
||||
# Unknown type... Struct or String
|
||||
SOAPUnknown.new(self, elename, type, extraattr)
|
||||
node = klass.decode(elename)
|
||||
node.extraattr.update(extraattr)
|
||||
return node
|
||||
end
|
||||
|
||||
# Unknown type... Struct or String
|
||||
SOAPUnknown.new(self, elename, type, extraattr)
|
||||
end
|
||||
|
||||
def decode_textbuf(node)
|
||||
|
@ -508,12 +515,22 @@ private
|
|||
id = value
|
||||
next
|
||||
end
|
||||
extraattr[qname] = value
|
||||
extraattr[qname] = decode_attr_value(ns, qname, value)
|
||||
end
|
||||
|
||||
return is_nil, type, arytype, root, offset, position, href, id, extraattr
|
||||
end
|
||||
|
||||
def decode_attr_value(ns, qname, value)
|
||||
if /\A#/ =~ value
|
||||
o = SOAPReference.new(value)
|
||||
@refpool << o
|
||||
o
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def decode_arypos(position)
|
||||
/^\[(.+)\]$/ =~ position
|
||||
$1.split(',').collect { |s| s.to_i }
|
||||
|
@ -524,7 +541,7 @@ private
|
|||
while !@refpool.empty? && count > 0
|
||||
@refpool = @refpool.find_all { |ref|
|
||||
o = @idpool.find { |item|
|
||||
('#' << item.id == ref.refid)
|
||||
'#' + item.id == ref.refid
|
||||
}
|
||||
unless o
|
||||
raise EncodingStyleError.new("Unresolved reference: #{ ref.refid }.")
|
||||
|
|
|
@ -39,7 +39,6 @@ public
|
|||
attr_accessor :charset
|
||||
attr_accessor :default_encodingstyle
|
||||
attr_accessor :generate_explicit_type
|
||||
attr_accessor :pretty
|
||||
|
||||
def initialize(opt = {})
|
||||
@reftarget = nil
|
||||
|
@ -48,37 +47,38 @@ public
|
|||
@default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
|
||||
@generate_explicit_type =
|
||||
opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true
|
||||
@pretty = true # opt[:pretty]
|
||||
@buf = @indent = @curr = nil
|
||||
end
|
||||
|
||||
def generate(obj, io = nil)
|
||||
@buf = io || ''
|
||||
@indent = ''
|
||||
|
||||
prologue
|
||||
@handlers.each do |uri, handler|
|
||||
handler.encode_prologue
|
||||
end
|
||||
|
||||
io = '' if io.nil?
|
||||
|
||||
ns = XSD::NS.new
|
||||
io << xmldecl
|
||||
encode_data(io, ns, true, obj, nil, 0)
|
||||
@buf << xmldecl
|
||||
encode_data(ns, true, obj, nil)
|
||||
|
||||
@handlers.each do |uri, handler|
|
||||
handler.encode_epilogue
|
||||
end
|
||||
epilogue
|
||||
|
||||
io
|
||||
@buf
|
||||
end
|
||||
|
||||
def encode_data(buf, ns, qualified, obj, parent, indent)
|
||||
def encode_data(ns, qualified, obj, parent)
|
||||
if obj.is_a?(SOAPEnvelopeElement)
|
||||
encode_element(buf, ns, qualified, obj, parent, indent)
|
||||
encode_element(ns, qualified, obj, parent)
|
||||
return
|
||||
end
|
||||
|
||||
if @reftarget && !obj.precedents.empty?
|
||||
@reftarget.add(obj.elename.name, obj)
|
||||
add_reftarget(obj.elename.name, obj)
|
||||
ref = SOAPReference.new
|
||||
ref.elename.name = obj.elename.name
|
||||
ref.__setobj__(obj)
|
||||
|
@ -102,22 +102,29 @@ public
|
|||
raise FormatEncodeError.new("Element name not defined: #{ obj }.")
|
||||
end
|
||||
|
||||
indent_str = ' ' * indent
|
||||
child_indent = @pretty ? indent + 2 : indent
|
||||
handler.encode_data(buf, ns, qualified, obj, parent, indent_str) do |child, child_q|
|
||||
encode_data(buf, ns.clone_ns, child_q, child, obj, child_indent)
|
||||
handler.encode_data(self, ns, qualified, obj, parent) do |child, child_q|
|
||||
indent_backup, @indent = @indent, @indent + ' '
|
||||
encode_data(ns.clone_ns, child_q, child, obj)
|
||||
@indent = indent_backup
|
||||
end
|
||||
handler.encode_data_end(buf, ns, qualified, obj, parent, indent_str)
|
||||
handler.encode_data_end(self, ns, qualified, obj, parent)
|
||||
end
|
||||
|
||||
def encode_element(buf, ns, qualified, obj, parent, indent)
|
||||
indent_str = ' ' * indent
|
||||
child_indent = @pretty ? indent + 2 : indent
|
||||
def add_reftarget(name, node)
|
||||
unless @reftarget
|
||||
raise FormatEncodeError.new("Reftarget is not defined.")
|
||||
end
|
||||
@reftarget.add(name, node)
|
||||
end
|
||||
|
||||
def encode_element(ns, qualified, obj, parent)
|
||||
attrs = {}
|
||||
if obj.is_a?(SOAPBody)
|
||||
@reftarget = obj
|
||||
obj.encode(buf, ns, attrs, indent_str) do |child, child_q|
|
||||
encode_data(buf, ns.clone_ns, child_q, child, obj, child_indent)
|
||||
obj.encode(self, ns, attrs) do |child, child_q|
|
||||
indent_backup, @indent = @indent, @indent + ' '
|
||||
encode_data(ns.clone_ns, child_q, child, obj)
|
||||
@indent = indent_backup
|
||||
end
|
||||
@reftarget = nil
|
||||
else
|
||||
|
@ -129,39 +136,38 @@ public
|
|||
SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)
|
||||
end
|
||||
end
|
||||
obj.encode(buf, ns, attrs, indent_str) do |child, child_q|
|
||||
encode_data(buf, ns.clone_ns, child_q, child, obj, child_indent)
|
||||
obj.encode(self, ns, attrs) do |child, child_q|
|
||||
indent_backup, @indent = @indent, @indent + ' '
|
||||
encode_data(ns.clone_ns, child_q, child, obj)
|
||||
@indent = indent_backup
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.assign_ns(attrs, ns, namespace, tag = nil)
|
||||
unless ns.assigned?(namespace)
|
||||
tag = ns.assign(namespace, tag)
|
||||
attrs['xmlns:' << tag] = namespace
|
||||
end
|
||||
end
|
||||
|
||||
def self.encode_tag(buf, elename, attrs = nil, indent = '')
|
||||
def encode_tag(elename, attrs = nil)
|
||||
if attrs
|
||||
buf << "\n#{ indent }<#{ elename }" <<
|
||||
@buf << "\n#{ @indent }<#{ elename }" <<
|
||||
attrs.collect { |key, value|
|
||||
%Q[ #{ key }="#{ value }"]
|
||||
}.join <<
|
||||
'>'
|
||||
else
|
||||
buf << "\n#{ indent }<#{ elename }>"
|
||||
@buf << "\n#{ @indent }<#{ elename }>"
|
||||
end
|
||||
end
|
||||
|
||||
def self.encode_tag_end(buf, elename, indent = '', cr = nil)
|
||||
def encode_tag_end(elename, cr = nil)
|
||||
if cr
|
||||
buf << "\n#{ indent }</#{ elename }>"
|
||||
@buf << "\n#{ @indent }</#{ elename }>"
|
||||
else
|
||||
buf << "</#{ elename }>"
|
||||
@buf << "</#{ elename }>"
|
||||
end
|
||||
end
|
||||
|
||||
def encode_rawstring(str)
|
||||
@buf << str
|
||||
end
|
||||
|
||||
EncodeMap = {
|
||||
'&' => '&',
|
||||
'<' => '<',
|
||||
|
@ -171,8 +177,15 @@ public
|
|||
"\r" => '
'
|
||||
}
|
||||
EncodeCharRegexp = Regexp.new("[#{EncodeMap.keys.join}]")
|
||||
def self.encode_str(str)
|
||||
str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
|
||||
def encode_string(str)
|
||||
@buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
|
||||
end
|
||||
|
||||
def self.assign_ns(attrs, ns, namespace, tag = nil)
|
||||
if namespace and !ns.assigned?(namespace)
|
||||
tag = ns.assign(namespace, tag)
|
||||
attrs['xmlns:' << tag] = namespace
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -24,6 +24,10 @@ module Mapping
|
|||
class Factory
|
||||
include TraverseSupport
|
||||
|
||||
def initialize
|
||||
# nothing to do
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
raise NotImplementError.new
|
||||
# return soap_obj
|
||||
|
@ -48,24 +52,13 @@ class Factory
|
|||
end
|
||||
end
|
||||
|
||||
def set_instance_vars(obj, values)
|
||||
values.each do |name, value|
|
||||
setter = name + "="
|
||||
if obj.respond_to?(setter)
|
||||
obj.__send__(setter, value)
|
||||
else
|
||||
obj.instance_eval("@#{ name } = value")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setiv2obj(obj, node, map)
|
||||
return if node.nil?
|
||||
vars = {}
|
||||
node.each do |name, value|
|
||||
vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
|
||||
end
|
||||
set_instance_vars(obj, vars)
|
||||
Mapping.set_instance_vars(obj, vars)
|
||||
end
|
||||
|
||||
def setiv2soap(node, obj, map)
|
||||
|
@ -76,13 +69,6 @@ class Factory
|
|||
end
|
||||
end
|
||||
|
||||
def addiv2soap(node, obj, map)
|
||||
return if obj.instance_variables.empty?
|
||||
ivars = SOAPStruct.new # Undefined type.
|
||||
setiv2soap(ivars, obj, map)
|
||||
node.add('ivars', ivars)
|
||||
end
|
||||
|
||||
# It breaks Thread.current[:SOAPMarshalDataKey].
|
||||
def mark_marshalled_obj(obj, soap_obj)
|
||||
Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj
|
||||
|
@ -103,14 +89,21 @@ class Factory
|
|||
end
|
||||
|
||||
class StringFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if !@allow_original_mapping and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
begin
|
||||
if XSD::Charset.is_ces(obj, $KCODE)
|
||||
encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding)
|
||||
soap_obj = soap_class.new(encoded)
|
||||
else
|
||||
return nil
|
||||
unless XSD::Charset.is_ces(obj, $KCODE)
|
||||
return nil
|
||||
end
|
||||
encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding)
|
||||
soap_obj = soap_class.new(encoded)
|
||||
rescue XSD::ValueSpaceError
|
||||
return nil
|
||||
end
|
||||
|
@ -119,14 +112,24 @@ class StringFactory_ < Factory
|
|||
end
|
||||
|
||||
def soap2obj(obj_class, node, info, map)
|
||||
obj = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE)
|
||||
obj = create_empty_object(obj_class)
|
||||
decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE)
|
||||
obj.replace(decoded)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
return true, obj
|
||||
end
|
||||
end
|
||||
|
||||
class BasetypeFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if !@allow_original_mapping and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
soap_obj = nil
|
||||
begin
|
||||
soap_obj = soap_class.new(obj)
|
||||
|
@ -145,7 +148,16 @@ class BasetypeFactory_ < Factory
|
|||
end
|
||||
|
||||
class DateTimeFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if !@allow_original_mapping and
|
||||
Time === obj and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
soap_obj = nil
|
||||
begin
|
||||
soap_obj = soap_class.new(obj)
|
||||
|
@ -176,6 +188,7 @@ end
|
|||
|
||||
class Base64Factory_ < Factory
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
return nil unless obj.instance_variables.empty?
|
||||
soap_obj = soap_class.new(obj)
|
||||
mark_marshalled_obj(obj, soap_obj) if soap_obj
|
||||
soap_obj
|
||||
|
@ -189,9 +202,17 @@ class Base64Factory_ < Factory
|
|||
end
|
||||
|
||||
class ArrayFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
# [[1], [2]] is converted to Array of Array, not 2-D Array.
|
||||
# To create M-D Array, you must call Mapping.ary2md.
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if !@allow_original_mapping and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
arytype = Mapping.obj2element(obj)
|
||||
if arytype.name
|
||||
arytype.namespace ||= RubyTypeNamespace
|
||||
|
@ -217,7 +238,15 @@ class ArrayFactory_ < Factory
|
|||
end
|
||||
|
||||
class TypedArrayFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if !@allow_original_mapping and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
arytype = info[:type] || info[0]
|
||||
param = SOAPArray.new(ValueArrayName, 1, arytype)
|
||||
mark_marshalled_obj(obj, param)
|
||||
|
@ -271,9 +300,17 @@ end
|
|||
|
||||
MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')
|
||||
class HashFactory_ < Factory
|
||||
def initialize(allow_original_mapping = false)
|
||||
super()
|
||||
@allow_original_mapping = allow_original_mapping
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
if obj.default or
|
||||
(obj.respond_to?(:default_proc) and obj.default_proc)
|
||||
if !@allow_original_mapping and !obj.instance_variables.empty?
|
||||
return nil
|
||||
end
|
||||
if !obj.default.nil? or
|
||||
(obj.respond_to?(:default_proc) and obj.default_proc)
|
||||
return nil
|
||||
end
|
||||
param = SOAPStruct.new(MapQName)
|
||||
|
|
|
@ -129,6 +129,16 @@ module Mapping
|
|||
return registry.soap2obj(node.class, node)
|
||||
end
|
||||
|
||||
def self.set_instance_vars(obj, values)
|
||||
values.each do |name, value|
|
||||
setter = name + "="
|
||||
if obj.respond_to?(setter)
|
||||
obj.__send__(setter, value)
|
||||
else
|
||||
obj.instance_eval("@#{ name } = value")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here.
|
||||
# Caution: '.' is not allowed here.
|
||||
|
|
|
@ -39,6 +39,8 @@ module MappedException; end
|
|||
|
||||
|
||||
RubyTypeName = XSD::QName.new(RubyTypeInstanceNamespace, 'rubyType')
|
||||
RubyExtendName = XSD::QName.new(RubyTypeInstanceNamespace, 'extends')
|
||||
RubyIVarName = XSD::QName.new(RubyTypeInstanceNamespace, 'ivars')
|
||||
|
||||
|
||||
# Inner class to pass an exception.
|
||||
|
@ -217,11 +219,11 @@ class Registry
|
|||
[::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory],
|
||||
[::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory],
|
||||
[::String, ::SOAP::SOAPString, StringFactory],
|
||||
[::DateTime, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Date, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Date, ::SOAP::SOAPDate, BasetypeFactory],
|
||||
[::Time, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Time, ::SOAP::SOAPTime, BasetypeFactory],
|
||||
[::DateTime, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Date, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Date, ::SOAP::SOAPDate, DateTimeFactory],
|
||||
[::Time, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Time, ::SOAP::SOAPTime, DateTimeFactory],
|
||||
[::Float, ::SOAP::SOAPDouble, BasetypeFactory,
|
||||
{:derived_class => true}],
|
||||
[::Float, ::SOAP::SOAPFloat, BasetypeFactory,
|
||||
|
@ -261,11 +263,11 @@ class Registry
|
|||
[::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory],
|
||||
[::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory],
|
||||
[::String, ::SOAP::SOAPString, StringFactory],
|
||||
[::DateTime, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Date, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Date, ::SOAP::SOAPDate, BasetypeFactory],
|
||||
[::Time, ::SOAP::SOAPDateTime, BasetypeFactory],
|
||||
[::Time, ::SOAP::SOAPTime, BasetypeFactory],
|
||||
[::DateTime, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Date, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Date, ::SOAP::SOAPDate, DateTimeFactory],
|
||||
[::Time, ::SOAP::SOAPDateTime, DateTimeFactory],
|
||||
[::Time, ::SOAP::SOAPTime, DateTimeFactory],
|
||||
[::Float, ::SOAP::SOAPDouble, BasetypeFactory,
|
||||
{:derived_class => true}],
|
||||
[::Float, ::SOAP::SOAPFloat, BasetypeFactory,
|
||||
|
@ -304,18 +306,18 @@ class Registry
|
|||
@config = config
|
||||
@map = Map.new(self)
|
||||
if @config[:allow_original_mapping]
|
||||
allow_original_mapping = true
|
||||
@allow_original_mapping = true
|
||||
@map.init(RubyOriginalMap)
|
||||
else
|
||||
allow_original_mapping = false
|
||||
@allow_original_mapping = false
|
||||
@map.init(SOAPBaseMap)
|
||||
end
|
||||
|
||||
allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
|
||||
@allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
|
||||
@config[:allow_untyped_struct] : true
|
||||
@rubytype_factory = RubytypeFactory.new(
|
||||
:allow_untyped_struct => allow_untyped_struct,
|
||||
:allow_original_mapping => allow_original_mapping
|
||||
:allow_untyped_struct => @allow_untyped_struct,
|
||||
:allow_original_mapping => @allow_original_mapping
|
||||
)
|
||||
@default_factory = @rubytype_factory
|
||||
@excn_handler_obj2soap = nil
|
||||
|
@ -329,53 +331,20 @@ class Registry
|
|||
|
||||
# This mapping registry ignores type hint.
|
||||
def obj2soap(klass, obj, type = nil)
|
||||
ret = nil
|
||||
if obj.is_a?(SOAPStruct) || obj.is_a?(SOAPArray)
|
||||
obj.replace do |ele|
|
||||
Mapping._obj2soap(ele, self)
|
||||
end
|
||||
return obj
|
||||
elsif obj.is_a?(SOAPBasetype)
|
||||
return obj
|
||||
soap = _obj2soap(klass, obj, type)
|
||||
if @allow_original_mapping
|
||||
addextend2soap(soap, obj)
|
||||
end
|
||||
begin
|
||||
ret = @map.obj2soap(klass, obj) ||
|
||||
@default_factory.obj2soap(klass, obj, nil, self)
|
||||
rescue MappingError
|
||||
end
|
||||
return ret if ret
|
||||
|
||||
if @excn_handler_obj2soap
|
||||
ret = @excn_handler_obj2soap.call(obj) { |yield_obj|
|
||||
Mapping._obj2soap(yield_obj, self)
|
||||
}
|
||||
end
|
||||
return ret if ret
|
||||
|
||||
raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.")
|
||||
soap
|
||||
end
|
||||
|
||||
def soap2obj(klass, node)
|
||||
if node.extraattr.key?(RubyTypeName)
|
||||
conv, obj = @rubytype_factory.soap2obj(klass, node, nil, self)
|
||||
return obj if conv
|
||||
else
|
||||
conv, obj = @map.soap2obj(klass, node)
|
||||
return obj if conv
|
||||
conv, obj = @default_factory.soap2obj(klass, node, nil, self)
|
||||
return obj if conv
|
||||
obj = _soap2obj(klass, node)
|
||||
if @allow_original_mapping
|
||||
addextend2obj(obj, node.extraattr[RubyExtendName])
|
||||
addiv2obj(obj, node.extraattr[RubyIVarName])
|
||||
end
|
||||
|
||||
if @excn_handler_soap2obj
|
||||
begin
|
||||
return @excn_handler_soap2obj.call(node) { |yield_node|
|
||||
Mapping._soap2obj(yield_node, self)
|
||||
}
|
||||
rescue Exception
|
||||
end
|
||||
end
|
||||
|
||||
raise MappingError.new("Cannot map #{ node.type.name } to Ruby object.")
|
||||
obj
|
||||
end
|
||||
|
||||
def default_factory=(factory)
|
||||
|
@ -397,6 +366,86 @@ class Registry
|
|||
def find_mapped_obj_class(soap_class)
|
||||
@map.find_mapped_obj_class(soap_class)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _obj2soap(klass, obj, type)
|
||||
ret = nil
|
||||
if obj.is_a?(SOAPStruct) or obj.is_a?(SOAPArray)
|
||||
obj.replace do |ele|
|
||||
Mapping._obj2soap(ele, self)
|
||||
end
|
||||
return obj
|
||||
elsif obj.is_a?(SOAPBasetype)
|
||||
return obj
|
||||
end
|
||||
begin
|
||||
ret = @map.obj2soap(klass, obj) ||
|
||||
@default_factory.obj2soap(klass, obj, nil, self)
|
||||
rescue MappingError
|
||||
end
|
||||
return ret if ret
|
||||
if @excn_handler_obj2soap
|
||||
ret = @excn_handler_obj2soap.call(obj) { |yield_obj|
|
||||
Mapping._obj2soap(yield_obj, self)
|
||||
}
|
||||
end
|
||||
return ret if ret
|
||||
raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.")
|
||||
end
|
||||
|
||||
# Might return nil as a mapping result.
|
||||
def _soap2obj(klass, node)
|
||||
if node.extraattr.key?(RubyTypeName)
|
||||
conv, obj = @rubytype_factory.soap2obj(klass, node, nil, self)
|
||||
return obj if conv
|
||||
else
|
||||
conv, obj = @map.soap2obj(klass, node)
|
||||
return obj if conv
|
||||
conv, obj = @default_factory.soap2obj(klass, node, nil, self)
|
||||
return obj if conv
|
||||
end
|
||||
|
||||
if @excn_handler_soap2obj
|
||||
begin
|
||||
return @excn_handler_soap2obj.call(node) { |yield_node|
|
||||
Mapping._soap2obj(yield_node, self)
|
||||
}
|
||||
rescue Exception
|
||||
end
|
||||
end
|
||||
raise MappingError.new("Cannot map #{ node.type.name } to Ruby object.")
|
||||
end
|
||||
|
||||
def addiv2obj(obj, attr)
|
||||
return unless attr
|
||||
vars = {}
|
||||
attr.__getobj__.each do |name, value|
|
||||
vars[name] = Mapping._soap2obj(value, self)
|
||||
end
|
||||
Mapping.set_instance_vars(obj, vars)
|
||||
end
|
||||
|
||||
def addextend2obj(obj, attr)
|
||||
return unless attr
|
||||
attr.split(/ /).reverse_each do |mstr|
|
||||
obj.extend(Mapping.class_from_name(mstr))
|
||||
end
|
||||
end
|
||||
|
||||
def addextend2soap(node, obj)
|
||||
return if obj.is_a?(Symbol) or obj.is_a?(Fixnum)
|
||||
list = (class << obj; self; end).ancestors - obj.class.ancestors
|
||||
unless list.empty?
|
||||
node.extraattr[RubyExtendName] = list.collect { |c|
|
||||
if c.name.empty?
|
||||
raise TypeError.new("singleton can't be dumped #{ obj }")
|
||||
end
|
||||
c.name
|
||||
}.join(" ")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -22,22 +22,28 @@ module Mapping
|
|||
|
||||
|
||||
class RubytypeFactory < Factory
|
||||
TYPE_STRING = 'String'
|
||||
TYPE_ARRAY = 'Array'
|
||||
TYPE_REGEXP = 'Regexp'
|
||||
TYPE_RANGE = 'Range'
|
||||
TYPE_CLASS = 'Class'
|
||||
TYPE_MODULE = 'Module'
|
||||
TYPE_SYMBOL = 'Symbol'
|
||||
TYPE_STRUCT = 'Struct'
|
||||
TYPE_HASH = 'Map'
|
||||
|
||||
TYPE_STRING = XSD::QName.new(RubyTypeNamespace, 'String')
|
||||
TYPE_TIME = XSD::QName.new(RubyTypeNamespace, 'Time')
|
||||
TYPE_ARRAY = XSD::QName.new(RubyTypeNamespace, 'Array')
|
||||
TYPE_REGEXP = XSD::QName.new(RubyTypeNamespace, 'Regexp')
|
||||
TYPE_RANGE = XSD::QName.new(RubyTypeNamespace, 'Range')
|
||||
TYPE_CLASS = XSD::QName.new(RubyTypeNamespace, 'Class')
|
||||
TYPE_MODULE = XSD::QName.new(RubyTypeNamespace, 'Module')
|
||||
TYPE_SYMBOL = XSD::QName.new(RubyTypeNamespace, 'Symbol')
|
||||
TYPE_STRUCT = XSD::QName.new(RubyTypeNamespace, 'Struct')
|
||||
TYPE_HASH = XSD::QName.new(RubyTypeNamespace, 'Map')
|
||||
|
||||
def initialize(config = {})
|
||||
@config = config
|
||||
@allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
|
||||
@config[:allow_untyped_struct] : true
|
||||
@allow_original_mapping = @config.key?(:allow_original_mapping) ?
|
||||
@config[:allow_original_mapping] : false
|
||||
@string_factory = StringFactory_.new(true)
|
||||
@basetype_factory = BasetypeFactory_.new(true)
|
||||
@datetime_factory = DateTimeFactory_.new(true)
|
||||
@array_factory = ArrayFactory_.new(true)
|
||||
@hash_factory = HashFactory_.new(true)
|
||||
end
|
||||
|
||||
def obj2soap(soap_class, obj, info, map)
|
||||
|
@ -47,48 +53,83 @@ class RubytypeFactory < Factory
|
|||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
unless XSD::Charset.is_ces(obj, $KCODE)
|
||||
return nil
|
||||
end
|
||||
encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding)
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_STRING))
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('string', SOAPString.new(encoded))
|
||||
param = @string_factory.obj2soap(SOAPString, obj, info, map)
|
||||
if obj.class != String
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Time
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map)
|
||||
if obj.class != Time
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Array
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
arytype = Mapping.obj2element(obj)
|
||||
if arytype.name
|
||||
arytype.namespace ||= RubyTypeNamespace
|
||||
else
|
||||
arytype = XSD::AnyTypeName
|
||||
end
|
||||
if obj.instance_variables.empty?
|
||||
param = SOAPArray.new(ValueArrayName, 1, arytype)
|
||||
mark_marshalled_obj(obj, param)
|
||||
obj.each do |var|
|
||||
param.add(Mapping._obj2soap(var, map))
|
||||
end
|
||||
else
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_ARRAY))
|
||||
mark_marshalled_obj(obj, param)
|
||||
ary = SOAPArray.new(ValueArrayName, 1, arytype)
|
||||
obj.each do |var|
|
||||
ary.add(Mapping._obj2soap(var, map))
|
||||
end
|
||||
param.add('array', ary)
|
||||
addiv2soap(param, obj, map)
|
||||
end
|
||||
param = @array_factory.obj2soap(nil, obj, info, map)
|
||||
if obj.class != Array
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
addiv2soapattr(param, obj, map)
|
||||
when NilClass
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = @basetype_factory.obj2soap(SOAPNil, obj, info, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when FalseClass, TrueClass
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Integer
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = @basetype_factory.obj2soap(SOAPInt, obj, info, map)
|
||||
param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map)
|
||||
param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Float
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map)
|
||||
if obj.class != Float
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Hash
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
if obj.respond_to?(:default_proc) && obj.default_proc
|
||||
raise TypeError.new("cannot dump hash with default proc")
|
||||
end
|
||||
param = SOAPStruct.new(TYPE_HASH)
|
||||
mark_marshalled_obj(obj, param)
|
||||
if obj.class != Hash
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
obj.each do |key, value|
|
||||
elem = SOAPStruct.new # Undefined type.
|
||||
elem.add("key", Mapping._obj2soap(key, map))
|
||||
elem.add("value", Mapping._obj2soap(value, map))
|
||||
param.add("item", elem)
|
||||
end
|
||||
param.add('default', Mapping._obj2soap(obj.default, map))
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Regexp
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_REGEXP))
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = SOAPStruct.new(TYPE_REGEXP)
|
||||
mark_marshalled_obj(obj, param)
|
||||
if obj.class != Regexp
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
|
@ -119,9 +160,12 @@ class RubytypeFactory < Factory
|
|||
end
|
||||
end
|
||||
param.add('options', SOAPInt.new(options))
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Range
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_RANGE))
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = SOAPStruct.new(TYPE_RANGE)
|
||||
mark_marshalled_obj(obj, param)
|
||||
if obj.class != Range
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
|
@ -129,57 +173,42 @@ class RubytypeFactory < Factory
|
|||
param.add('begin', Mapping._obj2soap(obj.begin, map))
|
||||
param.add('end', Mapping._obj2soap(obj.end, map))
|
||||
param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?))
|
||||
addiv2soap(param, obj, map)
|
||||
when Hash
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Class
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
if obj.respond_to?(:default_proc) && obj.default_proc
|
||||
raise TypeError.new("cannot dump hash with default proc")
|
||||
end
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_HASH))
|
||||
mark_marshalled_obj(obj, param)
|
||||
if obj.class != Hash
|
||||
param.extraattr[RubyTypeName] = obj.class.name
|
||||
end
|
||||
obj.each do |key, value|
|
||||
elem = SOAPStruct.new # Undefined type.
|
||||
elem.add("key", Mapping._obj2soap(key, map))
|
||||
elem.add("value", Mapping._obj2soap(value, map))
|
||||
param.add("item", elem)
|
||||
end
|
||||
param.add('default', Mapping._obj2soap(obj.default, map))
|
||||
addiv2soap(param, obj, map)
|
||||
when Class
|
||||
if obj.name.empty?
|
||||
raise TypeError.new("Can't dump anonymous class #{ obj }.")
|
||||
end
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_CLASS))
|
||||
param = SOAPStruct.new(TYPE_CLASS)
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('name', SOAPString.new(obj.name))
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Module
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
if obj.name.empty?
|
||||
raise TypeError.new("Can't dump anonymous module #{ obj }.")
|
||||
end
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_MODULE))
|
||||
param = SOAPStruct.new(TYPE_MODULE)
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('name', SOAPString.new(obj.name))
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Symbol
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_SYMBOL))
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = SOAPStruct.new(TYPE_SYMBOL)
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('id', SOAPString.new(obj.id2name))
|
||||
addiv2soap(param, obj, map)
|
||||
when Exception
|
||||
typestr = Mapping.name2elename(obj.class.to_s)
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('message', Mapping._obj2soap(obj.message, map))
|
||||
param.add('backtrace', Mapping._obj2soap(obj.backtrace, map))
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Struct
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_STRUCT))
|
||||
unless @allow_original_mapping
|
||||
return nil
|
||||
end
|
||||
param = SOAPStruct.new(TYPE_STRUCT)
|
||||
mark_marshalled_obj(obj, param)
|
||||
param.add('type', ele_type = SOAPString.new(obj.class.to_s))
|
||||
ele_member = SOAPStruct.new
|
||||
|
@ -188,29 +217,23 @@ class RubytypeFactory < Factory
|
|||
Mapping._obj2soap(obj[member], map))
|
||||
end
|
||||
param.add('member', ele_member)
|
||||
addiv2soap(param, obj, map)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when IO, Binding, Continuation, Data, Dir, File::Stat, MatchData, Method,
|
||||
Proc, Thread, ThreadGroup
|
||||
Proc, Thread, ThreadGroup # from 1.8: Process::Status, UnboundMethod
|
||||
return nil
|
||||
when ::SOAP::Mapping::Object
|
||||
param = SOAPStruct.new(XSD::AnyTypeName)
|
||||
mark_marshalled_obj(obj, param)
|
||||
setiv2soap(param, obj, map) # addiv2soap?
|
||||
else
|
||||
if obj.class.name.empty?
|
||||
raise TypeError.new("Can't dump anonymous class #{ obj }.")
|
||||
end
|
||||
if check_singleton(obj)
|
||||
raise TypeError.new("singleton can't be dumped #{ obj }")
|
||||
end
|
||||
type = Mapping.class2element(obj.class)
|
||||
param = SOAPStruct.new(type)
|
||||
addiv2soapattr(param, obj, map)
|
||||
when Exception
|
||||
typestr = Mapping.name2elename(obj.class.to_s)
|
||||
param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))
|
||||
mark_marshalled_obj(obj, param)
|
||||
if obj.class <= Marshallable
|
||||
setiv2soap(param, obj, map)
|
||||
else
|
||||
setiv2soap(param, obj, map) # Should not be marshalled?
|
||||
end
|
||||
param.add('message', Mapping._obj2soap(obj.message, map))
|
||||
param.add('backtrace', Mapping._obj2soap(obj.backtrace, map))
|
||||
addiv2soapattr(param, obj, map)
|
||||
else
|
||||
param = unknownobj2soap(soap_class, obj, info, map)
|
||||
end
|
||||
param
|
||||
end
|
||||
|
@ -218,26 +241,42 @@ class RubytypeFactory < Factory
|
|||
def soap2obj(obj_class, node, info, map)
|
||||
rubytype = node.extraattr[RubyTypeName]
|
||||
if rubytype or node.type.namespace == RubyTypeNamespace
|
||||
rubytype2obj(node, map, rubytype)
|
||||
rubytype2obj(node, info, map, rubytype)
|
||||
elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName
|
||||
anytype2obj(node, map)
|
||||
anytype2obj(node, info, map)
|
||||
else
|
||||
unknowntype2obj(node, map)
|
||||
unknowntype2obj(node, info, map)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_singleton(obj)
|
||||
unless singleton_methods_true(obj).empty?
|
||||
return true
|
||||
def addiv2soapattr(node, obj, map)
|
||||
return if obj.instance_variables.empty?
|
||||
ivars = SOAPStruct.new # Undefined type.
|
||||
setiv2soap(ivars, obj, map)
|
||||
node.extraattr[RubyIVarName] = ivars
|
||||
end
|
||||
|
||||
def unknownobj2soap(soap_class, obj, info, map)
|
||||
if obj.class.name.empty?
|
||||
raise TypeError.new("Can't dump anonymous class #{ obj }.")
|
||||
end
|
||||
singleton_class = class << obj; self; end
|
||||
if !singleton_class.instance_variables.empty? or
|
||||
!(singleton_class.ancestors - obj.class.ancestors).empty?
|
||||
return true
|
||||
if !singleton_methods_true(obj).empty? or
|
||||
!singleton_class.instance_variables.empty?
|
||||
raise TypeError.new("singleton can't be dumped #{ obj }")
|
||||
end
|
||||
false
|
||||
if !(singleton_class.ancestors - obj.class.ancestors).empty?
|
||||
typestr = Mapping.name2elename(obj.class.to_s)
|
||||
type = XSD::QName.new(RubyTypeNamespace, typestr)
|
||||
else
|
||||
type = Mapping.class2element(obj.class)
|
||||
end
|
||||
param = SOAPStruct.new(type)
|
||||
mark_marshalled_obj(obj, param)
|
||||
setiv2soap(param, obj, map)
|
||||
param
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= '1.8.0'
|
||||
|
@ -250,53 +289,36 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
def rubytype2obj(node, map, rubytype)
|
||||
def rubytype2obj(node, info, map, rubytype)
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : nil
|
||||
obj = nil
|
||||
case node.class
|
||||
case node
|
||||
when SOAPString
|
||||
obj = string2obj(node, map, rubytype)
|
||||
obj.replace(node.data)
|
||||
return @string_factory.soap2obj(klass || String, node, info, map)
|
||||
when SOAPDateTime
|
||||
#return @datetime_factory.soap2obj(klass || Time, node, info, map)
|
||||
klass ||= Time
|
||||
t = node.to_time
|
||||
arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec]
|
||||
obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
return true, obj
|
||||
when SOAPArray
|
||||
obj = array2obj(node, map, rubytype)
|
||||
node.soap2array(obj) do |elem|
|
||||
elem ? Mapping._soap2obj(elem, map) : nil
|
||||
end
|
||||
return true, obj
|
||||
return @array_factory.soap2obj(klass || Array, node, info, map)
|
||||
when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble
|
||||
return @basetype_factory.soap2obj(nil, node, info, map)
|
||||
when SOAPStruct
|
||||
return rubytypestruct2obj(node, info, map, rubytype)
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
case node.type.name
|
||||
when TYPE_STRING
|
||||
obj = string2obj(node, map, rubytype)
|
||||
obj.replace(node['string'].data)
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_ARRAY
|
||||
obj = array2obj(node, map, rubytype)
|
||||
node['array'].soap2array(obj) do |elem|
|
||||
elem ? Mapping._soap2obj(elem, map) : nil
|
||||
end
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_REGEXP
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp
|
||||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
source = node['source'].string
|
||||
options = node['options'].data || 0
|
||||
obj.instance_eval { initialize(source, options) }
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_RANGE
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Range
|
||||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
first = Mapping._soap2obj(node['begin'], map)
|
||||
last = Mapping._soap2obj(node['end'], map)
|
||||
exclude_end = node['exclude_end'].data
|
||||
obj.instance_eval { initialize(first, last, exclude_end) }
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
def rubytypestruct2obj(node, info, map, rubytype)
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : nil
|
||||
obj = nil
|
||||
case node.type
|
||||
when TYPE_HASH
|
||||
unless @allow_original_mapping
|
||||
return false
|
||||
end
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Hash
|
||||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
|
@ -308,16 +330,27 @@ private
|
|||
if node.key?('default')
|
||||
obj.default = Mapping._soap2obj(node['default'], map)
|
||||
end
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_REGEXP
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp
|
||||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
source = node['source'].string
|
||||
options = node['options'].data || 0
|
||||
Regexp.instance_method(:initialize).bind(obj).call(source, options)
|
||||
when TYPE_RANGE
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Range
|
||||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
first = Mapping._soap2obj(node['begin'], map)
|
||||
last = Mapping._soap2obj(node['end'], map)
|
||||
exclude_end = node['exclude_end'].data
|
||||
Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end)
|
||||
when TYPE_CLASS
|
||||
obj = Mapping.class_from_name(node['name'].data)
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_MODULE
|
||||
obj = Mapping.class_from_name(node['name'].data)
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_SYMBOL
|
||||
obj = node['id'].data.intern
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
when TYPE_STRUCT
|
||||
typestr = Mapping.elename2name(node['type'].data)
|
||||
klass = Mapping.class_from_name(typestr)
|
||||
|
@ -333,40 +366,15 @@ private
|
|||
obj = create_empty_object(klass)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
node['member'].each do |name, value|
|
||||
obj[Mapping.elename2name(name)] =
|
||||
Mapping._soap2obj(value, map)
|
||||
obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
|
||||
end
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
else
|
||||
conv, obj = exception2obj(node, map)
|
||||
unless conv
|
||||
return false
|
||||
end
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
return unknowntype2obj(node, info, map)
|
||||
end
|
||||
return true, obj
|
||||
end
|
||||
|
||||
def exception2obj(node, map)
|
||||
typestr = Mapping.elename2name(node.type.name)
|
||||
klass = Mapping.class_from_name(typestr)
|
||||
if klass.nil?
|
||||
return false
|
||||
end
|
||||
unless klass <= Exception
|
||||
return false
|
||||
end
|
||||
message = Mapping._soap2obj(node['message'], map)
|
||||
backtrace = Mapping._soap2obj(node['backtrace'], map)
|
||||
obj = create_empty_object(klass)
|
||||
obj = obj.exception(message)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
obj.set_backtrace(backtrace)
|
||||
setiv2obj(obj, node['ivars'], map)
|
||||
return true, obj
|
||||
end
|
||||
|
||||
def anytype2obj(node, map)
|
||||
def anytype2obj(node, info, map)
|
||||
case node
|
||||
when SOAPBasetype
|
||||
return true, node.data
|
||||
|
@ -383,22 +391,24 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
def unknowntype2obj(node, map)
|
||||
def unknowntype2obj(node, info, map)
|
||||
if node.is_a?(SOAPStruct)
|
||||
obj = struct2obj(node, map)
|
||||
obj = unknownstruct2obj(node, info, map)
|
||||
return true, obj if obj
|
||||
if !@allow_untyped_struct
|
||||
return false
|
||||
end
|
||||
return anytype2obj(node, map)
|
||||
return anytype2obj(node, info, map)
|
||||
else
|
||||
# Basetype which is not defined...
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def struct2obj(node, map)
|
||||
obj = nil
|
||||
def unknownstruct2obj(node, info, map)
|
||||
unless node.type.name
|
||||
return nil
|
||||
end
|
||||
typestr = Mapping.elename2name(node.type.name)
|
||||
klass = Mapping.class_from_name(typestr)
|
||||
if klass.nil?
|
||||
|
@ -407,6 +417,9 @@ private
|
|||
if klass.nil?
|
||||
return nil
|
||||
end
|
||||
if klass <= ::Exception
|
||||
return exception2obj(klass, node, map)
|
||||
end
|
||||
klass_type = Mapping.class2qname(klass)
|
||||
return nil unless node.type.match(klass_type)
|
||||
obj = create_empty_object(klass)
|
||||
|
@ -415,6 +428,16 @@ private
|
|||
obj
|
||||
end
|
||||
|
||||
def exception2obj(klass, node, map)
|
||||
message = Mapping._soap2obj(node['message'], map)
|
||||
backtrace = Mapping._soap2obj(node['backtrace'], map)
|
||||
obj = create_empty_object(klass)
|
||||
obj = obj.exception(message)
|
||||
mark_unmarshalled_obj(node, obj)
|
||||
obj.set_backtrace(backtrace)
|
||||
obj
|
||||
end
|
||||
|
||||
# Only creates empty array. Do String#replace it with real string.
|
||||
def array2obj(node, map, rubytype)
|
||||
klass = rubytype ? Mapping.class_from_name(rubytype) : Array
|
||||
|
|
|
@ -58,10 +58,10 @@ module Marshal
|
|||
|
||||
def unmarshal(stream, mapping_registry = MarshalMappingRegistry)
|
||||
header, body = SOAP::Processor.unmarshal(stream)
|
||||
#Mapping.soap2obj(body.root_node, mapping_registry)
|
||||
Mapping.soap2obj(body.root_node, mapping_registry)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ class StandaloneServer < Logger::Application
|
|||
|
||||
def initialize(app_name, namespace, host = "0.0.0.0", port = 8080)
|
||||
super(app_name)
|
||||
self.level = Logger::Severity::INFO
|
||||
@namespace = namespace
|
||||
@host = host
|
||||
@port = port
|
||||
|
|
|
@ -223,7 +223,8 @@ class WSDLDriver
|
|||
@endpoint_url = nil
|
||||
@wiredump_dev = nil
|
||||
@wiredump_file_base = nil
|
||||
@httpproxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
||||
name = 'http_proxy'
|
||||
@httpproxy = ENV[name] || ENV[name.upcase]
|
||||
|
||||
@wsdl_elements = @wsdl.collect_elements
|
||||
@wsdl_types = @wsdl.collect_complextypes
|
||||
|
|
|
@ -485,7 +485,7 @@ module XSDDateTimeImpl
|
|||
|
||||
def to_time
|
||||
begin
|
||||
if @data.of * SecInDay == Time.now.utc_offset
|
||||
if @data.offset * SecInDay == Time.now.utc_offset
|
||||
d = @data
|
||||
usec = (d.sec_fraction * SecInDay * 1000000).to_f
|
||||
Time.local(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec)
|
||||
|
@ -643,7 +643,7 @@ private
|
|||
s = format('%02d:%02d:%02d', @data.hour, @data.min, @data.sec)
|
||||
if @data.sec_fraction.nonzero?
|
||||
fr = @data.sec_fraction * SecInDay
|
||||
shiftsize = fr.denominator.to_s.size
|
||||
shiftsize = fr.denominator.to_s.size + 1
|
||||
fr_s = (fr * (10 ** shiftsize)).to_i.to_s
|
||||
s << '.' << '0' * (shiftsize - fr_s.size) << fr_s.sub(/0+$/, '')
|
||||
end
|
||||
|
|
|
@ -60,6 +60,10 @@ class NamedElements
|
|||
@elements << rhs
|
||||
self
|
||||
end
|
||||
|
||||
def delete(rhs)
|
||||
@elements.delete(rhs)
|
||||
end
|
||||
|
||||
def +(rhs)
|
||||
o = NamedElements.new
|
||||
|
|
|
@ -39,8 +39,7 @@ STDERR.reopen(File.open(errout, "w"))
|
|||
STDERR.sync = true
|
||||
Dir.chdir(#{q(DIR)})
|
||||
cmd = "\\"#{ruby}\\" \\"endblockwarn.rb\\""
|
||||
exec(cmd)
|
||||
exit!("must not reach here")
|
||||
system(cmd)
|
||||
EOF
|
||||
launcher.close
|
||||
launcherpath = launcher.path
|
||||
|
|
|
@ -252,6 +252,19 @@ module MarshalTestLib
|
|||
marshal_equal(o) {|obj| class << obj; ancestors end}
|
||||
end
|
||||
|
||||
def test_extend_string
|
||||
o = String.new
|
||||
o.extend Mod1
|
||||
marshal_equal(o) { |obj| obj.kind_of? Mod1 }
|
||||
o = String.new
|
||||
o.extend Module.new
|
||||
assert_raises(TypeError) { marshaltest(o) }
|
||||
o = String.new
|
||||
o.extend Mod1
|
||||
o.extend Mod2
|
||||
marshal_equal(o) {|obj| class << obj; ancestors end}
|
||||
end
|
||||
|
||||
def test_anonymous
|
||||
c = Class.new
|
||||
assert_raises(TypeError) { marshaltest(c) }
|
||||
|
|
|
@ -7,6 +7,10 @@ module Marshal
|
|||
|
||||
|
||||
module MarshalTestLib
|
||||
|
||||
module Mod1; end
|
||||
module Mod2; end
|
||||
|
||||
def encode(o)
|
||||
SOAPMarshal.dump(o)
|
||||
end
|
||||
|
@ -23,19 +27,20 @@ module MarshalTestLib
|
|||
o2
|
||||
end
|
||||
|
||||
def marshal_equal(o1)
|
||||
def marshal_equal(o1, msg = nil)
|
||||
msg = msg ? msg + "(#{ caller[0] })" : caller[0]
|
||||
o2 = marshaltest(o1)
|
||||
assert_equal(o1.class, o2.class, caller[0])
|
||||
assert_equal(o1.class, o2.class, msg)
|
||||
iv1 = o1.instance_variables.sort
|
||||
iv2 = o2.instance_variables.sort
|
||||
assert_equal(iv1, iv2)
|
||||
val1 = iv1.map {|var| o1.instance_eval {eval var}}
|
||||
val2 = iv1.map {|var| o2.instance_eval {eval var}}
|
||||
assert_equal(val1, val2, caller[0])
|
||||
assert_equal(val1, val2, msg)
|
||||
if block_given?
|
||||
assert_equal(yield(o1), yield(o2), caller[0])
|
||||
assert_equal(yield(o1), yield(o2), msg)
|
||||
else
|
||||
assert_equal(o1, o2, caller[0])
|
||||
assert_equal(o1, o2, msg)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -50,6 +55,30 @@ module MarshalTestLib
|
|||
marshal_equal(MyObject.new(2)) {|o| o.v}
|
||||
end
|
||||
|
||||
def test_object_extend
|
||||
o1 = Object.new
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
def test_object_subclass_extend
|
||||
o1 = MyObject.new(2)
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
class MyArray < Array; def initialize(v, *args) super args; @v = v; end end
|
||||
def test_array
|
||||
marshal_equal([1,2,3])
|
||||
|
@ -59,6 +88,12 @@ module MarshalTestLib
|
|||
marshal_equal(MyArray.new(0, 1,2,3))
|
||||
end
|
||||
|
||||
def test_array_ivar
|
||||
o1 = Array.new
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
class MyException < Exception; def initialize(v, *args) super(*args); @v = v; end; attr_reader :v; end
|
||||
def test_exception
|
||||
marshal_equal(Exception.new('foo')) {|o| o.message}
|
||||
|
@ -94,6 +129,36 @@ module MarshalTestLib
|
|||
assert_raises(TypeError) { marshaltest(h) }
|
||||
end
|
||||
|
||||
def test_hash_ivar
|
||||
o1 = Hash.new
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
def test_hash_extend
|
||||
o1 = Hash.new
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
def test_hash_subclass_extend
|
||||
o1 = MyHash.new(2)
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
def test_bignum
|
||||
marshal_equal(-0x4000_0000_0000_0001)
|
||||
marshal_equal(-0x4000_0001)
|
||||
|
@ -122,6 +187,24 @@ module MarshalTestLib
|
|||
marshal_equal(-0.0) {|o| 1.0/o}
|
||||
end
|
||||
|
||||
def test_float_ivar
|
||||
o1 = 1.23
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
def test_float_extend
|
||||
o1 = 0.0/0.0
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
class MyRange < Range; def initialize(v, *args) super(*args); @v = v; end end
|
||||
def test_range
|
||||
marshal_equal(1..2)
|
||||
|
@ -129,19 +212,17 @@ module MarshalTestLib
|
|||
end
|
||||
|
||||
def test_range_subclass
|
||||
STDERR.puts("test_range_subclass: known bug should be fixed.")
|
||||
return
|
||||
marshal_equal(MyRange.new(4,5,8, false))
|
||||
end
|
||||
|
||||
class MyRegexp < Regexp; def initialize(v, *args) super(*args); @v = v; end end
|
||||
def test_regexp
|
||||
marshal_equal(/a/)
|
||||
marshal_equal(/A/i)
|
||||
marshal_equal(/A/mx)
|
||||
end
|
||||
|
||||
def test_regexp_subclass
|
||||
STDERR.puts("test_regexp_subclass: known bug should be fixed.")
|
||||
return
|
||||
marshal_equal(MyRegexp.new(10, "a"))
|
||||
end
|
||||
|
||||
|
@ -150,10 +231,34 @@ module MarshalTestLib
|
|||
marshal_equal("abc")
|
||||
end
|
||||
|
||||
def test_string_ivar
|
||||
o1 = String.new
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
def test_string_subclass
|
||||
marshal_equal(MyString.new(10, "a"))
|
||||
end
|
||||
|
||||
def test_string_subclass_cycle
|
||||
str = MyString.new(10, "b")
|
||||
str.instance_eval { @v = str }
|
||||
marshal_equal(str) { |o|
|
||||
assert_equal(o.__id__, o.instance_eval { @v }.__id__)
|
||||
o.instance_eval { @v }
|
||||
}
|
||||
end
|
||||
|
||||
def test_string_subclass_extend
|
||||
o = "abc"
|
||||
o.extend(Mod1)
|
||||
str = MyString.new(o, "c")
|
||||
marshal_equal(str) { |o|
|
||||
assert(o.instance_eval { @v }).kind_of?(Mod1)
|
||||
}
|
||||
end
|
||||
|
||||
MyStruct = Struct.new("MyStruct", :a, :b)
|
||||
class MySubStruct < MyStruct; def initialize(v, *args) super(*args); @v = v; end end
|
||||
def test_struct
|
||||
|
@ -164,6 +269,24 @@ module MarshalTestLib
|
|||
marshal_equal(MySubStruct.new(10,1,2))
|
||||
end
|
||||
|
||||
def test_struct_ivar
|
||||
o1 = MyStruct.new
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
def test_struct_subclass_extend
|
||||
o1 = MyStruct.new
|
||||
o1.extend(Mod1)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
o1.extend(Mod2)
|
||||
marshal_equal(o1) { |o|
|
||||
(class << self; self; end).ancestors
|
||||
}
|
||||
end
|
||||
|
||||
def test_symbol
|
||||
marshal_equal(:a)
|
||||
marshal_equal(:a?)
|
||||
|
@ -201,16 +324,21 @@ module MarshalTestLib
|
|||
def test_time
|
||||
# once there was a bug caused by usec overflow. try a little harder.
|
||||
10.times do
|
||||
marshal_equal(Time.now)
|
||||
t = Time.now
|
||||
marshal_equal(t, t.usec.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def test_time_subclass
|
||||
STDERR.puts("test_time_subclass: known bug should be fixed.")
|
||||
return
|
||||
marshal_equal(MyTime.new(10))
|
||||
end
|
||||
|
||||
def test_time_ivar
|
||||
o1 = Time.now
|
||||
o1.instance_eval { @iv = 1 }
|
||||
marshal_equal(o1) {|o| o.instance_eval { @iv }}
|
||||
end
|
||||
|
||||
def test_true
|
||||
marshal_equal(true)
|
||||
end
|
||||
|
@ -250,15 +378,7 @@ module MarshalTestLib
|
|||
assert_raises(TypeError) { marshaltest(ENV) }
|
||||
end
|
||||
|
||||
module Mod1 end
|
||||
module Mod2 end
|
||||
def test_extend
|
||||
o = Object.new
|
||||
o.extend Module.new
|
||||
assert_raises(TypeError) { marshaltest(o) }
|
||||
|
||||
STDERR.puts("test_range_subclass: known bug should be fixed.")
|
||||
return
|
||||
o = Object.new
|
||||
o.extend Mod1
|
||||
marshal_equal(o) { |obj| obj.kind_of? Mod1 }
|
||||
|
@ -266,6 +386,22 @@ module MarshalTestLib
|
|||
o.extend Mod1
|
||||
o.extend Mod2
|
||||
marshal_equal(o) {|obj| class << obj; ancestors end}
|
||||
o = Object.new
|
||||
o.extend Module.new
|
||||
assert_raises(TypeError) { marshaltest(o) }
|
||||
end
|
||||
|
||||
def test_extend_string
|
||||
o = String.new
|
||||
o.extend Mod1
|
||||
marshal_equal(o) { |obj| obj.kind_of? Mod1 }
|
||||
o = String.new
|
||||
o.extend Mod1
|
||||
o.extend Mod2
|
||||
marshal_equal(o) {|obj| class << obj; ancestors end}
|
||||
o = String.new
|
||||
o.extend Module.new
|
||||
assert_raises(TypeError) { marshaltest(o) }
|
||||
end
|
||||
|
||||
def test_anonymous
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
xmlns:i2="http://www.winfessor.com/SoapBoxWebService/ExceptionDataSet.xsd"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:i0="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd"
|
||||
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
|
||||
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
|
||||
targetNamespace="http://www.winfessor.com/SoapBoxWebService/SoapBoxWebService"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/">
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:mstns="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd" id="MessageDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element msdata:IsDataSet="true" name="MessageDataSet">
|
||||
<xs:schema
|
||||
xmlns:mstns="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd"
|
||||
xmlns="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd"
|
||||
attributeFormDefault="qualified"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://www.winfessor.com/SoapBoxWebService/MessageDataSet.xsd"
|
||||
id="MessageDataSet"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="MessageDataSet">
|
||||
<xs:complexType>
|
||||
<xs:choice maxOccurs="unbounded" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
</xs:schema>
|
||||
|
|
Loading…
Reference in a new issue