wf4ever-rosrs-client 0.1.1

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.
@@ -0,0 +1,233 @@
1
+ module ROSRS
2
+
3
+ class ResearchObject
4
+
5
+ attr_reader :uri, :session
6
+
7
+ def initialize(rosrs_session, uri)
8
+ @session = rosrs_session
9
+ if URI(uri).relative?
10
+ uri = (rosrs_session.uri + URI(uri)).to_s
11
+ end
12
+ uri = uri + '/' unless uri.end_with?('/')
13
+ @uri = uri
14
+ @loaded = false
15
+ end
16
+
17
+ def self.create(session, name)
18
+ c,r,u,m = session.create_research_object(name)
19
+ self.new(session, u)
20
+ end
21
+
22
+ ##
23
+ # Has this RO's manifest been fetched and parsed?
24
+ def loaded?
25
+ @loaded
26
+ end
27
+
28
+ ##
29
+ # Fetch and parse the RO manifest
30
+ def load
31
+ manifest_uri, @manifest = @session.get_manifest(uri)
32
+ @folders = extract_folders
33
+ @resources = extract_resources
34
+ @annotations = extract_annotations
35
+ @loaded = true
36
+ end
37
+
38
+ def manifest
39
+ load unless loaded?
40
+ @manifest
41
+ end
42
+
43
+ ##
44
+ # Get Annotations in this RO for the given resource_uri.
45
+ # If resource_uri is nil, get the Annotations on the RO itself.
46
+ def annotations(resource_uri = nil)
47
+ load unless loaded?
48
+ if resource_uri.nil?
49
+ @annotations[@uri]
50
+ else
51
+ @annotations[resource_uri] || []
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Return the Resource object for the given resource_uri, if it exists.
57
+ # If resource_uri is nil, return all Resources in the RO.
58
+ def resources(resource_uri = nil)
59
+ load unless loaded?
60
+ if resource_uri.nil?
61
+ @resources.values
62
+ else
63
+ @resources[resource_uri]
64
+ end
65
+ end
66
+
67
+ ##
68
+ # Return the Folder object for the given resource_uri, if it exists.
69
+ # If resource_uri is nil, return all Folder in the RO.
70
+ def folders(resource_uri = nil)
71
+ load unless loaded?
72
+ if resource_uri.nil?
73
+ @folders.values
74
+ else
75
+ @folders[resource_uri]
76
+ end
77
+ end
78
+
79
+ ##
80
+ # Return the root folder of the RO.
81
+ def root_folder
82
+ load unless loaded?
83
+ @root_folder
84
+ end
85
+
86
+ ##
87
+ # Delete this RO from the repository
88
+ def delete
89
+ code = @session.delete_research_object(@uri)[0]
90
+ @loaded = false
91
+ code == 204
92
+ end
93
+
94
+ ##
95
+ # Create an annotation for a given resource_uri, using the supplied annotation body.
96
+ def create_annotation(resource_uri, annotation)
97
+ annotation = ROSRS::Annotation.create(self, resource_uri, annotation)
98
+ load unless loaded?
99
+ @annotations[resource_uri] ||= []
100
+ @annotations[resource_uri] << annotation
101
+ annotation
102
+ end
103
+
104
+ ##
105
+ # Create a folder in the research object.
106
+ def create_folder(name)
107
+ folder = ROSRS::Folder.create(self, name)
108
+ load unless loaded?
109
+ @folders[folder.uri] = folder
110
+ folder
111
+ end
112
+
113
+ ##
114
+ # Aggregate a resource
115
+ # If a body (and optional content type) is given, it will create an internal resource with that body, plus the proxy
116
+ # that points to it. If only the first argument is given, an external resource will be created.
117
+ def aggregate(uri, body = nil, content_type = 'text/plain')
118
+ resource = ROSRS::Resource.create(self, uri, body, content_type)
119
+ load unless loaded?
120
+ @resources[resource.uri] = resource
121
+ end
122
+
123
+ ##
124
+ # Remove the chosen resource from the RO
125
+ def remove(resource)
126
+ resource.delete
127
+ end
128
+
129
+ def remove_resource(resource)
130
+ @resources.delete(resource.uri)
131
+ @annotations.delete(resource.uri)
132
+ resource
133
+ end
134
+
135
+ def remove_folder(folder)
136
+ @folders.delete(folder.uri)
137
+ @annotations.delete(folder.uri)
138
+ folder
139
+ end
140
+
141
+ def remove_annotation(annotation)
142
+ @annotations[annotation.resource_uri].delete(annotation)
143
+ annotation
144
+ end
145
+
146
+ private
147
+
148
+ def extract_annotations
149
+ annotations = {}
150
+ queries = [RDF::RO.annotatesAggregatedResource, RDF::AO.annotatesResource].collect do |predicate|
151
+ RDF::Query.new do
152
+ pattern [:annotation_uri, RDF.type, RDF::RO.AggregatedAnnotation]
153
+ pattern [:annotation_uri, predicate, :resource_uri]
154
+ pattern [:annotation_uri, RDF::AO.body, :body_uri]
155
+ pattern [:annotation_uri, RDF::DC.creator, :created_by]
156
+ pattern [:annotation_uri, RDF::DC.created, :created_at]
157
+ end
158
+ end
159
+
160
+ queries.each do |query|
161
+ @manifest.query(query) do |result|
162
+ annotations[result.resource_uri.to_s] ||= []
163
+ annotations[result.resource_uri.to_s] << ROSRS::Annotation.new(self,
164
+ result.annotation_uri.to_s,
165
+ result.body_uri.to_s,
166
+ result.resource_uri.to_s,
167
+ :created_at => result.created_at.to_s,
168
+ :created_by => result.created_by.to_s)
169
+ end
170
+ end
171
+
172
+ annotations
173
+ end
174
+
175
+ def extract_folders
176
+ folders = {}
177
+
178
+ query = RDF::Query.new do
179
+ pattern [:research_object, RDF::ORE.aggregates, :folder]
180
+ pattern [:folder, RDF.type, RDF::RO.Folder]
181
+ pattern [:proxy_uri, RDF::ORE.proxyFor, :folder]
182
+ end
183
+
184
+ @manifest.query(query).each do |result|
185
+ folder_uri = result.folder.to_s
186
+ folders[folder_uri] = ROSRS::Folder.new(self, folder_uri, result.proxy_uri.to_s)
187
+ end
188
+
189
+ @root_folder = folders[extract_root_folder]
190
+
191
+ folders
192
+ end
193
+
194
+ def extract_root_folder
195
+ query = RDF::Query.new do
196
+ pattern [:research_object, RDF::ORE.aggregates, :folder]
197
+ pattern [:research_object, RDF::RO.rootFolder, :folder]
198
+ pattern [:folder, RDF.type, RDF::RO.Folder]
199
+ pattern [:proxy_uri, RDF::ORE.proxyFor, :folder]
200
+ end
201
+
202
+ result = @manifest.query(query).first
203
+ if result
204
+ result.folder.to_s
205
+ else
206
+ nil
207
+ end
208
+ end
209
+
210
+ def extract_resources
211
+ resources = {}
212
+ folder_resources = @folders.values.map {|f| f.uri}
213
+
214
+ query = RDF::Query.new do
215
+ pattern [:research_object, RDF::ORE.aggregates, :resource]
216
+ pattern [:resource, RDF.type, RDF::RO.Resource]
217
+ #pattern [:resource, RDF::RO.name, :name]
218
+ pattern [:proxy_uri, RDF::ORE.proxyFor, :resource]
219
+ pattern [:resource, RDF::DC.creator, :created_by]
220
+ pattern [:resource, RDF::DC.created, :created_at]
221
+ end
222
+
223
+ @manifest.query(query).each do |result|
224
+ unless folder_resources.include?(result.resource.to_s) # We only want non-folder resources
225
+ resources[result.resource.to_s] = ROSRS::Resource.new(self, result.resource.to_s, result.proxy_uri.to_s)
226
+ end
227
+ end
228
+
229
+ resources
230
+ end
231
+
232
+ end
233
+ end
@@ -0,0 +1,59 @@
1
+ module ROSRS
2
+
3
+ class Resource
4
+ attr_reader :research_object, :uri, :proxy_uri, :created_at, :created_by
5
+
6
+ def initialize(research_object, uri, proxy_uri = nil, options = {})
7
+ @research_object = research_object
8
+ @uri = uri
9
+ @proxy_uri = proxy_uri
10
+ @session = @research_object.session
11
+ @created_at = options[:created_at]
12
+ @created_by = options[:created_by]
13
+ end
14
+
15
+ ##
16
+ # Get all the annotations on this resource
17
+ def annotations
18
+ @research_object.annotations(@uri)
19
+ end
20
+
21
+ ##
22
+ # Add an annotation to this resource
23
+ def annotate(annotation)
24
+ @research_object.create_annotation(@uri, annotation)
25
+ end
26
+
27
+ ##
28
+ # Removes this resource from the Research Object.
29
+ def delete
30
+ code = @session.delete_resource(@proxy_uri)[0]
31
+ @loaded = false
32
+ @research_object.remove_resource(self)
33
+ code == 204
34
+ end
35
+
36
+ def internal?
37
+ @uri.include?(@research_object.uri)
38
+ end
39
+
40
+ def external?
41
+ !internal?
42
+ end
43
+
44
+ def self.create(research_object, uri, body = nil, content_type = 'text/plain')
45
+ if body.nil?
46
+ code, reason, proxy_uri, resource_uri = research_object.session.aggregate_external_resource(research_object.uri, uri)
47
+ self.new(research_object, resource_uri, proxy_uri)
48
+ else
49
+ code, reason, proxy_uri, resource_uri = research_object.session.aggregate_internal_resource(research_object.uri,
50
+ uri,
51
+ :body => body,
52
+ :ctype => content_type)
53
+ self.new(research_object, resource_uri, proxy_uri)
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end