| 1 |
# SOAP4R - SOAP EncodingStyle handler library |
|---|
| 2 |
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. |
|---|
| 3 |
|
|---|
| 4 |
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can |
|---|
| 5 |
# redistribute it and/or modify it under the same terms of Ruby's license; |
|---|
| 6 |
# either the dual license version in 2003, or any later version. |
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
require 'soap/encodingstyle/handler' |
|---|
| 10 |
require 'soap/mapping/registry' |
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
module SOAP |
|---|
| 14 |
module EncodingStyle |
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
class SOAPHandler < Handler |
|---|
| 18 |
Namespace = SOAP::EncodingNamespace |
|---|
| 19 |
add_handler |
|---|
| 20 |
|
|---|
| 21 |
def initialize(charset = nil) |
|---|
| 22 |
super(charset) |
|---|
| 23 |
@refpool = [] |
|---|
| 24 |
@idpool = [] |
|---|
| 25 |
@textbuf = [] |
|---|
| 26 |
@is_first_top_ele = true |
|---|
| 27 |
end |
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
### |
|---|
| 31 |
## encode interface. |
|---|
| 32 |
# |
|---|
| 33 |
def encode_data(generator, ns, data, parent) |
|---|
| 34 |
attrs = encode_attrs(generator, ns, data, parent) |
|---|
| 35 |
if parent && parent.is_a?(SOAPArray) && parent.position |
|---|
| 36 |
attrs[ns.name(AttrPositionName)] = "[#{parent.position.join(',')}]" |
|---|
| 37 |
end |
|---|
| 38 |
name = generator.encode_name(ns, data, attrs) |
|---|
| 39 |
case data |
|---|
| 40 |
when SOAPReference |
|---|
| 41 |
attrs['href'] = data.refidstr |
|---|
| 42 |
generator.encode_tag(name, attrs) |
|---|
| 43 |
when SOAPExternalReference |
|---|
| 44 |
data.referred |
|---|
| 45 |
attrs['href'] = data.refidstr |
|---|
| 46 |
generator.encode_tag(name, attrs) |
|---|
| 47 |
when SOAPRawString |
|---|
| 48 |
generator.encode_tag(name, attrs) |
|---|
| 49 |
generator.encode_rawstring(data.to_s) |
|---|
| 50 |
when XSD::XSDString |
|---|
| 51 |
generator.encode_tag(name, attrs) |
|---|
| 52 |
generator.encode_string(@charset ? |
|---|
| 53 |
XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s) |
|---|
| 54 |
when XSD::XSDAnySimpleType |
|---|
| 55 |
generator.encode_tag(name, attrs) |
|---|
| 56 |
generator.encode_string(data.to_s) |
|---|
| 57 |
when SOAPStruct |
|---|
| 58 |
generator.encode_tag(name, attrs) |
|---|
| 59 |
data.each do |key, value| |
|---|
| 60 |
generator.encode_child(ns, value, data) |
|---|
| 61 |
end |
|---|
| 62 |
when SOAPArray |
|---|
| 63 |
generator.encode_tag(name, attrs) |
|---|
| 64 |
data.traverse do |child, *rank| |
|---|
| 65 |
data.position = data.sparse ? rank : nil |
|---|
| 66 |
generator.encode_child(ns, child, data) |
|---|
| 67 |
end |
|---|
| 68 |
else |
|---|
| 69 |
raise EncodingStyleError.new( |
|---|
| 70 |
"unknown object:#{data} in this encodingStyle") |
|---|
| 71 |
end |
|---|
| 72 |
end |
|---|
| 73 |
|
|---|
| 74 |
def encode_data_end(generator, ns, data, parent) |
|---|
| 75 |
name = generator.encode_name_end(ns, data) |
|---|
| 76 |
cr = (data.is_a?(SOAPCompoundtype) and data.have_member) |
|---|
| 77 |
generator.encode_tag_end(name, cr) |
|---|
| 78 |
end |
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
### |
|---|
| 82 |
## decode interface. |
|---|
| 83 |
# |
|---|
| 84 |
class SOAPTemporalObject |
|---|
| 85 |
attr_accessor :parent |
|---|
| 86 |
attr_accessor :position |
|---|
| 87 |
attr_accessor :id |
|---|
| 88 |
attr_accessor :root |
|---|
| 89 |
|
|---|
| 90 |
def initialize |
|---|
| 91 |
@parent = nil |
|---|
| 92 |
@position = nil |
|---|
| 93 |
@id = nil |
|---|
| 94 |
@root = nil |
|---|
| 95 |
end |
|---|
| 96 |
end |
|---|
| 97 |
|
|---|
| 98 |
class SOAPUnknown < SOAPTemporalObject |
|---|
| 99 |
attr_reader :type |
|---|
| 100 |
attr_accessor :definedtype |
|---|
| 101 |
attr_reader :extraattr |
|---|
| 102 |
|
|---|
| 103 |
def initialize(handler, elename, type, extraattr) |
|---|
| 104 |
super() |
|---|
| 105 |
@handler = handler |
|---|
| 106 |
@elename = elename |
|---|
| 107 |
@type = type |
|---|
| 108 |
@extraattr = extraattr |
|---|
| 109 |
@definedtype = nil |
|---|
| 110 |
end |
|---|
| 111 |
|
|---|
| 112 |
def as_struct |
|---|
| 113 |
if @extraattr[XSD::AttrNilName] == 'true' |
|---|
| 114 |
return as_nil |
|---|
| 115 |
end |
|---|
| 116 |
o = SOAPStruct.decode(@elename, @type) |
|---|
| 117 |
o.id = @id |
|---|
| 118 |
o.root = @root |
|---|
| 119 |
o.parent = @parent |
|---|
| 120 |
o.position = @position |
|---|
| 121 |
o.extraattr.update(@extraattr) |
|---|
| 122 |
@handler.decode_parent(@parent, o) |
|---|
| 123 |
o |
|---|
| 124 |
end |
|---|
| 125 |
|
|---|
| 126 |
def as_string |
|---|
| 127 |
if @extraattr[XSD::AttrNilName] == 'true' |
|---|
| 128 |
return as_nil |
|---|
| 129 |
end |
|---|
| 130 |
o = SOAPString.decode(@elename) |
|---|
| 131 |
o.id = @id |
|---|
| 132 |
o.root = @root |
|---|
| 133 |
o.parent = @parent |
|---|
| 134 |
o.position = @position |
|---|
| 135 |
o.extraattr.update(@extraattr) |
|---|
| 136 |
@handler.decode_parent(@parent, o) |
|---|
| 137 |
o |
|---|
| 138 |
end |
|---|
| 139 |
|
|---|
| 140 |
def as_nil |
|---|
| 141 |
o = SOAPNil.decode(@elename) |
|---|
| 142 |
o.id = @id |
|---|
| 143 |
o.root = @root |
|---|
| 144 |
o.parent = @parent |
|---|
| 145 |
o.position = @position |
|---|
| 146 |
o.extraattr.update(@extraattr) |
|---|
| 147 |
@handler.decode_parent(@parent, o) |
|---|
| 148 |
o |
|---|
| 149 |
end |
|---|
| 150 |
end |
|---|
| 151 |
|
|---|
| 152 |
def decode_tag(ns, elename, attrs, parent) |
|---|
| 153 |
@textbuf.clear |
|---|
| 154 |
is_nil, type, arytype, root, offset, position, href, id = |
|---|
| 155 |
extract_attrs(ns, attrs) |
|---|
| 156 |
o = nil |
|---|
| 157 |
if is_nil |
|---|
| 158 |
o = SOAPNil.decode(elename) |
|---|
| 159 |
elsif href |
|---|
| 160 |
o = SOAPReference.decode(elename, href) |
|---|
| 161 |
@refpool << o |
|---|
| 162 |
elsif @decode_typemap |
|---|
| 163 |
o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, attrs) |
|---|
| 164 |
else |
|---|
| 165 |
o = decode_tag_by_type(ns, elename, type, parent.node, arytype, attrs) |
|---|
| 166 |
end |
|---|
| 167 |
|
|---|
| 168 |
if o.is_a?(SOAPArray) |
|---|
| 169 |
if offset |
|---|
| 170 |
o.offset = decode_arypos(offset) |
|---|
| 171 |
o.sparse = true |
|---|
| 172 |
else |
|---|
| 173 |
o.sparse = false |
|---|
| 174 |
end |
|---|
| 175 |
end |
|---|
| 176 |
|
|---|
| 177 |
o.parent = parent |
|---|
| 178 |
o.id = id |
|---|
| 179 |
o.root = root |
|---|
| 180 |
o.position = position |
|---|
| 181 |
|
|---|
| 182 |
unless o.is_a?(SOAPTemporalObject) |
|---|
| 183 |
@idpool << o if o.id |
|---|
| 184 |
decode_parent(parent, o) |
|---|
| 185 |
end |
|---|
| 186 |
o |
|---|
| 187 |
end |
|---|
| 188 |
|
|---|
| 189 |
def decode_tag_end(ns, node) |
|---|
| 190 |
textbufstr = @textbuf.join |
|---|
| 191 |
@textbuf.clear |
|---|
| 192 |
o = node.node |
|---|
| 193 |
if o.is_a?(SOAPUnknown) |
|---|
| 194 |
newnode = if /\A\s*\z/ =~ textbufstr |
|---|
| 195 |
o.as_struct |
|---|
| 196 |
else |
|---|
| 197 |
o.as_string |
|---|
| 198 |
end |
|---|
| 199 |
if newnode.id |
|---|
| 200 |
@idpool << newnode |
|---|
| 201 |
end |
|---|
| 202 |
node.replace_node(newnode) |
|---|
| 203 |
o = node.node |
|---|
| 204 |
end |
|---|
| 205 |
decode_textbuf(o, textbufstr) |
|---|
| 206 |
# unlink definedtype |
|---|
| 207 |
o.definedtype = nil |
|---|
| 208 |
end |
|---|
| 209 |
|
|---|
| 210 |
def decode_text(ns, text) |
|---|
| 211 |
@textbuf << text |
|---|
| 212 |
end |
|---|
| 213 |
|
|---|
| 214 |
def decode_prologue |
|---|
| 215 |
@refpool.clear |
|---|
| 216 |
@idpool.clear |
|---|
| 217 |
@is_first_top_ele = true |
|---|
| 218 |
end |
|---|
| 219 |
|
|---|
| 220 |
def decode_epilogue |
|---|
| 221 |
decode_resolve_id |
|---|
| 222 |
end |
|---|
| 223 |
|
|---|
| 224 |
def decode_parent(parent, node) |
|---|
| 225 |
return unless parent.node |
|---|
| 226 |
case parent.node |
|---|
| 227 |
when SOAPUnknown |
|---|
| 228 |
newparent = parent.node.as_struct |
|---|
| 229 |
node.parent = newparent |
|---|
| 230 |
if newparent.id |
|---|
| 231 |
@idpool << newparent |
|---|
| 232 |
end |
|---|
| 233 |
parent.replace_node(newparent) |
|---|
| 234 |
decode_parent(parent, node) |
|---|
| 235 |
when SOAPStruct |
|---|
| 236 |
parent.node.add(node.elename.name, node) |
|---|
| 237 |
node.parent = parent.node |
|---|
| 238 |
when SOAPArray |
|---|
| 239 |
if node.position |
|---|
| 240 |
parent.node[*(decode_arypos(node.position))] = node |
|---|
| 241 |
parent.node.sparse = true |
|---|
| 242 |
else |
|---|
| 243 |
parent.node.add(node) |
|---|
| 244 |
end |
|---|
| 245 |
node.parent = parent.node |
|---|
| 246 |
else |
|---|
| 247 |
raise EncodingStyleError.new("illegal parent: #{parent.node}") |
|---|
| 248 |
end |
|---|
| 249 |
end |
|---|
| 250 |
|
|---|
| 251 |
private |
|---|
| 252 |
|
|---|
| 253 |
def content_ranksize(typename) |
|---|
| 254 |
typename.scan(/\[[\d,]*\]$/)[0] |
|---|
| 255 |
end |
|---|
| 256 |
|
|---|
| 257 |
def content_typename(typename) |
|---|
| 258 |
typename.sub(/\[,*\]$/, '') |
|---|
| 259 |
end |
|---|
| 260 |
|
|---|
| 261 |
def create_arytype(ns, data) |
|---|
| 262 |
XSD::QName.new(data.arytype.namespace, |
|---|
| 263 |
content_typename(data.arytype.name) + "[#{data.size.join(',')}]") |
|---|
| 264 |
end |
|---|
| 265 |
|
|---|
| 266 |
def encode_attrs(generator, ns, data, parent) |
|---|
| 267 |
attrs = {} |
|---|
| 268 |
return attrs if data.is_a?(SOAPReference) |
|---|
| 269 |
|
|---|
| 270 |
if !parent || parent.encodingstyle != EncodingNamespace |
|---|
| 271 |
if @generate_explicit_type |
|---|
| 272 |
Generator.assign_ns(attrs, ns, EnvelopeNamespace) |
|---|
| 273 |
attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace |
|---|
| 274 |
end |
|---|
| 275 |
data.encodingstyle = EncodingNamespace |
|---|
| 276 |
end |
|---|
| 277 |
|
|---|
| 278 |
if data.is_a?(SOAPNil) |
|---|
| 279 |
attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue |
|---|
| 280 |
elsif @generate_explicit_type |
|---|
| 281 |
if data.type.namespace |
|---|
| 282 |
Generator.assign_ns(attrs, ns, data.type.namespace) |
|---|
| 283 |
end |
|---|
| 284 |
if data.is_a?(SOAPArray) |
|---|
| 285 |
if data.arytype.namespace |
|---|
| 286 |
Generator.assign_ns(attrs, ns, data.arytype.namespace) |
|---|
| 287 |
end |
|---|
| 288 |
Generator.assign_ns(attrs, ns, EncodingNamespace) |
|---|
| 289 |
attrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data)) |
|---|
| 290 |
if data.type.name |
|---|
| 291 |
attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) |
|---|
| 292 |
end |
|---|
| 293 |
elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type) |
|---|
| 294 |
# No need to add. |
|---|
| 295 |
elsif !data.type.namespace |
|---|
| 296 |
# No need to add. |
|---|
| 297 |
else |
|---|
| 298 |
attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) |
|---|
| 299 |
end |
|---|
| 300 |
end |
|---|
| 301 |
data.extraattr.each do |key, value| |
|---|
| 302 |
keytag = key |
|---|
| 303 |
if key.is_a?(XSD::QName) |
|---|
| 304 |
keytag = encode_attr_key(attrs, ns, key) |
|---|
| 305 |
end |
|---|
| 306 |
if value.is_a?(XSD::QName) |
|---|
| 307 |
value = encode_qname(attrs, ns, value) |
|---|
| 308 |
else |
|---|
| 309 |
value = encode_attr_value(generator, ns, key, value) |
|---|
| 310 |
end |
|---|
| 311 |
attrs[keytag] = value |
|---|
| 312 |
end |
|---|
| 313 |
if data.id |
|---|
| 314 |
attrs['id'] = data.id |
|---|
| 315 |
end |
|---|
| 316 |
attrs |
|---|
| 317 |
end |
|---|
| 318 |
|
|---|
| 319 |
def encode_attr_value(generator, ns, qname, value) |
|---|
| 320 |
case value |
|---|
| 321 |
when SOAPType |
|---|
| 322 |
ref = SOAPReference.new(value) |
|---|
| 323 |
generator.add_reftarget(qname.name, value) |
|---|
| 324 |
ref.refidstr |
|---|
| 325 |
else |
|---|
| 326 |
value.to_s |
|---|
| 327 |
end |
|---|
| 328 |
end |
|---|
| 329 |
|
|---|
| 330 |
def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 331 |
o = nil |
|---|
| 332 |
if parent.class == SOAPBody |
|---|
| 333 |
# root element: should branch by root attribute? |
|---|
| 334 |
if @is_first_top_ele |
|---|
| 335 |
# Unqualified name is allowed here. |
|---|
| 336 |
@is_first_top_ele = false |
|---|
| 337 |
type = @decode_typemap[elename] || |
|---|
| 338 |
@decode_typemap.find_name(elename.name) |
|---|
| 339 |
if type |
|---|
| 340 |
o = SOAPStruct.new(elename) |
|---|
| 341 |
o.elename = elename |
|---|
| 342 |
o.definedtype = type |
|---|
| 343 |
return o |
|---|
| 344 |
end |
|---|
| 345 |
end |
|---|
| 346 |
# multi-ref element. |
|---|
| 347 |
if typestr |
|---|
| 348 |
typename = ns.parse(typestr) |
|---|
| 349 |
typedef = @decode_typemap[typename] |
|---|
| 350 |
if typedef |
|---|
| 351 |
return decode_definedtype(elename, typename, typedef, arytypestr) |
|---|
| 352 |
end |
|---|
| 353 |
end |
|---|
| 354 |
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 355 |
end |
|---|
| 356 |
|
|---|
| 357 |
if parent.type == XSD::AnyTypeName |
|---|
| 358 |
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 359 |
end |
|---|
| 360 |
|
|---|
| 361 |
# parent.definedtype == nil means the parent is SOAPUnknown. SOAPUnknown |
|---|
| 362 |
# is generated by decode_tag_by_type when its type is anyType. |
|---|
| 363 |
parenttype = parent.definedtype || @decode_typemap[parent.type] |
|---|
| 364 |
unless parenttype |
|---|
| 365 |
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 366 |
end |
|---|
| 367 |
|
|---|
| 368 |
definedtype_name = parenttype.child_type(elename) |
|---|
| 369 |
if definedtype_name and (klass = TypeMap[definedtype_name]) |
|---|
| 370 |
return decode_basetype(klass, elename) |
|---|
| 371 |
elsif definedtype_name == XSD::AnyTypeName |
|---|
| 372 |
return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 373 |
end |
|---|
| 374 |
|
|---|
| 375 |
if definedtype_name |
|---|
| 376 |
typedef = @decode_typemap[definedtype_name] |
|---|
| 377 |
else |
|---|
| 378 |
typedef = parenttype.child_defined_complextype(elename) |
|---|
| 379 |
end |
|---|
| 380 |
decode_definedtype(elename, definedtype_name, typedef, arytypestr) |
|---|
| 381 |
end |
|---|
| 382 |
|
|---|
| 383 |
def decode_definedtype(elename, typename, typedef, arytypestr) |
|---|
| 384 |
unless typedef |
|---|
| 385 |
raise EncodingStyleError.new("unknown type '#{typename}'") |
|---|
| 386 |
end |
|---|
| 387 |
if typedef.is_a?(::WSDL::XMLSchema::SimpleType) |
|---|
| 388 |
decode_defined_simpletype(elename, typename, typedef, arytypestr) |
|---|
| 389 |
else |
|---|
| 390 |
decode_defined_complextype(elename, typename, typedef, arytypestr) |
|---|
| 391 |
end |
|---|
| 392 |
end |
|---|
| 393 |
|
|---|
| 394 |
def decode_basetype(klass, elename) |
|---|
| 395 |
klass.decode(elename) |
|---|
| 396 |
end |
|---|
| 397 |
|
|---|
| 398 |
def decode_defined_simpletype(elename, typename, typedef, arytypestr) |
|---|
| 399 |
if typedef.base |
|---|
| 400 |
o = decode_basetype(TypeMap[typedef.base], elename) |
|---|
| 401 |
o.definedtype = typedef |
|---|
| 402 |
o |
|---|
| 403 |
else |
|---|
| 404 |
raise RuntimeError.new("unsupported simpleType: #{typedef}") |
|---|
| 405 |
end |
|---|
| 406 |
end |
|---|
| 407 |
|
|---|
| 408 |
def decode_defined_complextype(elename, typename, typedef, arytypestr) |
|---|
| 409 |
case typedef.compoundtype |
|---|
| 410 |
when :TYPE_STRUCT, :TYPE_MAP |
|---|
| 411 |
o = SOAPStruct.decode(elename, typename) |
|---|
| 412 |
o.definedtype = typedef |
|---|
| 413 |
return o |
|---|
| 414 |
when :TYPE_ARRAY |
|---|
| 415 |
expected_arytype = typedef.find_arytype |
|---|
| 416 |
if arytypestr |
|---|
| 417 |
actual_arytype = XSD::QName.new(expected_arytype.namespace, |
|---|
| 418 |
content_typename(expected_arytype.name) << |
|---|
| 419 |
content_ranksize(arytypestr)) |
|---|
| 420 |
o = SOAPArray.decode(elename, typename, actual_arytype) |
|---|
| 421 |
else |
|---|
| 422 |
o = SOAPArray.new(typename, 1, expected_arytype) |
|---|
| 423 |
o.elename = elename |
|---|
| 424 |
end |
|---|
| 425 |
o.definedtype = typedef |
|---|
| 426 |
return o |
|---|
| 427 |
when :TYPE_EMPTY |
|---|
| 428 |
o = SOAPNil.decode(elename) |
|---|
| 429 |
o.definedtype = typedef |
|---|
| 430 |
return o |
|---|
| 431 |
else |
|---|
| 432 |
raise RuntimeError.new( |
|---|
| 433 |
"Unknown kind of complexType: #{typedef.compoundtype}") |
|---|
| 434 |
end |
|---|
| 435 |
nil |
|---|
| 436 |
end |
|---|
| 437 |
|
|---|
| 438 |
def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, attrs) |
|---|
| 439 |
if arytypestr |
|---|
| 440 |
type = typestr ? ns.parse(typestr) : ValueArrayName |
|---|
| 441 |
node = SOAPArray.decode(elename, type, ns.parse(arytypestr)) |
|---|
| 442 |
node.extraattr.update(attrs) |
|---|
| 443 |
return node |
|---|
| 444 |
end |
|---|
| 445 |
|
|---|
| 446 |
type = nil |
|---|
| 447 |
if typestr |
|---|
| 448 |
type = ns.parse(typestr) |
|---|
| 449 |
elsif parent.is_a?(SOAPArray) |
|---|
| 450 |
type = parent.arytype |
|---|
| 451 |
else |
|---|
| 452 |
# Since it's in dynamic(without any type) encoding process, |
|---|
| 453 |
# assumes entity as its type itself. |
|---|
| 454 |
# <SOAP-ENC:Array ...> => type Array in SOAP-ENC. |
|---|
| 455 |
# <Country xmlns="foo"> => type Country in foo. |
|---|
| 456 |
type = elename |
|---|
| 457 |
end |
|---|
| 458 |
|
|---|
| 459 |
if klass = TypeMap[type] |
|---|
| 460 |
node = decode_basetype(klass, elename) |
|---|
| 461 |
node.extraattr.update(attrs) |
|---|
| 462 |
return node |
|---|
| 463 |
end |
|---|
| 464 |
|
|---|
| 465 |
# Unknown type... Struct or String |
|---|
| 466 |
SOAPUnknown.new(self, elename, type, attrs) |
|---|
| 467 |
end |
|---|
| 468 |
|
|---|
| 469 |
def decode_textbuf(node, textbufstr) |
|---|
| 470 |
case node |
|---|
| 471 |
when XSD::XSDHexBinary, XSD::XSDBase64Binary |
|---|
| 472 |
node.set_encoded(textbufstr) |
|---|
| 473 |
when XSD::XSDString |
|---|
| 474 |
if @charset |
|---|
| 475 |
textbufstr = XSD::Charset.encoding_from_xml(textbufstr, @charset) |
|---|
| 476 |
end |
|---|
| 477 |
if node.definedtype |
|---|
| 478 |
node.definedtype.check_lexical_format(textbufstr) |
|---|
| 479 |
end |
|---|
| 480 |
node.set(textbufstr) |
|---|
| 481 |
when SOAPNil |
|---|
| 482 |
# Nothing to do. |
|---|
| 483 |
when SOAPBasetype |
|---|
| 484 |
node.set(textbufstr) |
|---|
| 485 |
else |
|---|
| 486 |
# Nothing to do... |
|---|
| 487 |
end |
|---|
| 488 |
end |
|---|
| 489 |
|
|---|
| 490 |
NilLiteralMap = { |
|---|
| 491 |
'true' => true, |
|---|
| 492 |
'1' => true, |
|---|
| 493 |
'false' => false, |
|---|
| 494 |
'0' => false |
|---|
| 495 |
} |
|---|
| 496 |
RootLiteralMap = { |
|---|
| 497 |
'1' => 1, |
|---|
| 498 |
'0' => 0 |
|---|
| 499 |
} |
|---|
| 500 |
def extract_attrs(ns, attrs) |
|---|
| 501 |
is_nil = NilLiteralMap[attrs[XSD::AttrNilName]] |
|---|
| 502 |
type = attrs[XSD::AttrTypeName] |
|---|
| 503 |
arytype = attrs[AttrArrayTypeName] |
|---|
| 504 |
root = attrs[AttrRootName] |
|---|
| 505 |
offset = attrs[AttrOffsetName] |
|---|
| 506 |
position = attrs[AttrPositionName] |
|---|
| 507 |
href = attrs[AttrHrefName] |
|---|
| 508 |
id = attrs[AttrIdName] |
|---|
| 509 |
if attrs.key?(Mapping::RubyIVarName) |
|---|
| 510 |
attrs[Mapping::RubyIVarName] = |
|---|
| 511 |
decode_ref_value(ns, attrs[Mapping::RubyIVarName]) |
|---|
| 512 |
end |
|---|
| 513 |
return is_nil, type, arytype, root, offset, position, href, id |
|---|
| 514 |
end |
|---|
| 515 |
|
|---|
| 516 |
def decode_ref_value(ns, value) |
|---|
| 517 |
if /\A#/ =~ value |
|---|
| 518 |
o = SOAPReference.decode(nil, value) |
|---|
| 519 |
@refpool << o |
|---|
| 520 |
o |
|---|
| 521 |
else |
|---|
| 522 |
value |
|---|
| 523 |
end |
|---|
| 524 |
end |
|---|
| 525 |
|
|---|
| 526 |
def decode_arypos(position) |
|---|
| 527 |
/^\[(.+)\]$/ =~ position |
|---|
| 528 |
$1.split(',').collect { |s| s.to_i } |
|---|
| 529 |
end |
|---|
| 530 |
|
|---|
| 531 |
def decode_resolve_id |
|---|
| 532 |
count = @refpool.length # To avoid infinite loop |
|---|
| 533 |
while !@refpool.empty? && count > 0 |
|---|
| 534 |
@refpool = @refpool.find_all { |ref| |
|---|
| 535 |
o = @idpool.find { |item| |
|---|
| 536 |
item.id == ref.refid |
|---|
| 537 |
} |
|---|
| 538 |
if o.is_a?(SOAPReference) |
|---|
| 539 |
true # link of link. |
|---|
| 540 |
elsif o |
|---|
| 541 |
ref.__setobj__(o) |
|---|
| 542 |
false |
|---|
| 543 |
elsif o = ref.rootnode.external_content[ref.refid] |
|---|
| 544 |
ref.__setobj__(o) |
|---|
| 545 |
false |
|---|
| 546 |
else |
|---|
| 547 |
raise EncodingStyleError.new("unresolved reference: #{ref.refid}") |
|---|
| 548 |
end |
|---|
| 549 |
} |
|---|
| 550 |
count -= 1 |
|---|
| 551 |
end |
|---|
| 552 |
end |
|---|
| 553 |
end |
|---|
| 554 |
|
|---|
| 555 |
SOAPHandler.new |
|---|
| 556 |
|
|---|
| 557 |
|
|---|
| 558 |
end |
|---|
| 559 |
end |
|---|