Class SOAP::EncodingStyle::SOAPHandler
In: lib/soap/encodingstyle/soapHandler.rb
Parent: Handler

Methods

Classes and Modules

Class SOAP::EncodingStyle::SOAPHandler::SOAPTemporalObject
Class SOAP::EncodingStyle::SOAPHandler::SOAPUnknown

Constants

Namespace = SOAP::EncodingNamespace
NilLiteralMap = { 'true' => true, '1' => true, 'false' => false, '0' => false
RootLiteralMap = { '1' => 1, '0' => 0

Public Class methods

[Source]

    # File lib/soap/encodingstyle/soapHandler.rb, line 20
20:   def initialize(charset = nil)
21:     super(charset)
22:     @refpool = []
23:     @idpool = []
24:     @textbuf = ''
25:     @is_first_top_ele = true
26:   end

Public Instance methods

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 211
211:   def decode_epilogue
212:     decode_resolve_id
213:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 215
215:   def decode_parent(parent, node)
216:     return unless parent.node
217:     case parent.node
218:     when SOAPUnknown
219:       newparent = parent.node.as_struct
220:       node.parent = newparent
221:       if newparent.id
222:         @idpool << newparent
223:       end
224:       parent.replace_node(newparent)
225:       decode_parent(parent, node)
226:     when SOAPStruct
227:       parent.node.add(node.elename.name, node)
228:       node.parent = parent.node
229:     when SOAPArray
230:       if node.position
231:         parent.node[*(decode_arypos(node.position))] = node
232:         parent.node.sparse = true
233:       else
234:         parent.node.add(node)
235:       end
236:       node.parent = parent.node
237:     else
238:       raise EncodingStyleError.new("illegal parent: #{parent.node}")
239:     end
240:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 205
205:   def decode_prologue
206:     @refpool.clear
207:     @idpool.clear
208:     @is_first_top_ele = true
209:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 145
145:   def decode_tag(ns, elename, attrs, parent)
146:     @textbuf = ''
147:     is_nil, type, arytype, root, offset, position, href, id, extraattr =
148:       decode_attrs(ns, attrs)
149:     o = nil
150:     if is_nil
151:       o = SOAPNil.decode(elename)
152:     elsif href
153:       o = SOAPReference.decode(elename, href)
154:       @refpool << o
155:     elsif @decode_typemap
156:       o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, extraattr)
157:     else
158:       o = decode_tag_by_type(ns, elename, type, parent.node, arytype, extraattr)
159:     end
160: 
161:     if o.is_a?(SOAPArray)
162:       if offset
163:         o.offset = decode_arypos(offset)
164:         o.sparse = true
165:       else
166:         o.sparse = false
167:       end
168:     end
169: 
170:     o.parent = parent
171:     o.id = id
172:     o.root = root
173:     o.position = position
174: 
175:     unless o.is_a?(SOAPTemporalObject)
176:       @idpool << o if o.id
177:       decode_parent(parent, o)
178:     end
179:     o
180:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 182
182:   def decode_tag_end(ns, node)
183:     o = node.node
184:     if o.is_a?(SOAPUnknown)
185:       newnode = if /\A\s*\z/ =~ @textbuf
186:         o.as_struct
187:       else
188:         o.as_string
189:       end
190:       if newnode.id
191:         @idpool << newnode
192:       end
193:       node.replace_node(newnode)
194:       o = node.node
195:     end
196:     decode_textbuf(o)
197:     # unlink definedtype
198:     o.definedtype = nil
199:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 201
201:   def decode_text(ns, text)
202:     @textbuf << text
203:   end

encode interface.

[Source]

    # File lib/soap/encodingstyle/soapHandler.rb, line 32
32:   def encode_data(generator, ns, data, parent)
33:     attrs = encode_attrs(generator, ns, data, parent)
34:     if parent && parent.is_a?(SOAPArray) && parent.position
35:       attrs[ns.name(AttrPositionName)] = "[#{parent.position.join(',')}]"
36:     end
37:     name = generator.encode_name(ns, data, attrs)
38:     case data
39:     when SOAPReference
40:       attrs['href'] = data.refidstr
41:       generator.encode_tag(name, attrs)
42:     when SOAPExternalReference
43:       data.referred
44:       attrs['href'] = data.refidstr
45:       generator.encode_tag(name, attrs)
46:     when SOAPRawString
47:       generator.encode_tag(name, attrs)
48:       generator.encode_rawstring(data.to_s)
49:     when XSD::XSDString
50:       generator.encode_tag(name, attrs)
51:       generator.encode_string(@charset ?
52:         XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
53:     when XSD::XSDAnySimpleType
54:       generator.encode_tag(name, attrs)
55:       generator.encode_string(data.to_s)
56:     when SOAPStruct
57:       generator.encode_tag(name, attrs)
58:       data.each do |key, value|
59:         generator.encode_child(ns, value, data)
60:       end
61:     when SOAPArray
62:       generator.encode_tag(name, attrs)
63:       data.traverse do |child, *rank|
64:         data.position = data.sparse ? rank : nil
65:         generator.encode_child(ns, child, data)
66:       end
67:     else
68:       raise EncodingStyleError.new(
69:         "unknown object:#{data} in this encodingStyle")
70:     end
71:   end

[Source]

    # File lib/soap/encodingstyle/soapHandler.rb, line 73
73:   def encode_data_end(generator, ns, data, parent)
74:     name = generator.encode_name_end(ns, data)
75:     cr = data.is_a?(SOAPCompoundtype)
76:     generator.encode_tag_end(name, cr)
77:   end

Private Instance methods

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 244
244:   def content_ranksize(typename)
245:     typename.scan(/\[[\d,]*\]$/)[0]
246:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 248
248:   def content_typename(typename)
249:     typename.sub(/\[,*\]$/, '')
250:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 252
252:   def create_arytype(ns, data)
253:     XSD::QName.new(data.arytype.namespace,
254:       content_typename(data.arytype.name) + "[#{data.size.join(',')}]")
255:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 549
549:   def decode_arypos(position)
550:     /^\[(.+)\]$/ =~ position
551:     $1.split(',').collect { |s| s.to_i }
552:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 539
539:   def decode_attr_value(ns, qname, value)
540:     if /\A#/ =~ value
541:       o = SOAPReference.decode(nil, value)
542:       @refpool << o
543:       o
544:     else
545:       value
546:     end
547:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 483
483:   def decode_attrs(ns, attrs)
484:     is_nil = false
485:     type = nil
486:     arytype = nil
487:     root = nil
488:     offset = nil
489:     position = nil
490:     href = nil
491:     id = nil
492:     extraattr = {}
493: 
494:     attrs.each do |key, value|
495:       qname = ns.parse(key)
496:       case qname.namespace
497:       when XSD::InstanceNamespace
498:         case qname.name
499:         when XSD::NilLiteral
500:           is_nil = NilLiteralMap[value] or
501:             raise EncodingStyleError.new("cannot accept attribute value: #{value} as the value of xsi:#{XSD::NilLiteral} (expected 'true', 'false', '1', or '0')")
502:           next
503:         when XSD::AttrType
504:           type = value
505:           next
506:         end
507:       when EncodingNamespace
508:         case qname.name
509:         when AttrArrayType
510:           arytype = value
511:           next
512:         when AttrRoot
513:           root = RootLiteralMap[value] or
514:             raise EncodingStyleError.new(
515:               "illegal root attribute value: #{value}")
516:           next
517:         when AttrOffset
518:           offset = value
519:           next
520:         when AttrPosition
521:           position = value
522:           next
523:         end
524:       end
525:       if key == 'href'
526:         href = value
527:         next
528:       elsif key == 'id'
529:         id = value
530:         next
531:       end
532:       qname = ns.parse_local(key)
533:       extraattr[qname] = decode_attr_value(ns, qname, value)
534:     end
535: 
536:     return is_nil, type, arytype, root, offset, position, href, id, extraattr
537:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 380
380:   def decode_basetype(klass, elename)
381:     klass.decode(elename)
382:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 390
390:   def decode_defined_complextype(elename, typename, typedef, arytypestr)
391:     case typedef.compoundtype
392:     when :TYPE_STRUCT, :TYPE_MAP
393:       o = SOAPStruct.decode(elename, typename)
394:       o.definedtype = typedef
395:       return o
396:     when :TYPE_ARRAY
397:       expected_arytype = typedef.find_arytype
398:       if arytypestr
399:         actual_arytype = XSD::QName.new(expected_arytype.namespace,
400:           content_typename(expected_arytype.name) <<
401:           content_ranksize(arytypestr))
402:         o = SOAPArray.decode(elename, typename, actual_arytype)
403:       else
404:         o = SOAPArray.new(typename, 1, expected_arytype)
405:         o.elename = elename
406:       end
407:       o.definedtype = typedef
408:       return o
409:     when :TYPE_EMPTY
410:       o = SOAPNil.decode(elename)
411:       o.definedtype = typedef
412:       return o
413:     else
414:       raise RuntimeError.new(
415:         "Unknown kind of complexType: #{typedef.compoundtype}")
416:     end
417:     nil
418:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 384
384:   def decode_defined_simpletype(elename, typename, typedef, arytypestr)
385:     o = decode_basetype(TypeMap[typedef.base], elename)
386:     o.definedtype = typedef
387:     o
388:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 369
369:   def decode_definedtype(elename, typename, typedef, arytypestr)
370:     unless typedef
371:       raise EncodingStyleError.new("unknown type '#{typename}'")
372:     end
373:     if typedef.is_a?(::WSDL::XMLSchema::SimpleType)
374:       decode_defined_simpletype(elename, typename, typedef, arytypestr)
375:     else
376:       decode_defined_complextype(elename, typename, typedef, arytypestr)
377:     end
378:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 554
554:   def decode_resolve_id
555:     count = @refpool.length     # To avoid infinite loop
556:     while !@refpool.empty? && count > 0
557:       @refpool = @refpool.find_all { |ref|
558:         o = @idpool.find { |item|
559:           item.id == ref.refid
560:         }
561:         if o.is_a?(SOAPReference)
562:           true # link of link.
563:         elsif o
564:           ref.__setobj__(o)
565:           false
566:         elsif o = ref.rootnode.external_content[ref.refid]
567:           ref.__setobj__(o)
568:           false
569:         else
570:           raise EncodingStyleError.new("unresolved reference: #{ref.refid}")
571:         end
572:       }
573:       count -= 1
574:     end
575:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 420
420:   def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr)
421:     if arytypestr
422:       type = typestr ? ns.parse(typestr) : ValueArrayName
423:       node = SOAPArray.decode(elename, type, ns.parse(arytypestr))
424:       node.extraattr.update(extraattr)
425:       return node
426:     end
427: 
428:     type = nil
429:     if typestr
430:       type = ns.parse(typestr)
431:     elsif parent.is_a?(SOAPArray)
432:       type = parent.arytype
433:     else
434:       # Since it's in dynamic(without any type) encoding process,
435:       # assumes entity as its type itself.
436:       #   <SOAP-ENC:Array ...> => type Array in SOAP-ENC.
437:       #   <Country xmlns="foo"> => type Country in foo.
438:       type = elename
439:     end
440: 
441:     if (klass = TypeMap[type])
442:       node = decode_basetype(klass, elename)
443:       node.extraattr.update(extraattr)
444:       return node
445:     end
446: 
447:     # Unknown type... Struct or String
448:     SOAPUnknown.new(self, elename, type, extraattr)
449:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 313
313:   def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr)
314:     o = nil
315:     if parent.class == SOAPBody
316:       # root element: should branch by root attribute?
317:       if @is_first_top_ele
318:         # Unqualified name is allowed here.
319:         @is_first_top_ele = false
320:         type = @decode_typemap[elename] ||
321:           @decode_typemap.find_name(elename.name)
322:         if type
323:           o = SOAPStruct.new(elename)
324:           o.definedtype = type
325:           return o
326:         end
327:       end
328:       # multi-ref element.
329:       if typestr
330:         typename = ns.parse(typestr)
331:         typedef = @decode_typemap[typename]
332:         if typedef
333:           return decode_definedtype(elename, typename, typedef, arytypestr)
334:         end
335:       end
336:       return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
337:         extraattr)
338:     end
339: 
340:     if parent.type == XSD::AnyTypeName
341:       return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
342:         extraattr)
343:     end
344: 
345:     # parent.definedtype == nil means the parent is SOAPUnknown.  SOAPUnknown
346:     # is generated by decode_tag_by_type when its type is anyType.
347:     parenttype = parent.definedtype || @decode_typemap[parent.type]
348:     unless parenttype
349:       return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
350:         extraattr)
351:     end
352: 
353:     definedtype_name = parenttype.child_type(elename)
354:     if definedtype_name and (klass = TypeMap[definedtype_name])
355:       return decode_basetype(klass, elename)
356:     elsif definedtype_name == XSD::AnyTypeName
357:       return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,
358:         extraattr)
359:     end
360: 
361:     if definedtype_name
362:       typedef = @decode_typemap[definedtype_name]
363:     else
364:       typedef = parenttype.child_defined_complextype(elename)
365:     end
366:     decode_definedtype(elename, definedtype_name, typedef, arytypestr)
367:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 451
451:   def decode_textbuf(node)
452:     case node
453:     when XSD::XSDHexBinary, XSD::XSDBase64Binary
454:       node.set_encoded(@textbuf)
455:     when XSD::XSDString
456:       if @charset
457:         @textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset)
458:       end
459:       if node.definedtype
460:         node.definedtype.check_lexical_format(@textbuf)
461:       end
462:       node.set(@textbuf)
463:     when SOAPNil
464:       # Nothing to do.
465:     when SOAPBasetype
466:       node.set(@textbuf)
467:     else
468:       # Nothing to do...
469:     end
470:     @textbuf = ''
471:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 303
303:   def encode_attr_value(generator, ns, qname, value)
304:     if value.is_a?(SOAPType)
305:       ref = SOAPReference.new(value)
306:       generator.add_reftarget(qname.name, value)
307:       ref.refidstr
308:     else
309:       value.to_s
310:     end
311:   end

[Source]

     # File lib/soap/encodingstyle/soapHandler.rb, line 257
257:   def encode_attrs(generator, ns, data, parent)
258:     attrs = {}
259:     return attrs if data.is_a?(SOAPReference)
260: 
261:     if !parent || parent.encodingstyle != EncodingNamespace
262:       if @generate_explicit_type
263:         SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)
264:         attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace
265:       end
266:       data.encodingstyle = EncodingNamespace
267:     end
268: 
269:     if data.is_a?(SOAPNil)
270:       attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue
271:     elsif @generate_explicit_type
272:       if data.type.namespace
273:         SOAPGenerator.assign_ns(attrs, ns, data.type.namespace)
274:       end
275:       if data.is_a?(SOAPArray)
276:         if data.arytype.namespace
277:           SOAPGenerator.assign_ns(attrs, ns, data.arytype.namespace)
278:         end
279:         SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)
280:         attrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data))
281:         if data.type.name
282:           attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)
283:         end
284:       elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type)
285:         # No need to add.
286:       elsif !data.type.namespace
287:         # No need to add.
288:       else
289:         attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)
290:       end
291:     end
292: 
293:     data.extraattr.each do |key, value|
294:       SOAPGenerator.assign_ns(attrs, ns, key.namespace)
295:       attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value)
296:     end
297:     if data.id
298:       attrs['id'] = data.id
299:     end
300:     attrs
301:   end

[Validate]