Class | SOAP::EncodingStyle::SOAPHandler |
In: |
lib/soap/encodingstyle/soapHandler.rb
|
Parent: | Handler |
Namespace | = | SOAP::EncodingNamespace |
NilLiteralMap | = | { 'true' => true, '1' => true, 'false' => false, '0' => false |
RootLiteralMap | = | { '1' => 1, '0' => 0 |
# 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
# File lib/soap/encodingstyle/soapHandler.rb, line 211 211: def decode_epilogue 212: decode_resolve_id 213: end
# 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
# 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
# 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
# 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
# File lib/soap/encodingstyle/soapHandler.rb, line 201 201: def decode_text(ns, text) 202: @textbuf << text 203: end
encode interface.
# 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
# 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
# File lib/soap/encodingstyle/soapHandler.rb, line 244 244: def content_ranksize(typename) 245: typename.scan(/\[[\d,]*\]$/)[0] 246: end
# File lib/soap/encodingstyle/soapHandler.rb, line 248 248: def content_typename(typename) 249: typename.sub(/\[,*\]$/, '') 250: end
# 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
# 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
# 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
# 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
# File lib/soap/encodingstyle/soapHandler.rb, line 380 380: def decode_basetype(klass, elename) 381: klass.decode(elename) 382: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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