Class: SOAP::SOAPGenerator

Class | SOAP::SOAPGenerator
In: | soap/generator.rb
Parent: | Object

CAUTION: MT-unsafe

### Methods

add_reftarget assign_ns element_local? element_qualified? encode_child encode_data encode_element encode_name encode_name_end encode_rawstring encode_string encode_tag encode_tag_end generate new

### Included Modules

SOAP

### Classes and Modules

Class SOAP::SOAPGenerator::FormatEncodeError

### Constants

EncodeMap | = | { '&' => '&amp;', '<' => '&lt;', '>' => '&gt;', '"' => '&quot;', '\'' => '&apos;', "\r" => '&#xd;'
EncodeCharRegexp | = | Regexp.new("[#{EncodeMap.keys.join}]")

### 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)

[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 = {})

[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)

[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)

[Source]

    # File soap/generator.rb, line 209
      def element_local?(element)
        element.elename.namespace.nil?
      end

element_qualified?(element)

[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)

[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)

[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)

[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)

[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)

[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)

[Source]

    # File soap/generator.rb, line 181
      def encode_rawstring(str)
        @buf << str
      end

encode_string(str)

[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)

[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)

[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)

[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

[Validate]