aws-sdk 1.0.0

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 (205) hide show
  1. data/.yardopts +6 -0
  2. data/LICENSE.txt +171 -0
  3. data/NOTICE.txt +2 -0
  4. data/README.rdoc +189 -0
  5. data/lib/aws-sdk.rb +14 -0
  6. data/lib/aws.rb +63 -0
  7. data/lib/aws/api_config.rb +45 -0
  8. data/lib/aws/api_config/.document +0 -0
  9. data/lib/aws/api_config/EC2-2011-02-28.yml +2314 -0
  10. data/lib/aws/api_config/SNS-2010-03-31.yml +171 -0
  11. data/lib/aws/api_config/SQS-2009-02-01.yml +161 -0
  12. data/lib/aws/api_config/SimpleDB-2009-04-15.yml +278 -0
  13. data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +147 -0
  14. data/lib/aws/api_config_transform.rb +32 -0
  15. data/lib/aws/async_handle.rb +90 -0
  16. data/lib/aws/authorize_v2.rb +37 -0
  17. data/lib/aws/authorize_v3.rb +37 -0
  18. data/lib/aws/base_client.rb +524 -0
  19. data/lib/aws/cacheable.rb +92 -0
  20. data/lib/aws/common.rb +228 -0
  21. data/lib/aws/configurable.rb +36 -0
  22. data/lib/aws/configuration.rb +272 -0
  23. data/lib/aws/configured_client_methods.rb +81 -0
  24. data/lib/aws/configured_grammars.rb +65 -0
  25. data/lib/aws/configured_option_grammars.rb +46 -0
  26. data/lib/aws/configured_xml_grammars.rb +47 -0
  27. data/lib/aws/default_signer.rb +38 -0
  28. data/lib/aws/ec2.rb +321 -0
  29. data/lib/aws/ec2/attachment.rb +149 -0
  30. data/lib/aws/ec2/attachment_collection.rb +57 -0
  31. data/lib/aws/ec2/availability_zone.rb +80 -0
  32. data/lib/aws/ec2/availability_zone_collection.rb +47 -0
  33. data/lib/aws/ec2/block_device_mappings.rb +53 -0
  34. data/lib/aws/ec2/client.rb +54 -0
  35. data/lib/aws/ec2/client/xml.rb +127 -0
  36. data/lib/aws/ec2/collection.rb +39 -0
  37. data/lib/aws/ec2/config_transform.rb +63 -0
  38. data/lib/aws/ec2/elastic_ip.rb +107 -0
  39. data/lib/aws/ec2/elastic_ip_collection.rb +85 -0
  40. data/lib/aws/ec2/errors.rb +29 -0
  41. data/lib/aws/ec2/filtered_collection.rb +65 -0
  42. data/lib/aws/ec2/has_permissions.rb +46 -0
  43. data/lib/aws/ec2/image.rb +245 -0
  44. data/lib/aws/ec2/image_collection.rb +235 -0
  45. data/lib/aws/ec2/instance.rb +515 -0
  46. data/lib/aws/ec2/instance_collection.rb +276 -0
  47. data/lib/aws/ec2/key_pair.rb +86 -0
  48. data/lib/aws/ec2/key_pair_collection.rb +102 -0
  49. data/lib/aws/ec2/permission_collection.rb +177 -0
  50. data/lib/aws/ec2/region.rb +81 -0
  51. data/lib/aws/ec2/region_collection.rb +55 -0
  52. data/lib/aws/ec2/request.rb +27 -0
  53. data/lib/aws/ec2/reserved_instances.rb +50 -0
  54. data/lib/aws/ec2/reserved_instances_collection.rb +44 -0
  55. data/lib/aws/ec2/reserved_instances_offering.rb +55 -0
  56. data/lib/aws/ec2/reserved_instances_offering_collection.rb +43 -0
  57. data/lib/aws/ec2/resource.rb +340 -0
  58. data/lib/aws/ec2/resource_tag_collection.rb +218 -0
  59. data/lib/aws/ec2/security_group.rb +246 -0
  60. data/lib/aws/ec2/security_group/ip_permission.rb +70 -0
  61. data/lib/aws/ec2/security_group/ip_permission_collection.rb +59 -0
  62. data/lib/aws/ec2/security_group_collection.rb +132 -0
  63. data/lib/aws/ec2/snapshot.rb +138 -0
  64. data/lib/aws/ec2/snapshot_collection.rb +90 -0
  65. data/lib/aws/ec2/tag.rb +88 -0
  66. data/lib/aws/ec2/tag_collection.rb +114 -0
  67. data/lib/aws/ec2/tagged_collection.rb +48 -0
  68. data/lib/aws/ec2/tagged_item.rb +87 -0
  69. data/lib/aws/ec2/volume.rb +190 -0
  70. data/lib/aws/ec2/volume_collection.rb +95 -0
  71. data/lib/aws/errors.rb +129 -0
  72. data/lib/aws/http/builtin_handler.rb +69 -0
  73. data/lib/aws/http/curb_handler.rb +123 -0
  74. data/lib/aws/http/handler.rb +77 -0
  75. data/lib/aws/http/httparty_handler.rb +61 -0
  76. data/lib/aws/http/request.rb +136 -0
  77. data/lib/aws/http/request_param.rb +63 -0
  78. data/lib/aws/http/response.rb +75 -0
  79. data/lib/aws/ignore_result_element.rb +38 -0
  80. data/lib/aws/indifferent_hash.rb +86 -0
  81. data/lib/aws/inflection.rb +46 -0
  82. data/lib/aws/lazy_error_classes.rb +64 -0
  83. data/lib/aws/meta_utils.rb +43 -0
  84. data/lib/aws/model.rb +57 -0
  85. data/lib/aws/naming.rb +32 -0
  86. data/lib/aws/option_grammar.rb +544 -0
  87. data/lib/aws/policy.rb +912 -0
  88. data/lib/aws/rails.rb +209 -0
  89. data/lib/aws/record.rb +79 -0
  90. data/lib/aws/record/attribute.rb +94 -0
  91. data/lib/aws/record/attribute_macros.rb +288 -0
  92. data/lib/aws/record/attributes/boolean.rb +49 -0
  93. data/lib/aws/record/attributes/datetime.rb +86 -0
  94. data/lib/aws/record/attributes/float.rb +48 -0
  95. data/lib/aws/record/attributes/integer.rb +68 -0
  96. data/lib/aws/record/attributes/sortable_float.rb +60 -0
  97. data/lib/aws/record/attributes/sortable_integer.rb +95 -0
  98. data/lib/aws/record/attributes/string.rb +69 -0
  99. data/lib/aws/record/base.rb +728 -0
  100. data/lib/aws/record/conversion.rb +38 -0
  101. data/lib/aws/record/dirty_tracking.rb +286 -0
  102. data/lib/aws/record/errors.rb +153 -0
  103. data/lib/aws/record/exceptions.rb +48 -0
  104. data/lib/aws/record/finder_methods.rb +262 -0
  105. data/lib/aws/record/naming.rb +31 -0
  106. data/lib/aws/record/scope.rb +157 -0
  107. data/lib/aws/record/validations.rb +653 -0
  108. data/lib/aws/record/validator.rb +237 -0
  109. data/lib/aws/record/validators/acceptance.rb +51 -0
  110. data/lib/aws/record/validators/block.rb +38 -0
  111. data/lib/aws/record/validators/confirmation.rb +43 -0
  112. data/lib/aws/record/validators/count.rb +108 -0
  113. data/lib/aws/record/validators/exclusion.rb +43 -0
  114. data/lib/aws/record/validators/format.rb +57 -0
  115. data/lib/aws/record/validators/inclusion.rb +56 -0
  116. data/lib/aws/record/validators/length.rb +107 -0
  117. data/lib/aws/record/validators/numericality.rb +138 -0
  118. data/lib/aws/record/validators/presence.rb +45 -0
  119. data/lib/aws/resource_cache.rb +39 -0
  120. data/lib/aws/response.rb +113 -0
  121. data/lib/aws/response_cache.rb +50 -0
  122. data/lib/aws/s3.rb +109 -0
  123. data/lib/aws/s3/access_control_list.rb +252 -0
  124. data/lib/aws/s3/acl_object.rb +266 -0
  125. data/lib/aws/s3/bucket.rb +320 -0
  126. data/lib/aws/s3/bucket_collection.rb +122 -0
  127. data/lib/aws/s3/bucket_version_collection.rb +85 -0
  128. data/lib/aws/s3/client.rb +999 -0
  129. data/lib/aws/s3/client/xml.rb +190 -0
  130. data/lib/aws/s3/data_options.rb +99 -0
  131. data/lib/aws/s3/errors.rb +43 -0
  132. data/lib/aws/s3/multipart_upload.rb +318 -0
  133. data/lib/aws/s3/multipart_upload_collection.rb +78 -0
  134. data/lib/aws/s3/object_collection.rb +159 -0
  135. data/lib/aws/s3/object_metadata.rb +67 -0
  136. data/lib/aws/s3/object_upload_collection.rb +83 -0
  137. data/lib/aws/s3/object_version.rb +141 -0
  138. data/lib/aws/s3/object_version_collection.rb +78 -0
  139. data/lib/aws/s3/paginated_collection.rb +94 -0
  140. data/lib/aws/s3/policy.rb +76 -0
  141. data/lib/aws/s3/prefix_and_delimiter_collection.rb +56 -0
  142. data/lib/aws/s3/prefixed_collection.rb +84 -0
  143. data/lib/aws/s3/presigned_post.rb +504 -0
  144. data/lib/aws/s3/request.rb +198 -0
  145. data/lib/aws/s3/s3_object.rb +794 -0
  146. data/lib/aws/s3/tree.rb +116 -0
  147. data/lib/aws/s3/tree/branch_node.rb +71 -0
  148. data/lib/aws/s3/tree/child_collection.rb +108 -0
  149. data/lib/aws/s3/tree/leaf_node.rb +99 -0
  150. data/lib/aws/s3/tree/node.rb +22 -0
  151. data/lib/aws/s3/tree/parent.rb +90 -0
  152. data/lib/aws/s3/uploaded_part.rb +82 -0
  153. data/lib/aws/s3/uploaded_part_collection.rb +86 -0
  154. data/lib/aws/service_interface.rb +60 -0
  155. data/lib/aws/simple_db.rb +202 -0
  156. data/lib/aws/simple_db/attribute.rb +159 -0
  157. data/lib/aws/simple_db/attribute_collection.rb +227 -0
  158. data/lib/aws/simple_db/client.rb +52 -0
  159. data/lib/aws/simple_db/client/options.rb +34 -0
  160. data/lib/aws/simple_db/client/xml.rb +68 -0
  161. data/lib/aws/simple_db/consistent_read_option.rb +42 -0
  162. data/lib/aws/simple_db/delete_attributes.rb +64 -0
  163. data/lib/aws/simple_db/domain.rb +118 -0
  164. data/lib/aws/simple_db/domain_collection.rb +116 -0
  165. data/lib/aws/simple_db/domain_metadata.rb +112 -0
  166. data/lib/aws/simple_db/errors.rb +46 -0
  167. data/lib/aws/simple_db/expect_condition_option.rb +45 -0
  168. data/lib/aws/simple_db/item.rb +84 -0
  169. data/lib/aws/simple_db/item_collection.rb +594 -0
  170. data/lib/aws/simple_db/item_data.rb +70 -0
  171. data/lib/aws/simple_db/put_attributes.rb +62 -0
  172. data/lib/aws/simple_db/request.rb +27 -0
  173. data/lib/aws/simple_email_service.rb +373 -0
  174. data/lib/aws/simple_email_service/client.rb +39 -0
  175. data/lib/aws/simple_email_service/client/options.rb +24 -0
  176. data/lib/aws/simple_email_service/client/xml.rb +38 -0
  177. data/lib/aws/simple_email_service/email_address_collection.rb +66 -0
  178. data/lib/aws/simple_email_service/errors.rb +29 -0
  179. data/lib/aws/simple_email_service/quotas.rb +64 -0
  180. data/lib/aws/simple_email_service/request.rb +27 -0
  181. data/lib/aws/sns.rb +69 -0
  182. data/lib/aws/sns/client.rb +37 -0
  183. data/lib/aws/sns/client/options.rb +24 -0
  184. data/lib/aws/sns/client/xml.rb +38 -0
  185. data/lib/aws/sns/errors.rb +29 -0
  186. data/lib/aws/sns/policy.rb +49 -0
  187. data/lib/aws/sns/request.rb +27 -0
  188. data/lib/aws/sns/subscription.rb +100 -0
  189. data/lib/aws/sns/subscription_collection.rb +84 -0
  190. data/lib/aws/sns/topic.rb +384 -0
  191. data/lib/aws/sns/topic_collection.rb +70 -0
  192. data/lib/aws/sns/topic_subscription_collection.rb +58 -0
  193. data/lib/aws/sqs.rb +70 -0
  194. data/lib/aws/sqs/client.rb +38 -0
  195. data/lib/aws/sqs/client/xml.rb +36 -0
  196. data/lib/aws/sqs/errors.rb +33 -0
  197. data/lib/aws/sqs/policy.rb +50 -0
  198. data/lib/aws/sqs/queue.rb +507 -0
  199. data/lib/aws/sqs/queue_collection.rb +105 -0
  200. data/lib/aws/sqs/received_message.rb +184 -0
  201. data/lib/aws/sqs/received_sns_message.rb +112 -0
  202. data/lib/aws/sqs/request.rb +44 -0
  203. data/lib/aws/xml_grammar.rb +923 -0
  204. data/rails/init.rb +15 -0
  205. metadata +298 -0
@@ -0,0 +1,32 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/inflection'
15
+
16
+ module AWS
17
+
18
+ # @private
19
+ module Naming
20
+
21
+ def service_name
22
+ debugger if self.name == nil
23
+ self.name.split(/::/)[1]
24
+ end
25
+
26
+ def service_ruby_name
27
+ @service_ruby_name ||= Inflection.ruby_name(service_name)
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,544 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/inflection'
15
+ require 'aws/meta_utils'
16
+ require 'aws/http/request_param'
17
+ require 'base64'
18
+ require 'set'
19
+
20
+ module AWS
21
+
22
+ # @private
23
+ class OptionGrammar
24
+
25
+ # @private
26
+ class DefaultOption; end
27
+
28
+ # @private
29
+ class FormatError < ArgumentError
30
+ attr_accessor :expectation
31
+ attr_accessor :context_description
32
+
33
+ def initialize(expectation, context)
34
+ @expectation = expectation
35
+ @context_description = context
36
+ end
37
+
38
+ def to_s
39
+ "expected #{expectation} for #{context_description}"
40
+ end
41
+ end
42
+
43
+ # @private
44
+ module Descriptors
45
+
46
+ # @private
47
+ module NoArgs
48
+ def apply(option)
49
+ option.extend self
50
+ end
51
+ end
52
+
53
+ module Timestamp
54
+
55
+ extend NoArgs
56
+
57
+ def validate(value, context = nil)
58
+ true
59
+ # raise format_error("timestamp value", context) unless
60
+ # case value
61
+ # when String
62
+ # value =~ /^\d+$/ or value =~ /^\d{4}-\d{2}-d{2}T\d{2}:\d{2}:\d{2}Z$/
63
+ # when String then value =~ /^2009-12-04T20:56:05.000Z\d+$/
64
+ # when Integer then true
65
+ # when DateTime then true
66
+ # when Timestamp then true
67
+ # when Date then true
68
+ # else false
69
+ # end
70
+ # end
71
+ # value.respond_to? :to_str
72
+ end
73
+
74
+ def encode_value(value)
75
+ value.to_s
76
+ # value.to_s
77
+ # case value
78
+ # when Integer
79
+ # when
80
+ # case value
81
+ # when nil, '' then nil
82
+ # when DateTime then raw
83
+ # when Integer then DateTime.parse(Time.at(raw).to_s) # timestamp
84
+ # else DateTime.parse(raw.to_s) # work with Time, Date and String objects
85
+ # end
86
+ end
87
+ end
88
+
89
+ # @private
90
+ module String
91
+
92
+ extend NoArgs
93
+
94
+ def validate(value, context = nil)
95
+ raise format_error("string value", context) unless
96
+ value.respond_to? :to_str
97
+ end
98
+
99
+ def encode_value(value)
100
+ value.to_s
101
+ end
102
+
103
+ end
104
+
105
+ # @private
106
+ module Blob
107
+
108
+ extend NoArgs
109
+
110
+ def validate(value, context = nil)
111
+ raise format_error("string value", context) unless
112
+ value.respond_to? :to_str
113
+ end
114
+
115
+ def encode_value(value)
116
+ Base64.encode64(value.to_s)
117
+ end
118
+
119
+ end
120
+
121
+ # @private
122
+ module Integer
123
+
124
+ extend NoArgs
125
+
126
+ def validate(value, context = nil)
127
+ raise format_error("integer value", context) unless
128
+ value.respond_to? :to_int
129
+ end
130
+
131
+ def encode_value(value)
132
+ value.to_s
133
+ end
134
+
135
+ end
136
+
137
+ # @private
138
+ module Boolean
139
+
140
+ extend NoArgs
141
+
142
+ def validate(value, context = nil)
143
+ raise format_error("boolean value", context) unless
144
+ value == true || value == false
145
+ end
146
+
147
+ def encode_value(value)
148
+ value.to_s
149
+ end
150
+
151
+ end
152
+
153
+ # @private
154
+ module Required
155
+ extend NoArgs
156
+ def required?; true; end
157
+ end
158
+
159
+ # @private
160
+ module Rename
161
+ def self.apply(option, new_name)
162
+ new_name = Inflection.ruby_name(new_name)
163
+ MetaUtils.extend_method(option, :ruby_name) { new_name }
164
+ end
165
+ end
166
+
167
+ # @private
168
+ module ListMethods
169
+
170
+ module ClassMethods
171
+
172
+ def apply(option, member_descriptors)
173
+ super(option)
174
+ member_option = option.member_option if option.respond_to?(:member_option)
175
+ member_option ||= ListMember.new
176
+ member_option = member_option.extend_with_config(*member_descriptors)
177
+ MetaUtils.extend_method(option, :member_option) { member_option }
178
+ end
179
+
180
+ end
181
+
182
+ module InstanceMethods
183
+
184
+ def validate(value, context = nil)
185
+ raise format_error("enumerable value", context) unless
186
+ value.respond_to? :each
187
+ i = 0
188
+ value.each do |member|
189
+ i += 1
190
+ member_option.validate(member,
191
+ "member #{i} of #{context_description(context)}")
192
+ end
193
+ end
194
+
195
+ def request_params(value, prefix = nil)
196
+ params = []
197
+ value.each do |v|
198
+ name = prefixed_name(prefix) + join + (params.size + 1).to_s
199
+ params << member_option.request_params(v, name)
200
+ end
201
+ return [Http::Request::Param.new(prefixed_name(prefix), "")] if params.empty?
202
+ params
203
+ end
204
+
205
+ def join
206
+ '.'
207
+ end
208
+
209
+ end
210
+
211
+ end
212
+
213
+ module List
214
+
215
+ extend NoArgs
216
+ extend ListMethods::ClassMethods
217
+ include ListMethods::InstanceMethods
218
+
219
+ end
220
+
221
+ module MemberedList
222
+
223
+ extend NoArgs
224
+ extend ListMethods::ClassMethods
225
+ include ListMethods::InstanceMethods
226
+
227
+ def join
228
+ '.member.'
229
+ end
230
+
231
+ end
232
+
233
+ class ListMember < DefaultOption
234
+
235
+ def initialize options = {}
236
+ super("##list-member##")
237
+ @prefix = options[:prefix] || ''
238
+ end
239
+
240
+ def prefixed_name(prefix)
241
+ "#{prefix}#{@prefix}"
242
+ end
243
+
244
+ end
245
+
246
+ # @private
247
+ module Structure
248
+
249
+ extend NoArgs
250
+
251
+ def self.apply(option, members)
252
+ options = {}
253
+ options = option.member_options.inject({}) do |memo, member_option|
254
+ memo[member_option.name] = member_option
255
+ memo
256
+ end if option.respond_to?(:member_options)
257
+
258
+ super(option)
259
+
260
+ members.each do |(name, descriptors)|
261
+ member_option = options[name] || DefaultOption.new(name)
262
+ member_option = member_option.extend_with_config(*descriptors)
263
+ options[name] = member_option
264
+ end
265
+
266
+ MetaUtils.extend_method(option, :member_options) { options.values }
267
+ by_ruby_name = options.values.inject({}) do |memo, member_option|
268
+ memo[member_option.ruby_name] = member_option
269
+ memo
270
+ end
271
+ MetaUtils.extend_method(option, :member_option) { |n| by_ruby_name[n] }
272
+ end
273
+
274
+ def validate(value, context = nil)
275
+ raise format_error("hash value", context) unless
276
+ value.respond_to?(:to_hash)
277
+
278
+ context = context_description(context)
279
+
280
+ value.each do |name, v|
281
+ name = name.to_s
282
+ raise ArgumentError.new("unexpected key #{name} for #{context}") unless
283
+ member_option(name)
284
+ member_option(name).validate(v, "key #{name} of #{context}")
285
+ end
286
+
287
+ member_options.each do |option|
288
+ raise ArgumentError.new("missing required key #{option.ruby_name} for #{context}") if
289
+ option.required? and
290
+ !value.has_key?(option.ruby_name) and
291
+ !value.has_key?(option.ruby_name.to_sym)
292
+ end
293
+ end
294
+
295
+ def request_params(values, prefix = nil)
296
+ values.map do |name, value|
297
+ name = name.to_s
298
+ member_option(name).request_params(value, prefixed_name(prefix))
299
+ end.flatten
300
+ end
301
+
302
+ end
303
+
304
+ # @private
305
+ module Boolean
306
+ extend NoArgs
307
+ end
308
+
309
+ end
310
+
311
+ class DefaultOption
312
+
313
+ attr_reader :name
314
+
315
+ def initialize(name)
316
+ @name = name
317
+ end
318
+
319
+ def ruby_name
320
+ Inflection.ruby_name(name)
321
+ end
322
+
323
+ def request_params(value, prefix = nil)
324
+ [Http::Request::Param.new(prefixed_name(prefix), encode_value(value))]
325
+ end
326
+
327
+ def prefixed_name(prefix)
328
+ return "#{prefix}.#{name}" if prefix
329
+ name
330
+ end
331
+
332
+ def encode_value(value)
333
+ value
334
+ end
335
+
336
+ def required?; false; end
337
+
338
+ def format_error(expected, context = nil)
339
+ context = context_description(context)
340
+ FormatError.new(expected, context)
341
+ end
342
+
343
+ def context_description(context)
344
+ context or "option #{ruby_name}"
345
+ end
346
+
347
+ def extend_with_config(*descriptors)
348
+ option = clone
349
+ descriptors.each do |desc|
350
+ if desc.kind_of?(Hash)
351
+ (name, arg) = desc.to_a.first
352
+ else
353
+ name = desc
354
+ arg = nil
355
+ end
356
+ class_name = Inflection.class_name(name.to_s)
357
+ mod = Descriptors::const_get(class_name)
358
+ if arg
359
+ mod.apply(option, arg)
360
+ else
361
+ mod.apply(option)
362
+ end
363
+ end
364
+ option
365
+ end
366
+
367
+ include Descriptors::String
368
+
369
+ end
370
+
371
+ # @private
372
+ module ModuleMethods
373
+
374
+ include Inflection
375
+
376
+ def customize(config = [])
377
+ m = Class.new(self)
378
+ supported_options = m.supported_options.inject({}) do |memo, opt|
379
+ memo[opt.name] = opt
380
+ memo
381
+ end
382
+ config.each do |option_config|
383
+ if config.kind_of?(Hash)
384
+ (name, value_desc) = option_config
385
+ else
386
+ (name, value_desc) = parse_option(option_config)
387
+ end
388
+ option = supported_options[name] || DefaultOption.new(name)
389
+ option = option.extend_with_config(*value_desc)
390
+ supported_options[option.name] = option
391
+ end
392
+
393
+ supported_ary = supported_options.values
394
+ MetaUtils.extend_method(m, :supported_options) { supported_ary }
395
+ supported_ruby_names = supported_ary.inject({}) do |memo, opt|
396
+ memo[opt.ruby_name] = opt
397
+ memo
398
+ end
399
+ MetaUtils.extend_method(m, :option) { |n| supported_ruby_names[n] }
400
+ supported_ary.each do |opt|
401
+ MetaUtils.extend_method(m, "validate_#{opt.ruby_name}") do |value|
402
+ opt.validate(value)
403
+ end
404
+ end
405
+
406
+ m
407
+ end
408
+
409
+ def option(name)
410
+ nil
411
+ end
412
+
413
+ def supported_options
414
+ []
415
+ end
416
+
417
+ def validate(options)
418
+ options.each do |name, value|
419
+ name = name.to_s
420
+ raise ArgumentError.new("unexpected option #{name}") unless
421
+ option(name)
422
+ option(name).validate(value)
423
+ end
424
+ supported_options.each do |option|
425
+ raise ArgumentError.new("missing required option #{option.ruby_name}") unless
426
+ !option.required? ||
427
+ options.has_key?(option.ruby_name) || options.has_key?(option.ruby_name.to_sym)
428
+ end
429
+ end
430
+
431
+ def request_params(options)
432
+ validate(options)
433
+ options.map do |(name, value)|
434
+ name = name.to_s
435
+ option(name).request_params(value)
436
+ end.flatten
437
+ end
438
+
439
+ def included(m)
440
+ m.extend(self::ModuleMethods)
441
+ end
442
+
443
+ protected
444
+ def parse_option(option)
445
+ value_desc = nil
446
+ if option.kind_of? Hash
447
+ raise ArgumentError.new("passed empty hash where an option was expected") if
448
+ option.empty?
449
+
450
+ raise ArgumentError.new("too many entries in option description") if
451
+ option.size > 1
452
+
453
+ (name, value_desc) = option.to_a.first
454
+ name = name.to_s
455
+
456
+ raise ArgumentError.new("expected an array for "+
457
+ "value description of option #{name},"+
458
+ "got #{value_desc.inspect}") unless
459
+ value_desc.nil? or value_desc.kind_of?(Array)
460
+ else
461
+ name = option
462
+ end
463
+
464
+ value_desc ||= []
465
+
466
+ [name, value_desc]
467
+ end
468
+
469
+ protected
470
+ def apply_required_descriptor(m, name)
471
+ name = ruby_name(name)
472
+ MetaUtils.extend_method(m, :validate) do |opts|
473
+ raise ArgumentError.new("missing required option #{name}") unless
474
+ opts.key? name or opts.key? name.to_sym
475
+ end
476
+ end
477
+
478
+ protected
479
+ def apply_integer_descriptor(m, name)
480
+ MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
481
+ raise ArgumentError.new("expected integer value for option #{ruby_name(name)}") unless
482
+ value.respond_to? :to_int
483
+ end
484
+ end
485
+
486
+ protected
487
+ def apply_string_descriptor(m, name)
488
+ MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
489
+ raise ArgumentError.new("expected string value for option #{ruby_name(name)}") unless
490
+ value.respond_to? :to_str
491
+ end
492
+ end
493
+
494
+ protected
495
+ def apply_list_descriptor(m, name, arg)
496
+ MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
497
+ raise ArgumentError.new("expected value for option #{ruby_name(name)} "+
498
+ "to respond to #each") unless
499
+ value.respond_to? :each
500
+ end
501
+ MetaUtils.extend_method(m, "params_for_#{ruby_name(name)}") do |value|
502
+ i = 0
503
+ values = []
504
+ value.each do |member|
505
+ i += 1
506
+ values << Http::Request::Param.new(name+"."+i.to_s, member.to_s)
507
+ end
508
+ if i > 0
509
+ values
510
+ else
511
+ Http::Request::Param.new(name, "")
512
+ end
513
+ end
514
+ end
515
+
516
+ protected
517
+ def apply_rename_descriptor(m, name, new_name)
518
+ name = ruby_name(name)
519
+ MetaUtils.extend_method(m, :validate) do |opts|
520
+ raise ArgumentError.new("unexpected option foo") if
521
+ opts.key?(name) or opts.key?(name.to_sym)
522
+
523
+ opts = opts.dup
524
+ opts[name] = opts[new_name] if opts.key?(new_name)
525
+ opts[name.to_sym] = opts[new_name.to_sym] if opts.key?(new_name.to_sym)
526
+ opts.delete(new_name)
527
+ opts.delete(new_name.to_sym)
528
+ super(opts)
529
+ end
530
+
531
+ # couldn't find a better way to alias a class method
532
+ method = m.method("params_for_#{name}")
533
+ MetaUtils.extend_method(m, "params_for_#{new_name}") do |value|
534
+ method.call(value)
535
+ end
536
+ end
537
+
538
+ end
539
+
540
+ extend ModuleMethods
541
+
542
+ end
543
+
544
+ end