aws-sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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