class SOAP::Generator
CAUTION: MT-unsafe
Constants
- ENCODE_CHAR_REGEXP
- EncodeMap
Attributes
charset[RW]
default_encodingstyle[RW]
generate_explicit_type[RW]
use_default_namespace[RW]
use_numeric_character_reference[RW]
Public Class Methods
assign_ns(attrs, ns, namespace, tag = nil)
click to toggle source
# File lib/soap/generator.rb, line 220 def self.assign_ns(attrs, ns, namespace, tag = nil) if namespace.nil? raise FormatEncodeError.new("empty namespace") end override_default_ns = (tag == '' and namespace != ns.default_namespace) if override_default_ns or !ns.assigned?(namespace) assign_ns!(attrs, ns, namespace, tag) end end
assign_ns!(attrs, ns, namespace, tag = nil)
click to toggle source
# File lib/soap/generator.rb, line 230 def self.assign_ns!(attrs, ns, namespace, tag = nil) tag = ns.assign(namespace, tag) if tag == '' attr = 'xmlns' else attr = "xmlns:#{tag}" end attrs[attr] = namespace end
new(opt = {})
click to toggle source
# File lib/soap/generator.rb, line 36 def initialize(opt = {}) @reftarget = nil @handlers = {} @charset = opt[:charset] || XSD::Charset.xml_encoding_label @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace @generate_explicit_type = opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true @use_default_namespace = opt[:use_default_namespace] @attributeformdefault = opt[:attributeformdefault] @use_numeric_character_reference = opt[:use_numeric_character_reference] @indentstr = opt[:no_indent] ? '' : ' ' @buf = @indent = @curr = nil @default_ns = opt[:default_ns] @default_ns_tag = opt[:default_ns_tag] end
Public Instance Methods
add_reftarget(name, node)
click to toggle source
# File lib/soap/generator.rb, line 119 def add_reftarget(name, node) unless @reftarget raise FormatEncodeError.new("Reftarget is not defined.") end @reftarget.add(name, node) end
element_local?(element)
click to toggle source
# File lib/soap/generator.rb, line 216 def element_local?(element) element.elename.namespace.nil? end
encode_child(ns, child, parent)
click to toggle source
# File lib/soap/generator.rb, line 126 def encode_child(ns, child, parent) indent_backup, @indent = @indent, @indent + @indentstr encode_data(ns.clone_ns, child, parent) @indent = indent_backup end
encode_data(ns, obj, parent)
click to toggle source
# File lib/soap/generator.rb, line 84 def encode_data(ns, obj, parent) if obj.respond_to?(:to_xmlpart) formatted = trim_eol(obj.to_xmlpart) formatted = trim_indent(formatted) formatted = formatted.gsub(/^/, @indent).sub(/\n+\z/, '') @buf << "\n#{formatted}" return elsif obj.is_a?(SOAPEnvelopeElement) encode_element(ns, obj, parent) return end if @reftarget && !obj.precedents.empty? add_reftarget(obj.elename.name, obj) ref = SOAPReference.new(obj) ref.elename = ref.elename.dup_name(obj.elename.name) obj.precedents.clear # Avoid cyclic delay. obj.encodingstyle = parent.encodingstyle # SOAPReference is encoded here. obj = ref end encodingstyle = obj.encodingstyle # Children's encodingstyle is derived from its parent. encodingstyle ||= parent.encodingstyle if parent obj.encodingstyle = encodingstyle handler = find_handler(encodingstyle || @default_encodingstyle) unless handler raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.") end if !obj.elename.name raise FormatEncodeError.new("Element name not defined: #{ obj }.") end handler.encode_data(self, ns, obj, parent) handler.encode_data_end(self, ns, obj, parent) end
encode_element(ns, obj, parent)
click to toggle source
# File lib/soap/generator.rb, line 132 def encode_element(ns, obj, parent) attrs = obj.extraattr if obj.is_a?(SOAPBody) @reftarget = obj obj.encode(self, ns, attrs) do |child| indent_backup, @indent = @indent, @indent + @indentstr encode_data(ns.clone_ns, child, obj) @indent = indent_backup end @reftarget = nil else if obj.is_a?(SOAPEnvelope) # xsi:nil="true" can appear even if dumping without explicit type. Generator.assign_ns(attrs, ns, XSD::InstanceNamespace) if @generate_explicit_type Generator.assign_ns(attrs, ns, XSD::Namespace) end end obj.encode(self, ns, attrs) do |child| indent_backup, @indent = @indent, @indent + @indentstr encode_data(ns.clone_ns, child, obj) @indent = indent_backup end end end
encode_name(ns, data, attrs)
click to toggle source
# File lib/soap/generator.rb, line 158 def encode_name(ns, data, attrs) if element_local?(data) data.elename.name else if @use_default_namespace Generator.assign_ns(attrs, ns, data.elename.namespace, '') else Generator.assign_ns(attrs, ns, data.elename.namespace) end ns.name(data.elename) end end
encode_name_end(ns, data)
click to toggle source
# File lib/soap/generator.rb, line 171 def encode_name_end(ns, data) if element_local?(data) data.elename.name else ns.name(data.elename) end end
encode_rawstring(str)
click to toggle source
# File lib/soap/generator.rb, line 208 def encode_rawstring(str) @buf << str end
encode_string(str)
click to toggle source
# File lib/soap/generator.rb, line 212 def encode_string(str) @buf << get_encoded(str) end
encode_tag(elename, attrs = nil)
click to toggle source
# File lib/soap/generator.rb, line 179 def encode_tag(elename, attrs = nil) if attrs.nil? or attrs.empty? @buf << "\n#{ @indent }<#{ elename }>" return end ary = [] attrs.each do |key, value| ary << %Q[#{ key }="#{ get_encoded(value.to_s) }"] end case ary.size when 0 @buf << "\n#{ @indent }<#{ elename }>" when 1 @buf << %Q[\n#{ @indent }<#{ elename } #{ ary[0] }>] else @buf << "\n#{ @indent }<#{ elename } " << ary.join("\n#{ @indent }#{ @indentstr * 2 }") << '>' end end
encode_tag_end(elename, cr = nil)
click to toggle source
# File lib/soap/generator.rb, line 200 def encode_tag_end(elename, cr = nil) if cr @buf << "\n#{ @indent }</#{ elename }>" else @buf << "</#{ elename }>" end end
generate(obj, io = nil)
click to toggle source
# File lib/soap/generator.rb, line 52 def generate(obj, io = nil) @buf = io || '' @indent = '' @encode_char_regexp = get_encode_char_regexp() prologue @handlers.each do |uri, handler| handler.encode_prologue end ns = SOAP::NS.new if @default_ns @default_ns.each_ns do |default_ns, default_tag| Generator.assign_ns(obj.extraattr, ns, default_ns, default_tag) end end if @default_ns_tag @default_ns_tag.each_ns do |default_ns, default_tag| ns.known_tag[default_ns] = default_tag end end @buf << xmldecl encode_data(ns, obj, nil) @handlers.each do |uri, handler| handler.encode_epilogue end epilogue @buf end
Private Instance Methods
epilogue()
click to toggle source
# File lib/soap/generator.rb, line 245 def epilogue end
find_handler(encodingstyle)
click to toggle source
# File lib/soap/generator.rb, line 279 def find_handler(encodingstyle) unless @handlers.key?(encodingstyle) factory = SOAP::EncodingStyle::Handler.handler(encodingstyle) if factory handler = factory.new(@charset) handler.generate_explicit_type = @generate_explicit_type handler.encode_prologue @handlers[encodingstyle] = handler end end @handlers[encodingstyle] end
get_encode_char_regexp()
click to toggle source
# File lib/soap/generator.rb, line 274 def get_encode_char_regexp ENCODE_CHAR_REGEXP[XSD::Charset.encoding] ||= Regexp.new("[#{EncodeMap.keys.join}]", nil, XSD::Charset.encoding) end
get_encoded(str)
click to toggle source
# File lib/soap/generator.rb, line 259 def get_encoded(str) if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str) str.gsub!(@encode_char_regexp) { |c| EncodeMap[c] } str.unpack("U*").collect { |c| if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f) c.chr else sprintf("&#x%x;", c) end }.join else str.gsub(@encode_char_regexp) { |c| EncodeMap[c] } end end
prologue()
click to toggle source
# File lib/soap/generator.rb, line 242 def prologue end
xmldecl()
click to toggle source
# File lib/soap/generator.rb, line 292 def xmldecl if @charset %Q[<?xml version="1.0" encoding="#{ @charset }" ?>] else %Q[<?xml version="1.0" ?>] end end