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

CAUTION: MT-unsafe

Methods

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

[Source]

     # File lib/soap/generator.rb, line 225
225:   def self.assign_ns(attrs, ns, namespace, tag = nil)
226:     if namespace.nil?
227:       raise FormatEncodeError.new("empty namespace")
228:     end
229:     unless ns.assigned?(namespace)
230:       tag = ns.assign(namespace, tag)
231:       if tag == ''
232:         attr = 'xmlns'
233:       else
234:         attr = "xmlns:#{tag}"
235:       end
236:       attrs[attr] = namespace
237:     end
238:   end

[Source]

    # File lib/soap/generator.rb, line 33
33:   def initialize(opt = {})
34:     @reftarget = nil
35:     @handlers = {}
36:     @charset = opt[:charset] || XSD::Charset.xml_encoding_label
37:     @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
38:     @generate_explicit_type =
39:       opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true
40:     @elementformdefault = opt[:elementformdefault]
41:     @attributeformdefault = opt[:attributeformdefault]
42:     @use_numeric_character_reference = opt[:use_numeric_character_reference]
43:     @indentstr = opt[:no_indent] ? '' : '  '
44:     @buf = @indent = @curr = nil
45:   end

Public Instance methods

[Source]

     # File lib/soap/generator.rb, line 97
 97:   def add_reftarget(name, node)
 98:     unless @reftarget
 99:       raise FormatEncodeError.new("Reftarget is not defined.")
100:     end
101:     @reftarget.add(name, node)
102:   end

[Source]

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

[Source]

     # File lib/soap/generator.rb, line 213
213:   def element_qualified?(element)
214:     if element.respond_to?(:qualified)
215:       if element.qualified.nil?
216:         @elementformdefault
217:       else
218:         element.qualified
219:       end
220:     else
221:       @elementformdefault
222:     end
223:   end

[Source]

     # File lib/soap/generator.rb, line 104
104:   def encode_child(ns, child, parent)
105:     indent_backup, @indent = @indent, @indent + @indentstr
106:     encode_data(ns.clone_ns, child, parent)
107:     @indent = indent_backup
108:   end

[Source]

    # File lib/soap/generator.rb, line 68
68:   def encode_data(ns, obj, parent)
69:     if obj.is_a?(SOAPEnvelopeElement)
70:       encode_element(ns, obj, parent)
71:       return
72:     end
73:     if @reftarget && !obj.precedents.empty?
74:       add_reftarget(obj.elename.name, obj)
75:       ref = SOAPReference.new(obj)
76:       ref.elename = ref.elename.dup_name(obj.elename.name)
77:       obj.precedents.clear      # Avoid cyclic delay.
78:       obj.encodingstyle = parent.encodingstyle
79:       # SOAPReference is encoded here.
80:       obj = ref
81:     end
82:     encodingstyle = obj.encodingstyle
83:     # Children's encodingstyle is derived from its parent.
84:     encodingstyle ||= parent.encodingstyle if parent
85:     obj.encodingstyle = encodingstyle
86:     handler = find_handler(encodingstyle || @default_encodingstyle)
87:     unless handler
88:       raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
89:     end
90:     if !obj.elename.name
91:       raise FormatEncodeError.new("Element name not defined: #{ obj }.")
92:     end
93:     handler.encode_data(self, ns, obj, parent)
94:     handler.encode_data_end(self, ns, obj, parent)
95:   end

[Source]

     # File lib/soap/generator.rb, line 110
110:   def encode_element(ns, obj, parent)
111:     attrs = {}
112:     if obj.is_a?(SOAPBody)
113:       @reftarget = obj
114:       obj.encode(self, ns, attrs) do |child|
115:         indent_backup, @indent = @indent, @indent + @indentstr
116:         encode_data(ns.clone_ns, child, obj)
117:         @indent = indent_backup
118:       end
119:       @reftarget = nil
120:     else
121:       if obj.is_a?(SOAPEnvelope)
122:         # xsi:nil="true" can appear even if dumping without explicit type.
123:         SOAPGenerator.assign_ns(attrs, ns,
124:           XSD::InstanceNamespace, XSINamespaceTag)
125:         if @generate_explicit_type
126:           SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)
127:         end
128:       end
129:       obj.encode(self, ns, attrs) do |child|
130:         indent_backup, @indent = @indent, @indent + @indentstr
131:         encode_data(ns.clone_ns, child, obj)
132:         @indent = indent_backup
133:       end
134:     end
135:   end

[Source]

     # File lib/soap/generator.rb, line 137
137:   def encode_name(ns, data, attrs)
138:     if element_local?(data)
139:       data.elename.name
140:     else
141:       if element_qualified?(data)
142:         SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')
143:       else
144:         SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)
145:       end
146:       ns.name(data.elename)
147:     end
148:   end

[Source]

     # File lib/soap/generator.rb, line 150
150:   def encode_name_end(ns, data)
151:     if element_local?(data)
152:       data.elename.name
153:     else
154:       ns.name(data.elename)
155:     end
156:   end

[Source]

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

[Source]

     # File lib/soap/generator.rb, line 194
194:   def encode_string(str)
195:     if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)
196:       str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] }
197:       @buf << str.unpack("U*").collect { |c|
198:         if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)
199:           c.chr
200:         else
201:           sprintf("&#x%x;", c)
202:         end
203:       }.join
204:     else
205:       @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }
206:     end
207:   end

[Source]

     # File lib/soap/generator.rb, line 158
158:   def encode_tag(elename, attrs = nil)
159:     if !attrs or attrs.empty?
160:       @buf << "\n#{ @indent }<#{ elename }>"
161:     elsif attrs.size == 1
162:       key, value = attrs.shift
163:       @buf << %Q[\n#{ @indent }<#{ elename } #{ key }="#{ value }">]
164:     else
165:       @buf << "\n#{ @indent }<#{ elename } " <<
166:         attrs.collect { |key, value|
167:           %Q[#{ key }="#{ value }"]
168:         }.join("\n#{ @indent }#{ @indentstr * 2 }") <<
169:         '>'
170:     end
171:   end

[Source]

     # File lib/soap/generator.rb, line 173
173:   def encode_tag_end(elename, cr = nil)
174:     if cr
175:       @buf << "\n#{ @indent }</#{ elename }>"
176:     else
177:       @buf << "</#{ elename }>"
178:     end
179:   end

[Source]

    # File lib/soap/generator.rb, line 47
47:   def generate(obj, io = nil)
48:     @buf = io || ''
49:     @indent = ''
50: 
51:     prologue
52:     @handlers.each do |uri, handler|
53:       handler.encode_prologue
54:     end
55: 
56:     ns = XSD::NS.new
57:     @buf << xmldecl
58:     encode_data(ns, obj, nil)
59: 
60:     @handlers.each do |uri, handler|
61:       handler.encode_epilogue
62:     end
63:     epilogue
64: 
65:     @buf
66:   end

Private Instance methods

[Source]

     # File lib/soap/generator.rb, line 245
245:   def epilogue
246:   end

[Source]

     # File lib/soap/generator.rb, line 248
248:   def find_handler(encodingstyle)
249:     unless @handlers.key?(encodingstyle)
250:       handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset)
251:       handler.generate_explicit_type = @generate_explicit_type
252:       handler.encode_prologue
253:       @handlers[encodingstyle] = handler
254:     end
255:     @handlers[encodingstyle]
256:   end

[Source]

     # File lib/soap/generator.rb, line 242
242:   def prologue
243:   end

[Source]

     # File lib/soap/generator.rb, line 258
258:   def xmldecl
259:     if @charset
260:       %Q[<?xml version="1.0" encoding="#{ @charset }" ?>]
261:     else
262:       %Q[<?xml version="1.0" ?>]
263:     end
264:   end

[Validate]