PageRenderTime 208ms CodeModel.GetById 161ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/Ruby/lib/ruby/1.8/soap/mapping/factory.rb

http://github.com/agross/netopenspace
Ruby | 355 lines | 303 code | 39 blank | 13 comment | 30 complexity | c88391e35217d51026725eb45270f419 MD5 | raw file
  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
  9module SOAP
 10module Mapping
 11
 12
 13class 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
 62private
 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
 77end
 78
 79class 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
111end
112
113class 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
141end
142
143class 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
174end
175
176class 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
189end
190
191class 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
203end
204
205class 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
239end
240
241class 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
275end
276
277class 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
300end
301
302MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')
303class 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
351end
352
353
354end
355end