In Files

  • soap/generator.rb

Class/Module Index [+]

Quicksearch

SOAP::SOAPGenerator

CAUTION: MT-unsafe

Attributes

charset[RW]
default_encodingstyle[RW]
generate_explicit_type[RW]
use_numeric_character_reference[RW]

Public Class Methods

assign_ns(attrs, ns, namespace, tag = nil) click to toggle source
 
               # File soap/generator.rb, line 225
def self.assign_ns(attrs, ns, namespace, tag = nil)
  if namespace.nil?
    raise FormatEncodeError.new("empty namespace")
  end
  unless ns.assigned?(namespace)
    tag = ns.assign(namespace, tag)
    if tag == ''
      attr = 'xmlns'
    else
      attr = "xmlns:#{tag}"
    end
    attrs[attr] = namespace
  end
end
            
new(opt = {}) click to toggle source
 
               # File soap/generator.rb, line 33
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
  @elementformdefault = opt[:elementformdefault]
  @attributeformdefault = opt[:attributeformdefault]
  @use_numeric_character_reference = opt[:use_numeric_character_reference]
  @indentstr = opt[:no_indent] ? '' : '  '
  @buf = @indent = @curr = nil
end
            

Public Instance Methods

add_reftarget(name, node) click to toggle source
 
               # File soap/generator.rb, line 97
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 soap/generator.rb, line 209
def element_local?(element)
  element.elename.namespace.nil?
end
            
element_qualified?(element) click to toggle source
 
               # File soap/generator.rb, line 213
def element_qualified?(element)
  if element.respond_to?(:qualified)
    if element.qualified.nil?
      @elementformdefault
    else
      element.qualified
    end
  else
    @elementformdefault
  end
end
            
encode_child(ns, child, parent) click to toggle source
 
               # File soap/generator.rb, line 104
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 soap/generator.rb, line 68
def encode_data(ns, obj, parent)
  if 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 soap/generator.rb, line 110
def encode_element(ns, obj, parent)
  attrs = {}
  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.
      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|
      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 soap/generator.rb, line 137
def encode_name(ns, data, attrs)
  if element_local?(data)
    data.elename.name
  else
    if element_qualified?(data)
      SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
    else
      SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
    end
    ns.name(data.elename)
  end
end
            
encode_name_end(ns, data) click to toggle source
 
               # File soap/generator.rb, line 150
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 soap/generator.rb, line 181
def encode_rawstring(str)
  @buf << str
end
            
encode_string(str) click to toggle source
 
               # File soap/generator.rb, line 194
def encode_string(str)
  if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)
    str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] }
    @buf << str.unpack("U*").collect { |c|
      if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)
        c.chr
      else
        sprintf("&#x%x;", c)
      end
    }.join
  else
    @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
  end
end
            
encode_tag(elename, attrs = nil) click to toggle source
 
               # File soap/generator.rb, line 158
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 }#{ @indentstr * 2 }") <<
      '>'
  end
end
            
encode_tag_end(elename, cr = nil) click to toggle source
 
               # File soap/generator.rb, line 173
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 soap/generator.rb, line 47
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, obj, nil)

  @handlers.each do |uri, handler|
    handler.encode_epilogue
  end
  epilogue

  @buf
end