1 | # SOAP4R - XML Literal EncodingStyle handler library
|
---|
2 | # Copyright (C) 2001, 2003-2005 NAKAMURA, Hiroshi <[email protected]>.
|
---|
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 |
|
---|
11 |
|
---|
12 | module SOAP
|
---|
13 | module EncodingStyle
|
---|
14 |
|
---|
15 |
|
---|
16 | class LiteralHandler < Handler
|
---|
17 | Namespace = SOAP::LiteralNamespace
|
---|
18 | add_handler
|
---|
19 |
|
---|
20 | def initialize(charset = nil)
|
---|
21 | super(charset)
|
---|
22 | @textbuf = ''
|
---|
23 | end
|
---|
24 |
|
---|
25 |
|
---|
26 | ###
|
---|
27 | ## encode interface.
|
---|
28 | #
|
---|
29 | def encode_data(generator, ns, data, parent)
|
---|
30 | attrs = {}
|
---|
31 | name = generator.encode_name(ns, data, attrs)
|
---|
32 | data.extraattr.each do |k, v|
|
---|
33 | # ToDo: check generator.attributeformdefault here
|
---|
34 | if k.is_a?(XSD::QName)
|
---|
35 | if k.namespace
|
---|
36 | SOAPGenerator.assign_ns(attrs, ns, k.namespace)
|
---|
37 | k = ns.name(k)
|
---|
38 | else
|
---|
39 | k = k.name
|
---|
40 | end
|
---|
41 | end
|
---|
42 | attrs[k] = v
|
---|
43 | end
|
---|
44 | case data
|
---|
45 | when SOAPRawString
|
---|
46 | generator.encode_tag(name, attrs)
|
---|
47 | generator.encode_rawstring(data.to_s)
|
---|
48 | when XSD::XSDString
|
---|
49 | generator.encode_tag(name, attrs)
|
---|
50 | str = data.to_s
|
---|
51 | str = XSD::Charset.encoding_to_xml(str, @charset) if @charset
|
---|
52 | generator.encode_string(str)
|
---|
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 = nil
|
---|
65 | generator.encode_child(ns, child, data)
|
---|
66 | end
|
---|
67 | when SOAPElement
|
---|
68 | # passes 2 times for simplifying namespace definition
|
---|
69 | data.each do |key, value|
|
---|
70 | if value.elename.namespace
|
---|
71 | SOAPGenerator.assign_ns(attrs, ns, value.elename.namespace)
|
---|
72 | end
|
---|
73 | end
|
---|
74 | generator.encode_tag(name, attrs)
|
---|
75 | generator.encode_rawstring(data.text) if data.text
|
---|
76 | data.each do |key, value|
|
---|
77 | generator.encode_child(ns, value, data)
|
---|
78 | end
|
---|
79 | else
|
---|
80 | raise EncodingStyleError.new(
|
---|
81 | "unknown object:#{data} in this encodingStyle")
|
---|
82 | end
|
---|
83 | end
|
---|
84 |
|
---|
85 | def encode_data_end(generator, ns, data, parent)
|
---|
86 | name = generator.encode_name_end(ns, data)
|
---|
87 | cr = (data.is_a?(SOAPCompoundtype) or
|
---|
88 | (data.is_a?(SOAPElement) and !data.text))
|
---|
89 | generator.encode_tag_end(name, cr)
|
---|
90 | end
|
---|
91 |
|
---|
92 |
|
---|
93 | ###
|
---|
94 | ## decode interface.
|
---|
95 | #
|
---|
96 | class SOAPTemporalObject
|
---|
97 | attr_accessor :parent
|
---|
98 |
|
---|
99 | def initialize
|
---|
100 | @parent = nil
|
---|
101 | end
|
---|
102 | end
|
---|
103 |
|
---|
104 | class SOAPUnknown < SOAPTemporalObject
|
---|
105 | def initialize(handler, elename, extraattr)
|
---|
106 | super()
|
---|
107 | @handler = handler
|
---|
108 | @elename = elename
|
---|
109 | @extraattr = extraattr
|
---|
110 | end
|
---|
111 |
|
---|
112 | def as_element
|
---|
113 | o = SOAPElement.decode(@elename)
|
---|
114 | o.parent = @parent
|
---|
115 | o.extraattr.update(@extraattr)
|
---|
116 | @handler.decode_parent(@parent, o)
|
---|
117 | o
|
---|
118 | end
|
---|
119 |
|
---|
120 | def as_string
|
---|
121 | o = SOAPString.decode(@elename)
|
---|
122 | o.parent = @parent
|
---|
123 | o.extraattr.update(@extraattr)
|
---|
124 | @handler.decode_parent(@parent, o)
|
---|
125 | o
|
---|
126 | end
|
---|
127 |
|
---|
128 | def as_nil
|
---|
129 | o = SOAPNil.decode(@elename)
|
---|
130 | o.parent = @parent
|
---|
131 | o.extraattr.update(@extraattr)
|
---|
132 | @handler.decode_parent(@parent, o)
|
---|
133 | o
|
---|
134 | end
|
---|
135 | end
|
---|
136 |
|
---|
137 | def decode_tag(ns, elename, attrs, parent)
|
---|
138 | @textbuf = ''
|
---|
139 | o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs))
|
---|
140 | o.parent = parent
|
---|
141 | o
|
---|
142 | end
|
---|
143 |
|
---|
144 | def decode_tag_end(ns, node)
|
---|
145 | o = node.node
|
---|
146 | if o.is_a?(SOAPUnknown)
|
---|
147 | newnode = if /\A\s*\z/ =~ @textbuf
|
---|
148 | o.as_element
|
---|
149 | else
|
---|
150 | o.as_string
|
---|
151 | end
|
---|
152 | node.replace_node(newnode)
|
---|
153 | o = node.node
|
---|
154 | end
|
---|
155 |
|
---|
156 | decode_textbuf(o)
|
---|
157 | @textbuf = ''
|
---|
158 | end
|
---|
159 |
|
---|
160 | def decode_text(ns, text)
|
---|
161 | # @textbuf is set at decode_tag_end.
|
---|
162 | @textbuf << text
|
---|
163 | end
|
---|
164 |
|
---|
165 | def decode_attrs(ns, attrs)
|
---|
166 | extraattr = {}
|
---|
167 | attrs.each do |key, value|
|
---|
168 | qname = ns.parse_local(key)
|
---|
169 | extraattr[qname] = value
|
---|
170 | end
|
---|
171 | extraattr
|
---|
172 | end
|
---|
173 |
|
---|
174 | def decode_prologue
|
---|
175 | end
|
---|
176 |
|
---|
177 | def decode_epilogue
|
---|
178 | end
|
---|
179 |
|
---|
180 | def decode_parent(parent, node)
|
---|
181 | return unless parent.node
|
---|
182 | case parent.node
|
---|
183 | when SOAPUnknown
|
---|
184 | newparent = parent.node.as_element
|
---|
185 | node.parent = newparent
|
---|
186 | parent.replace_node(newparent)
|
---|
187 | decode_parent(parent, node)
|
---|
188 | when SOAPElement
|
---|
189 | parent.node.add(node)
|
---|
190 | node.parent = parent.node
|
---|
191 | when SOAPStruct
|
---|
192 | parent.node.add(node.elename.name, node)
|
---|
193 | node.parent = parent.node
|
---|
194 | when SOAPArray
|
---|
195 | if node.position
|
---|
196 | parent.node[*(decode_arypos(node.position))] = node
|
---|
197 | parent.node.sparse = true
|
---|
198 | else
|
---|
199 | parent.node.add(node)
|
---|
200 | end
|
---|
201 | node.parent = parent.node
|
---|
202 | else
|
---|
203 | raise EncodingStyleError.new("illegal parent: #{parent.node}")
|
---|
204 | end
|
---|
205 | end
|
---|
206 |
|
---|
207 | private
|
---|
208 |
|
---|
209 | def decode_textbuf(node)
|
---|
210 | if node.is_a?(XSD::XSDString)
|
---|
211 | if @charset
|
---|
212 | node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))
|
---|
213 | else
|
---|
214 | node.set(@textbuf)
|
---|
215 | end
|
---|
216 | else
|
---|
217 | # Nothing to do...
|
---|
218 | end
|
---|
219 | end
|
---|
220 | end
|
---|
221 |
|
---|
222 | LiteralHandler.new
|
---|
223 |
|
---|
224 |
|
---|
225 | end
|
---|
226 | end
|
---|