rubysl-soap 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +8 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/lib/rubysl/soap.rb +1 -0
  7. data/lib/rubysl/soap/version.rb +5 -0
  8. data/lib/soap/attachment.rb +107 -0
  9. data/lib/soap/baseData.rb +942 -0
  10. data/lib/soap/element.rb +258 -0
  11. data/lib/soap/encodingstyle/aspDotNetHandler.rb +213 -0
  12. data/lib/soap/encodingstyle/handler.rb +100 -0
  13. data/lib/soap/encodingstyle/literalHandler.rb +226 -0
  14. data/lib/soap/encodingstyle/soapHandler.rb +582 -0
  15. data/lib/soap/generator.rb +268 -0
  16. data/lib/soap/header/handler.rb +57 -0
  17. data/lib/soap/header/handlerset.rb +70 -0
  18. data/lib/soap/header/simplehandler.rb +44 -0
  19. data/lib/soap/httpconfigloader.rb +119 -0
  20. data/lib/soap/mapping.rb +10 -0
  21. data/lib/soap/mapping/factory.rb +355 -0
  22. data/lib/soap/mapping/mapping.rb +381 -0
  23. data/lib/soap/mapping/registry.rb +541 -0
  24. data/lib/soap/mapping/rubytypeFactory.rb +475 -0
  25. data/lib/soap/mapping/typeMap.rb +50 -0
  26. data/lib/soap/mapping/wsdlencodedregistry.rb +280 -0
  27. data/lib/soap/mapping/wsdlliteralregistry.rb +418 -0
  28. data/lib/soap/marshal.rb +59 -0
  29. data/lib/soap/mimemessage.rb +240 -0
  30. data/lib/soap/netHttpClient.rb +190 -0
  31. data/lib/soap/parser.rb +251 -0
  32. data/lib/soap/processor.rb +66 -0
  33. data/lib/soap/property.rb +333 -0
  34. data/lib/soap/rpc/cgistub.rb +206 -0
  35. data/lib/soap/rpc/driver.rb +254 -0
  36. data/lib/soap/rpc/element.rb +325 -0
  37. data/lib/soap/rpc/httpserver.rb +129 -0
  38. data/lib/soap/rpc/proxy.rb +497 -0
  39. data/lib/soap/rpc/router.rb +594 -0
  40. data/lib/soap/rpc/rpc.rb +25 -0
  41. data/lib/soap/rpc/soaplet.rb +162 -0
  42. data/lib/soap/rpc/standaloneServer.rb +43 -0
  43. data/lib/soap/soap.rb +140 -0
  44. data/lib/soap/streamHandler.rb +229 -0
  45. data/lib/soap/wsdlDriver.rb +575 -0
  46. data/rubysl-soap.gemspec +19 -18
  47. metadata +115 -86
  48. data/lib/rubysl-soap.rb +0 -7
  49. data/lib/rubysl-soap/version.rb +0 -5
@@ -0,0 +1,10 @@
1
+ # SOAP4R - Ruby type mapping utility.
2
+ # Copyright (C) 2003 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/mapping/mapping'
10
+ require 'soap/mapping/registry'
@@ -0,0 +1,355 @@
1
+ # SOAP4R - Mapping factory.
2
+ # Copyright (C) 2000, 2001, 2002, 2003 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
+ module SOAP
10
+ module Mapping
11
+
12
+
13
+ class Factory
14
+ include TraverseSupport
15
+
16
+ def initialize
17
+ # nothing to do
18
+ end
19
+
20
+ def obj2soap(soap_class, obj, info, map)
21
+ raise NotImplementError.new
22
+ # return soap_obj
23
+ end
24
+
25
+ def soap2obj(obj_class, node, info, map)
26
+ raise NotImplementError.new
27
+ # return convert_succeeded_or_not, obj
28
+ end
29
+
30
+ def setiv2obj(obj, node, map)
31
+ return if node.nil?
32
+ if obj.is_a?(Array)
33
+ setiv2ary(obj, node, map)
34
+ else
35
+ setiv2struct(obj, node, map)
36
+ end
37
+ end
38
+
39
+ def setiv2soap(node, obj, map)
40
+ if obj.class.class_variables.include?('@@schema_element')
41
+ obj.class.class_eval('@@schema_element').each do |name, info|
42
+ type, qname = info
43
+ if qname
44
+ elename = qname.name
45
+ else
46
+ elename = Mapping.name2elename(name)
47
+ end
48
+ node.add(elename,
49
+ Mapping._obj2soap(obj.instance_variable_get('@' + name), map))
50
+ end
51
+ else
52
+ # should we sort instance_variables?
53
+ obj.instance_variables.each do |var|
54
+ name = var.sub(/^@/, '')
55
+ elename = Mapping.name2elename(name)
56
+ node.add(elename,
57
+ Mapping._obj2soap(obj.instance_variable_get(var), map))
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def setiv2ary(obj, node, map)
65
+ node.each do |name, value|
66
+ Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map))
67
+ end
68
+ end
69
+
70
+ def setiv2struct(obj, node, map)
71
+ vars = {}
72
+ node.each do |name, value|
73
+ vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
74
+ end
75
+ Mapping.set_attributes(obj, vars)
76
+ end
77
+ end
78
+
79
+ class StringFactory_ < Factory
80
+ def initialize(allow_original_mapping = false)
81
+ super()
82
+ @allow_original_mapping = allow_original_mapping
83
+ end
84
+
85
+ def obj2soap(soap_class, obj, info, map)
86
+ if !@allow_original_mapping and !obj.instance_variables.empty?
87
+ return nil
88
+ end
89
+ begin
90
+ unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES])
91
+ return nil
92
+ end
93
+ encoded = XSD::Charset.encoding_conv(obj,
94
+ Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
95
+ soap_obj = soap_class.new(encoded)
96
+ rescue XSD::ValueSpaceError
97
+ return nil
98
+ end
99
+ mark_marshalled_obj(obj, soap_obj)
100
+ soap_obj
101
+ end
102
+
103
+ def soap2obj(obj_class, node, info, map)
104
+ obj = Mapping.create_empty_object(obj_class)
105
+ decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding,
106
+ Thread.current[:SOAPExternalCES])
107
+ obj.replace(decoded)
108
+ mark_unmarshalled_obj(node, obj)
109
+ return true, obj
110
+ end
111
+ end
112
+
113
+ class BasetypeFactory_ < Factory
114
+ def initialize(allow_original_mapping = false)
115
+ super()
116
+ @allow_original_mapping = allow_original_mapping
117
+ end
118
+
119
+ def obj2soap(soap_class, obj, info, map)
120
+ if !@allow_original_mapping and !obj.instance_variables.empty?
121
+ return nil
122
+ end
123
+ soap_obj = nil
124
+ begin
125
+ soap_obj = soap_class.new(obj)
126
+ rescue XSD::ValueSpaceError
127
+ return nil
128
+ end
129
+ if @allow_original_mapping
130
+ # Basetype except String should not be multiref-ed in SOAP/1.1.
131
+ mark_marshalled_obj(obj, soap_obj)
132
+ end
133
+ soap_obj
134
+ end
135
+
136
+ def soap2obj(obj_class, node, info, map)
137
+ obj = node.data
138
+ mark_unmarshalled_obj(node, obj)
139
+ return true, obj
140
+ end
141
+ end
142
+
143
+ class DateTimeFactory_ < Factory
144
+ def initialize(allow_original_mapping = false)
145
+ super()
146
+ @allow_original_mapping = allow_original_mapping
147
+ end
148
+
149
+ def obj2soap(soap_class, obj, info, map)
150
+ if !@allow_original_mapping and
151
+ Time === obj and !obj.instance_variables.empty?
152
+ return nil
153
+ end
154
+ soap_obj = nil
155
+ begin
156
+ soap_obj = soap_class.new(obj)
157
+ rescue XSD::ValueSpaceError
158
+ return nil
159
+ end
160
+ mark_marshalled_obj(obj, soap_obj)
161
+ soap_obj
162
+ end
163
+
164
+ def soap2obj(obj_class, node, info, map)
165
+ if node.respond_to?(:to_obj)
166
+ obj = node.to_obj(obj_class)
167
+ return false if obj.nil?
168
+ mark_unmarshalled_obj(node, obj)
169
+ return true, obj
170
+ else
171
+ return false
172
+ end
173
+ end
174
+ end
175
+
176
+ class Base64Factory_ < Factory
177
+ def obj2soap(soap_class, obj, info, map)
178
+ return nil unless obj.instance_variables.empty?
179
+ soap_obj = soap_class.new(obj)
180
+ mark_marshalled_obj(obj, soap_obj) if soap_obj
181
+ soap_obj
182
+ end
183
+
184
+ def soap2obj(obj_class, node, info, map)
185
+ obj = node.string
186
+ mark_unmarshalled_obj(node, obj)
187
+ return true, obj
188
+ end
189
+ end
190
+
191
+ class URIFactory_ < Factory
192
+ def obj2soap(soap_class, obj, info, map)
193
+ soap_obj = soap_class.new(obj)
194
+ mark_marshalled_obj(obj, soap_obj) if soap_obj
195
+ soap_obj
196
+ end
197
+
198
+ def soap2obj(obj_class, node, info, map)
199
+ obj = node.data
200
+ mark_unmarshalled_obj(node, obj)
201
+ return true, obj
202
+ end
203
+ end
204
+
205
+ class ArrayFactory_ < Factory
206
+ def initialize(allow_original_mapping = false)
207
+ super()
208
+ @allow_original_mapping = allow_original_mapping
209
+ end
210
+
211
+ # [[1], [2]] is converted to Array of Array, not 2-D Array.
212
+ # To create M-D Array, you must call Mapping.ary2md.
213
+ def obj2soap(soap_class, obj, info, map)
214
+ if !@allow_original_mapping and !obj.instance_variables.empty?
215
+ return nil
216
+ end
217
+ arytype = Mapping.obj2element(obj)
218
+ if arytype.name
219
+ arytype.namespace ||= RubyTypeNamespace
220
+ else
221
+ arytype = XSD::AnyTypeName
222
+ end
223
+ soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
224
+ mark_marshalled_obj(obj, soap_obj)
225
+ obj.each do |item|
226
+ soap_obj.add(Mapping._obj2soap(item, map))
227
+ end
228
+ soap_obj
229
+ end
230
+
231
+ def soap2obj(obj_class, node, info, map)
232
+ obj = Mapping.create_empty_object(obj_class)
233
+ mark_unmarshalled_obj(node, obj)
234
+ node.soap2array(obj) do |elem|
235
+ elem ? Mapping._soap2obj(elem, map) : nil
236
+ end
237
+ return true, obj
238
+ end
239
+ end
240
+
241
+ class TypedArrayFactory_ < Factory
242
+ def initialize(allow_original_mapping = false)
243
+ super()
244
+ @allow_original_mapping = allow_original_mapping
245
+ end
246
+
247
+ def obj2soap(soap_class, obj, info, map)
248
+ if !@allow_original_mapping and !obj.instance_variables.empty?
249
+ return nil
250
+ end
251
+ arytype = info[:type] || info[0]
252
+ soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
253
+ mark_marshalled_obj(obj, soap_obj)
254
+ obj.each do |var|
255
+ soap_obj.add(Mapping._obj2soap(var, map))
256
+ end
257
+ soap_obj
258
+ end
259
+
260
+ def soap2obj(obj_class, node, info, map)
261
+ if node.rank > 1
262
+ return false
263
+ end
264
+ arytype = info[:type] || info[0]
265
+ unless node.arytype == arytype
266
+ return false
267
+ end
268
+ obj = Mapping.create_empty_object(obj_class)
269
+ mark_unmarshalled_obj(node, obj)
270
+ node.soap2array(obj) do |elem|
271
+ elem ? Mapping._soap2obj(elem, map) : nil
272
+ end
273
+ return true, obj
274
+ end
275
+ end
276
+
277
+ class TypedStructFactory_ < Factory
278
+ def obj2soap(soap_class, obj, info, map)
279
+ type = info[:type] || info[0]
280
+ soap_obj = soap_class.new(type)
281
+ mark_marshalled_obj(obj, soap_obj)
282
+ if obj.class <= SOAP::Marshallable
283
+ setiv2soap(soap_obj, obj, map)
284
+ else
285
+ setiv2soap(soap_obj, obj, map)
286
+ end
287
+ soap_obj
288
+ end
289
+
290
+ def soap2obj(obj_class, node, info, map)
291
+ type = info[:type] || info[0]
292
+ unless node.type == type
293
+ return false
294
+ end
295
+ obj = Mapping.create_empty_object(obj_class)
296
+ mark_unmarshalled_obj(node, obj)
297
+ setiv2obj(obj, node, map)
298
+ return true, obj
299
+ end
300
+ end
301
+
302
+ MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')
303
+ class HashFactory_ < Factory
304
+ def initialize(allow_original_mapping = false)
305
+ super()
306
+ @allow_original_mapping = allow_original_mapping
307
+ end
308
+
309
+ def obj2soap(soap_class, obj, info, map)
310
+ if !@allow_original_mapping and !obj.instance_variables.empty?
311
+ return nil
312
+ end
313
+ if !obj.default.nil? or
314
+ (obj.respond_to?(:default_proc) and obj.default_proc)
315
+ return nil
316
+ end
317
+ soap_obj = SOAPStruct.new(MapQName)
318
+ mark_marshalled_obj(obj, soap_obj)
319
+ obj.each do |key, value|
320
+ elem = SOAPStruct.new
321
+ elem.add("key", Mapping._obj2soap(key, map))
322
+ elem.add("value", Mapping._obj2soap(value, map))
323
+ # ApacheAxis allows only 'item' here.
324
+ soap_obj.add("item", elem)
325
+ end
326
+ soap_obj
327
+ end
328
+
329
+ def soap2obj(obj_class, node, info, map)
330
+ unless node.type == MapQName
331
+ return false
332
+ end
333
+ if node.class == SOAPStruct and node.key?('default')
334
+ return false
335
+ end
336
+ obj = Mapping.create_empty_object(obj_class)
337
+ mark_unmarshalled_obj(node, obj)
338
+ if node.class == SOAPStruct
339
+ node.each do |key, value|
340
+ obj[Mapping._soap2obj(value['key'], map)] =
341
+ Mapping._soap2obj(value['value'], map)
342
+ end
343
+ else
344
+ node.each do |value|
345
+ obj[Mapping._soap2obj(value['key'], map)] =
346
+ Mapping._soap2obj(value['value'], map)
347
+ end
348
+ end
349
+ return true, obj
350
+ end
351
+ end
352
+
353
+
354
+ end
355
+ end
@@ -0,0 +1,381 @@
1
+ # SOAP4R - Ruby type mapping utility.
2
+ # Copyright (C) 2000, 2001, 2003-2005 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 'xsd/codegen/gensupport'
10
+
11
+
12
+ module SOAP
13
+
14
+
15
+ module Mapping
16
+ RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6'
17
+ RubyTypeInstanceNamespace =
18
+ 'http://www.ruby-lang.org/xmlns/ruby/type-instance'
19
+ RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom'
20
+ ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap'
21
+
22
+
23
+ # TraverseSupport breaks following thread variables.
24
+ # Thread.current[:SOAPMarshalDataKey]
25
+ module TraverseSupport
26
+ def mark_marshalled_obj(obj, soap_obj)
27
+ raise if obj.nil?
28
+ Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj
29
+ end
30
+
31
+ def mark_unmarshalled_obj(node, obj)
32
+ return if obj.nil?
33
+ # node.id is not Object#id but SOAPReference#id
34
+ Thread.current[:SOAPMarshalDataKey][node.id] = obj
35
+ end
36
+ end
37
+
38
+
39
+ EMPTY_OPT = {}
40
+ def self.obj2soap(obj, registry = nil, type = nil, opt = EMPTY_OPT)
41
+ registry ||= Mapping::DefaultRegistry
42
+ soap_obj = nil
43
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
44
+ Thread.current[:SOAPMarshalDataKey] = {}
45
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
46
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
47
+ soap_obj = _obj2soap(obj, registry, type)
48
+ end
49
+ soap_obj
50
+ end
51
+
52
+ def self.soap2obj(node, registry = nil, klass = nil, opt = EMPTY_OPT)
53
+ registry ||= Mapping::DefaultRegistry
54
+ obj = nil
55
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
56
+ Thread.current[:SOAPMarshalDataKey] = {}
57
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
58
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
59
+ obj = _soap2obj(node, registry, klass)
60
+ end
61
+ obj
62
+ end
63
+
64
+ def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
65
+ registry ||= Mapping::DefaultRegistry
66
+ type = XSD::QName.new(type_ns, typename)
67
+ soap_ary = SOAPArray.new(ValueArrayName, 1, type)
68
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
69
+ Thread.current[:SOAPMarshalDataKey] = {}
70
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
71
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
72
+ ary.each do |ele|
73
+ soap_ary.add(_obj2soap(ele, registry, type))
74
+ end
75
+ end
76
+ soap_ary
77
+ end
78
+
79
+ def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
80
+ registry ||= Mapping::DefaultRegistry
81
+ type = XSD::QName.new(type_ns, typename)
82
+ md_ary = SOAPArray.new(ValueArrayName, rank, type)
83
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
84
+ Thread.current[:SOAPMarshalDataKey] = {}
85
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
86
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
87
+ add_md_ary(md_ary, ary, [], registry)
88
+ end
89
+ md_ary
90
+ end
91
+
92
+ def self.fault2exception(fault, registry = nil)
93
+ registry ||= Mapping::DefaultRegistry
94
+ detail = if fault.detail
95
+ soap2obj(fault.detail, registry) || ""
96
+ else
97
+ ""
98
+ end
99
+ if detail.is_a?(Mapping::SOAPException)
100
+ begin
101
+ e = detail.to_e
102
+ remote_backtrace = e.backtrace
103
+ e.set_backtrace(nil)
104
+ raise e # ruby sets current caller as local backtrace of e => e2.
105
+ rescue Exception => e
106
+ e.set_backtrace(remote_backtrace + e.backtrace[1..-1])
107
+ raise
108
+ end
109
+ else
110
+ fault.detail = detail
111
+ fault.set_backtrace(
112
+ if detail.is_a?(Array)
113
+ detail
114
+ else
115
+ [detail.to_s]
116
+ end
117
+ )
118
+ raise
119
+ end
120
+ end
121
+
122
+ def self._obj2soap(obj, registry, type = nil)
123
+ if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] and
124
+ !Thread.current[:SOAPMarshalNoReference]
125
+ SOAPReference.new(referent)
126
+ elsif registry
127
+ registry.obj2soap(obj, type)
128
+ else
129
+ raise MappingError.new("no mapping registry given")
130
+ end
131
+ end
132
+
133
+ def self._soap2obj(node, registry, klass = nil)
134
+ if node.nil?
135
+ return nil
136
+ elsif node.is_a?(SOAPReference)
137
+ target = node.__getobj__
138
+ # target.id is not Object#id but SOAPReference#id
139
+ if referent = Thread.current[:SOAPMarshalDataKey][target.id] and
140
+ !Thread.current[:SOAPMarshalNoReference]
141
+ return referent
142
+ else
143
+ return _soap2obj(target, registry, klass)
144
+ end
145
+ end
146
+ return registry.soap2obj(node, klass)
147
+ end
148
+
149
+ if Object.respond_to?(:allocate)
150
+ # ruby/1.7 or later.
151
+ def self.create_empty_object(klass)
152
+ klass.allocate
153
+ end
154
+ else
155
+ MARSHAL_TAG = {
156
+ String => ['"', 1],
157
+ Regexp => ['/', 2],
158
+ Array => ['[', 1],
159
+ Hash => ['{', 1]
160
+ }
161
+ def self.create_empty_object(klass)
162
+ if klass <= Struct
163
+ name = klass.name
164
+ return ::Marshal.load(sprintf("\004\006S:%c%s\000", name.length + 5, name))
165
+ end
166
+ if MARSHAL_TAG.has_key?(klass)
167
+ tag, terminate = MARSHAL_TAG[klass]
168
+ return ::Marshal.load(sprintf("\004\006%s%s", tag, "\000" * terminate))
169
+ end
170
+ MARSHAL_TAG.each do |k, v|
171
+ if klass < k
172
+ name = klass.name
173
+ tag, terminate = v
174
+ return ::Marshal.load(sprintf("\004\006C:%c%s%s%s", name.length + 5, name, tag, "\000" * terminate))
175
+ end
176
+ end
177
+ name = klass.name
178
+ ::Marshal.load(sprintf("\004\006o:%c%s\000", name.length + 5, name))
179
+ end
180
+ end
181
+
182
+ # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here.
183
+ # Caution: '.' is not allowed here.
184
+ # To follow XML spec., it should be NCName.
185
+ # (denied chars) => .[0-F][0-F]
186
+ # ex. a.b => a.2eb
187
+ #
188
+ def self.name2elename(name)
189
+ name.gsub(/([^a-zA-Z0-9:_\-]+)/n) {
190
+ '.' << $1.unpack('H2' * $1.size).join('.')
191
+ }.gsub(/::/n, '..')
192
+ end
193
+
194
+ def self.elename2name(name)
195
+ name.gsub(/\.\./n, '::').gsub(/((?:\.[0-9a-fA-F]{2})+)/n) {
196
+ [$1.delete('.')].pack('H*')
197
+ }
198
+ end
199
+
200
+ def self.const_from_name(name, lenient = false)
201
+ const = ::Object
202
+ name.sub(/\A::/, '').split('::').each do |const_str|
203
+ if XSD::CodeGen::GenSupport.safeconstname?(const_str)
204
+ if const.const_defined?(const_str)
205
+ const = const.const_get(const_str)
206
+ next
207
+ end
208
+ elsif lenient
209
+ const_str = XSD::CodeGen::GenSupport.safeconstname(const_str)
210
+ if const.const_defined?(const_str)
211
+ const = const.const_get(const_str)
212
+ next
213
+ end
214
+ end
215
+ return nil
216
+ end
217
+ const
218
+ end
219
+
220
+ def self.class_from_name(name, lenient = false)
221
+ const = const_from_name(name, lenient)
222
+ if const.is_a?(::Class)
223
+ const
224
+ else
225
+ nil
226
+ end
227
+ end
228
+
229
+ def self.module_from_name(name, lenient = false)
230
+ const = const_from_name(name, lenient)
231
+ if const.is_a?(::Module)
232
+ const
233
+ else
234
+ nil
235
+ end
236
+ end
237
+
238
+ def self.class2qname(klass)
239
+ name = schema_type_definition(klass)
240
+ namespace = schema_ns_definition(klass)
241
+ XSD::QName.new(namespace, name)
242
+ end
243
+
244
+ def self.class2element(klass)
245
+ type = Mapping.class2qname(klass)
246
+ type.name ||= Mapping.name2elename(klass.name)
247
+ type.namespace ||= RubyCustomTypeNamespace
248
+ type
249
+ end
250
+
251
+ def self.obj2element(obj)
252
+ name = namespace = nil
253
+ ivars = obj.instance_variables
254
+ if ivars.include?('@schema_type')
255
+ name = obj.instance_variable_get('@schema_type')
256
+ end
257
+ if ivars.include?('@schema_ns')
258
+ namespace = obj.instance_variable_get('@schema_ns')
259
+ end
260
+ if !name or !namespace
261
+ class2qname(obj.class)
262
+ else
263
+ XSD::QName.new(namespace, name)
264
+ end
265
+ end
266
+
267
+ def self.define_singleton_method(obj, name, &block)
268
+ sclass = (class << obj; self; end)
269
+ sclass.class_eval {
270
+ define_method(name, &block)
271
+ }
272
+ end
273
+
274
+ def self.get_attribute(obj, attr_name)
275
+ if obj.is_a?(::Hash)
276
+ obj[attr_name] || obj[attr_name.intern]
277
+ else
278
+ name = XSD::CodeGen::GenSupport.safevarname(attr_name)
279
+ if obj.instance_variables.include?('@' + name)
280
+ obj.instance_variable_get('@' + name)
281
+ elsif ((obj.is_a?(::Struct) or obj.is_a?(Marshallable)) and
282
+ obj.respond_to?(name))
283
+ obj.__send__(name)
284
+ end
285
+ end
286
+ end
287
+
288
+ def self.set_attributes(obj, values)
289
+ if obj.is_a?(::SOAP::Mapping::Object)
290
+ values.each do |attr_name, value|
291
+ obj.__add_xmlele_value(attr_name, value)
292
+ end
293
+ else
294
+ values.each do |attr_name, value|
295
+ name = XSD::CodeGen::GenSupport.safevarname(attr_name)
296
+ setter = name + "="
297
+ if obj.respond_to?(setter)
298
+ obj.__send__(setter, value)
299
+ else
300
+ obj.instance_variable_set('@' + name, value)
301
+ begin
302
+ define_attr_accessor(obj, name,
303
+ proc { instance_variable_get('@' + name) },
304
+ proc { |value| instance_variable_set('@' + name, value) })
305
+ rescue TypeError
306
+ # singleton class may not exist (e.g. Float)
307
+ end
308
+ end
309
+ end
310
+ end
311
+ end
312
+
313
+ def self.define_attr_accessor(obj, name, getterproc, setterproc = nil)
314
+ define_singleton_method(obj, name, &getterproc)
315
+ define_singleton_method(obj, name + '=', &setterproc) if setterproc
316
+ end
317
+
318
+ def self.schema_type_definition(klass)
319
+ class_schema_variable(:schema_type, klass)
320
+ end
321
+
322
+ def self.schema_ns_definition(klass)
323
+ class_schema_variable(:schema_ns, klass)
324
+ end
325
+
326
+ def self.schema_element_definition(klass)
327
+ schema_element = class_schema_variable(:schema_element, klass) or return nil
328
+ schema_ns = schema_ns_definition(klass)
329
+ elements = []
330
+ as_array = []
331
+ schema_element.each do |varname, definition|
332
+ class_name, name = definition
333
+ if /\[\]$/ =~ class_name
334
+ class_name = class_name.sub(/\[\]$/, '')
335
+ as_array << (name ? name.name : varname)
336
+ end
337
+ elements << [name || XSD::QName.new(schema_ns, varname), class_name]
338
+ end
339
+ [elements, as_array]
340
+ end
341
+
342
+ def self.schema_attribute_definition(klass)
343
+ class_schema_variable(:schema_attribute, klass)
344
+ end
345
+
346
+ class << Mapping
347
+ private
348
+
349
+ def class_schema_variable(sym, klass)
350
+ var = "@@#{sym}"
351
+ klass.class_variables.include?(var) ? klass.class_eval(var) : nil
352
+ end
353
+
354
+ def protect_threadvars(*symbols)
355
+ backup = {}
356
+ begin
357
+ symbols.each do |sym|
358
+ backup[sym] = Thread.current[sym]
359
+ end
360
+ yield
361
+ ensure
362
+ symbols.each do |sym|
363
+ Thread.current[sym] = backup[sym]
364
+ end
365
+ end
366
+ end
367
+
368
+ def add_md_ary(md_ary, ary, indices, registry)
369
+ for idx in 0..(ary.size - 1)
370
+ if ary[idx].is_a?(Array)
371
+ add_md_ary(md_ary, ary[idx], indices + [idx], registry)
372
+ else
373
+ md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry)
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end
379
+
380
+
381
+ end