zinfinit-actionwebservice 2.3.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/CHANGELOG +323 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +381 -0
  4. data/Rakefile +173 -0
  5. data/examples/googlesearch/README +143 -0
  6. data/examples/googlesearch/autoloading/google_search_api.rb +50 -0
  7. data/examples/googlesearch/autoloading/google_search_controller.rb +57 -0
  8. data/examples/googlesearch/delegated/google_search_service.rb +108 -0
  9. data/examples/googlesearch/delegated/search_controller.rb +7 -0
  10. data/examples/googlesearch/direct/google_search_api.rb +50 -0
  11. data/examples/googlesearch/direct/search_controller.rb +58 -0
  12. data/examples/metaWeblog/README +17 -0
  13. data/examples/metaWeblog/apis/blogger_api.rb +60 -0
  14. data/examples/metaWeblog/apis/blogger_service.rb +34 -0
  15. data/examples/metaWeblog/apis/meta_weblog_api.rb +67 -0
  16. data/examples/metaWeblog/apis/meta_weblog_service.rb +48 -0
  17. data/examples/metaWeblog/controllers/xmlrpc_controller.rb +16 -0
  18. data/generators/web_service/USAGE +28 -0
  19. data/generators/web_service/templates/api_definition.rb +5 -0
  20. data/generators/web_service/templates/controller.rb +8 -0
  21. data/generators/web_service/templates/functional_test.rb +19 -0
  22. data/generators/web_service/web_service_generator.rb +29 -0
  23. data/lib/action_web_service.rb +68 -0
  24. data/lib/action_web_service/api.rb +297 -0
  25. data/lib/action_web_service/base.rb +38 -0
  26. data/lib/action_web_service/casting.rb +149 -0
  27. data/lib/action_web_service/client.rb +3 -0
  28. data/lib/action_web_service/client/base.rb +28 -0
  29. data/lib/action_web_service/client/soap_client.rb +113 -0
  30. data/lib/action_web_service/client/xmlrpc_client.rb +58 -0
  31. data/lib/action_web_service/container.rb +3 -0
  32. data/lib/action_web_service/container/action_controller_container.rb +93 -0
  33. data/lib/action_web_service/container/delegated_container.rb +86 -0
  34. data/lib/action_web_service/container/direct_container.rb +69 -0
  35. data/lib/action_web_service/dispatcher.rb +2 -0
  36. data/lib/action_web_service/dispatcher/abstract.rb +207 -0
  37. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +397 -0
  38. data/lib/action_web_service/invocation.rb +202 -0
  39. data/lib/action_web_service/protocol.rb +4 -0
  40. data/lib/action_web_service/protocol/abstract.rb +112 -0
  41. data/lib/action_web_service/protocol/discovery.rb +37 -0
  42. data/lib/action_web_service/protocol/soap_protocol.rb +176 -0
  43. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +242 -0
  44. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +122 -0
  45. data/lib/action_web_service/scaffolding.rb +281 -0
  46. data/lib/action_web_service/simple.rb +53 -0
  47. data/lib/action_web_service/string_to_datetime_for_soap.rb +10 -0
  48. data/lib/action_web_service/struct.rb +68 -0
  49. data/lib/action_web_service/support/class_inheritable_options.rb +26 -0
  50. data/lib/action_web_service/support/signature_types.rb +256 -0
  51. data/lib/action_web_service/templates/scaffolds/layout.html.erb +65 -0
  52. data/lib/action_web_service/templates/scaffolds/methods.html.erb +6 -0
  53. data/lib/action_web_service/templates/scaffolds/parameters.html.erb +29 -0
  54. data/lib/action_web_service/templates/scaffolds/result.html.erb +30 -0
  55. data/lib/action_web_service/test_invoke.rb +110 -0
  56. data/lib/action_web_service/version.rb +9 -0
  57. data/lib/actionwebservice.rb +1 -0
  58. data/setup.rb +1379 -0
  59. data/test/abstract_client.rb +183 -0
  60. data/test/abstract_dispatcher.rb +548 -0
  61. data/test/abstract_unit.rb +39 -0
  62. data/test/api_test.rb +102 -0
  63. data/test/apis/auto_load_api.rb +3 -0
  64. data/test/apis/broken_auto_load_api.rb +2 -0
  65. data/test/base_test.rb +42 -0
  66. data/test/casting_test.rb +94 -0
  67. data/test/client_soap_test.rb +155 -0
  68. data/test/client_xmlrpc_test.rb +153 -0
  69. data/test/container_test.rb +73 -0
  70. data/test/dispatcher_action_controller_soap_test.rb +138 -0
  71. data/test/dispatcher_action_controller_xmlrpc_test.rb +59 -0
  72. data/test/fixtures/db_definitions/mysql.sql +8 -0
  73. data/test/fixtures/users.yml +12 -0
  74. data/test/gencov +3 -0
  75. data/test/invocation_test.rb +185 -0
  76. data/test/run +6 -0
  77. data/test/scaffolded_controller_test.rb +146 -0
  78. data/test/struct_test.rb +52 -0
  79. data/test/test_invoke_test.rb +112 -0
  80. metadata +173 -0
@@ -0,0 +1,53 @@
1
+ module ActionWebService
2
+ # To send simple types across the wire, derive from ActionWebService::Simple,
3
+ # and use +base+ to declare the base type for it restriction and,
4
+ # use +restriction+ to declare valid W3C restriction element for SimpleType.
5
+ #
6
+ # ActionWebService::Simple should be used when you want to declare valid custom simple type
7
+ # to be used inside expects, returns and structured types
8
+ #
9
+ #
10
+ # There plenty documentation available at W3C Archives
11
+ # http://www.w3.org/TR/xmlschema-2/
12
+ #
13
+ # === Example
14
+ #
15
+ # class Gender < ActionWebService::Simple
16
+ # base :string
17
+ # restriction :enumeration, "male|female"
18
+ # end
19
+ #
20
+ #
21
+ class Simple
22
+
23
+ def initialize(value)
24
+ @value = value
25
+ end
26
+
27
+ class << self
28
+ def base(type)
29
+ type = type.to_s.camelize(:lower)
30
+ write_inheritable_attribute("xml_base", type)
31
+ class_eval <<-END
32
+ def xml_base; "#{type}"; end
33
+ END
34
+ end
35
+
36
+ def restriction_base
37
+ read_inheritable_attribute("xml_base") || ""
38
+ end
39
+
40
+ def restriction(type, value)
41
+ type = type.to_s.camelize(:lower)
42
+ write_inheritable_hash("simple_restrictions", type => value)
43
+ end
44
+
45
+ def restrictions
46
+ read_inheritable_attribute("simple_restrictions") || {}
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,10 @@
1
+ module StringToDatetimeForSoap
2
+ def to_datetime
3
+ if /^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ self.strip
4
+ return Time.xmlschema(self).localtime
5
+ end
6
+ super
7
+ end
8
+ end
9
+
10
+ String.send :include, StringToDatetimeForSoap
@@ -0,0 +1,68 @@
1
+ module ActionWebService
2
+ # To send structured types across the wire, derive from ActionWebService::Struct,
3
+ # and use +member+ to declare structure members.
4
+ #
5
+ # ActionWebService::Struct should be used in method signatures when you want to accept or return
6
+ # structured types that have no Active Record model class representations, or you don't
7
+ # want to expose your entire Active Record model to remote callers.
8
+ #
9
+ # === Example
10
+ #
11
+ # class Person < ActionWebService::Struct
12
+ # member :id, :int
13
+ # member :firstnames, [:string]
14
+ # member :lastname, :string
15
+ # member :email, :string
16
+ # end
17
+ # person = Person.new(:id => 5, :firstname => 'john', :lastname => 'doe')
18
+ #
19
+ # Active Record model classes are already implicitly supported in method
20
+ # signatures.
21
+ class Struct
22
+ # If a Hash is given as argument to an ActionWebService::Struct constructor,
23
+ # it can contain initial values for the structure member.
24
+ def initialize(values={})
25
+ if values.is_a?(Hash)
26
+ values.map do |k,v|
27
+ __send__('%s=' % k.to_s, v)
28
+ end
29
+ end
30
+ end
31
+
32
+ # The member with the given name
33
+ def [](name)
34
+ send(name.to_s)
35
+ end
36
+
37
+ # Iterates through each member
38
+ def each_pair(&block)
39
+ self.class.members.each do |name, type|
40
+ yield name, self.__send__(name)
41
+ end
42
+ end
43
+
44
+ class << self
45
+ # Creates a structure member with the specified +name+ and +type+. Generates
46
+ # accessor methods for reading and writing the member value.
47
+ def member(name, type)
48
+ name = name.to_sym
49
+ type = ActionWebService::SignatureTypes.canonical_signature_entry({ name => type }, 0)
50
+ write_inheritable_hash("struct_members", name => type)
51
+ class_eval <<-END
52
+ def #{name}; @#{name}; end
53
+ def #{name}=(value)
54
+ @#{name} = value;
55
+ end
56
+ END
57
+ end
58
+
59
+ def members # :nodoc:
60
+ read_inheritable_attribute("struct_members") || {}
61
+ end
62
+
63
+ def member_type(name) # :nodoc:
64
+ members[name.to_sym]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,26 @@
1
+ class Class # :nodoc:
2
+ def class_inheritable_option(sym, default_value=nil)
3
+ write_inheritable_attribute sym, default_value
4
+ class_eval <<-EOS
5
+ def self.#{sym}(value=nil)
6
+ if !value.nil?
7
+ write_inheritable_attribute(:#{sym}, value)
8
+ else
9
+ read_inheritable_attribute(:#{sym})
10
+ end
11
+ end
12
+
13
+ def self.#{sym}=(value)
14
+ write_inheritable_attribute(:#{sym}, value)
15
+ end
16
+
17
+ def #{sym}
18
+ self.class.#{sym}
19
+ end
20
+
21
+ def #{sym}=(value)
22
+ self.class.#{sym} = value
23
+ end
24
+ EOS
25
+ end
26
+ end
@@ -0,0 +1,256 @@
1
+ module ActionWebService # :nodoc:
2
+ # Action Web Service supports the following base types in a signature:
3
+ #
4
+ # [<tt>:int</tt>] Represents an integer value, will be cast to an integer using <tt>Integer(value)</tt>
5
+ # [<tt>:string</tt>] Represents a string value, will be cast to an string using the <tt>to_s</tt> method on an object
6
+ # [<tt>:base64</tt>] Represents a Base 64 value, will contain the binary bytes of a Base 64 value sent by the caller
7
+ # [<tt>:bool</tt>] Represents a boolean value, whatever is passed will be cast to boolean (<tt>true</tt>, '1', 'true', 'y', 'yes' are taken to represent true; <tt>false</tt>, '0', 'false', 'n', 'no' and <tt>nil</tt> represent false)
8
+ # [<tt>:float</tt>] Represents a floating point value, will be cast to a float using <tt>Float(value)</tt>
9
+ # [<tt>:time</tt>] Represents a timestamp, will be cast to a <tt>Time</tt> object
10
+ # [<tt>:datetime</tt>] Represents a timestamp, will be cast to a <tt>DateTime</tt> object
11
+ # [<tt>:date</tt>] Represents a date, will be cast to a <tt>Date</tt> object
12
+ #
13
+ # For structured types, you'll need to pass in the Class objects of
14
+ # ActionWebService::Struct and ActiveRecord::Base derivatives.
15
+ module SignatureTypes
16
+ def canonical_signature(signature) # :nodoc:
17
+ return nil if signature.nil?
18
+ unless signature.is_a?(Array)
19
+ raise(ActionWebServiceError, "Expected signature to be an Array")
20
+ end
21
+ i = -1
22
+ signature.map{ |spec| canonical_signature_entry(spec, i += 1) }
23
+ end
24
+
25
+ def canonical_signature_entry(spec, i) # :nodoc:
26
+ orig_spec = spec
27
+ name = "param#{i}"
28
+ if spec.is_a?(Hash)
29
+ name, spec = spec.keys.first, spec.values.first
30
+ end
31
+ type = spec
32
+ if spec.is_a?(Array)
33
+ ArrayType.new(orig_spec, canonical_signature_entry(spec[0], 0), name)
34
+ else
35
+ type = canonical_type(type)
36
+ if type.is_a?(Symbol)
37
+ BaseType.new(orig_spec, type, name)
38
+ else
39
+ if type.is_a?(Hash)
40
+ complexity, type = type.keys.first.to_sym, type.values.first
41
+ end
42
+ element = complexity || :complex
43
+ element == :simple ? SimpleType.new(orig_spec, type, name) : StructuredType.new(orig_spec, type, name)
44
+ end
45
+ end
46
+ end
47
+
48
+ def canonical_type(type) # :nodoc:
49
+ type_name = symbol_name(type) || class_to_type_name(type)
50
+ type = type_name || type
51
+ return canonical_type_name(type) if type.is_a?(Symbol)
52
+ type
53
+ end
54
+
55
+ def canonical_type_name(name) # :nodoc:
56
+ name = name.to_sym
57
+ case name
58
+ when :int, :integer, :fixnum, :bignum
59
+ :int
60
+ when :string, :text
61
+ :string
62
+ when :base64, :binary
63
+ :base64
64
+ when :bool, :boolean
65
+ :bool
66
+ when :float, :double
67
+ :float
68
+ when :decimal
69
+ :decimal
70
+ when :time, :timestamp
71
+ :time
72
+ when :datetime
73
+ :datetime
74
+ when :date
75
+ :date
76
+ else
77
+ raise(TypeError, "#{name} is not a valid base type")
78
+ end
79
+ end
80
+
81
+ def canonical_type_class(type) # :nodoc:
82
+ type = canonical_type(type)
83
+ type.is_a?(Symbol) ? type_name_to_class(type) : type
84
+ end
85
+
86
+ def symbol_name(name) # :nodoc:
87
+ return name.to_sym if name.is_a?(Symbol) || name.is_a?(String)
88
+ nil
89
+ end
90
+
91
+ def class_to_type_name(klass) # :nodoc:
92
+ klass = klass.class unless klass.is_a?(Class)
93
+ if derived_from?(Integer, klass) || derived_from?(Fixnum, klass) || derived_from?(Bignum, klass)
94
+ :int
95
+ elsif klass == String
96
+ :string
97
+ elsif klass == Base64
98
+ :base64
99
+ elsif klass == TrueClass || klass == FalseClass
100
+ :bool
101
+ elsif derived_from?(Float, klass) || derived_from?(Precision, klass) || derived_from?(Numeric, klass)
102
+ :float
103
+ elsif klass == Time
104
+ :time
105
+ elsif klass == DateTime
106
+ :datetime
107
+ elsif klass == Date
108
+ :date
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
114
+ def type_name_to_class(name) # :nodoc:
115
+ case canonical_type_name(name)
116
+ when :int
117
+ Integer
118
+ when :string
119
+ String
120
+ when :base64
121
+ Base64
122
+ when :bool
123
+ TrueClass
124
+ when :float
125
+ Float
126
+ when :decimal
127
+ BigDecimal
128
+ when :time
129
+ Time
130
+ when :date
131
+ Date
132
+ when :datetime
133
+ DateTime
134
+ else
135
+ nil
136
+ end
137
+ end
138
+
139
+ def derived_from?(ancestor, child) # :nodoc:
140
+ child.ancestors.include?(ancestor)
141
+ end
142
+
143
+ module_function :type_name_to_class
144
+ module_function :class_to_type_name
145
+ module_function :symbol_name
146
+ module_function :canonical_type_class
147
+ module_function :canonical_type_name
148
+ module_function :canonical_type
149
+ module_function :canonical_signature_entry
150
+ module_function :canonical_signature
151
+ module_function :derived_from?
152
+ end
153
+
154
+ class BaseType # :nodoc:
155
+ include SignatureTypes
156
+
157
+ attr :spec
158
+ attr :type
159
+ attr :type_class
160
+ attr :name
161
+
162
+ def initialize(spec, type, name)
163
+ @spec = spec
164
+ @type = canonical_type(type)
165
+ @type_class = canonical_type_class(@type)
166
+ @name = name
167
+ end
168
+
169
+ def custom?
170
+ false
171
+ end
172
+
173
+ def array?
174
+ false
175
+ end
176
+
177
+ def structured?
178
+ false
179
+ end
180
+
181
+ def simple?
182
+ false
183
+ end
184
+
185
+ def human_name(show_name=true)
186
+ type_type = array? ? element_type.type.to_s : self.type.to_s
187
+ str = array? ? (type_type + '[]') : type_type
188
+ show_name ? (str + " " + name.to_s) : str
189
+ end
190
+ end
191
+
192
+ class ArrayType < BaseType # :nodoc:
193
+ attr :element_type
194
+
195
+ def initialize(spec, element_type, name)
196
+ super(spec, Array, name)
197
+ @element_type = element_type
198
+ end
199
+
200
+ def custom?
201
+ true
202
+ end
203
+
204
+ def array?
205
+ true
206
+ end
207
+ end
208
+
209
+ class StructuredType < BaseType # :nodoc:
210
+ def each_member
211
+ if @type_class.respond_to?(:members)
212
+ @type_class.members.each do |name, type|
213
+ yield name, type
214
+ end
215
+ elsif @type_class.respond_to?(:columns)
216
+ i = -1
217
+ @type_class.columns.each do |column|
218
+ yield column.name, canonical_signature_entry(column.type, i += 1)
219
+ end
220
+ end
221
+ end
222
+
223
+ def custom?
224
+ true
225
+ end
226
+
227
+ def structured?
228
+ true
229
+ end
230
+ end
231
+
232
+ class SimpleType < BaseType # :nodoc:
233
+ def base
234
+ @type_class.restriction_base if @type_class.respond_to?(:restriction_base)
235
+ end
236
+
237
+ def restrictions
238
+ if @type_class.respond_to?(:restrictions)
239
+ @type_class.restrictions.each do |name, value|
240
+ yield name, value
241
+ end
242
+ end
243
+ end
244
+
245
+ def custom?
246
+ true
247
+ end
248
+
249
+ def simple?
250
+ true
251
+ end
252
+ end
253
+
254
+ class Base64 < String # :nodoc:
255
+ end
256
+ end
@@ -0,0 +1,65 @@
1
+ <html>
2
+ <head>
3
+ <title><%= @scaffold_class.wsdl_service_name %> Web Service</title>
4
+ <style>
5
+ body { background-color: #fff; color: #333; }
6
+
7
+ body, p, ol, ul, td {
8
+ font-family: verdana, arial, helvetica, sans-serif;
9
+ font-size: 13px;
10
+ line-height: 18px;
11
+ }
12
+
13
+ pre {
14
+ background-color: #eee;
15
+ padding: 10px;
16
+ font-size: 11px;
17
+ }
18
+
19
+ a { color: #000; }
20
+ a:visited { color: #666; }
21
+ a:hover { color: #fff; background-color:#000; }
22
+
23
+ .fieldWithErrors {
24
+ padding: 2px;
25
+ background-color: red;
26
+ display: table;
27
+ }
28
+
29
+ #errorExplanation {
30
+ width: 400px;
31
+ border: 2px solid red;
32
+ padding: 7px;
33
+ padding-bottom: 12px;
34
+ margin-bottom: 20px;
35
+ background-color: #f0f0f0;
36
+ }
37
+
38
+ #errorExplanation h2 {
39
+ text-align: left;
40
+ font-weight: bold;
41
+ padding: 5px 5px 5px 15px;
42
+ font-size: 12px;
43
+ margin: -7px;
44
+ background-color: #c00;
45
+ color: #fff;
46
+ }
47
+
48
+ #errorExplanation p {
49
+ color: #333;
50
+ margin-bottom: 0;
51
+ padding: 5px;
52
+ }
53
+
54
+ #errorExplanation ul li {
55
+ font-size: 12px;
56
+ list-style: square;
57
+ }
58
+ </style>
59
+ </head>
60
+ <body>
61
+
62
+ <%= @content_for_layout %>
63
+
64
+ </body>
65
+ </html>