diff options
Diffstat (limited to 'lib/soap')
36 files changed, 0 insertions, 8072 deletions
diff --git a/lib/soap/attachment.rb b/lib/soap/attachment.rb deleted file mode 100644 index 1a59b14018..0000000000 --- a/lib/soap/attachment.rb +++ /dev/null @@ -1,107 +0,0 @@ -# soap/attachment.rb: SOAP4R - SwA implementation. -# Copyright (C) 2002, 2003 Jamie Herre and 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' - - -module SOAP - - -class SOAPAttachment < SOAPExternalReference - attr_reader :data - - def initialize(value) - super() - @data = value - end - -private - - def external_contentid - @data.contentid - end -end - - -class Attachment - attr_reader :io - attr_accessor :contenttype - - def initialize(string_or_readable = nil) - @string_or_readable = string_or_readable - @contenttype = "application/octet-stream" - @contentid = nil - end - - def contentid - @contentid ||= Attachment.contentid(self) - end - - def contentid=(contentid) - @contentid = contentid - end - - def mime_contentid - '<' + contentid + '>' - end - - def content - if @content == nil and @string_or_readable != nil - @content = @string_or_readable.respond_to?(:read) ? - @string_or_readable.read : @string_or_readable - end - @content - end - - def to_s - content - end - - def write(out) - out.write(content) - end - - def save(filename) - File.open(filename, "wb") do |f| - write(f) - end - end - - def self.contentid(obj) - # this needs to be fixed - [obj.__id__.to_s, Process.pid.to_s].join('.') - end - - def self.mime_contentid(obj) - '<' + contentid(obj) + '>' - end -end - - -module Mapping - class AttachmentFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - soap_obj = soap_class.new(obj) - mark_marshalled_obj(obj, soap_obj) - soap_obj - end - - def soap2obj(obj_class, node, info, map) - obj = node.data - mark_unmarshalled_obj(node, obj) - return true, obj - end - end - - DefaultRegistry.add(::SOAP::Attachment, ::SOAP::SOAPAttachment, - AttachmentFactory.new, nil) -end - - -end diff --git a/lib/soap/baseData.rb b/lib/soap/baseData.rb deleted file mode 100644 index 49c1d2d1f4..0000000000 --- a/lib/soap/baseData.rb +++ /dev/null @@ -1,815 +0,0 @@ -# soap/baseData.rb: SOAP4R - Base type library -# Copyright (C) 2000, 2001, 2003, 2004 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 'xsd/datatypes' -require 'soap/soap' - - -module SOAP - - -### -## Mix-in module for SOAP base type classes. -# -module SOAPModuleUtils - include SOAP - -public - - def decode(elename) - d = self.new - d.elename = elename - d - end -end - - -### -## for SOAP type(base and compound) -# -module SOAPType - attr_accessor :encodingstyle - attr_accessor :elename - attr_accessor :id - attr_reader :precedents - attr_accessor :root - attr_accessor :parent - attr_accessor :position - attr_reader :extraattr - attr_accessor :definedtype - - def initialize(*arg) - super(*arg) - @encodingstyle = nil - @elename = XSD::QName.new - @id = nil - @precedents = [] - @root = false - @parent = nil - @position = nil - @definedtype = nil - @extraattr = {} - end - - def rootnode - node = self - while node = node.parent - break if SOAPEnvelope === node - end - node - end -end - - -### -## for SOAP base type -# -module SOAPBasetype - include SOAPType - include SOAP - - def initialize(*arg) - super(*arg) - end -end - - -### -## for SOAP compound type -# -module SOAPCompoundtype - include SOAPType - include SOAP - - def initialize(*arg) - super(*arg) - end -end - - -### -## Convenience datatypes. -# -class SOAPReference < XSD::NSDBase - include SOAPBasetype - extend SOAPModuleUtils - -public - - attr_accessor :refid - - # Override the definition in SOAPBasetype. - def initialize(obj = nil) - super() - @type = XSD::QName.new - @refid = nil - @obj = nil - __setobj__(obj) if obj - end - - def __getobj__ - @obj - end - - def __setobj__(obj) - @obj = obj - @refid = @obj.id || SOAPReference.create_refid(@obj) - @obj.id = @refid unless @obj.id - @obj.precedents << self - # Copies NSDBase information - @obj.type = @type unless @obj.type - end - - # Why don't I use delegate.rb? - # -> delegate requires target object type at initialize time. - # Why don't I use forwardable.rb? - # -> forwardable requires a list of forwarding methods. - # - # ToDo: Maybe I should use forwardable.rb and give it a methods list like - # delegate.rb... - # - def method_missing(msg_id, *params) - if @obj - @obj.send(msg_id, *params) - else - nil - end - end - - def refidstr - '#' + @refid - end - - def self.create_refid(obj) - 'id' + obj.__id__.to_s - end - - def self.decode(elename, refidstr) - if /\A#(.*)\z/ =~ refidstr - refid = $1 - elsif /\Acid:(.*)\z/ =~ refidstr - refid = $1 - else - raise ArgumentError.new("illegal refid #{refidstr}") - end - d = super(elename) - d.refid = refid - d - end -end - - -class SOAPExternalReference < XSD::NSDBase - include SOAPBasetype - extend SOAPModuleUtils - - def initialize - super() - @type = XSD::QName.new - end - - def referred - rootnode.external_content[external_contentid] = self - end - - def refidstr - 'cid:' + external_contentid - end - -private - - def external_contentid - raise NotImplementedError.new - end -end - - -class SOAPNil < XSD::XSDNil - include SOAPBasetype - extend SOAPModuleUtils -end - -# SOAPRawString is for sending raw string. In contrast to SOAPString, -# SOAP4R does not do XML encoding and does not convert its CES. The string it -# holds is embedded to XML instance directly as a 'xsd:string'. -class SOAPRawString < XSD::XSDString - include SOAPBasetype - extend SOAPModuleUtils -end - - -### -## Basic datatypes. -# -class SOAPAnySimpleType < XSD::XSDAnySimpleType - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPString < XSD::XSDString - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPBoolean < XSD::XSDBoolean - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPDecimal < XSD::XSDDecimal - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPFloat < XSD::XSDFloat - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPDouble < XSD::XSDDouble - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPDuration < XSD::XSDDuration - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPDateTime < XSD::XSDDateTime - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPTime < XSD::XSDTime - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPDate < XSD::XSDDate - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPGYearMonth < XSD::XSDGYearMonth - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPGYear < XSD::XSDGYear - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPGMonthDay < XSD::XSDGMonthDay - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPGDay < XSD::XSDGDay - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPGMonth < XSD::XSDGMonth - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPHexBinary < XSD::XSDHexBinary - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPBase64 < XSD::XSDBase64Binary - include SOAPBasetype - extend SOAPModuleUtils - Type = QName.new(EncodingNamespace, Base64Literal) - -public - # Override the definition in SOAPBasetype. - def initialize(value = nil) - super(value) - @type = Type - end - - def as_xsd - @type = XSD::XSDBase64Binary::Type - end -end - -class SOAPAnyURI < XSD::XSDAnyURI - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPQName < XSD::XSDQName - include SOAPBasetype - extend SOAPModuleUtils -end - - -class SOAPInteger < XSD::XSDInteger - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPLong < XSD::XSDLong - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPInt < XSD::XSDInt - include SOAPBasetype - extend SOAPModuleUtils -end - -class SOAPShort < XSD::XSDShort - include SOAPBasetype - extend SOAPModuleUtils -end - - -### -## Compound datatypes. -# -class SOAPStruct < XSD::NSDBase - include SOAPCompoundtype - include Enumerable - -public - - def initialize(type = nil) - super() - @type = type || XSD::QName.new - @array = [] - @data = [] - end - - def to_s() - str = '' - self.each do |key, data| - str << "#{ key }: #{ data }\n" - end - str - end - - def add(name, value) - add_member(name, value) - end - - def [](idx) - if idx.is_a?(Range) - @data[idx] - elsif idx.is_a?(Integer) - if (idx > @array.size) - raise ArrayIndexOutOfBoundsError.new('In ' << @type.name) - end - @data[idx] - else - if @array.include?(idx) - @data[@array.index(idx)] - else - nil - end - end - end - - def []=(idx, data) - if @array.include?(idx) - data.parent = self if data.respond_to?(:parent=) - @data[@array.index(idx)] = data - else - add(idx, data) - end - end - - def key?(name) - @array.include?(name) - end - - def members - @array - end - - def each - for i in 0..(@array.length - 1) - yield(@array[i], @data[i]) - end - end - - def replace - members.each do |member| - self[member] = yield(self[member]) - end - end - - def self.decode(elename, type) - s = SOAPStruct.new(type) - s.elename = elename - s - end - -private - - def add_member(name, value = nil) - value = SOAPNil.new() if value.nil? - @array.push(name) - value.elename = value.elename.dup_name(name) - @data.push(value) - value.parent = self if value.respond_to?(:parent=) - value - end -end - - -# SOAPElement is not typed so it is not derived from NSDBase. -class SOAPElement - include Enumerable - - attr_accessor :encodingstyle - - attr_accessor :elename - attr_accessor :id - attr_reader :precedents - attr_accessor :root - attr_accessor :parent - attr_accessor :position - attr_accessor :extraattr - - attr_accessor :qualified - - def initialize(elename, text = nil) - if !elename.is_a?(XSD::QName) - elename = XSD::QName.new(nil, elename) - end - @encodingstyle = LiteralNamespace - @elename = elename - @id = nil - @precedents = [] - @root = false - @parent = nil - @position = nil - @extraattr = {} - - @qualified = false - - @array = [] - @data = [] - @text = text - end - - # Text interface. - attr_accessor :text - - # Element interfaces. - def add(value) - add_member(value.elename.name, value) - end - - def [](idx) - if @array.include?(idx) - @data[@array.index(idx)] - else - nil - end - end - - def []=(idx, data) - if @array.include?(idx) - data.parent = self if data.respond_to?(:parent=) - @data[@array.index(idx)] = data - else - add(data) - end - end - - def key?(name) - @array.include?(name) - end - - def members - @array - end - - def to_obj - if members.empty? - @text - else - hash = {} - each do |k, v| - hash[k] = v.is_a?(SOAPElement) ? v.to_obj : v.to_s - end - hash - end - end - - def each - for i in 0..(@array.length - 1) - yield(@array[i], @data[i]) - end - end - - def self.decode(elename) - o = SOAPElement.new(elename) - o - end - - def self.from_obj(hash_or_string) - o = SOAPElement.new(nil) - if hash_or_string.is_a?(Hash) - hash_or_string.each do |k, v| - child = self.from_obj(v) - child.elename = k.is_a?(XSD::QName) ? k : XSD::QName.new(nil, k.to_s) - o.add(child) - end - else - o.text = hash_or_string - end - o - end - -private - - def add_member(name, value) - add_accessor(name) - @array.push(name) - @data.push(value) - value.parent = self if value.respond_to?(:parent=) - value - end - - def add_accessor(name) - methodname = name - if self.respond_to?(methodname) - methodname = safe_accessor_name(methodname) - end - begin - instance_eval <<-EOS - def #{ methodname }() - @data[@array.index('#{ name }')] - end - - def #{ methodname }=(value) - @data[@array.index('#{ name }')] = value - end - EOS - rescue SyntaxError - methodname = safe_accessor_name(methodname) - retry - end - end - - def safe_accessor_name(name) - "var_" << name.gsub(/[^a-zA-Z0-9_]/, '') - end -end - - -class SOAPArray < XSD::NSDBase - include SOAPCompoundtype - include Enumerable - -public - - attr_accessor :sparse - - attr_reader :offset, :rank - attr_accessor :size, :size_fixed - attr_reader :arytype - - def initialize(type = nil, rank = 1, arytype = nil) - super() - @type = type || XSD::QName.new - @rank = rank - @data = Array.new - @sparse = false - @offset = Array.new(rank, 0) - @size = Array.new(rank, 0) - @size_fixed = false - @position = nil - @arytype = arytype - end - - def offset=(var) - @offset = var - @sparse = true - end - - def add(value) - self[*(@offset)] = value - end - - def [](*idxary) - if idxary.size != @rank - raise ArgumentError.new("Given #{ idxary.size } params does not match rank: #{ @rank }") - end - - retrieve(idxary) - end - - def []=(*idxary) - value = idxary.slice!(-1) - - if idxary.size != @rank - raise ArgumentError.new("Given #{ idxary.size } params(#{ idxary }) does not match rank: #{ @rank }") - end - - for i in 0..(idxary.size - 1) - if idxary[i] + 1 > @size[i] - @size[i] = idxary[i] + 1 - end - end - - data = retrieve(idxary[0, idxary.size - 1]) - data[idxary.last] = value - - if value.is_a?(SOAPType) - value.elename = value.elename.dup_name('item') - - # 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 - end - - @offset = idxary - value.parent = self if value.respond_to?(:parent=) - offsetnext - end - - def each - @data.each do |data| - yield(data) - end - end - - def to_a - @data.dup - end - - def replace - @data = deep_map(@data) do |ele| - yield(ele) - end - end - - def deep_map(ary, &block) - ary.collect do |ele| - if ele.is_a?(Array) - deep_map(ele, &block) - else - new_obj = block.call(ele) - new_obj.elename = new_obj.elename.dup_name('item') - new_obj - end - end - end - - def include?(var) - traverse_data(@data) do |v, *rank| - if v.is_a?(SOAPBasetype) && v.data == var - return true - end - end - false - end - - def traverse - traverse_data(@data) do |v, *rank| - unless @sparse - yield(v) - else - yield(v, *rank) if v && !v.is_a?(SOAPNil) - end - end - end - - def soap2array(ary) - traverse_data(@data) do |v, *position| - iteary = ary - for rank in 1..(position.size - 1) - idx = position[rank - 1] - if iteary[idx].nil? - iteary = iteary[idx] = Array.new - else - iteary = iteary[idx] - end - end - if block_given? - iteary[position.last] = yield(v) - else - iteary[position.last] = v - end - end - end - - def position - @position - end - -private - - def retrieve(idxary) - data = @data - for rank in 1..(idxary.size) - idx = idxary[rank - 1] - if data[idx].nil? - data = data[idx] = Array.new - else - data = data[idx] - end - end - data - end - - def traverse_data(data, rank = 1) - for idx in 0..(ranksize(rank) - 1) - if rank < @rank - traverse_data(data[idx], rank + 1) do |*v| - v[1, 0] = idx - yield(*v) - end - else - yield(data[idx], idx) - end - end - end - - def ranksize(rank) - @size[rank - 1] - end - - def offsetnext - move = false - idx = @offset.size - 1 - while !move && idx >= 0 - @offset[idx] += 1 - if @size_fixed - if @offset[idx] < @size[idx] - move = true - else - @offset[idx] = 0 - idx -= 1 - end - else - move = true - end - end - end - - # Module function - -public - - def self.decode(elename, type, arytype) - typestr, nofary = parse_type(arytype.name) - rank = nofary.count(',') + 1 - plain_arytype = XSD::QName.new(arytype.namespace, typestr) - o = SOAPArray.new(type, rank, plain_arytype) - size = [] - nofary.split(',').each do |s| - if s.empty? - size.clear - break - else - size << s.to_i - end - end - unless size.empty? - o.size = size - o.size_fixed = true - end - o.elename = elename - o - end - -private - - def self.create_arytype(typename, rank) - "#{ typename }[" << ',' * (rank - 1) << ']' - end - - TypeParseRegexp = Regexp.new('^(.+)\[([\d,]*)\]$') - - def self.parse_type(string) - TypeParseRegexp =~ string - return $1, $2 - end -end - - -require 'soap/mapping/typeMap' - - -end diff --git a/lib/soap/element.rb b/lib/soap/element.rb deleted file mode 100644 index 1494cd61dd..0000000000 --- a/lib/soap/element.rb +++ /dev/null @@ -1,251 +0,0 @@ -# SOAP4R - SOAP elements library -# Copyright (C) 2000, 2001, 2003, 2004 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 'xsd/qname' -require 'soap/baseData' - - -module SOAP - - -### -## SOAP elements -# -module SOAPEnvelopeElement; end - -class SOAPFault < SOAPStruct - include SOAPEnvelopeElement - include SOAPCompoundtype - -public - - def faultcode - self['faultcode'] - end - - def faultstring - self['faultstring'] - end - - def faultactor - self['faultactor'] - end - - def detail - self['detail'] - end - - def faultcode=(rhs) - self['faultcode'] = rhs - end - - def faultstring=(rhs) - self['faultstring'] = rhs - end - - def faultactor=(rhs) - self['faultactor'] = rhs - end - - def detail=(rhs) - self['detail'] = rhs - end - - def initialize(faultcode = nil, faultstring = nil, faultactor = nil, detail = nil) - super(EleFaultName) - @elename = EleFaultName - @encodingstyle = EncodingNamespace - - if faultcode - self.faultcode = faultcode - self.faultstring = faultstring - self.faultactor = faultactor - self.detail = detail - self.faultcode.elename = EleFaultCodeName if self.faultcode - self.faultstring.elename = EleFaultStringName if self.faultstring - self.faultactor.elename = EleFaultActorName if self.faultactor - self.detail.elename = EleFaultDetailName if self.detail - end - faultcode.parent = self if faultcode - faultstring.parent = self if faultstring - faultactor.parent = self if faultactor - detail.parent = self if detail - end - - 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) - generator.encode_tag(name, attrs) - yield(self.faultcode, false) - yield(self.faultstring, false) - yield(self.faultactor, false) - yield(self.detail, false) if self.detail - generator.encode_tag_end(name, true) - end -end - - -class SOAPBody < SOAPStruct - include SOAPEnvelopeElement - - def initialize(data = nil, is_fault = false) - super(nil) - @elename = EleBodyName - @encodingstyle = nil - add(data.elename.name, data) if data - @is_fault = is_fault - end - - def encode(generator, ns, attrs = {}) - name = ns.name(@elename) - generator.encode_tag(name, attrs) - if @is_fault - yield(@data, true) - else - @data.each do |data| - yield(data, true) - end - end - generator.encode_tag_end(name, true) - end - - def root_node - @data.each do |node| - if node.root == 1 - return node - end - end - # No specified root... - @data.each do |node| - if node.root != 0 - return node - end - end - - raise SOAPParser::FormatDecodeError.new('No root element.') - end -end - - -class SOAPHeaderItem < XSD::NSDBase - include SOAPEnvelopeElement - include SOAPCompoundtype - -public - - attr_accessor :element - attr_accessor :mustunderstand - attr_accessor :encodingstyle - - def initialize(element, mustunderstand = true, encodingstyle = nil) - super() - @type = nil - @element = element - @mustunderstand = mustunderstand - @encodingstyle = encodingstyle - element.parent = self if element - end - - def encode(generator, ns, attrs = {}) - attrs.each do |key, value| - @element.extraattr[key] = value - end - @element.extraattr[ns.name(AttrMustUnderstandName)] = - (@mustunderstand ? '1' : '0') - if @encodingstyle - @element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle - end - @element.encodingstyle = @encodingstyle if !@element.encodingstyle - yield(@element, true) - end -end - - -class SOAPHeader < SOAPStruct - include SOAPEnvelopeElement - - def initialize - super(nil) - @elename = EleHeaderName - @encodingstyle = nil - end - - def encode(generator, ns, attrs = {}) - name = ns.name(@elename) - generator.encode_tag(name, attrs) - @data.each do |data| - yield(data, true) - end - generator.encode_tag_end(name, true) - end - - def add(name, value) - mu = (value.extraattr[AttrMustUnderstandName] == '1') - encstyle = value.extraattr[AttrEncodingStyleName] - item = SOAPHeaderItem.new(value, mu, encstyle) - super(name, item) - end - - def length - @data.length - end - alias size length -end - - -class SOAPEnvelope < XSD::NSDBase - include SOAPEnvelopeElement - include SOAPCompoundtype - - attr_reader :header - attr_reader :body - attr_reader :external_content - - def initialize(header = nil, body = nil) - super() - @type = nil - @elename = EleEnvelopeName - @encodingstyle = nil - @header = header - @body = body - @external_content = {} - header.parent = self if header - body.parent = self if body - end - - def header=(header) - header.parent = self - @header = header - end - - def body=(body) - body.parent = self - @body = body - end - - def encode(generator, ns, attrs = {}) - SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace, - SOAPNamespaceTag) - name = ns.name(@elename) - generator.encode_tag(name, attrs) - - yield(@header, true) if @header and @header.length > 0 - yield(@body, true) - - generator.encode_tag_end(name, true) - end - - def to_ary - [header, body] - end -end - - -end diff --git a/lib/soap/encodingstyle/aspDotNetHandler.rb b/lib/soap/encodingstyle/aspDotNetHandler.rb deleted file mode 100644 index e976433a7b..0000000000 --- a/lib/soap/encodingstyle/aspDotNetHandler.rb +++ /dev/null @@ -1,220 +0,0 @@ -# SOAP4R - ASP.NET EncodingStyle handler library -# Copyright (C) 2001, 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/encodingstyle/handler' - - -module SOAP -module EncodingStyle - - -class ASPDotNetHandler < Handler - Namespace = 'http://tempuri.org/ASP.NET' - add_handler - - def initialize(charset = nil) - super(charset) - @textbuf = '' - @decode_typemap = nil - end - - - ### - ## encode interface. - # - def encode_data(generator, ns, qualified, 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 - - 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) - 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) - end - when SOAPArray - generator.encode_tag(name, attrs) - data.traverse do |child, *rank| - data.position = nil - yield(child, true) - end - else - raise EncodingStyleError.new("Unknown object:#{ data } in this encodingSt -yle.") - 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 - cr = data.is_a?(SOAPCompoundtype) - generator.encode_tag_end(name, cr) - end - - - ### - ## decode interface. - # - class SOAPTemporalObject - attr_accessor :parent - - def initialize - @parent = nil - end - end - - class SOAPUnknown < SOAPTemporalObject - def initialize(handler, elename) - super() - @handler = handler - @elename = elename - end - - def as_struct - o = SOAPStruct.decode(@elename, XSD::AnyTypeName) - o.parent = @parent - o.type.name = @name - @handler.decode_parent(@parent, o) - o - end - - def as_string - o = SOAPString.decode(@elename) - o.parent = @parent - @handler.decode_parent(@parent, o) - o - end - - def as_nil - o = SOAPNil.decode(@elename) - o.parent = @parent - @handler.decode_parent(@parent, o) - o - end - end - - def decode_tag(ns, elename, attrs, parent) - # ToDo: check if @textbuf is empty... - @textbuf = '' - o = SOAPUnknown.new(self, elename) - o.parent = parent - o - end - - def decode_tag_end(ns, node) - o = node.node - if o.is_a?(SOAPUnknown) - newnode = o.as_string -# if /\A\s*\z/ =~ @textbuf -# o.as_struct -# else -# o.as_string -# end - node.replace_node(newnode) - o = node.node - end - - decode_textbuf(o) - @textbuf = '' - end - - def decode_text(ns, text) - # @textbuf is set at decode_tag_end. - @textbuf << text - end - - def decode_prologue - end - - def decode_epilogue - end - - def decode_parent(parent, node) - case parent.node - when SOAPUnknown - newparent = parent.node.as_struct - node.parent = newparent - parent.replace_node(newparent) - decode_parent(parent, node) - - when SOAPStruct - data = parent.node[node.elename.name] - case data - when nil - parent.node.add(node.elename.name, node) - when SOAPArray - name, type_ns = node.elename.name, node.type.namespace - data.add(node) - node.elename, node.type.namespace = name, type_ns - else - parent.node[node.elename.name] = SOAPArray.new - name, type_ns = data.elename.name, data.type.namespace - parent.node[node.elename.name].add(data) - data.elename.name, data.type.namespace = name, type_ns - name, type_ns = node.elename.name, node.type.namespace - parent.node[node.elename.name].add(node) - node.elename.name, node.type.namespace = name, type_ns - end - - when SOAPArray - if node.position - parent.node[*(decode_arypos(node.position))] = node - parent.node.sparse = true - else - parent.node.add(node) - end - - when SOAPBasetype - raise EncodingStyleError.new("SOAP base type must not have a child.") - - else - # SOAPUnknown does not have parent. - # raise EncodingStyleError.new("Illegal parent: #{ parent }.") - end - end - -private - - def decode_textbuf(node) - if node.is_a?(XSD::XSDString) - if @charset - node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset)) - else - node.set(@textbuf) - end - else - # Nothing to do... - end - end -end - -ASPDotNetHandler.new - - -end -end diff --git a/lib/soap/encodingstyle/handler.rb b/lib/soap/encodingstyle/handler.rb deleted file mode 100644 index 7bf65a2fd5..0000000000 --- a/lib/soap/encodingstyle/handler.rb +++ /dev/null @@ -1,100 +0,0 @@ -# SOAP4R - EncodingStyle handler library -# Copyright (C) 2001, 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/soap' -require 'soap/baseData' -require 'soap/element' - - -module SOAP -module EncodingStyle - - -class Handler - @@handlers = {} - - class EncodingStyleError < Error; end - - class << self - def uri - self::Namespace - end - - def handler(uri) - @@handlers[uri] - end - - def each - @@handlers.each do |key, value| - yield(value) - end - end - - private - - def add_handler - @@handlers[self.uri] = self - end - end - - attr_reader :charset - attr_accessor :generate_explicit_type - def decode_typemap=(definedtypes) - @decode_typemap = definedtypes - end - - def initialize(charset) - @charset = charset - @generate_explicit_type = true - @decode_typemap = nil - end - - ### - ## 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.') - end - - def encode_data_end(generator, ns, qualified, data, parent) - raise NotImplementError.new('Method encode_data must be defined in derived class.') - end - - def encode_prologue - end - - def encode_epilogue - end - - ### - ## decode interface. - # - # Returns SOAP/OM data. - def decode_tag(ns, name, attrs, parent) - raise NotImplementError.new('Method decode_tag must be defined in derived class.') - end - - def decode_tag_end(ns, name) - raise NotImplementError.new('Method decode_tag_end must be defined in derived class.') - end - - def decode_text(ns, text) - raise NotImplementError.new('Method decode_text must be defined in derived class.') - end - - def decode_prologue - end - - def decode_epilogue - end -end - - -end -end diff --git a/lib/soap/encodingstyle/literalHandler.rb b/lib/soap/encodingstyle/literalHandler.rb deleted file mode 100644 index 72a10b2daa..0000000000 --- a/lib/soap/encodingstyle/literalHandler.rb +++ /dev/null @@ -1,227 +0,0 @@ -# SOAP4R - XML Literal EncodingStyle handler library -# Copyright (C) 2001, 2003, 2004 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/encodingstyle/handler' - - -module SOAP -module EncodingStyle - - -class LiteralHandler < Handler - Namespace = SOAP::LiteralNamespace - add_handler - - def initialize(charset = nil) - super(charset) - @textbuf = '' - end - - - ### - ## encode interface. - # - def encode_data(generator, ns, qualified, 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 - - case data - when SOAPRawString - generator.encode_tag(name, attrs) - generator.encode_rawstring(data.to_s) - when XSD::XSDString - generator.encode_tag(name, attrs) - str = data.to_s - str = XSD::Charset.encoding_to_xml(str, @charset) if @charset - generator.encode_string(str) - 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) - end - when SOAPArray - generator.encode_tag(name, attrs) - data.traverse do |child, *rank| - data.position = nil - yield(child, true) - end - when SOAPElement - generator.encode_tag(name, attrs.update(data.extraattr)) - generator.encode_rawstring(data.text) if data.text - data.each do |key, value| - yield(value, qualified) - end - else - raise EncodingStyleError.new("Unknown object:#{ data } in this encodingStyle.") - 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 - cr = data.is_a?(SOAPElement) && !data.text - generator.encode_tag_end(name, cr) - end - - - ### - ## decode interface. - # - class SOAPTemporalObject - attr_accessor :parent - - def initialize - @parent = nil - end - end - - class SOAPUnknown < SOAPTemporalObject - def initialize(handler, elename, extraattr) - super() - @handler = handler - @elename = elename - @extraattr = extraattr - end - - def as_element - o = SOAPElement.decode(@elename) - o.parent = @parent - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - - def as_string - o = SOAPString.decode(@elename) - o.parent = @parent - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - - def as_nil - o = SOAPNil.decode(@elename) - o.parent = @parent - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - end - - def decode_tag(ns, elename, attrs, parent) - # ToDo: check if @textbuf is empty... - @textbuf = '' - o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs)) - o.parent = parent - o - end - - def decode_tag_end(ns, node) - o = node.node - if o.is_a?(SOAPUnknown) - newnode = if /\A\s*\z/ =~ @textbuf - o.as_element - else - o.as_string - end - node.replace_node(newnode) - o = node.node - end - - decode_textbuf(o) - @textbuf = '' - end - - def decode_text(ns, text) - # @textbuf is set at decode_tag_end. - @textbuf << text - end - - def decode_attrs(ns, attrs) - extraattr = {} - attrs.each do |key, value| - qname = ns.parse(key) - extraattr[qname] = value - end - extraattr - end - - def decode_prologue - end - - def decode_epilogue - end - - def decode_parent(parent, node) - case parent.node - when SOAPUnknown - newparent = parent.node.as_element - node.parent = newparent - parent.replace_node(newparent) - decode_parent(parent, node) - - when SOAPElement - parent.node.add(node) - node.parent = parent.node - - when SOAPStruct - parent.node.add(node.elename.name, node) - node.parent = parent.node - - when SOAPArray - if node.position - parent.node[*(decode_arypos(node.position))] = node - parent.node.sparse = true - else - parent.node.add(node) - end - node.parent = parent.node - - when SOAPBasetype - raise EncodingStyleError.new("SOAP base type must not have a child.") - - else - # SOAPUnknown does not have parent. - raise EncodingStyleError.new("Illegal parent: #{ parent }.") - end - end - -private - - def decode_textbuf(node) - if node.is_a?(XSD::XSDString) - if @charset - node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset)) - else - node.set(@textbuf) - end - else - # Nothing to do... - end - end -end - -LiteralHandler.new - - -end -end diff --git a/lib/soap/encodingstyle/soapHandler.rb b/lib/soap/encodingstyle/soapHandler.rb deleted file mode 100644 index 114060bd02..0000000000 --- a/lib/soap/encodingstyle/soapHandler.rb +++ /dev/null @@ -1,589 +0,0 @@ -# SOAP4R - SOAP EncodingStyle handler library -# Copyright (C) 2001, 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/encodingstyle/handler' - - -module SOAP -module EncodingStyle - - -class SOAPHandler < Handler - Namespace = SOAP::EncodingNamespace - add_handler - - def initialize(charset = nil) - super(charset) - @refpool = [] - @idpool = [] - @textbuf = '' - @is_first_top_ele = true - end - - - ### - ## encode interface. - # - 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(',') }]" - 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 - - case data - when SOAPReference - attrs['href'] = data.refidstr - generator.encode_tag(name, attrs) - when SOAPExternalReference - data.referred - attrs['href'] = data.refidstr - generator.encode_tag(name, attrs) - 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) - 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| - yield(value, false) - end - when SOAPArray - generator.encode_tag(name, attrs) - data.traverse do |child, *rank| - data.position = data.sparse ? rank : nil - yield(child, false) - end - else - raise EncodingStyleError.new( - "Unknown object:#{ data } in this encodingStyle.") - 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 - cr = data.is_a?(SOAPCompoundtype) - generator.encode_tag_end(name, cr) - end - - - ### - ## decode interface. - # - class SOAPTemporalObject - attr_accessor :parent - attr_accessor :position - attr_accessor :id - attr_accessor :root - - def initialize - @parent = nil - @position = nil - @id = nil - @root = nil - end - end - - class SOAPUnknown < SOAPTemporalObject - attr_reader :type - attr_accessor :definedtype - attr_reader :extraattr - - def initialize(handler, elename, type, extraattr) - super() - @handler = handler - @elename = elename - @type = type - @extraattr = extraattr - @definedtype = nil - end - - def as_struct - o = SOAPStruct.decode(@elename, @type) - o.id = @id - o.root = @root - o.parent = @parent - o.position = @position - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - - def as_string - o = SOAPString.decode(@elename) - o.id = @id - o.root = @root - o.parent = @parent - o.position = @position - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - - def as_nil - o = SOAPNil.decode(@elename) - o.id = @id - o.root = @root - o.parent = @parent - o.position = @position - o.extraattr.update(@extraattr) - @handler.decode_parent(@parent, o) - o - end - end - - def decode_tag(ns, elename, attrs, parent) - # ToDo: check if @textbuf is empty... - @textbuf = '' - is_nil, type, arytype, root, offset, position, href, id, extraattr = - decode_attrs(ns, attrs) - o = nil - if is_nil - o = SOAPNil.decode(elename) - elsif href - o = SOAPReference.decode(elename, href) - @refpool << o - elsif @decode_typemap - o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, extraattr) - else - o = decode_tag_by_type(ns, elename, type, parent.node, arytype, extraattr) - end - - if o.is_a?(SOAPArray) - if offset - o.offset = decode_arypos(offset) - o.sparse = true - else - o.sparse = false - end - end - - o.parent = parent - o.id = id - o.root = root - o.position = position - - unless o.is_a?(SOAPTemporalObject) - @idpool << o if o.id - decode_parent(parent, o) - end - o - end - - def decode_tag_end(ns, node) - o = node.node - if o.is_a?(SOAPUnknown) - newnode = if /\A\s*\z/ =~ @textbuf - o.as_struct - else - o.as_string - end - if newnode.id - @idpool << newnode - end - node.replace_node(newnode) - o = node.node - end - decode_textbuf(o) - # unlink definedtype - o.definedtype = nil - end - - def decode_text(ns, text) - @textbuf << text - end - - def decode_prologue - @refpool.clear - @idpool.clear - @is_first_top_ele = true - end - - def decode_epilogue - decode_resolve_id - end - - def decode_parent(parent, node) - case parent.node - when SOAPUnknown - newparent = parent.node.as_struct - node.parent = newparent - if newparent.id - @idpool << newparent - end - parent.replace_node(newparent) - decode_parent(parent, node) - when SOAPStruct - parent.node.add(node.elename.name, node) - node.parent = parent.node - when SOAPArray - if node.position - parent.node[*(decode_arypos(node.position))] = node - parent.node.sparse = true - else - parent.node.add(node) - end - node.parent = parent.node - when SOAPBasetype - raise EncodingStyleError.new("SOAP base type must not have a child.") - else - raise EncodingStyleError.new("Illegal parent: #{ parent.node }.") - end - end - -private - - def content_ranksize(typename) - typename.scan(/\[[\d,]*\]$/)[0] - end - - def content_typename(typename) - typename.sub(/\[,*\]$/, '') - end - - def create_arytype(ns, data) - XSD::QName.new(data.arytype.namespace, - content_typename(data.arytype.name) + "[#{ data.size.join(',') }]") - end - - def encode_attrs(generator, ns, data, parent) - return {} if data.is_a?(SOAPReference) - attrs = {} - - if !parent || parent.encodingstyle != EncodingNamespace - if @generate_explicit_type - SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace) - attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace - end - data.encodingstyle = EncodingNamespace - end - - if data.is_a?(SOAPNil) - attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue - elsif @generate_explicit_type - if data.type.namespace - SOAPGenerator.assign_ns(attrs, ns, data.type.namespace) - end - if data.is_a?(SOAPArray) - if data.arytype.namespace - SOAPGenerator.assign_ns(attrs, ns, data.arytype.namespace) - end - SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace) - attrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data)) - if data.type.name - attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) - end - elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type) - # No need to add. - elsif !data.type.namespace - # No need to add. - else - attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) - end - end - - data.extraattr.each do |key, value| - SOAPGenerator.assign_ns(attrs, ns, key.namespace) - attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value) - end - if data.id - attrs['id'] = data.id - end - attrs - end - - def encode_attr_value(generator, ns, qname, value) - if value.is_a?(SOAPType) - ref = SOAPReference.new(value) - generator.add_reftarget(qname.name, value) - ref.refidstr - else - value.to_s - end - end - - def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr) - o = nil - if parent.class == SOAPBody - # root element: should branch by root attribute? - if @is_first_top_ele - # Unqualified name is allowed here. - @is_first_top_ele = false - type = @decode_typemap[elename] || - @decode_typemap.find_name(elename.name) - if type - o = SOAPStruct.new(elename) - o.definedtype = type - return o - end - end - # multi-ref element. - if typestr - typename = ns.parse(typestr) - typedef = @decode_typemap[typename] - if typedef - return decode_definedtype(elename, typename, typedef, arytypestr) - end - end - return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, - extraattr) - end - - if parent.type == XSD::AnyTypeName - return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, - extraattr) - end - - # parent.definedtype == nil means the parent is SOAPUnknown. SOAPUnknown - # is generated by decode_tag_by_type when its type is anyType. - parenttype = parent.definedtype || @decode_typemap[parent.type] - unless parenttype - return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, - extraattr) - end - - definedtype_name = parenttype.child_type(elename) - if definedtype_name and (klass = TypeMap[definedtype_name]) - return decode_basetype(klass, elename) - elsif definedtype_name == XSD::AnyTypeName - return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, - extraattr) - end - - if definedtype_name - typedef = @decode_typemap[definedtype_name] - else - typedef = parenttype.child_defined_complextype(elename) - end - decode_definedtype(elename, definedtype_name, typedef, arytypestr) - end - - def decode_definedtype(elename, typename, typedef, arytypestr) - unless typedef - raise EncodingStyleError.new("Unknown type '#{ typename }'.") - end - if typedef.is_a?(::WSDL::XMLSchema::SimpleType) - decode_defined_simpletype(elename, typename, typedef, arytypestr) - else - decode_defined_complextype(elename, typename, typedef, arytypestr) - end - end - - def decode_basetype(klass, elename) - klass.decode(elename) - end - - def decode_defined_simpletype(elename, typename, typedef, arytypestr) - o = decode_basetype(TypeMap[typedef.base], elename) - o.definedtype = typedef - o - end - - def decode_defined_complextype(elename, typename, typedef, arytypestr) - case typedef.compoundtype - when :TYPE_STRUCT - o = SOAPStruct.decode(elename, typename) - o.definedtype = typedef - return o - when :TYPE_ARRAY - expected_arytype = typedef.find_arytype - if arytypestr - actual_arytype = XSD::QName.new(expected_arytype.namespace, - content_typename(expected_arytype.name) << - content_ranksize(arytypestr)) - o = SOAPArray.decode(elename, typename, actual_arytype) - else - o = SOAPArray.new(typename, 1, expected_arytype) - o.elename = elename - end - o.definedtype = typedef - return o - end - nil - end - - def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr) - if arytypestr - type = typestr ? ns.parse(typestr) : ValueArrayName - node = SOAPArray.decode(elename, type, ns.parse(arytypestr)) - node.extraattr.update(extraattr) - return node - end - - type = nil - if typestr - type = ns.parse(typestr) - elsif parent.is_a?(SOAPArray) - type = parent.arytype - else - # Since it's in dynamic(without any type) encoding process, - # assumes entity as its type itself. - # <SOAP-ENC:Array ...> => type Array in SOAP-ENC. - # <Country xmlns="foo"> => type Country in foo. - type = elename - end - - if (klass = TypeMap[type]) - node = decode_basetype(klass, elename) - node.extraattr.update(extraattr) - return node - end - - # Unknown type... Struct or String - SOAPUnknown.new(self, elename, type, extraattr) - end - - def decode_textbuf(node) - case node - when XSD::XSDHexBinary, XSD::XSDBase64Binary - node.set_encoded(@textbuf) - when XSD::XSDString - if @charset - @textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset) - end - if node.definedtype - node.definedtype.check_lexical_format(@textbuf) - end - node.set(@textbuf) - when SOAPNil - # Nothing to do. - when SOAPBasetype - node.set(@textbuf) - else - # Nothing to do... - end - @textbuf = '' - end - - NilLiteralMap = { - 'true' => true, - '1' => true, - 'false' => false, - '0' => false - } - RootLiteralMap = { - '1' => 1, - '0' => 0 - } - def decode_attrs(ns, attrs) - is_nil = false - type = nil - arytype = nil - root = nil - offset = nil - position = nil - href = nil - id = nil - extraattr = {} - - attrs.each do |key, value| - qname = ns.parse(key) - case qname.namespace - when XSD::InstanceNamespace - case qname.name - when XSD::NilLiteral - is_nil = NilLiteralMap[value] or - raise EncodingStyleError.new("Cannot accept attribute value: #{ value } as the value of xsi:#{ XSD::NilLiteral } (expected 'true', 'false', '1', or '0').") - next - when XSD::AttrType - type = value - next - end - when EncodingNamespace - case qname.name - when AttrArrayType - arytype = value - next - when AttrRoot - root = RootLiteralMap[value] or - raise EncodingStyleError.new( - "Illegal root attribute value: #{ value }.") - next - when AttrOffset - offset = value - next - when AttrPosition - position = value - next - end - end - if key == 'href' - href = value - next - elsif key == 'id' - id = value - next - end - 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.decode(nil, value) - @refpool << o - o - else - value - end - end - - def decode_arypos(position) - /^\[(.+)\]$/ =~ position - $1.split(',').collect { |s| s.to_i } - end - - def decode_resolve_id - count = @refpool.length # To avoid infinite loop - while !@refpool.empty? && count > 0 - @refpool = @refpool.find_all { |ref| - o = @idpool.find { |item| - item.id == ref.refid - } - if o.is_a?(SOAPReference) - true # link of link. - elsif o - ref.__setobj__(o) - false - elsif o = ref.rootnode.external_content[ref.refid] - ref.__setobj__(o) - false - else - raise EncodingStyleError.new("Unresolved reference: #{ ref.refid }.") - end - } - count -= 1 - end - end -end - -SOAPHandler.new - - -end -end diff --git a/lib/soap/generator.rb b/lib/soap/generator.rb deleted file mode 100644 index edd90492c6..0000000000 --- a/lib/soap/generator.rb +++ /dev/null @@ -1,210 +0,0 @@ -# SOAP4R - SOAP XML Instance Generator library. -# Copyright (C) 2001, 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 'xsd/ns' -require 'soap/soap' -require 'soap/baseData' -require 'soap/encodingstyle/handler' - - -module SOAP - - -### -## CAUTION: MT-unsafe -# -class SOAPGenerator - include SOAP - - class FormatEncodeError < Error; end - -public - - attr_accessor :charset - attr_accessor :default_encodingstyle - attr_accessor :generate_explicit_type - - def initialize(opt = {}) - @reftarget = nil - @handlers = {} - @charset = opt[:charset] || XSD::Charset.encoding_label - @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace - @generate_explicit_type = - opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true - @buf = @indent = @curr = nil - end - - def generate(obj, io = nil) - @buf = io || '' - @indent = '' - - prologue - @handlers.each do |uri, handler| - handler.encode_prologue - end - - ns = XSD::NS.new - @buf << xmldecl - encode_data(ns, true, obj, nil) - - @handlers.each do |uri, handler| - handler.encode_epilogue - end - epilogue - - @buf - end - - def encode_data(ns, qualified, obj, parent) - if obj.is_a?(SOAPEnvelopeElement) - encode_element(ns, qualified, 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 - 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) - end - - 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(self, ns, attrs) do |child, nextq| - indent_backup, @indent = @indent, @indent + ' ' - encode_data(ns.clone_ns, nextq, child, obj) - @indent = indent_backup - end - @reftarget = nil - else - if obj.is_a?(SOAPEnvelope) - # xsi:nil="true" can appear even if dumping without explicit type. - SOAPGenerator.assign_ns(attrs, ns, - XSD::InstanceNamespace, XSINamespaceTag) - if @generate_explicit_type - 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) - @indent = indent_backup - end - end - end - - def encode_tag(elename, attrs = nil) - if !attrs or attrs.empty? - @buf << "\n#{ @indent }<#{ elename }>" - elsif attrs.size == 1 - key, value = attrs.shift - @buf << %Q[\n#{ @indent }<#{ elename } #{ key }="#{ value }">] - else - @buf << "\n#{ @indent }<#{ elename } " << - attrs.collect { |key, value| - %Q[#{ key }="#{ value }"] - }.join("\n#{ @indent } ") << - '>' - end - end - - def encode_tag_end(elename, cr = nil) - if cr - @buf << "\n#{ @indent }</#{ elename }>" - else - @buf << "</#{ elename }>" - end - end - - def encode_rawstring(str) - @buf << str - end - - EncodeMap = { - '&' => '&', - '<' => '<', - '>' => '>', - '"' => '"', - '\'' => ''', - "\r" => '
' - } - EncodeCharRegexp = Regexp.new("[#{EncodeMap.keys.join}]") - 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 - - def prologue - end - - def epilogue - end - - def find_handler(encodingstyle) - unless @handlers.key?(encodingstyle) - handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset) - handler.generate_explicit_type = @generate_explicit_type - handler.encode_prologue - @handlers[encodingstyle] = handler - end - @handlers[encodingstyle] - end - - def xmldecl - if @charset - %Q[<?xml version="1.0" encoding="#{ @charset }" ?>] - else - %Q[<?xml version="1.0" ?>] - end - end -end - - -end diff --git a/lib/soap/header/handler.rb b/lib/soap/header/handler.rb deleted file mode 100644 index 7da2836e24..0000000000 --- a/lib/soap/header/handler.rb +++ /dev/null @@ -1,57 +0,0 @@ -# SOAP4R - SOAP Header handler item -# Copyright (C) 2003, 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/element' - - -module SOAP -module Header - - -class Handler - attr_reader :elename - attr_reader :mustunderstand - attr_reader :encodingstyle - - def initialize(elename) - @elename = elename - @mustunderstand = false - @encodingstyle = nil - end - - # Should return a SOAP/OM, a SOAPHeaderItem or nil. - def on_outbound - nil - end - - # Given header is a SOAPHeaderItem or nil. - def on_inbound(header, mustunderstand = false) - # do something. - end - - def on_outbound_headeritem - item = on_outbound - if item.nil? - nil - elsif item.is_a?(::SOAP::SOAPHeaderItem) - item.elename = @elename - item - else - item.elename = @elename - ::SOAP::SOAPHeaderItem.new(item, @mustunderstand, @encodingstyle) - end - end - - def on_inbound_headeritem(header) - on_inbound(header.element, header.mustunderstand) - end -end - - -end -end diff --git a/lib/soap/header/handlerset.rb b/lib/soap/header/handlerset.rb deleted file mode 100644 index 499d6bb8a1..0000000000 --- a/lib/soap/header/handlerset.rb +++ /dev/null @@ -1,58 +0,0 @@ -# SOAP4R - SOAP Header handler set -# Copyright (C) 2003, 2004 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 'xsd/namedelements' - - -module SOAP -module Header - - -class HandlerSet - def initialize - @store = XSD::NamedElements.new - end - - def add(handler) - @store << handler - end - alias << add - - def delete(handler) - @store.delete(handler) - end - - def include?(handler) - @store.include?(handler) - end - - # returns: Array of SOAPHeaderItem - def on_outbound - @store.collect { |handler| - handler.on_outbound_headeritem - }.compact - end - - # headers: SOAPHeaderItem enumerable object - def on_inbound(headers) - headers.each do |name, item| - handler = @store.find { |handler| - handler.elename == item.element.elename - } - if handler - handler.on_inbound_headeritem(item) - elsif item.mustunderstand - raise UnhandledMustUnderstandHeaderError.new(item.element.elename.to_s) - end - end - end -end - - -end -end diff --git a/lib/soap/header/simplehandler.rb b/lib/soap/header/simplehandler.rb deleted file mode 100644 index e7268e04a3..0000000000 --- a/lib/soap/header/simplehandler.rb +++ /dev/null @@ -1,44 +0,0 @@ -# SOAP4R - SOAP Simple header item handler -# Copyright (C) 2003, 2004 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/header/handler' -require 'soap/baseData' - - -module SOAP -module Header - - -class SimpleHandler < SOAP::Header::Handler - def initialize(elename) - super(elename) - end - - # Should return a Hash or nil. - def on_simple_outbound - nil - end - - # Given header is a Hash or nil. - def on_simple_inbound(header, mustunderstand) - end - - def on_outbound - h = on_simple_outbound - h ? SOAPElement.from_obj(h) : nil - end - - def on_inbound(header, mustunderstand) - h = header.to_obj - on_simple_inbound(h, mustunderstand) - end -end - - -end -end diff --git a/lib/soap/mapping.rb b/lib/soap/mapping.rb deleted file mode 100644 index b83f8b484a..0000000000 --- a/lib/soap/mapping.rb +++ /dev/null @@ -1,10 +0,0 @@ -# SOAP4R - Ruby type mapping utility. -# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -require 'soap/mapping/mapping' -require 'soap/mapping/registry' diff --git a/lib/soap/mapping/factory.rb b/lib/soap/mapping/factory.rb deleted file mode 100644 index 6b9ac1eeaa..0000000000 --- a/lib/soap/mapping/factory.rb +++ /dev/null @@ -1,388 +0,0 @@ -# SOAP4R - Mapping factory. -# 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. - - -module SOAP -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 - end - - def soap2obj(obj_class, node, info, map) - raise NotImplementError.new - # return convert_succeeded_or_not, obj - end - - if Object.respond_to?(:allocate) - # ruby/1.7 or later. - def create_empty_object(klass) - klass.allocate - end - else - MARSHAL_TAG = { - String => ['"', 1], - Regexp => ['/', 2], - Array => ['[', 1], - Hash => ['{', 1] - } - def create_empty_object(klass) - if klass <= Struct - name = klass.name - return ::Marshal.load(sprintf("\004\006S:%c%s\000", name.length + 5, name)) - end - if MARSHAL_TAG.has_key?(klass) - tag, terminate = MARSHAL_TAG[klass] - return ::Marshal.load(sprintf("\004\006%s%s", tag, "\000" * terminate)) - end - MARSHAL_TAG.each do |k, v| - if klass < k - name = klass.name - tag, terminate = v - return ::Marshal.load(sprintf("\004\006C:%c%s%s%s", name.length + 5, name, tag, "\000" * terminate)) - end - end - name = klass.name - ::Marshal.load(sprintf("\004\006o:%c%s\000", name.length + 5, name)) - end - end - - def setiv2obj(obj, node, map) - return if node.nil? - if obj.is_a?(Array) - setiv2ary(obj, node, map) - else - setiv2struct(obj, node, map) - end - end - - def setiv2soap(node, obj, map) - # should we sort instance_variables? - obj.instance_variables.each do |var| - name = var.sub(/^@/, '') - node.add(Mapping.name2elename(name), - Mapping._obj2soap(obj.instance_eval(var), map)) - end - end - - # It breaks Thread.current[:SOAPMarshalDataKey]. - def mark_marshalled_obj(obj, soap_obj) - Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj - end - - # It breaks Thread.current[:SOAPMarshalDataKey]. - def mark_unmarshalled_obj(node, obj) - Thread.current[:SOAPMarshalDataKey][node.id] = obj - end - -private - - def setiv2ary(obj, node, map) - node.each do |name, value| - Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map)) - end - end - - def setiv2struct(obj, node, map) - vars = {} - node.each do |name, value| - vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map) - end - Mapping.set_instance_vars(obj, vars) - end -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 - 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 - mark_marshalled_obj(obj, soap_obj) - soap_obj - end - - def soap2obj(obj_class, node, info, map) - 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) - rescue XSD::ValueSpaceError - return nil - end - if @allow_original_mapping - # Basetype except String should not be multiref-ed in SOAP/1.1. - mark_marshalled_obj(obj, soap_obj) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - obj = node.data - mark_unmarshalled_obj(node, obj) - return true, obj - end -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) - rescue XSD::ValueSpaceError - return nil - end - mark_marshalled_obj(obj, soap_obj) - soap_obj - end - - def soap2obj(obj_class, node, info, map) - obj = nil - if obj_class == Time - obj = node.to_time - if obj.nil? - # Is out of range as a Time - return false - end - elsif obj_class == Date - obj = node.data - else - return false - end - mark_unmarshalled_obj(node, obj) - return true, obj - end -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 - end - - def soap2obj(obj_class, node, info, map) - obj = node.string - mark_unmarshalled_obj(node, obj) - return true, obj - end -end - -class URIFactory_ < Factory - def obj2soap(soap_class, obj, info, map) - soap_obj = soap_class.new(obj) - mark_marshalled_obj(obj, soap_obj) if soap_obj - soap_obj - end - - def soap2obj(obj_class, node, info, map) - obj = node.data - mark_unmarshalled_obj(node, obj) - return true, obj - end -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 - else - arytype = XSD::AnyTypeName - end - param = SOAPArray.new(ValueArrayName, 1, arytype) - mark_marshalled_obj(obj, param) - obj.each do |var| - param.add(Mapping._obj2soap(var, map)) - end - param - end - - def soap2obj(obj_class, node, info, map) - obj = create_empty_object(obj_class) - mark_unmarshalled_obj(node, obj) - node.soap2array(obj) do |elem| - elem ? Mapping._soap2obj(elem, map) : nil - end - return true, obj - end -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) - obj.each do |var| - param.add(Mapping._obj2soap(var, map)) - end - param - end - - def soap2obj(obj_class, node, info, map) - if node.rank > 1 - return false - end - arytype = info[:type] || info[0] - unless node.arytype == arytype - return false - end - obj = create_empty_object(obj_class) - mark_unmarshalled_obj(node, obj) - node.soap2array(obj) do |elem| - elem ? Mapping._soap2obj(elem, map) : nil - end - return true, obj - end -end - -class TypedStructFactory_ < Factory - def obj2soap(soap_class, obj, info, map) - type = info[:type] || info[0] - param = soap_class.new(type) - mark_marshalled_obj(obj, param) - if obj.class <= SOAP::Marshallable - setiv2soap(param, obj, map) - else - setiv2soap(param, obj, map) - end - param - end - - def soap2obj(obj_class, node, info, map) - type = info[:type] || info[0] - unless node.type == type - return false - end - obj = create_empty_object(obj_class) - mark_unmarshalled_obj(node, obj) - setiv2obj(obj, node, map) - return true, obj - end -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 !@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) - mark_marshalled_obj(obj, param) - obj.each do |key, value| - elem = SOAPStruct.new - elem.add("key", Mapping._obj2soap(key, map)) - elem.add("value", Mapping._obj2soap(value, map)) - # ApacheAxis allows only 'item' here. - param.add("item", elem) - end - param - end - - def soap2obj(obj_class, node, info, map) - unless node.type == MapQName - return false - end - if node.class == SOAPStruct and node.key?('default') - return false - end - obj = create_empty_object(obj_class) - mark_unmarshalled_obj(node, obj) - if node.class == SOAPStruct - node.each do |key, value| - obj[Mapping._soap2obj(value['key'], map)] = - Mapping._soap2obj(value['value'], map) - end - else - node.each do |value| - obj[Mapping._soap2obj(value['key'], map)] = - Mapping._soap2obj(value['value'], map) - end - end - return true, obj - end -end - - -end -end diff --git a/lib/soap/mapping/mapping.rb b/lib/soap/mapping/mapping.rb deleted file mode 100644 index db7ea607fd..0000000000 --- a/lib/soap/mapping/mapping.rb +++ /dev/null @@ -1,218 +0,0 @@ -# SOAP4R - Ruby type mapping utility. -# Copyright (C) 2000, 2001, 2003 NAKAMURA Hiroshi <nahi@ruby-lang.org>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -module SOAP - - -module Mapping - RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6' - RubyTypeInstanceNamespace = - 'http://www.ruby-lang.org/xmlns/ruby/type-instance' - RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom' - ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap' - - - # TraverseSupport breaks Thread.current[:SOAPMarshalDataKey]. - module TraverseSupport - def mark_marshalled_obj(obj, soap_obj) - Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj - end - - def mark_unmarshalled_obj(node, obj) - # node.id is not Object#id but SOAPReference#id - Thread.current[:SOAPMarshalDataKey][node.id] = obj - end - end - - - def self.obj2soap(obj, registry = nil, type = nil) - registry ||= Mapping::DefaultRegistry - Thread.current[:SOAPMarshalDataKey] = {} - soap_obj = _obj2soap(obj, registry, type) - Thread.current[:SOAPMarshalDataKey] = nil - soap_obj - end - - def self.soap2obj(node, registry = nil) - registry ||= Mapping::DefaultRegistry - Thread.current[:SOAPMarshalDataKey] = {} - obj = _soap2obj(node, registry) - Thread.current[:SOAPMarshalDataKey] = nil - obj - end - - def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil) - registry ||= Mapping::DefaultRegistry - type = XSD::QName.new(type_ns, typename) - soap_ary = SOAPArray.new(ValueArrayName, 1, type) - Thread.current[:SOAPMarshalDataKey] = {} - ary.each do |ele| - soap_ary.add(_obj2soap(ele, registry, type)) - end - Thread.current[:SOAPMarshalDataKey] = nil - soap_ary - end - - def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil) - registry ||= Mapping::DefaultRegistry - type = XSD::QName.new(type_ns, typename) - md_ary = SOAPArray.new(ValueArrayName, rank, type) - Thread.current[:SOAPMarshalDataKey] = {} - add_md_ary(md_ary, ary, [], registry) - Thread.current[:SOAPMarshalDataKey] = nil - md_ary - end - - def self.fault2exception(fault, registry = nil) - registry ||= Mapping::DefaultRegistry - detail = if fault.detail - soap2obj(fault.detail, registry) || "" - else - "" - end - if detail.is_a?(Mapping::SOAPException) - begin - e = detail.to_e - remote_backtrace = e.backtrace - e.set_backtrace(nil) - raise e # ruby sets current caller as local backtrace of e => e2. - rescue Exception => e - e.set_backtrace(remote_backtrace + e.backtrace[1..-1]) - raise - end - else - fault.detail = detail - fault.set_backtrace( - if detail.is_a?(Array) - detail - else - [detail.to_s] - end - ) - raise - end - end - - def self._obj2soap(obj, registry, type = nil) - if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] - SOAPReference.new(referent) - else - registry.obj2soap(obj.class, obj, type) - end - end - - def self._soap2obj(node, registry) - if node.is_a?(SOAPReference) - target = node.__getobj__ - # target.id is not Object#id but SOAPReference#id - if referent = Thread.current[:SOAPMarshalDataKey][target.id] - return referent - else - return _soap2obj(target, registry) - end - end - 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. - # To follow XML spec., it should be NCName. - # (denied chars) => .[0-F][0-F] - # ex. a.b => a.2eb - # - def self.name2elename(name) - name.gsub(/([^a-zA-Z0-9:_\-]+)/n) { - '.' << $1.unpack('H2' * $1.size).join('.') - }.gsub(/::/n, '..') - end - - def self.elename2name(name) - name.gsub(/\.\./n, '::').gsub(/((?:\.[0-9a-fA-F]{2})+)/n) { - [$1.delete('.')].pack('H*') - } - end - - def self.class_from_name(name) - if /^[A-Z]/ !~ name - return nil - end - klass = ::Object - name.split('::').each do |klass_str| - if klass.const_defined?(klass_str) - klass = klass.const_get(klass_str) - else - return nil - end - end - klass - end - - def self.class2qname(klass) - name = if klass.class_variables.include?("@@schema_type") - klass.class_eval("@@schema_type") - else - nil - end - namespace = if klass.class_variables.include?("@@schema_ns") - klass.class_eval("@@schema_ns") - else - nil - end - XSD::QName.new(namespace, name) - end - - def self.class2element(klass) - type = Mapping.class2qname(klass) - type.name ||= Mapping.name2elename(klass.name) - type.namespace ||= RubyCustomTypeNamespace - type - end - - def self.obj2element(obj) - name = namespace = nil - ivars = obj.instance_variables - if ivars.include?("@schema_type") - name = obj.instance_eval("@schema_type") - end - if ivars.include?("@schema_ns") - namespace = obj.instance_eval("@schema_ns") - end - if !name or !namespace - class2qname(obj.class) - else - XSD::QName.new(namespace, name) - end - end - - class << Mapping - private - def add_md_ary(md_ary, ary, indices, registry) - for idx in 0..(ary.size - 1) - if ary[idx].is_a?(Array) - add_md_ary(md_ary, ary[idx], indices + [idx], registry) - else - md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry) - end - end - end - end -end - - -end diff --git a/lib/soap/mapping/registry.rb b/lib/soap/mapping/registry.rb deleted file mode 100644 index 1317d40cd6..0000000000 --- a/lib/soap/mapping/registry.rb +++ /dev/null @@ -1,479 +0,0 @@ -# SOAP4R - 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' -require 'soap/mapping/factory' -require 'soap/mapping/rubytypeFactory' - - -module SOAP - - -module Marshallable - # @@type_ns = Mapping::RubyCustomTypeNamespace -end - - -module Mapping - - -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. -class SOAPException; include Marshallable - attr_reader :excn_type_name, :cause - def initialize(e) - @excn_type_name = Mapping.name2elename(e.class.to_s) - @cause = e - end - - def to_e - if @cause.is_a?(::Exception) - @cause.extend(::SOAP::Mapping::MappedException) - return @cause - elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace) - e = RuntimeError.new(@cause.message) - e.set_backtrace(@cause.backtrace) - return e - end - 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 - obj = klass.new(@cause.message) - obj.extend(::SOAP::Mapping::MappedException) - obj - end -end - - -# For anyType object: SOAP::Mapping::Object not ::Object -class Object; include Marshallable - def initialize - @__members = [] - @__value_type = {} - end - - def [](name) - if @__members.include?(name) - self.__send__(name) - else - self.__send__(Object.safe_name(name)) - end - end - - def []=(name, value) - if @__members.include?(name) - self.__send__(name + '=', value) - else - self.__send__(Object.safe_name(name) + '=', value) - end - end - - def __set_property(name, value) - var_name = name - unless @__members.include?(name) - var_name = __define_attr_accessor(var_name) - end - __set_property_value(var_name, value) - var_name - end - - def __members - @__members - end - -private - - def __set_property_value(name, value) - org = self.__send__(name) - case @__value_type[name] - when :single - self.__send__(name + '=', [org, value]) - @__value_type[name] = :multi - when :multi - org << value - else - self.__send__(name + '=', value) - @__value_type[name] = :single - end - value - end - - def __define_attr_accessor(name) - var_name = name - begin - instance_eval <<-EOS - def #{ var_name } - @#{ var_name } - end - - def #{ var_name }=(value) - @#{ var_name } = value - end - EOS - rescue SyntaxError - var_name = Object.safe_name(var_name) - retry - end - @__members << var_name - var_name - end - - def Object.safe_name(name) - require 'md5' - "var_" << MD5.new(name).hexdigest - end -end - - -class MappingError < Error; end - - -class Registry - class Map - def initialize(registry) - @map = [] - @registry = registry - end - - def obj2soap(klass, obj, type_qname = nil) - @map.each do |obj_class, soap_class, factory, info| - if klass == obj_class or - (info[:derived_class] and klass <= obj_class) - ret = factory.obj2soap(soap_class, obj, info, @registry) - return ret if ret - end - end - nil - end - - def soap2obj(klass, node) - @map.each do |obj_class, soap_class, factory, info| - if klass == soap_class or - (info[:derived_class] and klass <= soap_class) - conv, obj = factory.soap2obj(obj_class, node, info, @registry) - return true, obj if conv - end - end - return false - end - - # Give priority to former entry. - def init(init_map = []) - clear - init_map.reverse_each do |obj_class, soap_class, factory, info| - add(obj_class, soap_class, factory, info) - end - end - - # Give priority to latter entry. - def add(obj_class, soap_class, factory, info) - info ||= {} - @map.unshift([obj_class, soap_class, factory, info]) - end - - def clear - @map.clear - end - - def find_mapped_soap_class(target_obj_class) - @map.each do |obj_class, soap_class, factory, info| - if obj_class == target_obj_class - return soap_class - end - end - nil - end - - def find_mapped_obj_class(target_soap_class) - @map.each do |obj_class, soap_class, factory, info| - if soap_class == target_soap_class - return obj_class - end - end - nil - end - end - - StringFactory = StringFactory_.new - BasetypeFactory = BasetypeFactory_.new - DateTimeFactory = DateTimeFactory_.new - ArrayFactory = ArrayFactory_.new - Base64Factory = Base64Factory_.new - URIFactory = URIFactory_.new - TypedArrayFactory = TypedArrayFactory_.new - TypedStructFactory = TypedStructFactory_.new - - HashFactory = HashFactory_.new - - SOAPBaseMap = [ - [::NilClass, ::SOAP::SOAPNil, BasetypeFactory], - [::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory], - [::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory], - [::String, ::SOAP::SOAPString, StringFactory], - [::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, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPInt, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPLong, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPInteger, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPShort, BasetypeFactory, - {:derived_class => true}], - [::URI::Generic, ::SOAP::SOAPAnyURI, URIFactory, - {:derived_class => true}], - [::String, ::SOAP::SOAPBase64, Base64Factory], - [::String, ::SOAP::SOAPHexBinary, Base64Factory], - [::String, ::SOAP::SOAPDecimal, BasetypeFactory], - [::String, ::SOAP::SOAPDuration, BasetypeFactory], - [::String, ::SOAP::SOAPGYearMonth, BasetypeFactory], - [::String, ::SOAP::SOAPGYear, BasetypeFactory], - [::String, ::SOAP::SOAPGMonthDay, BasetypeFactory], - [::String, ::SOAP::SOAPGDay, BasetypeFactory], - [::String, ::SOAP::SOAPGMonth, BasetypeFactory], - [::String, ::SOAP::SOAPQName, BasetypeFactory], - - [::Hash, ::SOAP::SOAPArray, HashFactory], - [::Hash, ::SOAP::SOAPStruct, HashFactory], - - [::Array, ::SOAP::SOAPArray, ArrayFactory, - {:derived_class => true}], - - [::SOAP::Mapping::SOAPException, - ::SOAP::SOAPStruct, TypedStructFactory, - {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}], - ] - - RubyOriginalMap = [ - [::NilClass, ::SOAP::SOAPNil, BasetypeFactory], - [::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory], - [::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory], - [::String, ::SOAP::SOAPString, StringFactory], - [::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, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPInt, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPLong, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPInteger, BasetypeFactory, - {:derived_class => true}], - [::Integer, ::SOAP::SOAPShort, BasetypeFactory, - {:derived_class => true}], - [::URI::Generic, ::SOAP::SOAPAnyURI, URIFactory, - {:derived_class => true}], - [::String, ::SOAP::SOAPBase64, Base64Factory], - [::String, ::SOAP::SOAPHexBinary, Base64Factory], - [::String, ::SOAP::SOAPDecimal, BasetypeFactory], - [::String, ::SOAP::SOAPDuration, BasetypeFactory], - [::String, ::SOAP::SOAPGYearMonth, BasetypeFactory], - [::String, ::SOAP::SOAPGYear, BasetypeFactory], - [::String, ::SOAP::SOAPGMonthDay, BasetypeFactory], - [::String, ::SOAP::SOAPGDay, BasetypeFactory], - [::String, ::SOAP::SOAPGMonth, BasetypeFactory], - [::String, ::SOAP::SOAPQName, BasetypeFactory], - - [::Hash, ::SOAP::SOAPArray, HashFactory], - [::Hash, ::SOAP::SOAPStruct, HashFactory], - - # Does not allow Array's subclass here. - [::Array, ::SOAP::SOAPArray, ArrayFactory], - - [::SOAP::Mapping::SOAPException, - ::SOAP::SOAPStruct, TypedStructFactory, - {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}], - ] - - def initialize(config = {}) - @config = config - @map = Map.new(self) - if @config[:allow_original_mapping] - @allow_original_mapping = true - @map.init(RubyOriginalMap) - else - @allow_original_mapping = false - @map.init(SOAPBaseMap) - end - - @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 - ) - @default_factory = @rubytype_factory - @excn_handler_obj2soap = nil - @excn_handler_soap2obj = nil - end - - def add(obj_class, soap_class, factory, info = nil) - @map.add(obj_class, soap_class, factory, info) - end - alias set add - - # This mapping registry ignores type hint. - def obj2soap(klass, obj, type_qname = nil) - soap = _obj2soap(klass, obj, type_qname) - if @allow_original_mapping - addextend2soap(soap, obj) - end - soap - end - - def soap2obj(klass, node) - obj = _soap2obj(klass, node) - if @allow_original_mapping - addextend2obj(obj, node.extraattr[RubyExtendName]) - addiv2obj(obj, node.extraattr[RubyIVarName]) - end - obj - end - - def default_factory=(factory) - @default_factory = factory - end - - def excn_handler_obj2soap=(handler) - @excn_handler_obj2soap = handler - end - - def excn_handler_soap2obj=(handler) - @excn_handler_soap2obj = handler - end - - def find_mapped_soap_class(obj_class) - @map.find_mapped_soap_class(obj_class) - end - - def find_mapped_obj_class(soap_class) - @map.find_mapped_obj_class(soap_class) - end - -private - - def _obj2soap(klass, obj, type_qname) - 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, type_qname) || - @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 - - if RUBY_VERSION >= '1.8.0' - def addextend2obj(obj, attr) - return unless attr - attr.split(/ /).reverse_each do |mstr| - obj.extend(Mapping.class_from_name(mstr)) - end - end - else - # (class < false; self; end).ancestors includes "TrueClass" under 1.6... - def addextend2obj(obj, attr) - return unless attr - attr.split(/ /).reverse_each do |mstr| - m = Mapping.class_from_name(mstr) - obj.extend(m) if m.class == Module - end - 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 - - -DefaultRegistry = Registry.new -RubyOriginalRegistry = Registry.new(:allow_original_mapping => true) - - -end -end diff --git a/lib/soap/mapping/rubytypeFactory.rb b/lib/soap/mapping/rubytypeFactory.rb deleted file mode 100644 index a46d93275f..0000000000 --- a/lib/soap/mapping/rubytypeFactory.rb +++ /dev/null @@ -1,452 +0,0 @@ -# SOAP4R - Ruby type mapping factory. -# 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. - - -module SOAP -module Mapping - - -class RubytypeFactory < Factory - 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) - param = nil - case obj - when ::String - unless @allow_original_mapping - return nil - end - param = @string_factory.obj2soap(SOAPString, obj, info, map) - if obj.class != String - param.extraattr[RubyTypeName] = obj.class.name - end - 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 - 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 - 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 - end - param.add('source', SOAPBase64.new(obj.source)) - if obj.respond_to?('options') - # Regexp#options is from Ruby/1.7 - options = obj.options - else - options = 0 - obj.inspect.sub(/^.*\//, '').each_byte do |c| - options += case c - when ?i - 1 - when ?x - 2 - when ?m - 4 - when ?n - 16 - when ?e - 32 - when ?s - 48 - when ?u - 64 - end - end - end - param.add('options', SOAPInt.new(options)) - addiv2soapattr(param, obj, map) - when ::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 - end - 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?)) - addiv2soapattr(param, obj, map) - when ::Class - unless @allow_original_mapping - return nil - end - if obj.to_s[0] == ?# - raise TypeError.new("can't dump anonymous class #{ obj }") - end - param = SOAPStruct.new(TYPE_CLASS) - mark_marshalled_obj(obj, param) - param.add('name', SOAPString.new(obj.name)) - addiv2soapattr(param, obj, map) - when ::Module - unless @allow_original_mapping - return nil - end - if obj.to_s[0] == ?# - raise TypeError.new("can't dump anonymous module #{ obj }") - end - param = SOAPStruct.new(TYPE_MODULE) - mark_marshalled_obj(obj, param) - param.add('name', SOAPString.new(obj.name)) - addiv2soapattr(param, obj, map) - when ::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)) - addiv2soapattr(param, obj, map) - when ::Struct - unless @allow_original_mapping - # treat it as an user defined class. [ruby-talk:104980] - #param = unknownobj2soap(soap_class, obj, info, map) - param = SOAPStruct.new(XSD::AnyTypeName) - mark_marshalled_obj(obj, param) - obj.members.each do |member| - param.add(Mapping.name2elename(member), - Mapping._obj2soap(obj[member], map)) - end - else - param = SOAPStruct.new(TYPE_STRUCT) - mark_marshalled_obj(obj, param) - param.add('type', ele_type = SOAPString.new(obj.class.to_s)) - ele_member = SOAPStruct.new - obj.members.each do |member| - ele_member.add(Mapping.name2elename(member), - Mapping._obj2soap(obj[member], map)) - end - param.add('member', ele_member) - addiv2soapattr(param, obj, map) - end - when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat, - ::MatchData, Method, ::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) - 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) - 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 - - def soap2obj(obj_class, node, info, map) - rubytype = node.extraattr[RubyTypeName] - if rubytype or node.type.namespace == RubyTypeNamespace - rubytype2obj(node, info, map, rubytype) - elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName - anytype2obj(node, info, map) - else - unknowntype2obj(node, info, map) - end - end - -private - - 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_methods_true(obj).empty? or - !singleton_class.instance_variables.empty? - raise TypeError.new("singleton can't be dumped #{ obj }") - end - 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' - def singleton_methods_true(obj) - obj.singleton_methods(true) - end - else - def singleton_methods_true(obj) - obj.singleton_methods - end - end - - def rubytype2obj(node, info, map, rubytype) - klass = rubytype ? Mapping.class_from_name(rubytype) : nil - obj = nil - case node - when SOAPString - 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 - 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 - - def rubytypestruct2obj(node, info, map, rubytype) - klass = rubytype ? Mapping.class_from_name(rubytype) : nil - obj = nil - case node.type - when TYPE_HASH - klass = rubytype ? Mapping.class_from_name(rubytype) : Hash - obj = create_empty_object(klass) - mark_unmarshalled_obj(node, obj) - node.each do |key, value| - next unless key == 'item' - obj[Mapping._soap2obj(value['key'], map)] = - Mapping._soap2obj(value['value'], map) - end - if node.key?('default') - obj.default = Mapping._soap2obj(node['default'], map) - end - 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) - when TYPE_MODULE - obj = Mapping.class_from_name(node['name'].data) - when TYPE_SYMBOL - obj = node['id'].data.intern - when TYPE_STRUCT - typestr = Mapping.elename2name(node['type'].data) - klass = Mapping.class_from_name(typestr) - if klass.nil? - return false - end - unless klass <= ::Struct - return false - end - obj = create_empty_object(klass) - mark_unmarshalled_obj(node, obj) - node['member'].each do |name, value| - obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map) - end - else - return unknowntype2obj(node, info, map) - end - return true, obj - end - - def anytype2obj(node, info, map) - case node - when SOAPBasetype - return true, node.data - when SOAPStruct - klass = ::SOAP::Mapping::Object - obj = klass.new - mark_unmarshalled_obj(node, obj) - node.each do |name, value| - obj.__set_property(name, Mapping._soap2obj(value, map)) - end - return true, obj - else - return false - end - end - - def unknowntype2obj(node, info, map) - if node.is_a?(SOAPStruct) - obj = unknownstruct2obj(node, info, map) - return true, obj if obj - if !@allow_untyped_struct - return false - end - return anytype2obj(node, info, map) - else - # Basetype which is not defined... - return false - end - end - - 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? - 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) - mark_unmarshalled_obj(node, obj) - setiv2obj(obj, node, map) - 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 - obj = create_empty_object(klass) - mark_unmarshalled_obj(node, obj) - obj - end - - # Only creates empty string. Do String#replace it with real string. - def string2obj(node, map, rubytype) - klass = rubytype ? Mapping.class_from_name(rubytype) : String - obj = create_empty_object(klass) - mark_unmarshalled_obj(node, obj) - obj - end -end - - -end -end diff --git a/lib/soap/mapping/typeMap.rb b/lib/soap/mapping/typeMap.rb deleted file mode 100644 index 93f24b4bd8..0000000000 --- a/lib/soap/mapping/typeMap.rb +++ /dev/null @@ -1,41 +0,0 @@ -# SOAP4R - Base type mapping definition -# 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. - - -module SOAP - - -TypeMap = { - XSD::XSDAnySimpleType::Type => SOAPAnySimpleType, - XSD::XSDString::Type => SOAPString, - XSD::XSDBoolean::Type => SOAPBoolean, - XSD::XSDDecimal::Type => SOAPDecimal, - XSD::XSDFloat::Type => SOAPFloat, - XSD::XSDDouble::Type => SOAPDouble, - XSD::XSDDuration::Type => SOAPDuration, - XSD::XSDDateTime::Type => SOAPDateTime, - XSD::XSDTime::Type => SOAPTime, - XSD::XSDDate::Type => SOAPDate, - XSD::XSDGYearMonth::Type => SOAPGYearMonth, - XSD::XSDGYear::Type => SOAPGYear, - XSD::XSDGMonthDay::Type => SOAPGMonthDay, - XSD::XSDGDay::Type => SOAPGDay, - XSD::XSDGMonth::Type => SOAPGMonth, - XSD::XSDHexBinary::Type => SOAPHexBinary, - XSD::XSDBase64Binary::Type => SOAPBase64, - XSD::XSDAnyURI::Type => SOAPAnyURI, - XSD::XSDQName::Type => SOAPQName, - XSD::XSDInteger::Type => SOAPInteger, - XSD::XSDLong::Type => SOAPLong, - XSD::XSDInt::Type => SOAPInt, - XSD::XSDShort::Type => SOAPShort, - - SOAP::SOAPBase64::Type => SOAPBase64, -} - - -end diff --git a/lib/soap/mapping/wsdlRegistry.rb b/lib/soap/mapping/wsdlRegistry.rb deleted file mode 100644 index 64f49f2265..0000000000 --- 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/marshal.rb b/lib/soap/marshal.rb deleted file mode 100644 index 7202a6aba8..0000000000 --- a/lib/soap/marshal.rb +++ /dev/null @@ -1,58 +0,0 @@ -# SOAP4R - Marshalling/Unmarshalling Ruby's object using SOAP Encoding. -# Copyright (C) 2001, 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/mapping" -require "soap/processor" - - -module SOAP - - -module Marshal - # Trying xsd:dateTime data to be recovered as aTime. aDateTime if it fails. - MarshalMappingRegistry = Mapping::Registry.new(:allow_original_mapping => true) - MarshalMappingRegistry.add( - Time, - ::SOAP::SOAPDateTime, - ::SOAP::Mapping::Registry::DateTimeFactory - ) - - class << self - public - def dump(obj, io = nil) - marshal(obj, MarshalMappingRegistry, io) - end - - def load(stream) - unmarshal(stream, MarshalMappingRegistry) - end - - def marshal(obj, mapping_registry = MarshalMappingRegistry, io = nil) - elename = Mapping.name2elename(obj.class.to_s) - soap_obj = Mapping.obj2soap(obj, mapping_registry) - body = SOAPBody.new - body.add(elename, soap_obj) - env = SOAPEnvelope.new(nil, body) - SOAP::Processor.marshal(env, {}, io) - end - - def unmarshal(stream, mapping_registry = MarshalMappingRegistry) - env = SOAP::Processor.unmarshal(stream) - if env.nil? - raise ArgumentError.new("Illegal SOAP marshal format.") - end - Mapping.soap2obj(env.body.root_node, mapping_registry) - end - end -end - - -end - - -SOAPMarshal = SOAP::Marshal diff --git a/lib/soap/mimemessage.rb b/lib/soap/mimemessage.rb deleted file mode 100644 index 1197cebc8c..0000000000 --- a/lib/soap/mimemessage.rb +++ /dev/null @@ -1,238 +0,0 @@ -# SOAP4R - MIME Message implementation. -# Copyright (C) 2002 Jamie Herre. - -# 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/attachment' - - -module SOAP - - -# Classes for MIME message handling. Should be put somewhere else! -# Tried using the 'tmail' module but found that I needed something -# lighter in weight. - - -class MIMEMessage - class MIMEMessageError < StandardError; end - - MultipartContentType = 'multipart/\w+' - - class Header - attr_accessor :str, :key, :root - - def initialize - @attrs = {} - end - - def [](key) - @attrs[key] - end - - def []=(key, value) - @attrs[key] = value - end - - def to_s - @key + ": " + @str - end - end - - class Headers < Hash - def self.parse(str) - new.parse(str) - end - - def parse(str) - header_cache = nil - str.each do |line| - case line - when /^\A[^\: \t]+:\s*.+$/ - parse_line(header_cache) if header_cache - header_cache = line.sub(/\r?\n\z/, '') - when /^\A\s+(.*)$/ - # a continuous line at the beginning line crashes here. - header_cache << line - else - raise RuntimeError.new("unexpected header: #{line.inspect}") - end - end - parse_line(header_cache) if header_cache - self - end - - def parse_line(line) - if /^\A([^\: \t]+):\s*(.+)\z/ =~ line - header = parse_rhs($2.strip) - header.key = $1.strip - self[header.key.downcase] = header - else - raise RuntimeError.new("unexpected header line: #{line.inspect}") - end - end - - def parse_rhs(str) - a = str.split(/;+\s+/) - header = Header.new - header.str = str - header.root = a.shift - a.each do |pair| - if pair =~ /(\w+)\s*=\s*"?([^"]+)"?/ - header[$1.downcase] = $2 - else - raise RuntimeError.new("unexpected header component: #{pair.inspect}") - end - end - header - end - - def add(key, value) - if key != nil and value != nil - header = parse_rhs(value) - header.key = key - self[key.downcase] = header - end - end - - def to_s - self.values.collect { |hdr| - hdr.to_s - }.join("\r\n") - end - end - - class Part - attr_accessor :headers, :body - - def initialize - @headers = Headers.new - @headers.add("Content-Transfer-Encoding", "8bit") - @body = nil - end - - def self.parse(str) - new.parse(str) - end - - def parse(str) - headers, body = str.split(/\r\n\r\n/s) - if headers != nil and body != nil - @headers = Headers.parse(headers) - @body = body.sub(/\r\n\z/, '') - else - raise RuntimeError.new("unexpected part: #{str.inspect}") - end - self - end - - def contentid - if @contentid == nil and @headers.key?('content-id') - @contentid = @headers['content-id'].str - @contentid = $1 if @contentid =~ /^<(.+)>$/ - end - @contentid - end - - alias content body - - def to_s - @headers.to_s + "\r\n\r\n" + @body - end - end - - def initialize - @parts = [] - @headers = Headers.new - end - - def self.parse(head, str) - new.parse(head, str) - end - - attr_reader :parts, :headers - - def close - @headers.add( - "Content-Type", - "multipart/related; type=\"text/xml\"; boundary=\"#{boundary}\"; start=\"#{@parts[0].contentid}\"" - ) - end - - def parse(head, str) - @headers = Headers.parse(head + "\r\n" + "From: jfh\r\n") - boundary = @headers['content-type']['boundary'] - if boundary != nil - parts = str.split(/--#{Regexp.quote(boundary)}\s*(?:\r\n|--\r\n)/) - part = parts.shift # preamble must be ignored. - @parts = parts.collect { |part| Part.parse(part) } - else - @parts = [Part.parse(str)] - end - if @parts.length < 1 - raise MIMEMessageError.new("This message contains no valid parts!") - end - self - end - - def root - if @root == nil - start = @headers['content-type']['start'] - @root = (start && @parts.find { |prt| prt.contentid == start }) || - @parts[0] - end - @root - end - - def boundary - if @boundary == nil - @boundary = "----=Part_" + __id__.to_s + rand.to_s - end - @boundary - end - - def add_part(content) - part = Part.new - part.headers.add("Content-Type", - "text/xml; charset=" + XSD::Charset.encoding_label) - part.headers.add("Content-ID", Attachment.contentid(part)) - part.body = content - @parts.unshift(part) - end - - def add_attachment(attach) - part = Part.new - part.headers.add("Content-Type", attach.contenttype) - part.headers.add("Content-ID", attach.mime_contentid) - part.body = attach.content - @parts.unshift(part) - end - - def has_parts? - (@parts.length > 0) - end - - def headers_str - @headers.to_s - end - - def content_str - str = '' - @parts.each do |prt| - str << "--" + boundary + "\r\n" - str << prt.to_s + "\r\n" - end - str << '--' + boundary + "--\r\n" - str - end - - def to_s - str = headers_str + "\r\n\r\n" + conent_str - end -end - - -end diff --git a/lib/soap/netHttpClient.rb b/lib/soap/netHttpClient.rb deleted file mode 100644 index 1e9d71c5a3..0000000000 --- a/lib/soap/netHttpClient.rb +++ /dev/null @@ -1,174 +0,0 @@ -# SOAP4R - net/http wrapper -# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -require 'net/http' - - -module SOAP - - -class NetHttpClient - - SSLEnabled = begin - require 'net/https' - true - rescue LoadError - false - end - - attr_reader :proxy - attr_accessor :no_proxy - attr_accessor :debug_dev - attr_accessor :ssl_config # ignored for now. - attr_accessor :protocol_version # ignored for now. - - def initialize(proxy = nil, agent = nil) - @proxy = proxy ? URI.parse(proxy) : nil - @agent = agent - @debug_dev = nil - @session_manager = SessionManager.new - @no_proxy = nil - end - - def test_loopback_response - raise NotImplementedError.new("not supported for now") - end - - def proxy=(proxy_str) - if proxy_str.nil? - @proxy = nil - else - @proxy = URI.parse(proxy_str) - if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or - @proxy.host == nil or @proxy.port == nil - raise ArgumentError.new("unsupported proxy `#{proxy_str}'") - end - @proxy - end - end - - def set_basic_auth(uri, user_id, passwd) - # net/http does not handle url. - @basic_auth = [user_id, passwd] - end - - def set_cookie_store(filename) - raise NotImplementedError.new - end - - def save_cookie_store(filename) - raise NotImplementedError.new - end - - def reset(url) - # no persistent connection. ignored. - end - - def reset_all - # no persistent connection. ignored. - end - - def post(url, req_body, header = {}) - url = URI.parse(url) - extra = header.dup - extra['User-Agent'] = @agent if @agent - res = start(url) { |http| - http.post(url.request_uri, req_body, extra) - } - Response.new(res) - end - - def get_content(url, header = {}) - url = URI.parse(url) - extra = header.dup - extra['User-Agent'] = @agent if @agent - res = start(url) { |http| - http.get(url.request_uri, extra) - } - res.body - end - -private - - def start(url) - http = create_connection(url) - response = nil - http.start { |worker| - response, = yield(worker) - worker.finish - } - @debug_dev << response.body if @debug_dev - response - end - - def create_connection(url) - proxy_host = proxy_port = nil - unless no_proxy?(url) - proxy_host = @proxy.host - proxy_port = @proxy.port - end - http = Net::HTTP::Proxy(proxy_host, proxy_port).new(url.host, url.port) - if http.respond_to?(:set_debug_output) - http.set_debug_output(@debug_dev) - end - case url - when URI::HTTPS - if SSLEnabled - http.use_ssl = true - else - raise RuntimeError.new("Cannot connect to #{url} (OpenSSL is not installed.)") - end - when URI::HTTP - # OK - else - raise RuntimeError.new("Cannot connect to #{url} (Not HTTP.)") - end - http - end - - NO_PROXY_HOSTS = ['localhost'] - - def no_proxy?(uri) - if !@proxy or NO_PROXY_HOSTS.include?(uri.host) - return true - end - if @no_proxy - @no_proxy.scan(/([^:,]*)(?::(\d+))?/) do |host, port| - if /(\A|\.)#{Regexp.quote(host)}\z/i =~ uri.host && - (!port || uri.port == port.to_i) - return true - end - end - else - false - end - end - - class SessionManager - attr_accessor :connect_timeout - attr_accessor :send_timeout - attr_accessor :receive_timeout - end - - class Response - attr_reader :content - attr_reader :status - attr_reader :reason - attr_reader :contenttype - - def initialize(res) - @status = res.code.to_i - @reason = res.message - @contenttype = res['content-type'] - @content = res.body - end - end -end - - -end diff --git a/lib/soap/parser.rb b/lib/soap/parser.rb deleted file mode 100644 index 14704a6d9b..0000000000 --- a/lib/soap/parser.rb +++ /dev/null @@ -1,252 +0,0 @@ -# SOAP4R - SOAP XML Instance Parser library. -# Copyright (C) 2001, 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 'xsd/ns' -require 'xsd/xmlparser' -require 'soap/soap' -require 'soap/baseData' -require 'soap/encodingstyle/handler' - - -module SOAP - - -class Parser - include SOAP - - class ParseError < Error; end - class FormatDecodeError < ParseError; end - class UnexpectedElementError < ParseError; end - -private - - class ParseFrame - attr_reader :node - attr_reader :name - attr_reader :ns, :encodingstyle - - class NodeContainer - def initialize(node) - @node = node - end - - def node - @node - end - - def replace_node(node) - @node = node - end - end - - public - - def initialize(ns, name, node, encodingstyle) - @ns = ns - @name = name - self.node = node - @encodingstyle = encodingstyle - end - - def node=(node) - @node = NodeContainer.new(node) - end - end - -public - - attr_accessor :default_encodingstyle - attr_accessor :decode_typemap - attr_accessor :allow_unqualified_element - - def initialize(opt = {}) - @opt = opt - @parser = XSD::XMLParser.create_parser(self, opt) - @parsestack = nil - @lastnode = nil - @handlers = {} - @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace - @decode_typemap = opt[:decode_typemap] || nil - @allow_unqualified_element = opt[:allow_unqualified_element] || false - end - - def charset - @parser.charset - end - - def parse(string_or_readable) - @parsestack = [] - @lastnode = nil - - @handlers.each do |uri, handler| - handler.decode_prologue - end - - @parser.do_parse(string_or_readable) - - unless @parsestack.empty? - raise FormatDecodeError.new("Unbalanced tag in XML.") - end - - @handlers.each do |uri, handler| - handler.decode_epilogue - end - - @lastnode - end - - def start_element(name, attrs) - lastframe = @parsestack.last - ns = parent = parent_encodingstyle = nil - if lastframe - ns = lastframe.ns.clone_ns - parent = lastframe.node - parent_encodingstyle = lastframe.encodingstyle - else - ns = XSD::NS.new - parent = ParseFrame::NodeContainer.new(nil) - parent_encodingstyle = nil - end - - attrs = XSD::XMLParser.filter_ns(ns, attrs) - encodingstyle = find_encodingstyle(ns, attrs) - - # Children's encodingstyle is derived from its parent. - if encodingstyle.nil? - if parent.node.is_a?(SOAPHeader) - encodingstyle = LiteralNamespace - else - encodingstyle = parent_encodingstyle || @default_encodingstyle - end - end - - node = decode_tag(ns, name, attrs, parent, encodingstyle) - - @parsestack << ParseFrame.new(ns, name, node, encodingstyle) - end - - def characters(text) - 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) - else - # Ignore Text outside of SOAP Envelope. - p text if $DEBUG - end - end - - def end_element(name) - lastframe = @parsestack.pop - unless name == lastframe.name - raise UnexpectedElementError.new("Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.") - end - decode_tag_end(lastframe.ns, lastframe.node, lastframe.encodingstyle) - @lastnode = lastframe.node.node - end - -private - - def find_encodingstyle(ns, attrs) - attrs.each do |key, value| - if (ns.compare(EnvelopeNamespace, AttrEncodingStyle, key)) - return value - end - end - nil - end - - def decode_tag(ns, name, attrs, parent, encodingstyle) - ele = ns.parse(name) - - # Envelope based parsing. - if ((ele.namespace == EnvelopeNamespace) || - (@allow_unqualified_element && ele.namespace.nil?)) - o = decode_soap_envelope(ns, ele, attrs, parent) - return o if o - end - - # Encoding based parsing. - handler = find_handler(encodingstyle) - if handler - return handler.decode_tag(ns, ele, attrs, parent) - else - raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.") - end - end - - def decode_tag_end(ns, node, encodingstyle) - return unless encodingstyle - - handler = find_handler(encodingstyle) - if handler - return handler.decode_tag_end(ns, node) - else - raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.") - end - end - - def decode_text(ns, text, encodingstyle) - handler = find_handler(encodingstyle) - - if handler - handler.decode_text(ns, text) - else - # How should I do? - end - end - - def decode_soap_envelope(ns, ele, attrs, parent) - o = nil - if ele.name == EleEnvelope - o = SOAPEnvelope.new - if ext = @opt[:external_content] - ext.each do |k, v| - o.external_content[k] = v - end - end - elsif ele.name == EleHeader - unless parent.node.is_a?(SOAPEnvelope) - raise FormatDecodeError.new("Header should be a child of Envelope.") - end - o = SOAPHeader.new - parent.node.header = o - elsif ele.name == EleBody - unless parent.node.is_a?(SOAPEnvelope) - raise FormatDecodeError.new("Body should be a child of Envelope.") - end - o = SOAPBody.new - parent.node.body = o - elsif ele.name == EleFault - unless parent.node.is_a?(SOAPBody) - raise FormatDecodeError.new("Fault should be a child of Body.") - end - o = SOAPFault.new - parent.node.fault = o - end - o - end - - def find_handler(encodingstyle) - unless @handlers.key?(encodingstyle) - handler_factory = SOAP::EncodingStyle::Handler.handler(encodingstyle) || - SOAP::EncodingStyle::Handler.handler(EncodingNamespace) - handler = handler_factory.new(@parser.charset) - handler.decode_typemap = @decode_typemap - handler.decode_prologue - @handlers[encodingstyle] = handler - end - @handlers[encodingstyle] - end -end - - -end diff --git a/lib/soap/processor.rb b/lib/soap/processor.rb deleted file mode 100644 index 3c6dbedf2f..0000000000 --- a/lib/soap/processor.rb +++ /dev/null @@ -1,66 +0,0 @@ -# SOAP4R - marshal/unmarshal interface. -# Copyright (C) 2000, 2001, 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 'xsd/datatypes' -require 'soap/soap' -require 'soap/element' -require 'soap/parser' -require 'soap/generator' -require 'soap/encodingstyle/soapHandler' -require 'soap/encodingstyle/literalHandler' -require 'soap/encodingstyle/aspDotNetHandler' - - -module SOAP - - -module Processor - @@default_parser_option = {} - - class << self - public - - def marshal(env, opt = {}, io = nil) - generator = create_generator(opt) - marshalled_str = generator.generate(env, io) - unless env.external_content.empty? - opt[:external_content] = env.external_content - end - marshalled_str - end - - def unmarshal(stream, opt = {}) - parser = create_parser(opt) - parser.parse(stream) - end - - def default_parser_option=(rhs) - @@default_parser_option = rhs - end - - def default_parser_option - @@default_parser_option - end - - private - - def create_generator(opt) - SOAPGenerator.new(opt) - end - - def create_parser(opt) - if opt.empty? - opt = @@default_parser_option - end - ::SOAP::Parser.new(opt) - end - end -end - - -end diff --git a/lib/soap/property.rb b/lib/soap/property.rb deleted file mode 100644 index 113cc64f3c..0000000000 --- a/lib/soap/property.rb +++ /dev/null @@ -1,328 +0,0 @@ -# soap/property.rb: SOAP4R - Property implementation. -# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -module SOAP - - -# Property stream format: -# -# line separator is \r?\n. 1 line per a property. -# line which begins with '#' is a comment line. empty line is ignored, too. -# key/value separator is ':' or '='. -# '\' as escape character. but line separator cannot be escaped. -# \s at the head/tail of key/value are trimmed. -# -# '[' + key + ']' indicates property section. for example, -# -# [aaa.bbb] -# ccc = ddd -# eee.fff = ggg -# [] -# aaa.hhh = iii -# -# is the same as; -# -# aaa.bbb.ccc = ddd -# aaa.bbb.eee.fff = ggg -# aaa.hhh = iii -# -class Property - include Enumerable - - module Util - def const_from_name(fqname) - fqname.split("::").inject(Kernel) { |klass, name| klass.const_get(name) } - end - module_function :const_from_name - - def require_from_name(fqname) - require File.join(fqname.split("::").collect { |ele| ele.downcase }) - end - module_function :require_from_name - end - - def self.load(stream) - new.load(stream) - end - - def self.loadproperty(propname) - new.loadproperty(propname) - end - - def initialize - @store = Hash.new - @hook = Hash.new - @self_hook = Array.new - @locked = false - end - - KEY_REGSRC = '([^=:\\\\]*(?:\\\\.[^=:\\\\]*)*)' - DEF_REGSRC = '\\s*' + KEY_REGSRC + '\\s*[=:]\\s*(.*)' - COMMENT_REGEXP = Regexp.new('^(?:#.*|)$') - CATDEF_REGEXP = Regexp.new("^\\[\\s*#{KEY_REGSRC}\\s*\\]$") - LINE_REGEXP = Regexp.new("^#{DEF_REGSRC}$") - def load(stream) - key_prefix = "" - stream.each_with_index do |line, lineno| - line.sub!(/\r?\n\z/, '') - case line - when COMMENT_REGEXP - next - when CATDEF_REGEXP - key_prefix = $1.strip - when LINE_REGEXP - key, value = $1.strip, $2.strip - key = "#{key_prefix}.#{key}" unless key_prefix.empty? - key = eval("\"#{key}\"") - value = eval("\"#{value}\"") - self[key] = value - else - raise TypeError.new( - "property format error at line #{lineno + 1}: `#{line}'") - end - end - self - end - - # find property from $:. - def loadproperty(propname) - return loadpropertyfile(propname) if File.file?(propname) - $:.each do |path| - if File.file?(file = File.join(path, propname)) - return loadpropertyfile(file) - end - end - nil - end - - # name: a Symbol, String or an Array - def [](name) - referent(name_to_a(name)) - end - - # name: a Symbol, String or an Array - # value: an Object - def []=(name, value) - name_pair = name_to_a(name).freeze - hooks = assign(name_pair, value) - hooks.each do |hook| - hook.call(name_pair, value) - end - value - end - - # value: an Object - # key is generated by property - def <<(value) - self[generate_new_key] = value - end - - # name: a Symbol, String or an Array; nil means hook to the root - # cascade: true/false; for cascading hook of sub key - # hook: block which will be called with 2 args, name and value - def add_hook(name = nil, cascade = false, &hook) - if name == nil or name == true or name == false - cascade = name - assign_self_hook(cascade, &hook) - else - assign_hook(name_to_a(name), cascade, &hook) - end - end - - def each - @store.each do |key, value| - yield(key, value) - end - end - - def empty? - @store.empty? - end - - def keys - @store.keys - end - - def values - @store.values - end - - def lock(cascade = false) - if cascade - each_key do |key| - key.lock(cascade) - end - end - @locked = true - self - end - - def unlock(cascade = false) - @locked = false - if cascade - each_key do |key| - key.unlock(cascade) - end - end - self - end - - def locked? - @locked - end - -protected - - def deref_key(key) - check_lock(key) - ref = @store[key] ||= self.class.new - unless propkey?(ref) - raise ArgumentError.new("key `#{key}' already defined as a value") - end - ref - end - - def local_referent(key) - check_lock(key) - if propkey?(@store[key]) and @store[key].locked? - raise TypeError.new("cannot split any key from locked property") - end - @store[key] - end - - def local_assign(key, value) - check_lock(key) - if @locked - if propkey?(value) - raise TypeError.new("cannot add any key to locked property") - elsif propkey?(@store[key]) - raise TypeError.new("cannot override any key in locked property") - end - end - @store[key] = value - end - - def local_hook(key, direct) - hooks = [] - (@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade| - hooks << hook if direct or cascade - end - hooks - end - - def local_assign_hook(key, cascade, &hook) - check_lock(key) - @store[key] ||= nil - (@hook[key] ||= []) << [hook, cascade] - end - -private - - NO_HOOK = [].freeze - - def referent(ary) - ary[0..-2].inject(self) { |ref, name| - ref.deref_key(to_key(name)) - }.local_referent(to_key(ary.last)) - end - - def assign(ary, value) - ref = self - hook = NO_HOOK - ary[0..-2].each do |name| - key = to_key(name) - hook += ref.local_hook(key, false) - ref = ref.deref_key(key) - end - last_key = to_key(ary.last) - ref.local_assign(last_key, value) - hook + ref.local_hook(last_key, true) - end - - def assign_hook(ary, cascade, &hook) - ary[0..-2].inject(self) { |ref, name| - ref.deref_key(to_key(name)) - }.local_assign_hook(to_key(ary.last), cascade, &hook) - end - - def assign_self_hook(cascade, &hook) - check_lock(nil) - @self_hook << [hook, cascade] - end - - def each_key - self.each do |key, value| - if propkey?(value) - yield(value) - end - end - end - - def check_lock(key) - if @locked and (key.nil? or !@store.key?(key)) - raise TypeError.new("cannot add any key to locked property") - end - end - - def propkey?(value) - value.is_a?(::SOAP::Property) - end - - def name_to_a(name) - case name - when Symbol - [name] - when String - name.scan(/[^.\\]+(?:\\.[^.\\])*/) # split with unescaped '.' - when Array - name - else - raise ArgumentError.new("Unknown name #{name}(#{name.class})") - end - end - - def to_key(name) - name.to_s.downcase - end - - def generate_new_key - if @store.empty? - "0" - else - (key_max + 1).to_s - end - end - - def key_max - (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i - end - - def loadpropertyfile(file) - puts "find property at #{file}" if $DEBUG - File.open(file) do |f| - load(f) - end - end -end - - -end - - -# for ruby/1.6. -unless Enumerable.instance_methods.include?('inject') - module Enumerable - def inject(init) - result = init - each do |item| - result = yield(result, item) - end - result - end - end -end diff --git a/lib/soap/rpc/cgistub.rb b/lib/soap/rpc/cgistub.rb deleted file mode 100644 index 55437bac59..0000000000 --- a/lib/soap/rpc/cgistub.rb +++ /dev/null @@ -1,206 +0,0 @@ -# SOAP4R - CGI stub library -# Copyright (C) 2001, 2003, 2004 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/streamHandler' -require 'webrick/httpresponse' -require 'webrick/httpstatus' -require 'logger' -require 'soap/rpc/router' - - -module SOAP -module RPC - - -### -# SYNOPSIS -# CGIStub.new -# -# DESCRIPTION -# To be written... -# -class CGIStub < Logger::Application - include SOAP - - # There is a client which does not accept the media-type which is defined in - # SOAP spec. - attr_accessor :mediatype - - class CGIError < Error; end - - class SOAPRequest - ALLOWED_LENGTH = 1024 * 1024 - - def initialize(stream = $stdin) - @method = ENV['REQUEST_METHOD'] - @size = ENV['CONTENT_LENGTH'].to_i || 0 - @contenttype = ENV['CONTENT_TYPE'] - @soapaction = ENV['HTTP_SOAPAction'] - @source = stream - @body = nil - end - - def init - validate - @body = @source.read(@size) - self - end - - def dump - @body.dup - end - - def soapaction - @soapaction - end - - def contenttype - @contenttype - end - - def to_s - "method: #{ @method }, size: #{ @size }" - end - - private - - def validate # raise CGIError - if @method != 'POST' - raise CGIError.new("Method '#{ @method }' not allowed.") - end - - if @size > ALLOWED_LENGTH - raise CGIError.new("Content-length too long.") - end - end - end - - def initialize(appname, default_namespace) - super(appname) - set_log(STDERR) - self.level = ERROR - @default_namespace = default_namespace - @router = SOAP::RPC::Router.new(appname) - @remote_user = ENV['REMOTE_USER'] || 'anonymous' - @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown' - @request = nil - @response = nil - @mediatype = MediaType - on_init - end - - def add_rpc_servant(obj, namespace = @default_namespace, soapaction = nil) - RPC.defined_methods(obj).each do |name| - qname = XSD::QName.new(namespace, name) - param_size = obj.method(name).arity.abs - params = (1..param_size).collect { |i| "p#{i}" } - param_def = SOAP::RPC::SOAPMethod.create_param_def(params) - @router.add_method(obj, qname, soapaction, name, param_def) - end - end - alias add_servant add_rpc_servant - - def add_rpc_headerhandler(obj) - @router.headerhandler << obj - end - alias add_headerhandler add_rpc_headerhandler - - def on_init - # Override this method in derived class to call 'add_method' to add methods. - end - - def mapping_registry - @router.mapping_registry - end - - def mapping_registry=(value) - @router.mapping_registry = value - end - - def add_method(receiver, name, *param) - add_method_with_namespace_as(@default_namespace, receiver, - name, name, *param) - end - - def add_method_as(receiver, name, name_as, *param) - add_method_with_namespace_as(@default_namespace, receiver, - name, name_as, *param) - end - - def add_method_with_namespace(namespace, receiver, name, *param) - add_method_with_namespace_as(namespace, receiver, name, name, *param) - end - - def add_method_with_namespace_as(namespace, receiver, name, name_as, *param) - param_def = if param.size == 1 and param[0].is_a?(Array) - param[0] - else - SOAP::RPC::SOAPMethod.create_param_def(param) - end - qname = XSD::QName.new(namespace, name_as) - @router.add_method(receiver, qname, nil, name, param_def) - end - - def route(conn_data) - @router.route(conn_data) - end - - def create_fault_response(e) - @router.create_fault_response(e) - end - -private - - def run - prologue - - httpversion = WEBrick::HTTPVersion.new('1.0') - @response = WEBrick::HTTPResponse.new({:HTTPVersion => httpversion}) - conn_data = nil - begin - log(INFO) { "Received a request from '#{ @remote_user }@#{ @remote_host }'." } - # SOAP request parsing. - @request = SOAPRequest.new.init - @response['Status'] = 200 - conn_data = ::SOAP::StreamHandler::ConnectionData.new - conn_data.receive_string = @request.dump - conn_data.receive_contenttype = @request.contenttype - log(DEBUG) { "XML Request: #{conn_data.receive_string}" } - conn_data = route(conn_data) - log(DEBUG) { "XML Response: #{conn_data.send_string}" } - if conn_data.is_fault - @response['Status'] = 500 - end - @response['Cache-Control'] = 'private' - @response.body = conn_data.send_string - @response['content-type'] = conn_data.send_contenttype - rescue Exception - conn_data = create_fault_response($!) - @response['Cache-Control'] = 'private' - @response['Status'] = 500 - @response.body = conn_data.send_string - @response['content-type'] = conn_data.send_contenttype || @mediatype - ensure - buf = '' - @response.send_response(buf) - buf.sub!(/^[^\r]+\r\n/, '') # Trim status line. - log(DEBUG) { "SOAP CGI Response:\n#{ buf }" } - print buf - epilogue - end - - 0 - end - - def prologue; end - def epilogue; end -end - - -end -end diff --git a/lib/soap/rpc/driver.rb b/lib/soap/rpc/driver.rb deleted file mode 100644 index 0e59dde9be..0000000000 --- a/lib/soap/rpc/driver.rb +++ /dev/null @@ -1,300 +0,0 @@ -# SOAP4R - SOAP RPC driver -# Copyright (C) 2000, 2001, 2003, 2004 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/soap' -require 'soap/mapping' -require 'soap/rpc/rpc' -require 'soap/rpc/proxy' -require 'soap/rpc/element' -require 'soap/streamHandler' -require 'soap/property' -require 'soap/header/handlerset' - - -module SOAP -module RPC - - -class Driver - class EmptyResponseError < Error; end - - class << self - def __attr_proxy(symbol, assignable = false) - name = symbol.to_s - module_eval <<-EOD - def #{name} - @servant.#{name} - end - EOD - if assignable - module_eval <<-EOD - def #{name}=(rhs) - @servant.#{name} = rhs - end - EOD - end - end - end - - __attr_proxy :options - __attr_proxy :headerhandler - __attr_proxy :test_loopback_response - __attr_proxy :endpoint_url, true - __attr_proxy :mapping_registry, true - __attr_proxy :soapaction, true - __attr_proxy :default_encodingstyle, true - - def httpproxy - @servant.options["protocol.http.proxy"] - end - - def httpproxy=(httpproxy) - @servant.options["protocol.http.proxy"] = httpproxy - end - - def wiredump_dev - @servant.options["protocol.http.wiredump_dev"] - end - - def wiredump_dev=(wiredump_dev) - @servant.options["protocol.http.wiredump_dev"] = wiredump_dev - end - - def mandatorycharset - @servant.options["protocol.mandatorycharset"] - end - - def mandatorycharset=(mandatorycharset) - @servant.options["protocol.mandatorycharset"] = mandatorycharset - end - - def wiredump_file_base - @servant.options["protocol.wiredump_file_base"] - end - - def wiredump_file_base=(wiredump_file_base) - @servant.options["protocol.wiredump_file_base"] = wiredump_file_base - end - - def initialize(endpoint_url, namespace, soapaction = nil) - @servant = Servant__.new(self, endpoint_url, namespace) - @servant.soapaction = soapaction - @proxy = @servant.proxy - end - - def loadproperty(propertyname) - unless options.loadproperty(propertyname) - raise LoadError.new("No such property to load -- #{propertyname}") - end - end - - def inspect - "#<#{self.class}:#{@servant.streamhandler.inspect}>" - end - - def add_method(name, *params) - add_method_with_soapaction_as(name, name, @servant.soapaction, *params) - end - - def add_method_as(name, name_as, *params) - add_method_with_soapaction_as(name, name_as, @servant.soapaction, *params) - end - - def add_method_with_soapaction(name, soapaction, *params) - add_method_with_soapaction_as(name, name, soapaction, *params) - end - - def add_method_with_soapaction_as(name, name_as, soapaction, *params) - param_def = if params.size == 1 and params[0].is_a?(Array) - params[0] - else - SOAPMethod.create_param_def(params) - end - @servant.add_method(name_as, soapaction, name, param_def) - end - - def reset_stream - @servant.streamhandler.reset - end - - def invoke(headers, body) - @servant.invoke(headers, body) - end - - def call(name, *params) - @servant.call(name, *params) - end - -private - - def add_rpc_method_interface(name, param_def) - @servant.add_rpc_method_interface(name, param_def) - end - - class Servant__ - attr_reader :options - attr_reader :streamhandler - attr_reader :headerhandler - attr_reader :proxy - - def initialize(host, endpoint_url, namespace) - @host = host - @namespace = namespace - @mapping_registry = nil - @soapaction = nil - @wiredump_file_base = nil - @options = setup_options - @streamhandler = HTTPPostStreamHandler.new(endpoint_url, - @options["protocol.http"] ||= ::SOAP::Property.new) - @headerhandler = Header::HandlerSet.new - @proxy = Proxy.new(@streamhandler, @soapaction) - @proxy.allow_unqualified_element = true - end - - def endpoint_url - @streamhandler.endpoint_url - end - - def endpoint_url=(endpoint_url) - @streamhandler.endpoint_url = endpoint_url - @streamhandler.reset - end - - def mapping_registry - @mapping_registry - end - - def mapping_registry=(mapping_registry) - @mapping_registry = mapping_registry - end - - def soapaction - @soapaction - end - - def soapaction=(soapaction) - @soapaction = soapaction - end - - def default_encodingstyle - @proxy.default_encodingstyle - end - - def default_encodingstyle=(encodingstyle) - @proxy.default_encodingstyle = encodingstyle - end - - def test_loopback_response - @streamhandler.test_loopback_response - end - - def invoke(headers, body) - set_wiredump_file_base(body.elename.name) - env = @proxy.invoke(headers, body) - if env.nil? - return nil, nil - else - return env.header, env.body - end - end - - def call(name, *params) - set_wiredump_file_base(name) - # Convert parameters: params array => SOAPArray => members array - params = Mapping.obj2soap(params, @mapping_registry).to_a - env = @proxy.call(call_headers, name, *params) - raise EmptyResponseError.new("Empty response.") unless env - receive_headers(env.header) - begin - @proxy.check_fault(env.body) - rescue SOAP::FaultError => e - Mapping.fault2exception(e) - end - - ret = env.body.response ? - Mapping.soap2obj(env.body.response, @mapping_registry) : nil - if env.body.outparams - outparams = env.body.outparams.collect { |outparam| - Mapping.soap2obj(outparam) - } - return [ret].concat(outparams) - else - return ret - end - end - - def add_method(name_as, soapaction, name, param_def) - qname = XSD::QName.new(@namespace, name_as) - @proxy.add_method(qname, soapaction, name, param_def) - add_rpc_method_interface(name, param_def) - end - - def add_rpc_method_interface(name, param_def) - param_names = [] - i = 0 - @proxy.method[name].each_param_name(RPC::SOAPMethod::IN, - RPC::SOAPMethod::INOUT) do |param_name| - i += 1 - param_names << "arg#{ i }" - end - callparam = (param_names.collect { |pname| ", " + pname }).join - @host.instance_eval <<-EOS - def #{ name }(#{ param_names.join(", ") }) - @servant.call(#{ name.dump }#{ callparam }) - end - EOS - @host.method(name) - end - - private - - def call_headers - headers = @headerhandler.on_outbound - if headers.empty? - nil - else - h = ::SOAP::SOAPHeader.new - headers.each do |header| - h.add(header.elename.name, header) - end - h - end - end - - def receive_headers(headers) - @headerhandler.on_inbound(headers) if headers - end - - def set_wiredump_file_base(name) - if @wiredump_file_base - @streamhandler.wiredump_file_base = @wiredump_file_base + "_#{ name }" - end - end - - def setup_options - if opt = Property.loadproperty(::SOAP::PropertyName) - opt = opt["client"] - end - opt ||= Property.new - opt.add_hook("protocol.mandatorycharset") do |key, value| - @proxy.mandatorycharset = value - end - 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.proxy"] ||= Env::HTTP_PROXY - opt["protocol.http.no_proxy"] ||= Env::NO_PROXY - opt - end - end -end - - -end -end diff --git a/lib/soap/rpc/element.rb b/lib/soap/rpc/element.rb deleted file mode 100644 index 8a2f319293..0000000000 --- a/lib/soap/rpc/element.rb +++ /dev/null @@ -1,270 +0,0 @@ -# SOAP4R - RPC element definition. -# Copyright (C) 2000, 2001, 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' - - -module SOAP - -# Add method definitions for RPC to common definition in element.rb -class SOAPBody < SOAPStruct - public - - def request - root_node - end - - def response - if !@is_fault - if void? - nil - else - # Initial element is [retval]. - root_node[0] - end - else - root_node - end - end - - def outparams - if !@is_fault and !void? - op = root_node[1..-1] - op = nil if op && op.empty? - op - else - nil - end - end - - def void? - root_node.nil? - end - - def fault - if @is_fault - self['fault'] - else - nil - end - end - - def fault=(fault) - @is_fault = true - add_member('fault', fault) - end -end - - -module RPC - - -class RPCError < Error; end -class MethodDefinitionError < RPCError; end -class ParameterError < RPCError; end - -class SOAPMethod < SOAPStruct - RETVAL = 'retval' - IN = 'in' - OUT = 'out' - INOUT = 'inout' - - attr_reader :param_def - attr_reader :inparam - attr_reader :outparam - - def initialize(qname, param_def = nil) - super(nil) - @elename = qname - @encodingstyle = nil - - @param_def = param_def - - @signature = [] - @inparam_names = [] - @inoutparam_names = [] - @outparam_names = [] - - @inparam = {} - @outparam = {} - @retval_name = nil - - init_param(@param_def) if @param_def - end - - def have_outparam? - @outparam_names.size > 0 - end - - def each_param_name(*type) - @signature.each do |io_type, name, param_type| - if type.include?(io_type) - yield(name) - end - end - end - - def set_param(params) - params.each do |param, data| - @inparam[param] = data - data.elename.name = param - data.parent = self - end - end - - def set_outparam(params) - params.each do |param, data| - @outparam[param] = data - data.elename.name = param - end - end - - def SOAPMethod.create_param_def(param_names) - param_def = [] - param_names.each do |param_name| - param_def.push([IN, param_name, nil]) - end - param_def.push([RETVAL, 'return', nil]) - param_def - end - -private - - def init_param(param_def) - param_def.each do |io_type, name, param_type| - case io_type - when IN - @signature.push([IN, name, param_type]) - @inparam_names.push(name) - when OUT - @signature.push([OUT, name, param_type]) - @outparam_names.push(name) - when INOUT - @signature.push([INOUT, name, param_type]) - @inoutparam_names.push(name) - when RETVAL - if (@retval_name) - raise MethodDefinitionError.new('Duplicated retval') - end - @retval_name = name - else - raise MethodDefinitionError.new("Unknown type: #{ io_type }") - end - end - end -end - - -class SOAPMethodRequest < SOAPMethod - attr_accessor :soapaction - - def SOAPMethodRequest.create_request(qname, *params) - param_def = [] - param_value = [] - i = 0 - params.each do |param| - param_name = "p#{ i }" - i += 1 - param_def << [IN, param_name, nil] - param_value << [param_name, param] - end - param_def << [RETVAL, 'return', nil] - o = new(qname, param_def) - o.set_param(param_value) - o - end - - def initialize(qname, param_def = nil, soapaction = nil) - check_elename(qname) - super(qname, param_def) - @soapaction = soapaction - end - - def each - each_param_name(IN, INOUT) do |name| - unless @inparam[name] - raise ParameterError.new("Parameter: #{ name } was not given.") - end - yield(name, @inparam[name]) - end - end - - def dup - req = self.class.new(@elename.dup, @param_def, @soapaction) - req.encodingstyle = @encodingstyle - req - end - - def create_method_response - SOAPMethodResponse.new( - XSD::QName.new(@elename.namespace, @elename.name + 'Response'), - @param_def) - end - -private - - def check_elename(qname) - # NCName & ruby's method name - unless /\A[\w_][\w\d_\-]*\z/ =~ qname.name - raise MethodDefinitionError.new("Element name '#{qname.name}' not allowed") - end - end -end - - -class SOAPMethodResponse < SOAPMethod - - def initialize(qname, param_def = nil) - super(qname, param_def) - @retval = nil - end - - def retval=(retval) - @retval = retval - @retval.elename = @retval.elename.dup_name(@retval_name || 'return') - retval.parent = self - retval - end - - def each - if @retval_name and !@retval.is_a?(SOAPVoid) - yield(@retval_name, @retval) - end - - each_param_name(OUT, INOUT) do |param_name| - unless @outparam[param_name] - raise ParameterError.new("Parameter: #{ param_name } was not given.") - end - yield(param_name, @outparam[param_name]) - end - end -end - - -# To return(?) void explicitly. -# def foo(input_var) -# ... -# return SOAP::RPC::SOAPVoid.new -# end -class SOAPVoid < XSD::XSDAnySimpleType - include SOAPBasetype - extend SOAPModuleUtils - Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil) - -public - def initialize() - @elename = Name - @id = nil - @precedents = [] - @parent = nil - end -end - - -end -end diff --git a/lib/soap/rpc/httpserver.rb b/lib/soap/rpc/httpserver.rb deleted file mode 100644 index 7b1f961d9e..0000000000 --- a/lib/soap/rpc/httpserver.rb +++ /dev/null @@ -1,105 +0,0 @@ -# SOAP4R - WEBrick HTTP Server -# Copyright (C) 2003, 2004 by 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 'logger' -require 'soap/rpc/soaplet' -require 'soap/streamHandler' -require 'webrick' - - -module SOAP -module RPC - - -class HTTPServer < Logger::Application - attr_reader :server - attr_accessor :default_namespace - - def initialize(config) - super(config[:SOAPHTTPServerApplicationName] || self.class.name) - @default_namespace = config[:SOAPDefaultNamespace] - @webrick_config = config.dup - @webrick_config[:Logger] ||= @log - @server = nil - @soaplet = ::SOAP::RPC::SOAPlet.new - self.level = Logger::Severity::INFO - on_init - end - - def on_init - # define extra methods in derived class. - end - - def status - if @server - @server.status - else - nil - end - end - - def shutdown - @server.shutdown if @server - end - - def mapping_registry - @soaplet.app_scope_router.mapping_registry - end - - def mapping_registry=(mapping_registry) - @soaplet.app_scope_router.mapping_registry = mapping_registry - end - - def add_rpc_request_servant(factory, namespace = @default_namespace, - mapping_registry = nil) - @soaplet.add_rpc_request_servant(factory, namespace, mapping_registry) - end - - def add_rpc_servant(obj, namespace = @default_namespace) - @soaplet.add_rpc_servant(obj, namespace) - end - - def add_rpc_request_headerhandler(factory) - @soaplet.add_rpc_request_headerhandler(factory) - end - - def add_rpc_headerhandler(obj) - @soaplet.add_rpc_headerhandler(obj) - end - - def add_method(obj, name, *param) - add_method_as(obj, name, name, *param) - end - - def add_method_as(obj, name, name_as, *param) - qname = XSD::QName.new(@default_namespace, name_as) - soapaction = nil - method = obj.method(name) - param_def = if param.size == 1 and param[0].is_a?(Array) - param[0] - elsif param.empty? - ::SOAP::RPC::SOAPMethod.create_param_def( - (1..method.arity.abs).collect { |i| "p#{ i }" }) - else - SOAP::RPC::SOAPMethod.create_param_def(param) - end - @soaplet.app_scope_router.add_method(obj, qname, soapaction, name, param_def) - end - -private - - def run - @server = WEBrick::HTTPServer.new(@webrick_config) - @server.mount('/', @soaplet) - @server.start - end -end - - -end -end diff --git a/lib/soap/rpc/proxy.rb b/lib/soap/rpc/proxy.rb deleted file mode 100644 index 355bf2e81a..0000000000 --- a/lib/soap/rpc/proxy.rb +++ /dev/null @@ -1,171 +0,0 @@ -# SOAP4R - RPC Proxy library. -# Copyright (C) 2000, 2003, 2004 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/soap' -require 'soap/processor' -require 'soap/mapping' -require 'soap/rpc/rpc' -require 'soap/rpc/element' -require 'soap/streamHandler' -require 'soap/mimemessage' - - -module SOAP -module RPC - - -class Proxy - include SOAP - -public - - attr_accessor :soapaction - attr_accessor :mandatorycharset - attr_accessor :allow_unqualified_element - attr_accessor :default_encodingstyle - attr_reader :method - - def initialize(streamhandler, soapaction = nil) - @streamhandler = streamhandler - @soapaction = soapaction - @method = {} - @mandatorycharset = nil - @allow_unqualified_element = false - @default_encodingstyle = nil - end - - class Request - include RPC - - public - - attr_reader :method - attr_reader :namespace - attr_reader :name - - def initialize(model, values) - @method = model.dup - @namespace = @method.elename.namespace - @name = @method.elename.name - - params = {} - - if ((values.size == 1) and (values[0].is_a?(Hash))) - params = values[0] - else - i = 0 - @method.each_param_name(SOAPMethod::IN, SOAPMethod::INOUT) do |name| - params[name] = values[i] || SOAPNil.new - i += 1 - end - end - @method.set_param(params) - end - end - - def add_method(qname, soapaction, name, param_def) - @method[name] = SOAPMethodRequest.new(qname, param_def, soapaction) - end - - def create_request(name, *values) - if (@method.key?(name)) - method = @method[name] - method.encodingstyle = @default_encodingstyle if @default_encodingstyle - else - raise SOAP::RPC::MethodDefinitionError.new( - "Method: #{ name } not defined.") - end - Request.new(method, values) - end - - def invoke(req_header, req_body, soapaction = nil) - if req_header and !req_header.is_a?(SOAPHeader) - req_header = create_header(req_header) - end - if !req_body.is_a?(SOAPBody) - req_body = SOAPBody.new(req_body) - end - opt = create_options - opt[:external_content] = nil - req_env = SOAPEnvelope.new(req_header, req_body) - send_string = Processor.marshal(req_env, opt) - conn_data = StreamHandler::ConnectionData.new(send_string) - if ext = opt[:external_content] - mime = MIMEMessage.new - ext.each do |k, v| - mime.add_attachment(v.data) - end - mime.add_part(conn_data.send_string + "\r\n") - mime.close - conn_data.send_string = mime.content_str - conn_data.send_contenttype = mime.headers['content-type'].str - end - conn_data = @streamhandler.send(conn_data, soapaction) - if conn_data.receive_string.empty? - return nil, nil - end - unmarshal(conn_data, opt) - end - - def call(req_header, name, *values) - req = create_request(name, *values) - invoke(req_header, req.method, req.method.soapaction || @soapaction) - end - - def check_fault(body) - if body.fault - raise SOAP::FaultError.new(body.fault) - end - end - -private - - def unmarshal(conn_data, opt) - contenttype = conn_data.receive_contenttype - if /#{MIMEMessage::MultipartContentType}/i =~ contenttype - opt[:external_content] = {} - mime = MIMEMessage.parse("Content-Type: " + contenttype, - conn_data.receive_string) - mime.parts.each do |part| - value = Attachment.new(part.content) - value.contentid = part.contentid - obj = SOAPAttachment.new(value) - opt[:external_content][value.contentid] = obj if value.contentid - end - opt[:charset] = @mandatorycharset || - StreamHandler.parse_media_type(mime.root.headers['content-type'].str) - env = Processor.unmarshal(mime.root.content, opt) - else - opt[:charset] = @mandatorycharset || - ::SOAP::StreamHandler.parse_media_type(contenttype) - env = Processor.unmarshal(conn_data.receive_string, opt) - end - env - end - - def create_header(headers) - header = SOAPHeader.new() - headers.each do |content, mustunderstand, encodingstyle| - header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle)) - end - header - end - - def create_options - opt = {} - opt[:default_encodingstyle] = @default_encodingstyle - if @allow_unqualified_element - opt[:allow_unqualified_element] = true - end - opt - end -end - - -end -end diff --git a/lib/soap/rpc/router.rb b/lib/soap/rpc/router.rb deleted file mode 100644 index 9d8d1c8da6..0000000000 --- a/lib/soap/rpc/router.rb +++ /dev/null @@ -1,235 +0,0 @@ -# SOAP4R - RPC Routing library -# Copyright (C) 2001, 2002 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/soap' -require 'soap/processor' -require 'soap/mapping' -require 'soap/rpc/rpc' -require 'soap/rpc/element' -require 'soap/streamHandler' -require 'soap/mimemessage' -require 'soap/header/handlerset' - - -module SOAP -module RPC - - -class Router - include SOAP - - attr_reader :actor - attr_accessor :allow_unqualified_element - attr_accessor :default_encodingstyle - attr_accessor :mapping_registry - attr_reader :headerhandler - - def initialize(actor) - @actor = actor - @receiver = {} - @method_name = {} - @method = {} - @allow_unqualified_element = false - @default_encodingstyle = nil - @mapping_registry = nil - @headerhandler = Header::HandlerSet.new - end - - def add_method(receiver, qname, soapaction, name, param_def) - fqname = fqname(qname) - @receiver[fqname] = receiver - @method_name[fqname] = name - @method[fqname] = RPC::SOAPMethodRequest.new(qname, param_def, soapaction) - end - - def route(conn_data) - soap_response = nil - begin - env = unmarshal(conn_data) - if env.nil? - raise ArgumentError.new("Illegal SOAP marshal format.") - end - receive_headers(env.header) - soap_request = env.body.request - unless soap_request.is_a?(SOAPStruct) - raise RPCRoutingError.new("Not an RPC style.") - end - soap_response = dispatch(soap_request) - rescue Exception - soap_response = fault($!) - conn_data.is_fault = true - end - - opt = options - opt[:external_content] = nil - header = call_headers - body = SOAPBody.new(soap_response) - env = SOAPEnvelope.new(header, body) - response_string = Processor.marshal(env, opt) - conn_data.send_string = response_string - if ext = opt[:external_content] - mime = MIMEMessage.new - ext.each do |k, v| - mime.add_attachment(v.data) - end - mime.add_part(conn_data.send_string + "\r\n") - mime.close - conn_data.send_string = mime.content_str - conn_data.send_contenttype = mime.headers['content-type'].str - end - conn_data - end - - # Create fault response string. - def create_fault_response(e, charset = nil) - header = SOAPHeader.new - body = SOAPBody.new(fault(e)) - env = SOAPEnvelope.new(header, body) - opt = options - opt[:external_content] = nil - opt[:charset] = charset - response_string = Processor.marshal(env, opt) - conn_data = StreamHandler::ConnectionData.new(response_string) - conn_data.is_fault = true - if ext = opt[:external_content] - mime = MIMEMessage.new - ext.each do |k, v| - mime.add_attachment(v.data) - end - mime.add_part(conn_data.send_string + "\r\n") - mime.close - conn_data.send_string = mime.content_str - conn_data.send_contenttype = mime.headers['content-type'].str - end - conn_data - end - -private - - def call_headers - headers = @headerhandler.on_outbound - if headers.empty? - nil - else - h = ::SOAP::SOAPHeader.new - headers.each do |header| - h.add(header.elename.name, header) - end - h - end - end - - def receive_headers(headers) - @headerhandler.on_inbound(headers) if headers - end - - def unmarshal(conn_data) - opt = options - contenttype = conn_data.receive_contenttype - if /#{MIMEMessage::MultipartContentType}/i =~ contenttype - opt[:external_content] = {} - mime = MIMEMessage.parse("Content-Type: " + contenttype, - conn_data.receive_string) - mime.parts.each do |part| - value = Attachment.new(part.content) - value.contentid = part.contentid - obj = SOAPAttachment.new(value) - opt[:external_content][value.contentid] = obj if value.contentid - end - opt[:charset] = - StreamHandler.parse_media_type(mime.root.headers['content-type'].str) - env = Processor.unmarshal(mime.root.content, opt) - else - opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype) - env = Processor.unmarshal(conn_data.receive_string, opt) - end - charset = opt[:charset] - conn_data.send_contenttype = "text/xml; charset=\"#{charset}\"" - env - end - - # Create new response. - def create_response(qname, result) - name = fqname(qname) - if (@method.key?(name)) - method = @method[name] - else - raise RPCRoutingError.new("Method: #{ name } not defined.") - end - - soap_response = method.create_method_response - if soap_response.have_outparam? - unless result.is_a?(Array) - raise RPCRoutingError.new("Out parameter was not returned.") - end - outparams = {} - i = 1 - soap_response.each_param_name('out', 'inout') do |outparam| - outparams[outparam] = Mapping.obj2soap(result[i], @mapping_registry) - i += 1 - end - soap_response.set_outparam(outparams) - soap_response.retval = Mapping.obj2soap(result[0], @mapping_registry) - else - soap_response.retval = Mapping.obj2soap(result, @mapping_registry) - end - soap_response - end - - # Create fault response. - def fault(e) - detail = Mapping::SOAPException.new(e) - SOAPFault.new( - SOAPString.new('Server'), - SOAPString.new(e.to_s), - SOAPString.new(@actor), - Mapping.obj2soap(detail, @mapping_registry)) - end - - # Dispatch to defined method. - def dispatch(soap_method) - request_struct = Mapping.soap2obj(soap_method, @mapping_registry) - values = soap_method.collect { |key, value| request_struct[key] } - method = lookup(soap_method.elename, values) - unless method - raise RPCRoutingError.new( - "Method: #{ soap_method.elename } not supported.") - end - - result = method.call(*values) - create_response(soap_method.elename, result) - end - - # Method lookup - def lookup(qname, values) - name = fqname(qname) - # It may be necessary to check all part of method signature... - if @method.member?(name) - @receiver[name].method(@method_name[name].intern) - else - nil - end - end - - def fqname(qname) - "#{ qname.namespace }:#{ qname.name }" - end - - def options - opt = {} - opt[:default_encodingstyle] = @default_encodingstyle - if @allow_unqualified_element - opt[:allow_unqualified_element] = true - end - opt - end -end - - -end -end diff --git a/lib/soap/rpc/rpc.rb b/lib/soap/rpc/rpc.rb deleted file mode 100644 index 5f77b4d2e9..0000000000 --- a/lib/soap/rpc/rpc.rb +++ /dev/null @@ -1,25 +0,0 @@ -# SOAP4R - RPC utility. -# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -module SOAP - - -module RPC - ServerException = Mapping::MappedException - - def self.defined_methods(obj) - if obj.is_a?(Module) - obj.methods - Module.methods - else - obj.methods - Kernel.instance_methods(true) - end - end -end - - -end diff --git a/lib/soap/rpc/soaplet.rb b/lib/soap/rpc/soaplet.rb deleted file mode 100644 index 0c1427acf5..0000000000 --- a/lib/soap/rpc/soaplet.rb +++ /dev/null @@ -1,200 +0,0 @@ -# SOAP4R - SOAP handler servlet for WEBrick -# Copyright (C) 2001, 2002, 2003, 2004 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 'webrick/httpservlet/abstract' -require 'webrick/httpstatus' -require 'soap/rpc/router' -require 'soap/streamHandler' - -module SOAP -module RPC - - -class SOAPlet < WEBrick::HTTPServlet::AbstractServlet -public - attr_reader :app_scope_router - - def initialize - @router_map = {} - @app_scope_router = ::SOAP::RPC::Router.new(self.class.name) - @headerhandlerfactory = [] - @app_scope_headerhandler = nil - end - - # Add servant factory whose object has request scope. A servant object is - # instanciated for each request. - # - # Bear in mind that servant factories are distinguished by HTTP SOAPAction - # header in request. Client which calls request-scoped servant must have a - # SOAPAction header which is a namespace of the servant factory. - # I mean, use Driver#add_method_with_soapaction instead of Driver#add_method - # at client side. - # - # A factory must respond to :create. - # - def add_rpc_request_servant(factory, namespace, mapping_registry = nil) - unless factory.respond_to?(:create) - raise TypeError.new("factory must respond to 'create'") - end - router = setup_request_router(namespace) - router.factory = factory - router.mapping_registry = mapping_registry - end - - # Add servant object which has application scope. - def add_rpc_servant(obj, namespace) - router = @app_scope_router - SOAPlet.add_servant_to_router(router, obj, namespace) - add_router(namespace, router) - end - alias add_servant add_rpc_servant - - def add_rpc_request_headerhandler(factory) - unless factory.respond_to?(:create) - raise TypeError.new("factory must respond to 'create'") - end - @headerhandlerfactory << factory - end - - def add_rpc_headerhandler(obj) - @app_scope_headerhandler = obj - end - alias add_headerhandler add_rpc_headerhandler - - ### - ## Servlet interfaces for WEBrick. - # - def get_instance(config, *options) - @config = config - self - end - - def require_path_info? - false - end - - def do_GET(req, res) - res.header['Allow'] = 'POST' - raise WEBrick::HTTPStatus::MethodNotAllowed, "GET request not allowed." - end - - def do_POST(req, res) - namespace = parse_soapaction(req.meta_vars['HTTP_SOAPACTION']) - router = lookup_router(namespace) - with_headerhandler(router) do |router| - begin - conn_data = ::SOAP::StreamHandler::ConnectionData.new - conn_data.receive_string = req.body - conn_data.receive_contenttype = req['content-type'] - conn_data = router.route(conn_data) - if conn_data.is_fault - res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR - end - res.body = conn_data.send_string - res['content-type'] = conn_data.send_contenttype - rescue Exception => e - conn_data = router.create_fault_response(e) - res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR - res.body = conn_data.send_string - res['content-type'] = conn_data.send_contenttype || "text/xml" - end - end - - if res.body.is_a?(IO) - res.chunked = true - end - end - -private - - class RequestRouter < ::SOAP::RPC::Router - attr_accessor :factory - - def initialize(namespace = nil) - super(namespace) - @namespace = namespace - @factory = nil - end - - def route(soap_string) - obj = @factory.create - namespace = self.actor - router = ::SOAP::RPC::Router.new(@namespace) - SOAPlet.add_servant_to_router(router, obj, namespace) - router.route(soap_string) - end - end - - def setup_request_router(namespace) - router = @router_map[namespace] || RequestRouter.new(namespace) - add_router(namespace, router) - router - end - - def add_router(namespace, router) - @router_map[namespace] = router - end - - def parse_soapaction(soapaction) - if /^"(.*)"$/ =~ soapaction - soapaction = $1 - end - if soapaction.empty? - return nil - end - soapaction - end - - def lookup_router(namespace) - if namespace - @router_map[namespace] || @app_scope_router - else - @app_scope_router - end - end - - def with_headerhandler(router) - if @app_scope_headerhandler and - !router.headerhandler.include?(@app_scope_headerhandler) - router.headerhandler.add(@app_scope_headerhandler) - end - handlers = @headerhandlerfactory.collect { |f| f.create } - begin - handlers.each { |h| router.headerhandler.add(h) } - yield(router) - ensure - handlers.each { |h| router.headerhandler.delete(h) } - end - end - - class << self - public - def add_servant_to_router(router, obj, namespace) - ::SOAP::RPC.defined_methods(obj).each do |name| - begin - add_servant_method_to_router(router, obj, namespace, name) - rescue SOAP::RPC::MethodDefinitionError => e - p e if $DEBUG - end - end - end - - def add_servant_method_to_router(router, obj, namespace, name) - qname = XSD::QName.new(namespace, name) - soapaction = nil - method = obj.method(name) - param_def = ::SOAP::RPC::SOAPMethod.create_param_def( - (1..method.arity.abs).collect { |i| "p#{ i }" }) - router.add_method(obj, qname, soapaction, name, param_def) - end - end -end - - -end -end diff --git a/lib/soap/rpc/standaloneServer.rb b/lib/soap/rpc/standaloneServer.rb deleted file mode 100644 index 080343ba33..0000000000 --- a/lib/soap/rpc/standaloneServer.rb +++ /dev/null @@ -1,43 +0,0 @@ -# SOAP4R - WEBrick Server -# Copyright (C) 2003 by 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/rpc/httpserver' - - -module SOAP -module RPC - - -class StandaloneServer < HTTPServer - def initialize(appname, default_namespace, host = "0.0.0.0", port = 8080) - @appname = appname - @default_namespace = default_namespace - @host = host - @port = port - super(create_config) - end - - alias add_servant add_rpc_servant - alias add_headerhandler add_rpc_headerhandler - -private - - def create_config - { - :BindAddress => @host, - :Port => @port, - :AccessLog => [], - :SOAPDefaultNamespace => @default_namespace, - :SOAPHTTPServerApplicationName => @appname, - } - end -end - - -end -end diff --git a/lib/soap/soap.rb b/lib/soap/soap.rb deleted file mode 100644 index 02b26e4246..0000000000 --- a/lib/soap/soap.rb +++ /dev/null @@ -1,115 +0,0 @@ -# soap/soap.rb: SOAP4R - Base definitions. -# Copyright (C) 2000-2004 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 'xsd/qname' -require 'xsd/charset' - - -module SOAP - - -Version = '1.5.2' -PropertyName = 'soap/property' - -EnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/' -EncodingNamespace = 'http://schemas.xmlsoap.org/soap/encoding/' -LiteralNamespace = 'http://xml.apache.org/xml-soap/literalxml' - -NextActor = 'http://schemas.xmlsoap.org/soap/actor/next' - -EleEnvelope = 'Envelope' -EleHeader = 'Header' -EleBody = 'Body' -EleFault = 'Fault' -EleFaultString = 'faultstring' -EleFaultActor = 'faultactor' -EleFaultCode = 'faultcode' -EleFaultDetail = 'detail' - -AttrMustUnderstand = 'mustUnderstand' -AttrEncodingStyle = 'encodingStyle' -AttrActor = 'actor' -AttrRoot = 'root' -AttrArrayType = 'arrayType' -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) - -Base64Literal = 'base64' - -SOAPNamespaceTag = 'env' -XSDNamespaceTag = 'xsd' -XSINamespaceTag = 'xsi' - -MediaType = 'text/xml' - -class Error < StandardError; end - -class StreamError < Error; end -class HTTPStreamError < StreamError; end -class PostUnavailableError < HTTPStreamError; end -class MPostUnavailableError < HTTPStreamError; end - -class ArrayIndexOutOfBoundsError < Error; end -class ArrayStoreError < Error; end - -class RPCRoutingError < Error; end - -class UnhandledMustUnderstandHeaderError < Error; end - -class FaultError < Error - attr_reader :faultcode - attr_reader :faultstring - attr_reader :faultactor - attr_accessor :detail - - def initialize(fault) - @faultcode = fault.faultcode - @faultstring = fault.faultstring - @faultactor = fault.faultactor - @detail = fault.detail - super(self.to_s) - end - - def to_s - str = nil - if @faultstring and @faultstring.respond_to?('data') - str = @faultstring.data - end - str || '(No faultstring)' - end -end - -module Env - def self.getenv(name) - ENV[name.downcase] || ENV[name.upcase] - end - - use_proxy = getenv('soap_use_proxy') == 'on' - HTTP_PROXY = use_proxy ? getenv('http_proxy') : nil - NO_PROXY = use_proxy ? getenv('no_proxy') : nil -end - - -end diff --git a/lib/soap/streamHandler.rb b/lib/soap/streamHandler.rb deleted file mode 100644 index efadf21e07..0000000000 --- a/lib/soap/streamHandler.rb +++ /dev/null @@ -1,267 +0,0 @@ -# SOAP4R - Stream handler. -# Copyright (C) 2000, 2001, 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/soap' -require 'soap/property' - - -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 - STDERR.puts "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 - attr_accessor :send_string - attr_accessor :send_contenttype - attr_accessor :receive_string - attr_accessor :receive_contenttype - attr_accessor :is_fault - - def initialize(send_string = nil) - @send_string = send_string - @send_contenttype = nil - @receive_string = nil - @receive_contenttype = nil - @is_fault = false - end - end - - attr_accessor :endpoint_url - - def initialize(endpoint_url) - @endpoint_url = endpoint_url - end - - def self.parse_media_type(str) - if /^#{ MediaType }(?:\s*;\s*charset=([^"]+|"[^"]+"))?$/i !~ str - return nil - end - charset = $1 - charset.gsub!(/"/, '') if charset - charset || 'us-ascii' - end - - def self.create_media_type(charset) - "#{ MediaType }; charset=#{ charset }" - end -end - - -class HTTPPostStreamHandler < StreamHandler - include SOAP - -public - - attr_reader :client - attr_accessor :wiredump_file_base - - NofRetry = 10 # [times] - - def initialize(endpoint_url, options) - super(endpoint_url) - @client = Client.new(nil, "SOAP4R/#{ Version }") - @wiredump_file_base = nil - @charset = @wiredump_dev = nil - @options = options - set_options - @client.debug_dev = @wiredump_dev - @cookie_store = nil - end - - def test_loopback_response - @client.test_loopback_response - end - - def inspect - "#<#{self.class}:#{endpoint_url}>" - end - - def send(conn_data, soapaction = nil, charset = @charset) - send_post(conn_data, soapaction, charset) - end - - def reset - @client.reset(@endpoint_url) - @client.save_cookie_store if @cookie_store - end - -private - - def set_options - @client.proxy = @options["proxy"] - @options.add_hook("proxy") do |key, value| - @client.proxy = value - end - @client.no_proxy = @options["no_proxy"] - @options.add_hook("no_proxy") do |key, value| - @client.no_proxy = value - end - if @client.respond_to?(:protocol_version=) - @client.protocol_version = @options["protocol_version"] - @options.add_hook("protocol_version") do |key, value| - @client.protocol_version = value - end - end - set_cookie_store_file(@options["cookie_store_file"]) - @options.add_hook("cookie_store_file") do |key, value| - set_cookie_store_file(value) - end - @charset = @options["charset"] || XSD::Charset.charset_label($KCODE) - @options.add_hook("charset") do |key, value| - @charset = value - end - @wiredump_dev = @options["wiredump_dev"] - @options.add_hook("wiredump_dev") do |key, value| - @wiredump_dev = value - @client.debug_dev = @wiredump_dev - end - ssl_config = @options["ssl_config"] ||= ::SOAP::Property.new - set_ssl_config(ssl_config) - ssl_config.add_hook(true) do |key, value| - set_ssl_config(ssl_config) - end - basic_auth = @options["basic_auth"] ||= ::SOAP::Property.new - set_basic_auth(basic_auth) - basic_auth.add_hook do |key, value| - set_basic_auth(basic_auth) - end - @options.lock(true) - ssl_config.unlock - basic_auth.unlock - end - - def set_basic_auth(basic_auth) - basic_auth.values.each do |url, userid, passwd| - @client.set_basic_auth(url, userid, passwd) - end - end - - def set_cookie_store_file(value) - @cookie_store = value - @client.set_cookie_store(@cookie_store) if @cookie_store - end - - def set_ssl_config(ssl_config) - ssl_config.each do |key, value| - cfg = @client.ssl_config - case key - when 'client_cert' - cfg.client_cert = cert_from_file(value) - when 'client_key' - cfg.client_key = key_from_file(value) - when 'client_ca' - cfg.client_ca = value - when 'ca_path' - cfg.set_trust_ca(value) - when 'ca_file' - cfg.set_trust_ca(value) - when 'crl' - cfg.set_crl(value) - when 'verify_mode' - cfg.verify_mode = ssl_config_int(value) - when 'verify_depth' - cfg.verify_depth = ssl_config_int(value) - when 'options' - cfg.options = value - when 'ciphers' - cfg.ciphers = value - when 'verify_callback' - cfg.verify_callback = value - when 'cert_store' - cfg.cert_store = value - else - raise ArgumentError.new("unknown ssl_config property #{key}") - end - end - end - - def ssl_config_int(value) - if value.nil? or value.empty? - nil - else - begin - Integer(value) - rescue ArgumentError - ::SOAP::Property::Util.const_from_name(value) - end - end - end - - def cert_from_file(filename) - OpenSSL::X509::Certificate.new(File.open(filename) { |f| f.read }) - end - - def key_from_file(filename) - OpenSSL::PKey::RSA.new(File.open(filename) { |f| f.read }) - end - - def send_post(conn_data, soapaction, charset) - conn_data.send_contenttype ||= StreamHandler.create_media_type(charset) - - if @wiredump_file_base - filename = @wiredump_file_base + '_request.xml' - f = File.open(filename, "w") - f << conn_data.send_string - f.close - end - - extra = {} - extra['Content-Type'] = conn_data.send_contenttype - extra['SOAPAction'] = "\"#{ soapaction }\"" - send_string = conn_data.send_string - - @wiredump_dev << "Wire dump:\n\n" if @wiredump_dev - begin - res = @client.post(@endpoint_url, send_string, extra) - rescue - @client.reset(@endpoint_url) - raise - end - @wiredump_dev << "\n\n" if @wiredump_dev - - receive_string = res.content - - if @wiredump_file_base - filename = @wiredump_file_base + '_response.xml' - f = File.open(filename, "w") - f << receive_string - f.close - end - - case res.status - when 405 - raise PostUnavailableError.new("#{ res.status }: #{ res.reason }") - when 200, 500 - # Nothing to do. - else - raise HTTPStreamError.new("#{ res.status }: #{ res.reason }") - end - - conn_data.receive_string = receive_string - conn_data.receive_contenttype = res.contenttype - conn_data - end - - CRLF = "\r\n" -end - - -end diff --git a/lib/soap/wsdlDriver.rb b/lib/soap/wsdlDriver.rb deleted file mode 100644 index af868ea886..0000000000 --- a/lib/soap/wsdlDriver.rb +++ /dev/null @@ -1,598 +0,0 @@ -# SOAP4R - SOAP WSDL driver -# Copyright (C) 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 'wsdl/parser' -require 'wsdl/importer' -require 'xsd/qname' -require 'soap/element' -require 'soap/baseData' -require 'soap/streamHandler' -require 'soap/mimemessage' -require 'soap/mapping' -require 'soap/mapping/wsdlRegistry' -require 'soap/rpc/rpc' -require 'soap/rpc/element' -require 'soap/processor' -require 'soap/header/handlerset' -require 'logger' - - -module SOAP - - -class WSDLDriverFactory - class FactoryError < StandardError; end - - attr_reader :wsdl - - def initialize(wsdl, logdev = nil) - @logdev = logdev - @wsdl = import(wsdl) - end - - def inspect - "#<#{self.class}:#{@wsdl.name}>" - end - - def create_driver(servicename = nil, portname = nil) - service = if servicename - @wsdl.service(XSD::QName.new(@wsdl.targetnamespace, servicename)) - else - @wsdl.services[0] - end - if service.nil? - raise FactoryError.new("Service #{ servicename } not found in WSDL.") - end - port = if portname - service.ports[XSD::QName.new(@wsdl.targetnamespace, portname)] - else - service.ports[0] - end - if port.nil? - raise FactoryError.new("Port #{ portname } not found in WSDL.") - end - if port.soap_address.nil? - raise FactoryError.new("soap:address element not found in WSDL.") - end - WSDLDriver.new(@wsdl, port, @logdev) - end - - # Backward compatibility. - alias createDriver create_driver - -private - - def import(location) - WSDL::Importer.import(location) - end -end - - -class WSDLDriver - class << self - def __attr_proxy(symbol, assignable = false) - name = symbol.to_s - module_eval <<-EOD - def #{name} - @servant.#{name} - end - EOD - if assignable - module_eval <<-EOD - def #{name}=(rhs) - @servant.#{name} = rhs - end - EOD - end - end - end - - __attr_proxy :options - __attr_proxy :headerhandler - __attr_proxy :test_loopback_response - __attr_proxy :endpoint_url, true - __attr_proxy :mapping_registry, true # for RPC unmarshal - __attr_proxy :wsdl_mapping_registry, true # for RPC marshal - __attr_proxy :default_encodingstyle, true - __attr_proxy :allow_unqualified_element, true - __attr_proxy :generate_explicit_type, true - - def httpproxy - @servant.options["protocol.http.proxy"] - end - - def httpproxy=(httpproxy) - @servant.options["protocol.http.proxy"] = httpproxy - end - - def wiredump_dev - @servant.options["protocol.http.wiredump_dev"] - end - - def wiredump_dev=(wiredump_dev) - @servant.options["protocol.http.wiredump_dev"] = wiredump_dev - end - - def mandatorycharset - @servant.options["protocol.mandatorycharset"] - end - - def mandatorycharset=(mandatorycharset) - @servant.options["protocol.mandatorycharset"] = mandatorycharset - end - - def wiredump_file_base - @servant.options["protocol.wiredump_file_base"] - end - - def wiredump_file_base=(wiredump_file_base) - @servant.options["protocol.wiredump_file_base"] = wiredump_file_base - end - - def initialize(wsdl, port, logdev) - @servant = Servant__.new(self, wsdl, port, logdev) - end - - def inspect - "#<#{self.class}:#{@servant.port.name}>" - end - - def reset_stream - @servant.streamhandler.reset - end - - # Backward compatibility. - alias generateEncodeType= generate_explicit_type= - - class Servant__ - include Logger::Severity - include SOAP - - attr_reader :options - attr_reader :streamhandler - attr_reader :headerhandler - attr_reader :port - - attr_accessor :mapping_registry - attr_accessor :wsdl_mapping_registry - attr_accessor :default_encodingstyle - attr_accessor :allow_unqualified_element - attr_accessor :generate_explicit_type - - def initialize(host, wsdl, port, logdev) - @host = host - @wsdl = wsdl - @port = port - @logdev = logdev - - @options = setup_options - @mapping_registry = nil # for rpc unmarshal - @wsdl_mapping_registry = nil # for rpc marshal - @default_encodingstyle = EncodingNamespace - @allow_unqualified_element = true - @generate_explicit_type = false - @wiredump_file_base = nil - @mandatorycharset = nil - - @wsdl_elements = @wsdl.collect_elements - @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes - @rpc_decode_typemap = @wsdl_types + - @wsdl.soap_rpc_complextypes(port.find_binding) - @wsdl_mapping_registry = Mapping::WSDLRegistry.new(@rpc_decode_typemap) - @doc_mapper = Mapper.new(@wsdl_elements, @wsdl_types) - endpoint_url = @port.soap_address.location - @streamhandler = HTTPPostStreamHandler.new(endpoint_url, - @options["protocol.http"] ||= Property.new) - @headerhandler = Header::HandlerSet.new - # Convert a map which key is QName, to a Hash which key is String. - @operations = {} - @port.inputoperation_map.each do |op_name, op_info| - @operations[op_name.name] = op_info - add_method_interface(op_info) - end - end - - def endpoint_url - @streamhandler.endpoint_url - end - - def endpoint_url=(endpoint_url) - @streamhandler.endpoint_url = endpoint_url - @streamhandler.reset - end - - def test_loopback_response - @streamhandler.test_loopback_response - end - - def rpc_send(method_name, *params) - log(INFO) { "call: calling method '#{ method_name }'." } - log(DEBUG) { "call: parameters '#{ params.inspect }'." } - - op_info = @operations[method_name] - method = create_method_struct(op_info, params) - req_header = call_headers - req_body = SOAPBody.new(method) - req_env = SOAPEnvelope.new(req_header, req_body) - - if @wiredump_file_base - @streamhandler.wiredump_file_base = - @wiredump_file_base + '_' << method_name - end - - begin - opt = create_options - opt[:decode_typemap] = @rpc_decode_typemap - res_env = invoke(req_env, op_info, opt) - receive_headers(res_env.header) - if res_env.body.fault - raise ::SOAP::FaultError.new(res_env.body.fault) - end - rescue ::SOAP::FaultError => e - Mapping.fault2exception(e) - end - - ret = res_env.body.response ? - Mapping.soap2obj(res_env.body.response, @mapping_registry) : nil - - if res_env.body.outparams - outparams = res_env.body.outparams.collect { |outparam| - Mapping.soap2obj(outparam) - } - return [ret].concat(outparams) - else - return ret - end - end - - # req_header: [[element, mustunderstand, encodingstyle(QName/String)], ...] - # req_body: SOAPBasetype/SOAPCompoundtype - def document_send(name, header_obj, body_obj) - log(INFO) { "document_send: sending document '#{ name }'." } - op_info = @operations[name] - req_header = header_from_obj(header_obj, op_info) - req_body = body_from_obj(body_obj, op_info) - req_env = SOAPEnvelope.new(req_header, req_body) - opt = create_options - res_env = invoke(req_env, op_info, opt) - if res_env.body.fault - raise ::SOAP::FaultError.new(res_env.body.fault) - end - res_body_obj = res_env.body.response ? - Mapping.soap2obj(res_env.body.response, @mapping_registry) : nil - return res_env.header, res_body_obj - end - - private - - def call_headers - headers = @headerhandler.on_outbound - if headers.empty? - nil - else - h = ::SOAP::SOAPHeader.new - headers.each do |header| - h.add(header.elename.name, header) - end - h - end - end - - def receive_headers(headers) - @headerhandler.on_inbound(headers) if headers - end - - def create_method_struct(op_info, params) - parts_names = op_info.bodyparts.collect { |part| part.name } - obj = create_method_obj(parts_names, params) - method = Mapping.obj2soap(obj, @wsdl_mapping_registry, op_info.optype_name) - if method.members.size != parts_names.size - new_method = SOAPStruct.new - method.each do |key, value| - if parts_names.include?(key) - new_method.add(key, value) - end - end - method = new_method - end - method.elename = op_info.op_name - method.type = XSD::QName.new # Request should not be typed. - method - end - - def create_method_obj(names, params) - o = Object.new - for idx in 0 ... params.length - o.instance_eval("@#{ names[idx] } = params[idx]") - end - o - end - - def invoke(req_env, op_info, opt) - opt[:external_content] = nil - send_string = Processor.marshal(req_env, opt) - log(DEBUG) { "invoke: sending string #{ send_string }" } - conn_data = StreamHandler::ConnectionData.new(send_string) - if ext = opt[:external_content] - mime = MIMEMessage.new - ext.each do |k, v| - mime.add_attachment(v.data) - end - mime.add_part(conn_data.send_string + "\r\n") - mime.close - conn_data.send_string = mime.content_str - conn_data.send_contenttype = mime.headers['content-type'].str - end - conn_data = @streamhandler.send(conn_data, op_info.soapaction) - log(DEBUG) { "invoke: received string #{ conn_data.receive_string }" } - if conn_data.receive_string.empty? - return nil, nil - end - unmarshal(conn_data, opt) - end - - def unmarshal(conn_data, opt) - contenttype = conn_data.receive_contenttype - if /#{MIMEMessage::MultipartContentType}/i =~ contenttype - opt[:external_content] = {} - mime = MIMEMessage.parse("Content-Type: " + contenttype, - conn_data.receive_string) - mime.parts.each do |part| - value = Attachment.new(part.content) - value.contentid = part.contentid - obj = SOAPAttachment.new(value) - opt[:external_content][value.contentid] = obj if value.contentid - end - opt[:charset] = @mandatorycharset || - StreamHandler.parse_media_type(mime.root.headers['content-type'].str) - env = Processor.unmarshal(mime.root.content, opt) - else - opt[:charset] = @mandatorycharset || - ::SOAP::StreamHandler.parse_media_type(contenttype) - env = Processor.unmarshal(conn_data.receive_string, opt) - end - env - end - - def header_from_obj(obj, op_info) - if obj.is_a?(SOAPHeader) - obj - elsif op_info.headerparts.empty? - if obj.nil? - nil - else - raise RuntimeError.new("No header definition in schema.") - end - elsif op_info.headerparts.size == 1 - part = op_info.headerparts[0] - header = SOAPHeader.new() - header.add(headeritem_from_obj(obj, part.element || part.eletype)) - header - else - header = SOAPHeader.new() - op_info.headerparts.each do |part| - child = Mapper.find_attribute(obj, part.name) - ele = headeritem_from_obj(child, part.element || part.eletype) - header.add(part.name, ele) - end - header - end - end - - def headeritem_from_obj(obj, name) - if obj.nil? - SOAPElement.new(name) - elsif obj.is_a?(SOAPHeaderItem) - obj - else - @doc_mapper.obj2ele(obj, name) - end - end - - def body_from_obj(obj, op_info) - if obj.is_a?(SOAPBody) - obj - elsif op_info.bodyparts.empty? - if obj.nil? - nil - else - raise RuntimeError.new("No body found in schema.") - end - elsif op_info.bodyparts.size == 1 - part = op_info.bodyparts[0] - ele = bodyitem_from_obj(obj, part.element || part.type) - SOAPBody.new(ele) - else - body = SOAPBody.new - op_info.bodyparts.each do |part| - child = Mapper.find_attribute(obj, part.name) - ele = bodyitem_from_obj(child, part.element || part.type) - body.add(ele.elename.name, ele) - end - body - end - end - - def bodyitem_from_obj(obj, name) - if obj.nil? - SOAPElement.new(name) - elsif obj.is_a?(SOAPElement) - obj - else - @doc_mapper.obj2ele(obj, name) - end - end - - def add_method_interface(op_info) - case op_info.style - when :document - add_document_method_interface(op_info.op_name.name) - when :rpc - parts_names = op_info.bodyparts.collect { |part| part.name } - add_rpc_method_interface(op_info.op_name.name, parts_names) - else - raise RuntimeError.new("Unknown style: #{op_info.style}") - end - end - - def add_document_method_interface(name) - @host.instance_eval <<-EOS - def #{ name }(headers, body) - @servant.document_send(#{ name.dump }, headers, body) - end - EOS - end - - def add_rpc_method_interface(name, parts_names) - i = 0 - param_names = parts_names.collect { |orgname| i += 1; "arg#{ i }" } - callparam = (param_names.collect { |pname| ", " + pname }).join - @host.instance_eval <<-EOS - def #{ name }(#{ param_names.join(", ") }) - @servant.rpc_send(#{ name.dump }#{ callparam }) - end - EOS - end - - def create_options - opt = {} - opt[:default_encodingstyle] = @default_encodingstyle - opt[:allow_unqualified_element] = @allow_unqualified_element - opt[:generate_explicit_type] = @generate_explicit_type - opt - end - - def log(sev) - @logdev.add(sev, nil, self.class) { yield } if @logdev - end - - def setup_options - if opt = Property.loadproperty(::SOAP::PropertyName) - opt = opt["client"] - end - opt ||= Property.new - opt.add_hook("protocol.mandatorycharset") do |key, value| - @mandatorycharset = value - end - 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.proxy"] ||= Env::HTTP_PROXY - opt["protocol.http.no_proxy"] ||= Env::NO_PROXY - opt - end - - class MappingError < StandardError; end - class Mapper - def initialize(elements, types) - @elements = elements - @types = types - end - - def obj2ele(obj, name) - if ele = @elements[name] - _obj2ele(obj, ele) - elsif type = @types[name] - obj2type(obj, type) - else - raise MappingError.new("Cannot find name #{name} in schema.") - end - end - - def ele2obj(ele, *arg) - raise NotImplementedError.new - end - - def Mapper.find_attribute(obj, attr_name) - if obj.respond_to?(attr_name) - obj.__send__(attr_name) - elsif obj.is_a?(Hash) - obj[attr_name] || obj[attr_name.intern] - else - obj.instance_eval("@#{ attr_name }") - end - end - - private - - def _obj2ele(obj, ele) - o = nil - if ele.type - if type = @types[ele.type] - o = obj2type(obj, type) - elsif type = TypeMap[ele.type] - o = base2soap(obj, type) - else - raise MappingError.new("Cannot find type #{ele.type}.") - end - o.elename = ele.name - elsif ele.local_complextype - o = SOAPElement.new(ele.name) - ele.local_complextype.each_element do |child_ele| - o.add(_obj2ele(Mapper.find_attribute(obj, child_ele.name.name), - child_ele)) - end - else - raise MappingError.new("Illegal schema?") - end - o - 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 - if type.restriction.enumeration.include?(o) - raise MappingError.new("#{o} is not allowed for #{type.name}") - end - o - end - - def complex2soap(obj, type) - o = SOAPElement.new(type.name) - type.each_element do |child_ele| - o.add(_obj2ele(Mapper.find_attribute(obj, child_ele.name.name), - child_ele)) - end - o - end - - def _ele2obj(ele) - raise NotImplementedError.new - end - - def base2soap(obj, type) - soap_obj = nil - if type <= XSD::XSDString - soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? - XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : - obj) - else - soap_obj = type.new(obj) - end - soap_obj - end - end - end -end - - -end - - |
