actionwebservice 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG +21 -0
  2. data/README +50 -6
  3. data/Rakefile +9 -9
  4. data/TODO +6 -6
  5. data/lib/action_web_service.rb +4 -3
  6. data/lib/action_web_service/api.rb +248 -1
  7. data/lib/action_web_service/casting.rb +111 -0
  8. data/lib/action_web_service/client/soap_client.rb +17 -33
  9. data/lib/action_web_service/client/xmlrpc_client.rb +10 -34
  10. data/lib/action_web_service/container/delegated_container.rb +1 -1
  11. data/lib/action_web_service/dispatcher/abstract.rb +52 -72
  12. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +71 -55
  13. data/lib/action_web_service/protocol/abstract.rb +82 -3
  14. data/lib/action_web_service/protocol/discovery.rb +2 -2
  15. data/lib/action_web_service/protocol/soap_protocol.rb +95 -22
  16. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +197 -0
  17. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +56 -24
  18. data/lib/action_web_service/scaffolding.rb +237 -0
  19. data/lib/action_web_service/struct.rb +17 -4
  20. data/lib/action_web_service/support/signature_types.rb +194 -0
  21. data/lib/action_web_service/templates/scaffolds/layout.rhtml +65 -0
  22. data/lib/action_web_service/templates/scaffolds/methods.rhtml +6 -0
  23. data/lib/action_web_service/templates/scaffolds/parameters.rhtml +28 -0
  24. data/lib/action_web_service/templates/scaffolds/result.rhtml +30 -0
  25. data/lib/action_web_service/test_invoke.rb +23 -42
  26. data/test/abstract_dispatcher.rb +102 -48
  27. data/test/abstract_unit.rb +1 -1
  28. data/test/api_test.rb +40 -7
  29. data/test/casting_test.rb +82 -0
  30. data/test/client_soap_test.rb +3 -0
  31. data/test/client_xmlrpc_test.rb +5 -1
  32. data/test/dispatcher_action_controller_soap_test.rb +9 -12
  33. data/test/dispatcher_action_controller_xmlrpc_test.rb +1 -11
  34. data/test/run +1 -0
  35. data/test/scaffolded_controller_test.rb +67 -0
  36. data/test/struct_test.rb +33 -21
  37. data/test/test_invoke_test.rb +1 -1
  38. metadata +18 -31
  39. data/lib/action_web_service/api/base.rb +0 -135
  40. data/lib/action_web_service/vendor/ws.rb +0 -4
  41. data/lib/action_web_service/vendor/ws/common.rb +0 -8
  42. data/lib/action_web_service/vendor/ws/encoding.rb +0 -3
  43. data/lib/action_web_service/vendor/ws/encoding/abstract.rb +0 -26
  44. data/lib/action_web_service/vendor/ws/encoding/soap_rpc_encoding.rb +0 -90
  45. data/lib/action_web_service/vendor/ws/encoding/xmlrpc_encoding.rb +0 -53
  46. data/lib/action_web_service/vendor/ws/marshaling.rb +0 -3
  47. data/lib/action_web_service/vendor/ws/marshaling/abstract.rb +0 -17
  48. data/lib/action_web_service/vendor/ws/marshaling/soap_marshaling.rb +0 -277
  49. data/lib/action_web_service/vendor/ws/marshaling/xmlrpc_marshaling.rb +0 -116
  50. data/lib/action_web_service/vendor/ws/types.rb +0 -165
  51. data/test/ws/abstract_encoding.rb +0 -68
  52. data/test/ws/abstract_unit.rb +0 -13
  53. data/test/ws/gencov +0 -3
  54. data/test/ws/run +0 -5
  55. data/test/ws/soap_marshaling_test.rb +0 -91
  56. data/test/ws/soap_rpc_encoding_test.rb +0 -47
  57. data/test/ws/types_test.rb +0 -43
  58. data/test/ws/xmlrpc_encoding_test.rb +0 -34
@@ -1,116 +0,0 @@
1
- module WS
2
- module Marshaling
3
- class XmlRpcError < WSError
4
- end
5
-
6
- class XmlRpcMarshaler < AbstractMarshaler
7
- def initialize
8
- @caster = BaseTypeCaster.new
9
- @spec2binding = {}
10
- end
11
-
12
- def marshal(param)
13
- transform_outbound(param)
14
- end
15
-
16
- def unmarshal(obj)
17
- obj.param.value = transform_inbound(obj.param)
18
- obj.param
19
- end
20
-
21
- def typed_unmarshal(obj, spec)
22
- param = obj.param
23
- param.info.data = register_type(spec)
24
- param.value = transform_inbound(param)
25
- param
26
- end
27
-
28
- def register_type(spec)
29
- if @spec2binding.has_key?(spec)
30
- return @spec2binding[spec]
31
- end
32
-
33
- klass = BaseTypes.canonical_param_type_class(spec)
34
- type_binding = nil
35
- if klass.is_a?(Array)
36
- type_binding = XmlRpcArrayBinding.new(klass[0])
37
- else
38
- type_binding = XmlRpcBinding.new(klass)
39
- end
40
-
41
- @spec2binding[spec] = type_binding
42
- end
43
-
44
- def transform_outbound(param)
45
- binding = param.info.data
46
- case binding
47
- when XmlRpcArrayBinding
48
- param.value.map{|x| cast_outbound(x, binding.element_klass)}
49
- when XmlRpcBinding
50
- cast_outbound(param.value, param.info.type)
51
- end
52
- end
53
-
54
- def transform_inbound(param)
55
- return param.value if param.info.data.nil?
56
- binding = param.info.data
57
- param.info.type = binding.klass
58
- case binding
59
- when XmlRpcArrayBinding
60
- param.value.map{|x| cast_inbound(x, binding.element_klass)}
61
- when XmlRpcBinding
62
- cast_inbound(param.value, param.info.type)
63
- end
64
- end
65
-
66
- def cast_outbound(value, klass)
67
- if BaseTypes.base_type?(klass)
68
- @caster.cast(value, klass)
69
- elsif value.is_a?(Exception)
70
- XMLRPC::FaultException.new(2, value.message)
71
- elsif Object.const_defined?('ActiveRecord') && value.is_a?(ActiveRecord::Base)
72
- value.attributes
73
- else
74
- struct = {}
75
- value.instance_variables.each do |name|
76
- key = name.sub(/^@/, '')
77
- struct[key] = value.instance_variable_get(name)
78
- end
79
- struct
80
- end
81
- end
82
-
83
- def cast_inbound(value, klass)
84
- if BaseTypes.base_type?(klass)
85
- value = value.to_time if value.is_a?(XMLRPC::DateTime)
86
- @caster.cast(value, klass)
87
- elsif value.is_a?(XMLRPC::FaultException)
88
- value
89
- else
90
- obj = klass.new
91
- value.each do |name, val|
92
- obj.send('%s=' % name.to_s, val)
93
- end
94
- obj
95
- end
96
- end
97
- end
98
-
99
- class XmlRpcBinding
100
- attr :klass
101
-
102
- def initialize(klass)
103
- @klass = klass
104
- end
105
- end
106
-
107
- class XmlRpcArrayBinding < XmlRpcBinding
108
- attr :element_klass
109
-
110
- def initialize(element_klass)
111
- super(Array)
112
- @element_klass = element_klass
113
- end
114
- end
115
- end
116
- end
@@ -1,165 +0,0 @@
1
- require 'time'
2
- require 'date'
3
-
4
- module WS
5
- module BaseTypes
6
- class << self
7
- def type_name_to_class(name)
8
- case canonical_type_name(name)
9
- when :int
10
- Integer
11
- when :string
12
- String
13
- when :bool
14
- TrueClass
15
- when :float
16
- Float
17
- when :time
18
- Time
19
- when :date
20
- Date
21
- end
22
- end
23
-
24
- def class_to_type_name(klass)
25
- if WS.derived_from?(Integer, klass) || WS.derived_from?(Fixnum, klass) || WS.derived_from?(Bignum, klass)
26
- :int
27
- elsif klass == String
28
- :string
29
- elsif klass == TrueClass || klass == FalseClass
30
- :bool
31
- elsif WS.derived_from?(Float, klass) || WS.derived_from?(Precision, klass) || WS.derived_from?(Numeric, klass)
32
- :float
33
- elsif klass == Time || klass == DateTime
34
- :time
35
- elsif klass == Date
36
- :date
37
- else
38
- raise(TypeError, "#{klass} is not a valid base type")
39
- end
40
- end
41
-
42
- def base_type?(klass)
43
- !(canonical_type_class(klass) rescue nil).nil?
44
- end
45
-
46
- def canonical_type_class(klass)
47
- type_name_to_class(class_to_type_name(klass))
48
- end
49
-
50
- def canonical_param_type_class(spec)
51
- klass = spec.is_a?(Hash) ? spec.values[0] : spec
52
- array_element_class = klass.is_a?(Array) ? klass[0] : nil
53
- klass = array_element_class ? array_element_class : klass
54
- klass = type_name_to_class(klass) if klass.is_a?(Symbol) || klass.is_a?(String)
55
- base_class = canonical_type_class(klass) rescue nil
56
- klass = base_class unless base_class.nil?
57
- array_element_class ? [klass] : klass
58
- end
59
-
60
- def canonical_param_type_spec(spec)
61
- klass = canonical_param_type_class(spec)
62
- spec.is_a?(Hash) ? {spec.keys[0]=>klass} : klass
63
- end
64
-
65
- def canonical_type_name(name)
66
- name = name.to_sym
67
- case name
68
- when :int, :integer, :fixnum, :bignum
69
- :int
70
- when :string, :base64
71
- :string
72
- when :bool, :boolean
73
- :bool
74
- when :float, :double
75
- :float
76
- when :time, :datetime, :timestamp
77
- :time
78
- when :date
79
- :date
80
- else
81
- raise(TypeError, "#{name} is not a valid base type")
82
- end
83
- end
84
- end
85
- end
86
-
87
- class Param
88
- attr_accessor :value
89
- attr_accessor :info
90
-
91
- def initialize(value, info)
92
- @value = value
93
- @info = info
94
- end
95
- end
96
-
97
- class ParamInfo
98
- attr_accessor :name
99
- attr_accessor :type
100
- attr_accessor :data
101
-
102
- def initialize(name, type, data=nil)
103
- @name = name
104
- @type = type
105
- @data = data
106
- end
107
-
108
- def self.create(spec, data, index=nil)
109
- name = spec.is_a?(Hash) ? spec.keys[0].to_s : (index ? "param#{index}" : nil)
110
- type = BaseTypes.canonical_param_type_class(spec)
111
- ParamInfo.new(name, type, data)
112
- end
113
- end
114
-
115
- class BaseTypeCaster
116
- def initialize
117
- @handlers = {}
118
- install_handlers
119
- end
120
-
121
- def cast(value, klass)
122
- type_class = BaseTypes.canonical_type_class(klass)
123
- return value unless type_class
124
- @handlers[type_class].call(value, type_class)
125
- end
126
-
127
- protected
128
- def install_handlers
129
- handler = method(:cast_base_type)
130
- [:int, :string, :bool, :float, :time, :date].each do |name|
131
- type = BaseTypes.type_name_to_class(name)
132
- @handlers[type] = handler
133
- end
134
- @handlers[Fixnum] = handler
135
- end
136
-
137
- def cast_base_type(value, type_class)
138
- desired_class = BaseTypes.canonical_type_class(type_class)
139
- value_class = BaseTypes.canonical_type_class(value.class)
140
- return value if desired_class == value_class
141
- desired_name = BaseTypes.class_to_type_name(desired_class)
142
- case desired_name
143
- when :int
144
- Integer(value)
145
- when :string
146
- value.to_s
147
- when :bool
148
- return false if value.nil?
149
- int_value = Integer(value) rescue nil
150
- return true if int_value == 1
151
- return false if int_value == 0
152
- value = value.to_s
153
- return true if value == 'true'
154
- return false if value == 'false'
155
- raise(TypeError, "can't convert #{value} to boolean")
156
- when :float
157
- Float(value)
158
- when :time
159
- Time.parse(value.to_s)
160
- when :date
161
- Date.parse(value.to_s)
162
- end
163
- end
164
- end
165
- end
@@ -1,68 +0,0 @@
1
- require File.dirname(__FILE__) + '/abstract_unit'
2
-
3
- module Nested
4
- class StructClass
5
- attr_accessor :name
6
- attr_accessor :version
7
-
8
- def initialize
9
- @name = 5
10
- @version = "1.0"
11
- end
12
-
13
- def ==(other)
14
- @name == other.name && @version == other.version
15
- end
16
- end
17
- end
18
-
19
- module EncodingTest
20
- def setup
21
- @call_signature = [:int, :bool, :string, :float, [:time], Nested::StructClass]
22
- @call_params = [1, true, "string", 5.0, [Time.now], Nested::StructClass.new]
23
- @response_signature = [:string]
24
- @response_param = "hello world"
25
- test_setup
26
- end
27
-
28
- def test_abstract
29
- obj = WS::Encoding::AbstractEncoding.new
30
- assert_raises(NotImplementedError) do
31
- obj.encode_rpc_call(nil, nil)
32
- end
33
- assert_raises(NotImplementedError) do
34
- obj.decode_rpc_call(nil)
35
- end
36
- assert_raises(NotImplementedError) do
37
- obj.encode_rpc_response(nil, nil)
38
- end
39
- assert_raises(NotImplementedError) do
40
- obj.decode_rpc_response(nil)
41
- end
42
- end
43
-
44
- def encode_rpc_call(method_name, signature, params)
45
- params = params.dup
46
- (0..(signature.length-1)).each do |i|
47
- type_binding = @marshaler.register_type(signature[i])
48
- info = WS::ParamInfo.create(signature[i], type_binding, i)
49
- params[i] = @marshaler.marshal(WS::Param.new(params[i], info))
50
- end
51
- @encoder.encode_rpc_call(method_name, params)
52
- end
53
-
54
- def decode_rpc_call(obj)
55
- @encoder.decode_rpc_call(obj)
56
- end
57
-
58
- def encode_rpc_response(method_name, signature, param)
59
- type_binding = @marshaler.register_type(signature[0])
60
- info = WS::ParamInfo.create(signature[0], type_binding, 0)
61
- param = @marshaler.marshal(WS::Param.new(param, info))
62
- @encoder.encode_rpc_response(method_name, param)
63
- end
64
-
65
- def decode_rpc_response(obj)
66
- @encoder.decode_rpc_response(obj)
67
- end
68
- end
@@ -1,13 +0,0 @@
1
- require 'pathname'
2
- $:.unshift(Pathname.new(File.dirname(__FILE__)).realpath.to_s + '/../../lib/action_web_service/vendor')
3
- require 'test/unit'
4
- require 'ws'
5
- begin
6
- require 'active_record'
7
- rescue LoadError
8
- begin
9
- require 'rubygems'
10
- require_gem 'activerecord', '>= 1.6.0'
11
- rescue LoadError
12
- end
13
- end
data/test/ws/gencov DELETED
@@ -1,3 +0,0 @@
1
- #!/bin/sh
2
-
3
- rcov -x '.*_test\.rb,rubygems,abstract_,/run' ./run
data/test/ws/run DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- Dir[File.join(File.dirname(__FILE__), '*_test.rb')].each do |f|
4
- require f
5
- end
@@ -1,91 +0,0 @@
1
- require File.dirname(__FILE__) + '/abstract_unit'
2
-
3
- module Nested
4
- class MyClass
5
- attr_accessor :id
6
- attr_accessor :name
7
-
8
- def initialize(id, name)
9
- @id = id
10
- @name = name
11
- end
12
-
13
- def ==(other)
14
- @id == other.id && @name == other.name
15
- end
16
- end
17
- end
18
-
19
- class SoapMarshalingTest < Test::Unit::TestCase
20
- def setup
21
- @marshaler = WS::Marshaling::SoapMarshaler.new
22
- end
23
-
24
- def test_abstract
25
- marshaler = WS::Marshaling::AbstractMarshaler.new
26
- assert_raises(NotImplementedError) do
27
- marshaler.marshal(nil)
28
- end
29
- assert_raises(NotImplementedError) do
30
- marshaler.unmarshal(nil)
31
- end
32
- assert_equal(nil, marshaler.register_type(nil))
33
- end
34
-
35
- def test_marshaling
36
- info = WS::ParamInfo.create(Nested::MyClass, @marshaler.register_type(Nested::MyClass))
37
- param = WS::Param.new(Nested::MyClass.new(2, "name"), info)
38
- new_param = @marshaler.unmarshal(@marshaler.marshal(param))
39
- assert(param == new_param)
40
- end
41
-
42
- def test_exception_marshaling
43
- info = WS::ParamInfo.create(RuntimeError, @marshaler.register_type(RuntimeError))
44
- param = WS::Param.new(RuntimeError.new("hello, world"), info)
45
- new_param = @marshaler.unmarshal(@marshaler.marshal(param))
46
- assert_equal("hello, world", new_param.value.detail.cause.message)
47
- end
48
-
49
- def test_registration
50
- type_binding1 = @marshaler.register_type(:int)
51
- type_binding2 = @marshaler.register_type(:int)
52
- assert(type_binding1.equal?(type_binding2))
53
- end
54
-
55
- def test_active_record
56
- if Object.const_defined?('ActiveRecord')
57
- node_class = Class.new(ActiveRecord::Base) do
58
- def initialize(*args)
59
- super(*args)
60
- @new_record = false
61
- end
62
-
63
- class << self
64
- def name
65
- "Node"
66
- end
67
-
68
- def columns(*args)
69
- [
70
- ActiveRecord::ConnectionAdapters::Column.new('id', 0, 'int'),
71
- ActiveRecord::ConnectionAdapters::Column.new('name', nil, 'string'),
72
- ActiveRecord::ConnectionAdapters::Column.new('email', nil, 'string'),
73
- ]
74
- end
75
-
76
- def connection
77
- self
78
- end
79
- end
80
- end
81
- info = WS::ParamInfo.create(node_class, @marshaler.register_type(node_class), 0)
82
- ar_obj = node_class.new('name' => 'hello', 'email' => 'test@test.com')
83
- param = WS::Param.new(ar_obj, info)
84
- obj = @marshaler.marshal(param)
85
- param = @marshaler.unmarshal(obj)
86
- new_ar_obj = param.value
87
- assert_equal(ar_obj, new_ar_obj)
88
- assert(!ar_obj.equal?(new_ar_obj))
89
- end
90
- end
91
- end