wf4ever-rosrs-client 0.1.1

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