~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to lib/soap/mapping/factory.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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