Changeset 1011
- Timestamp:
- 10/14/03 01:04:12 (5 years ago)
- Files:
-
- trunk/lib/soap/mapping/factory.rb (modified) (10 diffs)
- trunk/lib/soap/mapping/mapping.rb (modified) (1 diff)
- trunk/lib/soap/mapping/registry.rb (modified) (3 diffs)
- trunk/lib/soap/mapping/rubytypeFactory.rb (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lib/soap/mapping/factory.rb
r1004 r1011 24 24 class Factory 25 25 include TraverseSupport 26 27 def initialize 28 # nothing to do 29 end 26 30 27 31 def obj2soap(soap_class, obj, info, map) … … 49 53 end 50 54 51 def set_instance_vars(obj, values)52 values.each do |name, value|53 setter = name + "="54 if obj.respond_to?(setter)55 obj.__send__(setter, value)56 else57 obj.instance_eval("@#{ name } = value")58 end59 end60 end61 62 55 def setiv2obj(obj, node, map) 63 56 return if node.nil? … … 66 59 vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map) 67 60 end 68 set_instance_vars(obj, vars)61 Mapping.set_instance_vars(obj, vars) 69 62 end 70 63 … … 97 90 98 91 class StringFactory_ < Factory 99 def obj2soap(soap_class, obj, info, map) 100 return nil unless obj.instance_variables.empty? 92 def initialize(allow_original_mapping = false) 93 super() 94 @allow_original_mapping = allow_original_mapping 95 end 96 97 def obj2soap(soap_class, obj, info, map) 98 if !@allow_original_mapping and !obj.instance_variables.empty? 99 return nil 100 end 101 101 begin 102 if XSD::Charset.is_ces(obj, $KCODE) 103 encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) 104 soap_obj = soap_class.new(encoded) 105 else 106 return nil 102 unless XSD::Charset.is_ces(obj, $KCODE) 103 return nil 107 104 end 105 encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) 106 soap_obj = soap_class.new(encoded) 108 107 rescue XSD::ValueSpaceError 109 108 return nil … … 114 113 115 114 def soap2obj(obj_class, node, info, map) 116 obj = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE) 115 obj = create_empty_object(obj_class) 116 decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE) 117 obj.replace(decoded) 117 118 mark_unmarshalled_obj(node, obj) 118 119 return true, obj … … 121 122 122 123 class BasetypeFactory_ < Factory 123 def obj2soap(soap_class, obj, info, map) 124 return nil unless obj.instance_variables.empty? 124 def initialize(allow_original_mapping = false) 125 super() 126 @allow_original_mapping = allow_original_mapping 127 end 128 129 def obj2soap(soap_class, obj, info, map) 130 if !@allow_original_mapping and !obj.instance_variables.empty? 131 return nil 132 end 125 133 soap_obj = nil 126 134 begin … … 141 149 142 150 class DateTimeFactory_ < Factory 143 def obj2soap(soap_class, obj, info, map) 144 return nil if Time === obj and !obj.instance_variables.empty? 151 def initialize(allow_original_mapping = false) 152 super() 153 @allow_original_mapping = allow_original_mapping 154 end 155 156 def obj2soap(soap_class, obj, info, map) 157 if !@allow_original_mapping and 158 Time === obj and !obj.instance_variables.empty? 159 return nil 160 end 145 161 soap_obj = nil 146 162 begin … … 187 203 188 204 class ArrayFactory_ < Factory 205 def initialize(allow_original_mapping = false) 206 super() 207 @allow_original_mapping = allow_original_mapping 208 end 209 189 210 # [[1], [2]] is converted to Array of Array, not 2-D Array. 190 211 # To create M-D Array, you must call Mapping.ary2md. 191 212 def obj2soap(soap_class, obj, info, map) 192 return nil unless obj.instance_variables.empty? 213 if !@allow_original_mapping and !obj.instance_variables.empty? 214 return nil 215 end 193 216 arytype = Mapping.obj2element(obj) 194 217 if arytype.name … … 216 239 217 240 class TypedArrayFactory_ < Factory 218 def obj2soap(soap_class, obj, info, map) 219 return nil unless obj.instance_variables.empty? 241 def initialize(allow_original_mapping = false) 242 super() 243 @allow_original_mapping = allow_original_mapping 244 end 245 246 def obj2soap(soap_class, obj, info, map) 247 if !@allow_original_mapping and !obj.instance_variables.empty? 248 return nil 249 end 220 250 arytype = info[:type] || info[0] 221 251 param = SOAPArray.new(ValueArrayName, 1, arytype) … … 271 301 MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map') 272 302 class HashFactory_ < Factory 273 def obj2soap(soap_class, obj, info, map) 274 return nil unless obj.instance_variables.empty? 275 if obj.default or 276 (obj.respond_to?(:default_proc) and obj.default_proc) 303 def initialize(allow_original_mapping = false) 304 super() 305 @allow_original_mapping = allow_original_mapping 306 end 307 308 def obj2soap(soap_class, obj, info, map) 309 if !@allow_original_mapping and !obj.instance_variables.empty? 310 return nil 311 end 312 if !obj.default.nil? or 313 (obj.respond_to?(:default_proc) and obj.default_proc) 277 314 return nil 278 315 end trunk/lib/soap/mapping/mapping.rb
r832 r1011 130 130 end 131 131 132 def self.set_instance_vars(obj, values) 133 values.each do |name, value| 134 setter = name + "=" 135 if obj.respond_to?(setter) 136 obj.__send__(setter, value) 137 else 138 obj.instance_eval("@#{ name } = value") 139 end 140 end 141 end 132 142 133 143 # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here. trunk/lib/soap/mapping/registry.rb
r1004 r1011 41 41 RubyTypeName = XSD::QName.new(RubyTypeInstanceNamespace, 'rubyType') 42 42 RubyExtendName = XSD::QName.new(RubyTypeInstanceNamespace, 'extends') 43 RubyIVarName = XSD::QName.new(RubyTypeInstanceNamespace, 'ivars') 43 44 44 45 … … 341 342 obj = _soap2obj(klass, node) 342 343 if @allow_original_mapping 343 setextend2obj(obj, node.extraattr[RubyExtendName]) 344 addextend2obj(obj, node.extraattr[RubyExtendName]) 345 addiv2obj(obj, node.extraattr[RubyIVarName]) 344 346 end 345 347 obj … … 416 418 end 417 419 418 def setextend2obj(obj, attr) 420 def addiv2obj(obj, attr) 421 return unless attr 422 vars = {} 423 attr.__getobj__.each do |name, value| 424 vars[name] = Mapping._soap2obj(value, self) 425 end 426 Mapping.set_instance_vars(obj, vars) 427 end 428 429 def addextend2obj(obj, attr) 419 430 return unless attr 420 431 attr.split(/ /).reverse_each do |mstr| trunk/lib/soap/mapping/rubytypeFactory.rb
r1004 r1011 23 23 24 24 class RubytypeFactory < Factory 25 TYPE_STRING = 'String' 26 TYPE_TIME = 'Time' 27 TYPE_ARRAY = 'Array' 28 TYPE_REGEXP = 'Regexp' 29 TYPE_RANGE = 'Range' 30 TYPE_CLASS = 'Class' 31 TYPE_MODULE = 'Module' 32 TYPE_SYMBOL = 'Symbol' 33 TYPE_STRUCT = 'Struct' 34 TYPE_HASH = 'Map' 35 36 RubyIVarName = 'ivars' 37 25 TYPE_STRING = XSD::QName.new(RubyTypeNamespace, 'String') 26 TYPE_TIME = XSD::QName.new(RubyTypeNamespace, 'Time') 27 TYPE_ARRAY = XSD::QName.new(RubyTypeNamespace, 'Array') 28 TYPE_REGEXP = XSD::QName.new(RubyTypeNamespace, 'Regexp') 29 TYPE_RANGE = XSD::QName.new(RubyTypeNamespace, 'Range') 30 TYPE_CLASS = XSD::QName.new(RubyTypeNamespace, 'Class') 31 TYPE_MODULE = XSD::QName.new(RubyTypeNamespace, 'Module') 32 TYPE_SYMBOL = XSD::QName.new(RubyTypeNamespace, 'Symbol') 33 TYPE_STRUCT = XSD::QName.new(RubyTypeNamespace, 'Struct') 34 TYPE_HASH = XSD::QName.new(RubyTypeNamespace, 'Map') 35 38 36 def initialize(config = {}) 39 37 @config = config … … 42 40 @allow_original_mapping = @config.key?(:allow_original_mapping) ? 43 41 @config[:allow_original_mapping] : false 42 @string_factory = StringFactory_.new(true) 43 @basetype_factory = BasetypeFactory_.new(true) 44 @datetime_factory = DateTimeFactory_.new(true) 45 @array_factory = ArrayFactory_.new(true) 46 @hash_factory = HashFactory_.new(true) 44 47 end 45 48 … … 51 54 return nil 52 55 end 53 unless XSD::Charset.is_ces(obj, $KCODE) 54 return nil 55 end 56 encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) 57 param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_STRING)) 58 mark_marshalled_obj(obj, param) 59 param.add('string', SOAPString.new(encoded)) 56 param = @string_factory.obj2soap(SOAPString, obj, info, map) 60 57 if obj.class != String 61 58 param.extraattr[RubyTypeName] = obj.class.name 62 59 end 63 addiv2soap (param, obj, map)60 addiv2soapattr(param, obj, map) 64 61 when Time 65 62 unless @allow_original_mapping 66 63 return nil 67 64 end 68 param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_TIME)) 69 mark_marshalled_obj(obj, param) 70 param.add('time', SOAPDateTime.new(obj)) 65 param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map) 71 66 if obj.class != Time 72 67 param.extraattr[RubyTypeName] = obj.class.name 73 68 end 74 addiv2soap (param, obj, map)69 addiv2soapattr(param, obj, map) 75 70 when Array 76 71 unless @allow_original_mapping 77 72 return nil 78 73 end 79 arytype = Mapping.obj2element(obj) 80 if arytype.name 81 arytype.namespace ||= RubyTypeNamespace 82 else 83 arytype = XSD::AnyTypeName 84 end 85 if obj.instance_variables.empty? 86 param = SOAPArray.new(ValueArrayName, 1, arytype) 87 mark_marshalled_obj(obj, param) 88 obj.each do |var| 89 param.add(Mapping._obj2soap(var, map)) 90 end 91 else 92 param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_ARRAY)) 93 mark_marshalled_obj(obj, param) 94 ary = SOAPArray.new(ValueArrayName, 1, arytype) 95 obj.each do |var| 96 ary.add(Mapping._obj2soap(var, map)) 97 end 98 param.add('array', ary) 99 addiv2soap(param, obj, map) 100 end 74 param = @array_factory.obj2soap(nil, obj, info, map) 101 75 if obj.class != Array 102 76 param.extraattr[RubyTypeName] = obj.class.name 103 77 end 78 addiv2soapattr(param, obj, map) 79 when NilClass 80 unless @allow_original_mapping 81 return nil 82 end 83 param = @basetype_factory.obj2soap(SOAPNil, obj, info, map) 84 addiv2soapattr(param, obj, map) 85 when FalseClass, TrueClass 86 unless @allow_original_mapping 87 return nil 88 end 89 param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map) 90 addiv2soapattr(param, obj, map) 91 when Integer 92 unless @allow_original_mapping 93 return nil 94 end 95 param = @basetype_factory.obj2soap(SOAPInt, obj, info, map) 96 param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map) 97 param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map) 98 addiv2soapattr(param, obj, map) 99 when Float 100 unless @allow_original_mapping 101 return nil 102 end 103 param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map) 104 if obj.class != Float 105 param.extraattr[RubyTypeName] = obj.class.name 106 end 107 addiv2soapattr(param, obj, map) 108 when Hash 109 unless @allow_original_mapping 110 return nil 111 end 112 if obj.respond_to?(:default_proc) && obj.default_proc 113 raise TypeError.new("cannot dump hash with default proc") 114 end 115 param = SOAPStruct.new(TYPE_HASH) 116 mark_marshalled_obj(obj, param) 117 if obj.class != Hash 118 param.extraattr[RubyTypeName] = obj.class.name 119 end 120 obj.each do |key, value| 121 elem = SOAPStruct.new # Undefined type. 122 elem.add("key", Mapping._obj2soap(key, map)) 123 elem.add("value", Mapping._obj2soap(value, map)) 124 param.add("item", elem) 125 end 126 param.add('default', Mapping._obj2soap(obj.default, map)) 127 addiv2soapattr(param, obj, map) 104 128 when Regexp 105 129 unless @allow_original_mapping 106 130 return nil 107 131 end 108 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_REGEXP))132 param = SOAPStruct.new(TYPE_REGEXP) 109 133 mark_marshalled_obj(obj, param) 110 134 if obj.class != Regexp … … 137 161 end 138 162 param.add('options', SOAPInt.new(options)) 139 addiv2soap (param, obj, map)163 addiv2soapattr(param, obj, map) 140 164 when Range 141 165 unless @allow_original_mapping 142 166 return nil 143 167 end 144 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_RANGE))168 param = SOAPStruct.new(TYPE_RANGE) 145 169 mark_marshalled_obj(obj, param) 146 170 if obj.class != Range … … 150 174 param.add('end', Mapping._obj2soap(obj.end, map)) 151 175 param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?)) 152 addiv2soap(param, obj, map) 153 when Hash 154 unless @allow_original_mapping 155 return nil 156 end 157 if obj.respond_to?(:default_proc) && obj.default_proc 158 raise TypeError.new("cannot dump hash with default proc") 159 end 160 param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, TYPE_HASH)) 161 mark_marshalled_obj(obj, param) 162 if obj.class != Hash 163 param.extraattr[RubyTypeName] = obj.class.name 164 end 165 obj.each do |key, value| 166 elem = SOAPStruct.new # Undefined type. 167 elem.add("key", Mapping._obj2soap(key, map)) 168 elem.add("value", Mapping._obj2soap(value, map)) 169 param.add("item", elem) 170 end 171 param.add('default', Mapping._obj2soap(obj.default, map)) 172 addiv2soap(param, obj, map) 176 addiv2soapattr(param, obj, map) 173 177 when Class 174 178 unless @allow_original_mapping … … 178 182 raise TypeError.new("Can't dump anonymous class #{ obj }.") 179 183 end 180 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_CLASS))184 param = SOAPStruct.new(TYPE_CLASS) 181 185 mark_marshalled_obj(obj, param) 182 186 param.add('name', SOAPString.new(obj.name)) 183 addiv2soap (param, obj, map)187 addiv2soapattr(param, obj, map) 184 188 when Module 185 189 unless @allow_original_mapping … … 189 193 raise TypeError.new("Can't dump anonymous module #{ obj }.") 190 194 end 191 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_MODULE))195 param = SOAPStruct.new(TYPE_MODULE) 192 196 mark_marshalled_obj(obj, param) 193 197 param.add('name', SOAPString.new(obj.name)) 194 addiv2soap (param, obj, map)198 addiv2soapattr(param, obj, map) 195 199 when Symbol 196 200 unless @allow_original_mapping 197 201 return nil 198 202 end 199 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_SYMBOL))203 param = SOAPStruct.new(TYPE_SYMBOL) 200 204 mark_marshalled_obj(obj, param) 201 205 param.add('id', SOAPString.new(obj.id2name)) 202 addiv2soap (param, obj, map)206 addiv2soapattr(param, obj, map) 203 207 when Struct 204 208 unless @allow_original_mapping 205 209 return nil 206 210 end 207 param = SOAPStruct.new( XSD::QName.new(RubyTypeNamespace, TYPE_STRUCT))211 param = SOAPStruct.new(TYPE_STRUCT) 208 212 mark_marshalled_obj(obj, param) 209 213 param.add('type', ele_type = SOAPString.new(obj.class.to_s)) … … 214 218 end 215 219 param.add('member', ele_member) 216 addiv2soap (param, obj, map)220 addiv2soapattr(param, obj, map) 217 221 when IO, Binding, Continuation, Data, Dir, File::Stat, MatchData, Method, 218 222 Proc, Thread, ThreadGroup 219 223 # from 1.8: Process::Status, UnboundMethod 220 # rest: FalseClass, Float, Bignum, Fixnum, TrueClass, NilClass221 224 return nil 222 225 when ::SOAP::Mapping::Object 223 226 param = SOAPStruct.new(XSD::AnyTypeName) 224 227 mark_marshalled_obj(obj, param) 225 addiv2soap (param, obj, map)228 addiv2soapattr(param, obj, map) 226 229 when Exception 227 230 typestr = Mapping.name2elename(obj.class.to_s) … … 230 233 param.add('message', Mapping._obj2soap(obj.message, map)) 231 234 param.add('backtrace', Mapping._obj2soap(obj.backtrace, map)) 232 addiv2soap (param, obj, map)235 addiv2soapattr(param, obj, map) 233 236 else 234 237 if obj.class.name.empty? … … 266 269 rubytype = node.extraattr[RubyTypeName] 267 270 if rubytype or node.type.namespace == RubyTypeNamespace 268 rubytype2obj(node, map, rubytype)271 rubytype2obj(node, info, map, rubytype) 269 272 elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName 270 anytype2obj(node, map)271 else 272 unknowntype2obj(node, map)273 anytype2obj(node, info, map) 274 else 275 unknowntype2obj(node, info, map) 273 276 end 274 277 end … … 276 279 private 277 280 278 def addiv2soap (node, obj, map)281 def addiv2soapattr(node, obj, map) 279 282 return if obj.instance_variables.empty? 280 283 ivars = SOAPStruct.new # Undefined type. 281 284 setiv2soap(ivars, obj, map) 282 node.add(RubyIVarName, ivars) 283 end 284 285 def rubytype2obj(node, map, rubytype) 285 node.extraattr[RubyIVarName] = ivars 286 end 287 288 def rubytype2obj(node, info, map, rubytype) 289 klass = rubytype ? Mapping.class_from_name(rubytype) : nil 286 290 obj = nil 287 case node .class291 case node 288 292 when SOAPString 289 obj = string2obj(node, map, rubytype) 290 obj.replace(node.data) 293 return @string_factory.soap2obj(klass || String, node, info, map) 294 when SOAPDateTime 295 #return @datetime_factory.soap2obj(klass || Time, node, info, map) 296 klass ||= Time 297 t = node.to_time 298 arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec] 299 obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg) 300 mark_unmarshalled_obj(node, obj) 291 301 return true, obj 292 302 when SOAPArray 293 obj = array2obj(node, map, rubytype) 294 node.soap2array(obj) do |elem| 295 elem ? Mapping._soap2obj(elem, map) : nil 296 end 297 return true, obj 298 end 299 300 case node.type.name 301 when TYPE_STRING 302 obj = string2obj(node, map, rubytype) 303 obj.replace(node['string'].data) 304 when TYPE_TIME 305 klass = rubytype ? Mapping.class_from_name(rubytype) : Time 306 t = node['time'].to_time 307 arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec] 308 obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg) 309 mark_unmarshalled_obj(node, obj) 310 when TYPE_ARRAY 311 obj = array2obj(node, map, rubytype) 312 node['array'].soap2array(obj) do |elem| 313 elem ? Mapping._soap2obj(elem, map) : nil 303 return @array_factory.soap2obj(klass || Array, node, info, map) 304 when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble 305 return @basetype_factory.soap2obj(nil, node, info, map) 306 when SOAPStruct 307 return rubytypestruct2obj(node, info, map, rubytype) 308 else 309 raise 310 end 311 end 312 313 def rubytypestruct2obj(node, info, map, rubytype) 314 klass = rubytype ? Mapping.class_from_name(rubytype) : nil 315 obj = nil 316 case node.type 317 when TYPE_HASH 318 klass = rubytype ? Mapping.class_from_name(rubytype) : Hash 319 obj = create_empty_object(klass) 320 mark_unmarshalled_obj(node, obj) 321 node.each do |key, value| 322 next unless key == 'item' 323 obj[Mapping._soap2obj(value['key'], map)] = 324 Mapping._soap2obj(value['value'], map) 325 end 326 if node.key?('default') 327 obj.default = Mapping._soap2obj(node['default'], map) 314 328 end 315 329 when TYPE_REGEXP … … 328 342 exclude_end = node['exclude_end'].data 329 343 Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end) 330 when TYPE_HASH331 klass = rubytype ? Mapping.class_from_name(rubytype) : Hash332 obj = create_empty_object(klass)333 mark_unmarshalled_obj(node, obj)334 node.each do |key, value|335 next unless key == 'item'336 obj[Mapping._soap2obj(value['key'], map)] =337 Mapping._soap2obj(value['value'], map)338 end339 if node.key?('default')340 obj.default = Mapping._soap2obj(node['default'], map)341 end342 344 when TYPE_CLASS 343 345 obj = Mapping.class_from_name(node['name'].data) … … 376 378 end 377 379 end 378 setiv2obj(obj, node[RubyIVarName], map)379 380 return true, obj 380 381 end 381 382 382 def anytype2obj(node, map)383 def anytype2obj(node, info, map) 383 384 case node 384 385 when SOAPBasetype … … 397 398 end 398 399 399 def unknowntype2obj(node, map)400 def unknowntype2obj(node, info, map) 400 401 if node.is_a?(SOAPStruct) 401 obj = unknownstruct2obj(node, map)402 obj = unknownstruct2obj(node, info, map) 402 403 return true, obj if obj 403 404 if !@allow_untyped_struct 404 405 return false 405 406 end 406 return anytype2obj(node, map)407 return anytype2obj(node, info, map) 407 408 else 408 409 # Basetype which is not defined... … … 411 412 end 412 413 413 def unknownstruct2obj(node, map) 414 obj = nil 414 def unknownstruct2obj(node, info, map) 415 unless node.type.name 416 return nil 417 end 415 418 typestr = Mapping.elename2name(node.type.name) 416 419 klass = Mapping.class_from_name(typestr)