diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-15 14:33:53 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-15 14:33:53 +0000 |
commit | 29c5ab0b77feaf975d83ab340d7194c9c4dffc9d (patch) | |
tree | 6ac40e3bffcf1735c8b7efc0f412bccc15befa6a /lib/soap/generator.rb | |
parent | 071c45df939e962e8cd6ecc51bd402b6a7cc91f6 (diff) | |
download | ruby-29c5ab0b77feaf975d83ab340d7194c9c4dffc9d.tar.gz |
* 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: svn+ssh://ci.ruby-lang.org/ruby/trunk@9169 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/soap/generator.rb')
-rw-r--r-- | lib/soap/generator.rb | 107 |
1 files changed, 80 insertions, 27 deletions
diff --git a/lib/soap/generator.rb b/lib/soap/generator.rb index a44d1468b1..f179555e1d 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' |