1 | # SOAP4R - ASP.NET 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 ASPDotNetHandler < Handler
|
---|
17 | Namespace = 'http://tempuri.org/ASP.NET'
|
---|
18 | add_handler
|
---|
19 |
|
---|
20 | def initialize(charset = nil)
|
---|
21 | super(charset)
|
---|
22 | @textbuf = ''
|
---|
23 | @decode_typemap = nil
|
---|
24 | end
|
---|
25 |
|
---|
26 |
|
---|
27 | ###
|
---|
28 | ## encode interface.
|
---|
29 | #
|
---|
30 | def encode_data(generator, ns, data, parent)
|
---|
31 | attrs = {}
|
---|
32 | # ASPDotNetHandler is intended to be used for accessing an ASP.NET doc/lit
|
---|
33 | # service as an rpc/encoded service. in the situation, local elements
|
---|
34 | # should be qualified. propagate parent's namespace to children.
|
---|
35 | if data.elename.namespace.nil?
|
---|
36 | data.elename.namespace = parent.elename.namespace
|
---|
37 | end
|
---|
38 | name = generator.encode_name(ns, data, attrs)
|
---|
39 | case data
|
---|
40 | when SOAPRawString
|
---|
41 | generator.encode_tag(name, attrs)
|
---|
42 | generator.encode_rawstring(data.to_s)
|
---|
43 | when XSD::XSDString
|
---|
44 | generator.encode_tag(name, attrs)
|
---|
45 | generator.encode_string(@charset ?
|
---|
46 | XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)
|
---|
47 | when XSD::XSDAnySimpleType
|
---|
48 | generator.encode_tag(name, attrs)
|
---|
49 | generator.encode_string(data.to_s)
|
---|
50 | when SOAPStruct
|
---|
51 | generator.encode_tag(name, attrs)
|
---|
52 | data.each do |key, value|
|
---|
53 | generator.encode_child(ns, value, data)
|
---|
54 | end
|
---|
55 | when SOAPArray
|
---|
56 | generator.encode_tag(name, attrs)
|
---|
57 | data.traverse do |child, *rank|
|
---|
58 | data.position = nil
|
---|
59 | generator.encode_child(ns, child, data)
|
---|
60 | end
|
---|
61 | else
|
---|
62 | raise EncodingStyleError.new(
|
---|
63 | "unknown object:#{data} in this encodingStyle")
|
---|
64 | end
|
---|
65 | end
|
---|
66 |
|
---|
67 | def encode_data_end(generator, ns, data, parent)
|
---|
68 | name = generator.encode_name_end(ns, data)
|
---|
69 | cr = data.is_a?(SOAPCompoundtype)
|
---|
70 | generator.encode_tag_end(name, cr)
|
---|
71 | end
|
---|
72 |
|
---|
73 |
|
---|
74 | ###
|
---|
75 | ## decode interface.
|
---|
76 | #
|
---|
77 | class SOAPTemporalObject
|
---|
78 | attr_accessor :parent
|
---|
79 |
|
---|
80 | def initialize
|
---|
81 | @parent = nil
|
---|
82 | end
|
---|
83 | end
|
---|
84 |
|
---|
85 | class SOAPUnknown < SOAPTemporalObject
|
---|
86 | def initialize(handler, elename)
|
---|
87 | super()
|
---|
88 | @handler = handler
|
---|
89 | @elename = elename
|
---|
90 | end
|
---|
91 |
|
---|
92 | def as_struct
|
---|
93 | o = SOAPStruct.decode(@elename, XSD::AnyTypeName)
|
---|
94 | o.parent = @parent
|
---|
95 | o.type.name = @name
|
---|
96 | @handler.decode_parent(@parent, o)
|
---|
97 | o
|
---|
98 | end
|
---|
99 |
|
---|
100 | def as_string
|
---|
101 | o = SOAPString.decode(@elename)
|
---|
102 | o.parent = @parent
|
---|
103 | @handler.decode_parent(@parent, o)
|
---|
104 | o
|
---|
105 | end
|
---|
106 |
|
---|
107 | def as_nil
|
---|
108 | o = SOAPNil.decode(@elename)
|
---|
109 | o.parent = @parent
|
---|
110 | @handler.decode_parent(@parent, o)
|
---|
111 | o
|
---|
112 | end
|
---|
113 | end
|
---|
114 |
|
---|
115 | def decode_tag(ns, elename, attrs, parent)
|
---|
116 | @textbuf = ''
|
---|
117 | o = SOAPUnknown.new(self, elename)
|
---|
118 | o.parent = parent
|
---|
119 | o
|
---|
120 | end
|
---|
121 |
|
---|
122 | def decode_tag_end(ns, node)
|
---|
123 | o = node.node
|
---|
124 | if o.is_a?(SOAPUnknown)
|
---|
125 | newnode = o.as_string
|
---|
126 | # if /\A\s*\z/ =~ @textbuf
|
---|
127 | # o.as_struct
|
---|
128 | # else
|
---|
129 | # o.as_string
|
---|
130 | # end
|
---|
131 | node.replace_node(newnode)
|
---|
132 | o = node.node
|
---|
133 | end
|
---|
134 |
|
---|
135 | decode_textbuf(o)
|
---|
136 | @textbuf = ''
|
---|
137 | end
|
---|
138 |
|
---|
139 | def decode_text(ns, text)
|
---|
140 | # @textbuf is set at decode_tag_end.
|
---|
141 | @textbuf << text
|
---|
142 | end
|
---|
143 |
|
---|
144 | def decode_prologue
|
---|
145 | end
|
---|
146 |
|
---|
147 | def decode_epilogue
|
---|
148 | end
|
---|
149 |
|
---|
150 | def decode_parent(parent, node)
|
---|
151 | case parent.node
|
---|
152 | when SOAPUnknown
|
---|
153 | newparent = parent.node.as_struct
|
---|
154 | node.parent = newparent
|
---|
155 | parent.replace_node(newparent)
|
---|
156 | decode_parent(parent, node)
|
---|
157 |
|
---|
158 | when SOAPStruct
|
---|
159 | data = parent.node[node.elename.name]
|
---|
160 | case data
|
---|
161 | when nil
|
---|
162 | parent.node.add(node.elename.name, node)
|
---|
163 | when SOAPArray
|
---|
164 | name, type_ns = node.elename.name, node.type.namespace
|
---|
165 | data.add(node)
|
---|
166 | node.elename, node.type.namespace = name, type_ns
|
---|
167 | else
|
---|
168 | parent.node[node.elename.name] = SOAPArray.new
|
---|
169 | name, type_ns = data.elename.name, data.type.namespace
|
---|
170 | parent.node[node.elename.name].add(data)
|
---|
171 | data.elename.name, data.type.namespace = name, type_ns
|
---|
172 | name, type_ns = node.elename.name, node.type.namespace
|
---|
173 | parent.node[node.elename.name].add(node)
|
---|
174 | node.elename.name, node.type.namespace = name, type_ns
|
---|
175 | end
|
---|
176 |
|
---|
177 | when SOAPArray
|
---|
178 | if node.position
|
---|
179 | parent.node[*(decode_arypos(node.position))] = node
|
---|
180 | parent.node.sparse = true
|
---|
181 | else
|
---|
182 | parent.node.add(node)
|
---|
183 | end
|
---|
184 |
|
---|
185 | when SOAPBasetype
|
---|
186 | raise EncodingStyleError.new("SOAP base type must not have a child")
|
---|
187 |
|
---|
188 | else
|
---|
189 | # SOAPUnknown does not have parent.
|
---|
190 | # raise EncodingStyleError.new("illegal parent: #{parent}")
|
---|
191 | end
|
---|
192 | end
|
---|
193 |
|
---|
194 | private
|
---|
195 |
|
---|
196 | def decode_textbuf(node)
|
---|
197 | if node.is_a?(XSD::XSDString)
|
---|
198 | if @charset
|
---|
199 | node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))
|
---|
200 | else
|
---|
201 | node.set(@textbuf)
|
---|
202 | end
|
---|
203 | else
|
---|
204 | # Nothing to do...
|
---|
205 | end
|
---|
206 | end
|
---|
207 | end
|
---|
208 |
|
---|
209 | ASPDotNetHandler.new
|
---|
210 |
|
---|
211 |
|
---|
212 | end
|
---|
213 | end
|
---|