raws 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.rdoc +50 -29
- data/Rakefile +5 -5
- data/VERSION +1 -1
- data/lib/raws/http.rb +1 -0
- data/lib/raws/s3.rb +84 -52
- data/lib/raws/s3/acl.rb +144 -0
- data/lib/raws/s3/adapter.rb +44 -20
- data/lib/raws/s3/metadata.rb +9 -3
- data/lib/raws/s3/model.rb +76 -50
- data/lib/raws/s3/owner.rb +8 -0
- data/lib/raws/sdb.rb +61 -50
- data/lib/raws/sdb/adapter.rb +2 -4
- data/lib/raws/sdb/model.rb +53 -44
- data/lib/raws/sdb/select.rb +1 -1
- data/lib/raws/sqs.rb +155 -89
- data/lib/raws/sqs/adapter.rb +28 -27
- data/lib/raws/sqs/message.rb +39 -0
- data/lib/raws/sqs/model.rb +33 -0
- data/lib/raws/xml.rb +0 -2
- data/lib/raws/xml/nokogiri.rb +4 -1
- data/raws.gemspec +24 -19
- data/spec/raws/s3/acl_spec.rb +30 -0
- data/spec/raws/s3/model_spec.rb +2 -3
- data/spec/raws/s3_spec.rb +34 -36
- data/spec/raws/sdb/model_spec.rb +104 -9
- data/spec/raws/sdb_spec.rb +43 -52
- data/spec/raws/sqs_spec.rb +40 -35
- data/spec/raws_spec.rb +2 -0
- data/spec/spec_config.rb.example +8 -13
- metadata +13 -8
- data/spec/spec.opts +0 -1
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -19,7 +19,7 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
19
19
|
RAWS::SQS['test_queue'].send('hello2')
|
20
20
|
RAWS::SQS['test_queue'].send('hello3')
|
21
21
|
|
22
|
-
RAWS::SQS['test_queue'].receive
|
22
|
+
RAWS::SQS['test_queue'].receive.each do |msg|
|
23
23
|
p msg.body
|
24
24
|
msg.delete
|
25
25
|
end
|
@@ -28,8 +28,6 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
28
28
|
|
29
29
|
=== SDB (Amazon SimpleDB)
|
30
30
|
|
31
|
-
プリミティブな使い方
|
32
|
-
|
33
31
|
require 'rubygems'
|
34
32
|
require 'raws'
|
35
33
|
|
@@ -61,8 +59,6 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
61
59
|
|
62
60
|
RAWS::SDB.delete_domain('test_domain')
|
63
61
|
|
64
|
-
クラスとして使う場合
|
65
|
-
|
66
62
|
require 'rubygems'
|
67
63
|
require 'raws'
|
68
64
|
|
@@ -72,8 +68,6 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
72
68
|
class Foo
|
73
69
|
include RAWS::SDB::Model
|
74
70
|
self.domain_name = 'test_domain'
|
75
|
-
|
76
|
-
sdb_accessor 'a', 'b'
|
77
71
|
end
|
78
72
|
|
79
73
|
Foo.create_domain
|
@@ -88,27 +82,14 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
88
82
|
foo2['c'] = '2000'
|
89
83
|
foo2.save
|
90
84
|
|
91
|
-
foo3 = Foo.new
|
92
|
-
foo3.a = ['30a', '30b']
|
93
|
-
foo3.b = '300'
|
94
|
-
foo3['c'] = '3000'
|
95
|
-
foo3.save
|
96
|
-
|
97
85
|
Foo.all.each do |a|
|
98
|
-
p [a
|
99
|
-
end
|
100
|
-
|
101
|
-
Foo.all.filter('a = ?', '10').each do |a|
|
102
|
-
p [a.a, a.b, a['c']]
|
103
|
-
a.delete
|
86
|
+
p [a['a'], a['b'], a['c']]
|
104
87
|
end
|
105
|
-
|
88
|
+
|
106
89
|
Foo.delete_domain
|
107
90
|
|
108
91
|
=== S3 (Amazon Simple Storage Service)
|
109
92
|
|
110
|
-
プリミティブな使い方
|
111
|
-
|
112
93
|
require 'rubygems'
|
113
94
|
require 'raws'
|
114
95
|
|
@@ -118,11 +99,12 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
118
99
|
RAWS::S3.create_bucket('test-bucket')
|
119
100
|
|
120
101
|
RAWS::S3['test-bucket'].put('helloworld') do |request|
|
102
|
+
request.header['x-amz-acl'] = 'public-read'
|
121
103
|
request.header['content-type'] = 'text/plain'
|
122
|
-
request.header['content-length'] =
|
104
|
+
request.header['content-length'] = "Hello World\n".size * 1000
|
123
105
|
request.send do |io|
|
124
106
|
1000.times do
|
125
|
-
io.write "
|
107
|
+
io.write "Hello World\n"
|
126
108
|
end
|
127
109
|
end
|
128
110
|
end
|
@@ -136,11 +118,29 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
136
118
|
end
|
137
119
|
end
|
138
120
|
end
|
121
|
+
|
122
|
+
acl = RAWS::S3['test-bucket'].acl
|
123
|
+
p [acl.owner.id, acl.owner.name]
|
124
|
+
acl.grants.each do |grant|
|
125
|
+
p [grant.permission, grant.class.name]
|
126
|
+
end
|
127
|
+
|
128
|
+
acl = RAWS::S3['test-bucket'].acl('helloworld')
|
129
|
+
p [acl.owner.id, acl.owner.name]
|
130
|
+
acl.grants.each do |grant|
|
131
|
+
p [grant.permission, grant.class.name]
|
132
|
+
end
|
133
|
+
|
134
|
+
acl.grants.delete_if do |grant|
|
135
|
+
grant.is_a? RAWS::S3::ACL::AllUsers
|
136
|
+
end
|
137
|
+
acl.save
|
138
|
+
|
139
|
+
acl.grants << RAWS::S3::ACL::AllUsers.new('READ')
|
140
|
+
acl.save
|
139
141
|
|
140
142
|
RAWS::S3.delete_bucket('test-bucket')
|
141
143
|
|
142
|
-
クラスとして使う場合
|
143
|
-
|
144
144
|
require 'rubygems'
|
145
145
|
require 'raws'
|
146
146
|
|
@@ -157,11 +157,12 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
157
157
|
foo = Foo.new('helloworld')
|
158
158
|
foo.metadata['ja'] = 'こんにちは'
|
159
159
|
foo.send(
|
160
|
+
'x-amz-acl' => 'public-read',
|
160
161
|
'content-type' => 'text/plain',
|
161
|
-
'content-length' =>
|
162
|
+
'content-length' => "Hello World\n".size * 1000
|
162
163
|
) do |io|
|
163
164
|
1000.times do
|
164
|
-
io.write "
|
165
|
+
io.write "Hello World\n"
|
165
166
|
end
|
166
167
|
end
|
167
168
|
|
@@ -173,6 +174,26 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
173
174
|
print chunk
|
174
175
|
end
|
175
176
|
end
|
177
|
+
|
178
|
+
acl = Foo.acl
|
179
|
+
p [acl.owner.id, acl.owner.name]
|
180
|
+
acl.grants.each do |grant|
|
181
|
+
p [grant.permission, grant.class.name]
|
182
|
+
end
|
183
|
+
|
184
|
+
acl = foo.acl
|
185
|
+
p [acl.owner.id, acl.owner.name]
|
186
|
+
acl.grants.each do |grant|
|
187
|
+
p [grant.permission, grant.class.name]
|
188
|
+
end
|
189
|
+
|
190
|
+
acl.grants.delete_if do |grant|
|
191
|
+
grant.is_a? RAWS::S3::ACL::AllUsers
|
192
|
+
end
|
193
|
+
acl.save
|
194
|
+
|
195
|
+
acl.grants << RAWS::S3::ACL::AllUsers.new('READ')
|
196
|
+
acl.save
|
176
197
|
|
177
198
|
Foo.delete_bucket
|
178
199
|
|
@@ -189,4 +210,4 @@ RAWS is a Ruby library for Amazon Web Service (AWS).
|
|
189
210
|
|
190
211
|
== Copyright
|
191
212
|
|
192
|
-
Copyright (c) 2009 Jun Kikuchi. See LICENSE for details.
|
213
|
+
Copyright (c) 2009, 2010 Jun Kikuchi. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -10,11 +10,11 @@ begin
|
|
10
10
|
gem.email = "kikuchi@bonnou.com"
|
11
11
|
gem.homepage = "http://github.com/JunKikuchi/raws"
|
12
12
|
gem.authors = ["Jun Kikuchi"]
|
13
|
-
gem.add_development_dependency "rspec"
|
14
|
-
gem.add_dependency 'typhoeus', '>=0.1.
|
15
|
-
gem.add_dependency 'ht2p', '>=0.0.
|
16
|
-
gem.add_dependency 'nokogiri', '>=1.
|
17
|
-
gem.add_dependency 'uuidtools', '>=2.
|
13
|
+
gem.add_development_dependency "rspec"
|
14
|
+
gem.add_dependency 'typhoeus', '>=0.1.14'
|
15
|
+
gem.add_dependency 'ht2p', '>=0.0.7'
|
16
|
+
gem.add_dependency 'nokogiri', '>=1.4.1'
|
17
|
+
gem.add_dependency 'uuidtools', '>=2.1.1'
|
18
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
19
|
end
|
20
20
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.11
|
data/lib/raws/http.rb
CHANGED
data/lib/raws/s3.rb
CHANGED
@@ -2,6 +2,8 @@ class RAWS::S3
|
|
2
2
|
autoload :Metadata, 'raws/s3/metadata'
|
3
3
|
autoload :Adapter, 'raws/s3/adapter'
|
4
4
|
autoload :Model, 'raws/s3/model'
|
5
|
+
autoload :Owner, 'raws/s3/owner'
|
6
|
+
autoload :ACL, 'raws/s3/acl'
|
5
7
|
|
6
8
|
class << self
|
7
9
|
include Enumerable
|
@@ -12,80 +14,97 @@ class RAWS::S3
|
|
12
14
|
@http ||= RAWS.http
|
13
15
|
end
|
14
16
|
|
17
|
+
# Creates a new bucket and returns the instance of RAWS::S3.
|
15
18
|
def create_bucket(bucket_name, location=nil, header={})
|
16
|
-
Adapter.put_bucket
|
19
|
+
Adapter.put_bucket bucket_name, location, header
|
20
|
+
self[bucket_name]
|
17
21
|
end
|
18
22
|
|
23
|
+
# Delete the bucket.
|
19
24
|
def delete_bucket(bucket_name, force=nil)
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
begin
|
26
|
+
objects = filter(bucket_name)
|
27
|
+
objects.each do |val|
|
28
|
+
delete(bucket_name, val['Key'])
|
29
|
+
end
|
30
|
+
end until objects.empty? if force == :force
|
23
31
|
|
24
32
|
Adapter.delete_bucket(bucket_name)
|
25
33
|
end
|
26
34
|
|
35
|
+
# Returns the instance of RAWS::S3::Owner.
|
27
36
|
def owner
|
28
|
-
Adapter.get_service.doc['ListAllMyBucketsResult']['Owner']
|
37
|
+
Owner.new Adapter.get_service.doc['ListAllMyBucketsResult']['Owner']
|
29
38
|
end
|
30
39
|
|
31
|
-
|
32
|
-
|
40
|
+
# Returns an array of RAWS::S3 objects.
|
41
|
+
def list_buckets
|
42
|
+
doc = Adapter.get_service.doc['ListAllMyBucketsResult']['Buckets']
|
43
|
+
if doc
|
44
|
+
doc['Bucket'].map do |val|
|
45
|
+
self[val['Name']]
|
46
|
+
end
|
47
|
+
else
|
48
|
+
[]
|
49
|
+
end
|
33
50
|
end
|
34
51
|
|
35
|
-
def buckets
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end.map do |val|
|
41
|
-
self[val['Name']]
|
52
|
+
def buckets(&block)
|
53
|
+
if block_given?
|
54
|
+
each(&block)
|
55
|
+
else
|
56
|
+
map
|
42
57
|
end
|
43
58
|
end
|
44
59
|
|
45
60
|
def each(&block)
|
46
|
-
|
61
|
+
list_buckets.each(&block)
|
47
62
|
end
|
48
63
|
|
64
|
+
# Returns the instance of RAWS::S3.
|
49
65
|
def [](bucket_name)
|
50
|
-
|
51
|
-
@cache[bucket_name] ||= self.new(bucket_name)
|
66
|
+
self.new bucket_name
|
52
67
|
end
|
53
68
|
|
54
69
|
def location(bucket_name)
|
55
|
-
|
56
|
-
|
57
|
-
location.empty? ? 'US' : location
|
70
|
+
doc = Adapter.get_bucket_location(bucket_name).doc['LocationConstraint']
|
71
|
+
doc || 'US'
|
58
72
|
end
|
59
73
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
74
|
+
def acl(bucket_name, key=nil)
|
75
|
+
ACL.new bucket_name, key
|
76
|
+
end
|
77
|
+
|
78
|
+
def filter(bucket_name, query={})
|
79
|
+
vals = Adapter.get_bucket(bucket_name, query).doc['ListBucketResult']
|
80
|
+
vals['Contents'] || []
|
67
81
|
end
|
68
82
|
alias :all :filter
|
69
83
|
|
70
|
-
def
|
71
|
-
Adapter.put_object
|
84
|
+
def put_object(bucket_name, key, header={}, &block)
|
85
|
+
Adapter.put_object bucket_name, key, header, &block
|
72
86
|
end
|
87
|
+
alias :put :put_object
|
73
88
|
|
74
|
-
def
|
75
|
-
Adapter.copy_object
|
89
|
+
def copy_object(src_bucket, src_key, dest_bucket, dest_key, header={})
|
90
|
+
Adapter.copy_object src_bucket, src_key, dest_bucket, dest_key, header
|
76
91
|
end
|
92
|
+
alias :copy :copy_object
|
77
93
|
|
78
|
-
def
|
79
|
-
Adapter.get_object
|
94
|
+
def get_object(bucket_name, key, header={}, &block)
|
95
|
+
Adapter.get_object bucket_name, key, header, &block
|
80
96
|
end
|
97
|
+
alias :get :get_object
|
81
98
|
|
82
|
-
def
|
83
|
-
Adapter.head_object
|
99
|
+
def head_object(bucket_name, key)
|
100
|
+
Adapter.head_object bucket_name, key
|
84
101
|
end
|
102
|
+
alias :head :head_object
|
85
103
|
|
86
|
-
def
|
87
|
-
Adapter.delete_object
|
104
|
+
def delete_object(bucket_name, key)
|
105
|
+
Adapter.delete_object bucket_name, key
|
88
106
|
end
|
107
|
+
alias :delete :delete_object
|
89
108
|
end
|
90
109
|
|
91
110
|
attr_reader :bucket_name
|
@@ -96,41 +115,54 @@ class RAWS::S3
|
|
96
115
|
end
|
97
116
|
|
98
117
|
def create_bucket(location=nil)
|
99
|
-
self.class.create_bucket
|
118
|
+
self.class.create_bucket @bucket_name, location
|
100
119
|
end
|
101
120
|
|
102
121
|
def delete_bucket(force=nil)
|
103
|
-
self.class.delete_bucket
|
122
|
+
self.class.delete_bucket @bucket_name, force
|
123
|
+
end
|
124
|
+
|
125
|
+
def owner
|
126
|
+
self.class.owner
|
104
127
|
end
|
105
128
|
|
106
129
|
def location
|
107
|
-
self.class.location
|
130
|
+
self.class.location @bucket_name
|
131
|
+
end
|
132
|
+
|
133
|
+
def acl(key=nil)
|
134
|
+
self.class.acl @bucket_name, key
|
108
135
|
end
|
109
136
|
|
110
|
-
def filter(
|
111
|
-
self.class.filter
|
137
|
+
def filter(query={})
|
138
|
+
self.class.filter @bucket_name, query
|
112
139
|
end
|
113
140
|
alias :all :filter
|
114
141
|
|
115
|
-
def
|
116
|
-
self.class.
|
142
|
+
def put_object(key, header={}, &block)
|
143
|
+
self.class.put_object @bucket_name, key, header, &block
|
117
144
|
end
|
145
|
+
alias :put :put_object
|
118
146
|
|
119
|
-
def
|
120
|
-
self.class.
|
147
|
+
def copy_object(key, dest_bucket, dest_key)
|
148
|
+
self.class.copy_object @bucket_name, key, dest_bucket, dest_key
|
121
149
|
end
|
150
|
+
alias :copy :copy_object
|
122
151
|
|
123
|
-
def
|
124
|
-
self.class.
|
152
|
+
def get_object(key, header={}, &block)
|
153
|
+
self.class.get_object @bucket_name, key, header, &block
|
125
154
|
end
|
155
|
+
alias :get :get_object
|
126
156
|
|
127
|
-
def
|
128
|
-
self.class.
|
157
|
+
def head_object(key)
|
158
|
+
self.class.head_object @bucket_name, key
|
129
159
|
end
|
160
|
+
alias :head :head_object
|
130
161
|
|
131
|
-
def
|
132
|
-
self.class.
|
162
|
+
def delete_object(key)
|
163
|
+
self.class.delete_object @bucket_name, key
|
133
164
|
end
|
165
|
+
alias :delete :delete_object
|
134
166
|
|
135
167
|
def <=>(a)
|
136
168
|
bucket_name <=> a.bucket_name
|
data/lib/raws/s3/acl.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
class RAWS::S3::ACL
|
2
|
+
class Owner
|
3
|
+
attr_accessor :id, :name
|
4
|
+
|
5
|
+
alias :display_name :name
|
6
|
+
|
7
|
+
def initialize(owner)
|
8
|
+
@id, @name = owner['ID'], owner['DisplayName']
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_xml
|
12
|
+
'<Owner>' <<
|
13
|
+
"<ID>#{@id}</ID>" <<
|
14
|
+
"<DisplayName>#{@name}</DisplayName>" <<
|
15
|
+
'</Owner>'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Grant
|
20
|
+
attr_accessor :permission
|
21
|
+
|
22
|
+
def initialize(permission)
|
23
|
+
@permission = permission
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_xml
|
27
|
+
"<Permission>#{@permission}</Permission>"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ID < Grant
|
32
|
+
attr_accessor :id, :name
|
33
|
+
|
34
|
+
def initialize(id, permission, name=nil)
|
35
|
+
super(permission)
|
36
|
+
@id, @name = id, name
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_xml
|
40
|
+
'<Grant>' <<
|
41
|
+
'<Grantee' <<
|
42
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' <<
|
43
|
+
' xsi:type="CanonicalUser">' <<
|
44
|
+
"<ID>#{@id}</ID>" <<
|
45
|
+
(@name ? "<DisplayName>#{@name}</DisplayName>" : '') <<
|
46
|
+
'</Grantee>' <<
|
47
|
+
super <<
|
48
|
+
'</Grant>'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Email < Grant
|
53
|
+
attr_accessor :email
|
54
|
+
|
55
|
+
def initialize(email, permission)
|
56
|
+
super(permission)
|
57
|
+
@email = email
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_xml
|
61
|
+
'<Grant>' <<
|
62
|
+
'<Grantee' <<
|
63
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' <<
|
64
|
+
' xsi:type="AmazonCustomerByEmail">' <<
|
65
|
+
"<EmailAddress>#{@email}</EmailAddress>" <<
|
66
|
+
'</Grantee>' <<
|
67
|
+
super <<
|
68
|
+
'</Grant>'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Group < Grant
|
73
|
+
def to_xml
|
74
|
+
'<Grant>' <<
|
75
|
+
'<Grantee' <<
|
76
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' <<
|
77
|
+
' xsi:type="Group">' <<
|
78
|
+
"<URI>http://acs.amazonaws.com/groups/global/#{
|
79
|
+
self.class.name.split('::').last
|
80
|
+
}</URI>" <<
|
81
|
+
'</Grantee>' <<
|
82
|
+
super <<
|
83
|
+
'</Grant>'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class AuthenticatedUsers < Group; end
|
88
|
+
|
89
|
+
class AllUsers < Group; end
|
90
|
+
|
91
|
+
class Grants < Array
|
92
|
+
def initialize(grants)
|
93
|
+
super()
|
94
|
+
grants.each do |grant|
|
95
|
+
grantee, permission = grant['Grantee'], grant['Permission']
|
96
|
+
if id = grantee['ID']
|
97
|
+
push ID.new(id, permission, grantee['DisplayName'])
|
98
|
+
elsif email = grantee['EmailAddress']
|
99
|
+
push Email.new(email, permission)
|
100
|
+
else
|
101
|
+
case grantee['URI']
|
102
|
+
when 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers'
|
103
|
+
push AuthenticatedUsers.new(permission)
|
104
|
+
when 'http://acs.amazonaws.com/groups/global/AllUsers'
|
105
|
+
push AllUsers.new(permission)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_xml
|
112
|
+
'<AccessControlList>' <<
|
113
|
+
map do |grant|
|
114
|
+
grant.to_xml
|
115
|
+
end.join <<
|
116
|
+
'</AccessControlList>'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
attr_reader :bucket_name, :key, :owner, :grants
|
121
|
+
|
122
|
+
def initialize(bucket_name, key=nil)
|
123
|
+
@bucket_name, @key = bucket_name, key
|
124
|
+
reload
|
125
|
+
end
|
126
|
+
|
127
|
+
def save
|
128
|
+
RAWS::S3::Adapter.put_acl(@bucket_name, @key, to_xml)
|
129
|
+
end
|
130
|
+
|
131
|
+
def reload
|
132
|
+
doc = RAWS::S3::Adapter.get_acl(@bucket_name, @key).doc
|
133
|
+
acp = doc['AccessControlPolicy']
|
134
|
+
@owner = Owner.new(acp['Owner'])
|
135
|
+
@grants = Grants.new(acp['AccessControlList']['Grant'])
|
136
|
+
end
|
137
|
+
|
138
|
+
def to_xml
|
139
|
+
'<AccessControlPolicy>' <<
|
140
|
+
owner.to_xml <<
|
141
|
+
grants.to_xml <<
|
142
|
+
'</AccessControlPolicy>'
|
143
|
+
end
|
144
|
+
end
|