triannon 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -16
- data/Rakefile +15 -18
- data/app/controllers/concerns/rdf_response_formats.rb +16 -14
- data/app/controllers/triannon/annotations_controller.rb +6 -6
- data/app/models/triannon/annotation.rb +5 -5
- data/app/models/triannon/annotation_ldp.rb +17 -16
- data/app/services/triannon/ldp_loader.rb +14 -4
- data/app/services/triannon/ldp_to_oa_mapper.rb +68 -59
- data/app/services/triannon/ldp_writer.rb +180 -59
- data/app/services/triannon/solr_searcher.rb +8 -8
- data/app/services/triannon/solr_writer.rb +12 -12
- data/config/jetty/etc/fedora-override-web.xml +67 -0
- data/config/routes.rb +2 -2
- data/config/triannon.yml +29 -6
- data/lib/generators/triannon/install_generator.rb +23 -3
- data/lib/rdf/triannon_vocab.rb +2 -2
- data/lib/tasks/triannon_tasks.rake +19 -5
- data/lib/triannon.rb +13 -20
- data/lib/triannon/iiif_anno_list.rb +4 -4
- data/lib/triannon/oa_graph_helper.rb +51 -0
- data/lib/triannon/version.rb +1 -1
- metadata +35 -39
- data/app/services/triannon/root_annotation_creator.rb +0 -36
- data/lib/triannon/graph.rb +0 -173
- data/lib/triannon/jsonld_context.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3fb1a2a5664cb23544e3809666e40fbeac50bf7
|
4
|
+
data.tar.gz: 530b85774e11c73ad4ace71448e200babf0e2887
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d053edac7a6da6482140dc9c9eb4fda5ea467f772b1cc94a5fc05f0b866e2b2575d81278db451d6101b4856fa9ed4974b9677df28f26801f7483f7be375cba95
|
7
|
+
data.tar.gz: 88807450e57ec3e5a801b8be3480dee4c4b7f5d2b46401e0abb0cbfdcbcdfa21306933d1d6b0aa521d251602f86df55bb6545e3ed8a9f81bc76323dd2e20d90d
|
data/README.md
CHANGED
@@ -24,21 +24,24 @@ $ rails g triannon:install
|
|
24
24
|
|
25
25
|
Edit the `config/triannon.yml` file:
|
26
26
|
|
27
|
-
* `
|
27
|
+
* `ldp:` Properties of LDP server
|
28
|
+
* `url:` the baseurl of LDP server
|
29
|
+
* `uber_container:` name of an LDP Basic Container holding specific anno containers
|
30
|
+
* `anno_containers:` (Future: the names of LDP Basic Containers holding individual annos)
|
28
31
|
* `solr_url:` Points to the baseurl of Solr instance configured for Triannon
|
29
32
|
* `triannon_base_url:` Used as the base url for all annotations hosted by your Triannon server. Identifiers from the LDP server will be appended to this base-url. Generally something like "https://your-triannon-rails-box/annotations", as "/annotations" is added to the path by the Triannon gem
|
30
33
|
|
31
|
-
Generate the root annotations container on your LDP server:
|
34
|
+
Generate the uber root annotations container on your LDP server:
|
32
35
|
|
33
36
|
```console
|
34
|
-
$ rake triannon:
|
37
|
+
$ rake triannon:create_uber_root_container
|
35
38
|
```
|
36
39
|
|
37
40
|
Set up caching for jsonld context documents:
|
38
41
|
|
39
42
|
* by using Rack::Cache for RestClient:
|
40
43
|
|
41
|
-
|
44
|
+
* add to Gemfile:
|
42
45
|
|
43
46
|
```ruby
|
44
47
|
gem 'rest-client'
|
@@ -46,8 +49,9 @@ gem 'rack-cache'
|
|
46
49
|
gem 'rest-client-components'
|
47
50
|
```
|
48
51
|
|
49
|
-
|
50
|
-
|
52
|
+
* bundle install
|
53
|
+
|
54
|
+
* create a config/initializers/rest_client.rb
|
51
55
|
|
52
56
|
```ruby
|
53
57
|
require 'restclient/components'
|
@@ -143,12 +147,13 @@ There is a bundled rake task for running triannon in a test rails application, b
|
|
143
147
|
```console
|
144
148
|
$ rake jetty:download
|
145
149
|
$ rake jetty:unzip
|
150
|
+
$ rake jetty:environment
|
151
|
+
$ rake triannon:jetty_setup
|
146
152
|
```
|
147
153
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
```
|
154
|
+
triannon:jetty_setup task does the following:
|
155
|
+
* turns off basic authorization in Fedora4
|
156
|
+
* sets up a Triannon flavored Solr
|
152
157
|
|
153
158
|
### Set up the testing Rails app that uses triannon gem
|
154
159
|
```console
|
@@ -171,14 +176,14 @@ well, try:
|
|
171
176
|
|
172
177
|
```console
|
173
178
|
$ rake jetty:stop
|
174
|
-
$ rake triannon:
|
179
|
+
$ rake triannon:jetty_setup
|
175
180
|
$ rake jetty:start
|
176
181
|
```
|
177
182
|
|
178
183
|
and then check again.
|
179
184
|
|
180
185
|
|
181
|
-
#### Check if
|
186
|
+
#### Check if Fedora4 is up
|
182
187
|
Go to http://localhost:8983/fedora/rest/
|
183
188
|
|
184
189
|
If all is well, you will not get an error message. If all is not well, try:
|
@@ -186,23 +191,23 @@ If all is well, you will not get an error message. If all is not well, try:
|
|
186
191
|
```console
|
187
192
|
$ rake jetty:stop
|
188
193
|
$ rake jetty:clean
|
189
|
-
$ rake triannon:
|
194
|
+
$ rake triannon:jetty_startup
|
190
195
|
$ rake jetty:start
|
191
196
|
```
|
192
197
|
|
193
198
|
and check for Solr and Fedora again.
|
194
199
|
|
195
|
-
#### Generate root annotations container
|
200
|
+
#### Generate uber root annotations container
|
196
201
|
After you ensure that Fedora4 is running:
|
197
202
|
|
198
203
|
```console
|
199
204
|
$ cd spec/internal
|
200
|
-
$ rake triannon:
|
205
|
+
$ rake triannon:create_uber_root_container
|
201
206
|
$ cd ../..
|
202
207
|
```
|
203
208
|
|
204
209
|
#### Configure spec/internal/config/triannon.yml as specified above
|
205
|
-
You
|
210
|
+
You probably won't need to change this file.
|
206
211
|
```console
|
207
212
|
$ vi spec/internal/config/triannon.yml
|
208
213
|
```
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ rescue LoadError
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
5
|
end
|
6
6
|
|
7
|
-
ZIP_URL = "https://github.com/
|
7
|
+
ZIP_URL = "https://github.com/projecthydra/hydra-jetty/archive/v8.3.1.zip"
|
8
8
|
|
9
9
|
require 'active_support/benchmarkable'
|
10
10
|
require 'jettywrapper'
|
@@ -16,6 +16,17 @@ task :ci => 'engine_cart:generate' do
|
|
16
16
|
Rake::Task['spec'].invoke
|
17
17
|
end
|
18
18
|
|
19
|
+
load 'rails/tasks/statistics.rake'
|
20
|
+
|
21
|
+
require 'rspec/core/rake_task'
|
22
|
+
|
23
|
+
RSpec::Core::RakeTask.new(:spec)
|
24
|
+
|
25
|
+
task :default => :ci
|
26
|
+
|
27
|
+
|
28
|
+
Dir.glob('lib/tasks/*.rake').each { |r| load r}
|
29
|
+
|
19
30
|
namespace :triannon do
|
20
31
|
desc 'run test rails app w triannon and jetty'
|
21
32
|
task :server_jetty do
|
@@ -55,22 +66,7 @@ namespace :triannon do
|
|
55
66
|
desc 'run test rails console w triannon but no jetty'
|
56
67
|
task :console => :console_no_jetty
|
57
68
|
|
58
|
-
|
59
|
-
desc "set up triannon solr in test jetty"
|
60
|
-
task :solr_jetty_setup do
|
61
|
-
`cp -r config/solr/triannon-core jetty/solr`
|
62
|
-
`cp config/solr/solr.xml jetty/solr`
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
load 'rails/tasks/statistics.rake'
|
68
|
-
|
69
|
-
require 'rspec/core/rake_task'
|
70
|
-
|
71
|
-
RSpec::Core::RakeTask.new(:spec)
|
72
|
-
|
73
|
-
task :default => :ci
|
69
|
+
end # namespace triannon
|
74
70
|
|
75
71
|
|
76
72
|
desc "Generate RDoc with YARD"
|
@@ -98,7 +94,8 @@ namespace :doc do
|
|
98
94
|
|
99
95
|
desc "Remove generated documenation"
|
100
96
|
task :clean do
|
101
|
-
rm_r 'rdoc' if File.
|
97
|
+
rm_r 'rdoc' if File.exist?('rdoc')
|
102
98
|
end
|
103
99
|
end
|
100
|
+
|
104
101
|
Bundler::GemHelper.install_tasks
|
@@ -24,9 +24,11 @@ module RdfResponseFormats
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
# parse the Accept HTTP header for the value of profile if it is a request for
|
28
|
-
#
|
29
|
-
#
|
27
|
+
# parse the Accept HTTP header for the value of profile if it is a request for
|
28
|
+
# jsonld or json.
|
29
|
+
# e.g. Accept: application/ld+json; profile="http://www.w3.org/ns/oa-context-20130208.json"
|
30
|
+
# @return [String] url for jsonld @context or nil if missing or
|
31
|
+
# non-jsonld/json format
|
30
32
|
def context_url_from_accept
|
31
33
|
if request.format == "jsonld" || request.format == "json"
|
32
34
|
accept_str = request.accept
|
@@ -35,9 +37,9 @@ module RdfResponseFormats
|
|
35
37
|
context_url = context_url[1, context_url.size] if context_url.start_with?('"')
|
36
38
|
context_url = context_url[0, context_url.size-1] if context_url.end_with?('"')
|
37
39
|
case context_url
|
38
|
-
when
|
39
|
-
|
40
|
-
|
40
|
+
when OA::Graph::OA_DATED_CONTEXT_URL,
|
41
|
+
OA::Graph::OA_CONTEXT_URL,
|
42
|
+
OA::Graph::IIIF_CONTEXT_URL
|
41
43
|
context_url
|
42
44
|
else
|
43
45
|
nil
|
@@ -46,19 +48,21 @@ module RdfResponseFormats
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
# parse the Accept HTTP Link for the value of rel if it is a request for
|
51
|
+
# parse the Accept HTTP Link for the value of rel if it is a request for
|
52
|
+
# jsonld or json
|
50
53
|
# e.g. Link: http://www.w3.org/ns/oa.json; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"
|
51
54
|
# note that the "type" part is optional
|
52
|
-
# @return [String] url for jsonld @context or nil if missing or
|
55
|
+
# @return [String] url for jsonld @context or nil if missing or
|
56
|
+
# non-jsonld/json format
|
53
57
|
def context_url_from_link
|
54
58
|
if request.format == "jsonld" || request.format == "json"
|
55
59
|
link_str = request.headers["Link"]
|
56
60
|
if link_str && link_str.split("; rel=") && link_str.split("; rel=").first
|
57
61
|
context_url = link_str.split("; rel=").first.strip
|
58
62
|
case context_url
|
59
|
-
when
|
60
|
-
|
61
|
-
|
63
|
+
when OA::Graph::OA_DATED_CONTEXT_URL,
|
64
|
+
OA::Graph::OA_CONTEXT_URL,
|
65
|
+
OA::Graph::IIIF_CONTEXT_URL
|
62
66
|
context_url
|
63
67
|
else
|
64
68
|
nil
|
@@ -67,6 +71,4 @@ module RdfResponseFormats
|
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
end
|
74
|
+
end
|
@@ -17,11 +17,11 @@ module Triannon
|
|
17
17
|
|
18
18
|
# GET /annotations/1
|
19
19
|
def show
|
20
|
-
# TODO: json.set! "@context",
|
20
|
+
# TODO: json.set! "@context", OA::Graph::OA_DATED_CONTEXT_URL - would this work?
|
21
21
|
respond_to do |format|
|
22
22
|
format.jsonld {
|
23
23
|
context_url = context_url_from_accept ? context_url_from_accept : context_url_from_link
|
24
|
-
if context_url && context_url ==
|
24
|
+
if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
|
25
25
|
render_jsonld_per_context("iiif", "application/ld+json")
|
26
26
|
else
|
27
27
|
render_jsonld_per_context(params[:jsonld_context], "application/ld+json")
|
@@ -36,7 +36,7 @@ module Triannon
|
|
36
36
|
format.json {
|
37
37
|
accept_return_type = mime_type_from_accept(["application/json", "text/x-json", "application/jsonrequest"])
|
38
38
|
context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
|
39
|
-
if context_url && context_url ==
|
39
|
+
if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
|
40
40
|
render_jsonld_per_context("iiif", accept_return_type)
|
41
41
|
else
|
42
42
|
render_jsonld_per_context(params[:jsonld_context], accept_return_type)
|
@@ -82,7 +82,7 @@ module Triannon
|
|
82
82
|
respond_to do |format|
|
83
83
|
format.jsonld {
|
84
84
|
context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
|
85
|
-
if context_url && context_url ==
|
85
|
+
if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
|
86
86
|
render :json => @annotation.jsonld_iiif, status: 201, content_type: "application/ld+json"
|
87
87
|
else
|
88
88
|
render :json => @annotation.jsonld_oa, status: 201, content_type: "application/ld+json"
|
@@ -97,7 +97,7 @@ module Triannon
|
|
97
97
|
format.json {
|
98
98
|
accept_return_type = mime_type_from_accept(["application/json", "text/x-json", "application/jsonrequest"])
|
99
99
|
context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
|
100
|
-
if context_url && context_url ==
|
100
|
+
if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
|
101
101
|
render :json => @annotation.jsonld_iiif, status: 201, content_type: accept_return_type if accept_return_type
|
102
102
|
else
|
103
103
|
render :json => @annotation.jsonld_oa, status: 201, content_type: accept_return_type if accept_return_type
|
@@ -155,7 +155,7 @@ private
|
|
155
155
|
# render json_ld respecting requested context
|
156
156
|
# @param [String] req_context set to "iiif" or "oa". Default is oa
|
157
157
|
# @param [String] mime_type the mime type to be set in the Content-Type header of the HTTP response
|
158
|
-
def render_jsonld_per_context
|
158
|
+
def render_jsonld_per_context(req_context, mime_type = nil)
|
159
159
|
case req_context
|
160
160
|
when "iiif", "IIIF"
|
161
161
|
if mime_type
|
@@ -60,22 +60,22 @@ module Triannon
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def persisted?
|
63
|
-
|
63
|
+
id.present?
|
64
64
|
end
|
65
65
|
|
66
66
|
def graph
|
67
67
|
@graph ||= begin
|
68
68
|
g = data_to_graph
|
69
|
-
|
69
|
+
OA::Graph.new g if g.kind_of? RDF::Graph
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
# @param g either a
|
73
|
+
# @param g either a OA::Graph or RDF::Graph object
|
74
74
|
def graph= g
|
75
|
-
if g.is_a?
|
75
|
+
if g.is_a? OA::Graph
|
76
76
|
@graph = g
|
77
77
|
elsif g.kind_of? RDF::Graph
|
78
|
-
@graph =
|
78
|
+
@graph = OA::Graph.new g
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Triannon
|
2
|
-
# an LDP aware model of an Annotation -- basically, a shim between the OA
|
3
|
-
# and the LDP storage.
|
2
|
+
# an LDP aware model of an Annotation -- basically, a shim between the OA
|
3
|
+
# notion of an annotation and the LDP storage.
|
4
4
|
class AnnotationLdp
|
5
5
|
|
6
6
|
# RDF::Graph object with all triples, including back end (e.g. LDP, Fedora)
|
@@ -10,43 +10,44 @@ module Triannon
|
|
10
10
|
|
11
11
|
# RDF::Graph without any back end (e.g. LDP, Fedora) triples
|
12
12
|
def stripped_graph
|
13
|
-
|
13
|
+
OA::Graph.remove_ldp_triples(OA::Graph.remove_fedora_triples(graph))
|
14
14
|
end
|
15
15
|
|
16
16
|
def base_uri
|
17
|
-
res = graph.query
|
17
|
+
res = graph.query OA::Graph.anno_query
|
18
18
|
res.first.s
|
19
19
|
end
|
20
20
|
|
21
21
|
# @return [Array<String>] the uris of each LDP body resource
|
22
22
|
def body_uris
|
23
|
-
q =
|
24
|
-
q << [:s, RDF::
|
23
|
+
q = OA::Graph.anno_query.dup
|
24
|
+
q << [:s, RDF::Vocab::OA.hasBody, :body_uri]
|
25
25
|
solns = graph.query q
|
26
26
|
result = []
|
27
|
-
solns.distinct.each { |soln|
|
28
|
-
result << soln.body_uri
|
27
|
+
solns.distinct.each { |soln|
|
28
|
+
result << soln.body_uri
|
29
29
|
}
|
30
30
|
result
|
31
31
|
end
|
32
32
|
|
33
33
|
# @return [Array<String>] the uris of each LDP target resource
|
34
34
|
def target_uris
|
35
|
-
q =
|
36
|
-
q << [:s, RDF::
|
35
|
+
q = OA::Graph.anno_query.dup
|
36
|
+
q << [:s, RDF::Vocab::OA.hasTarget, :target_uri]
|
37
37
|
solns = graph.query q
|
38
38
|
result = []
|
39
|
-
solns.distinct.each { |soln|
|
40
|
-
result << soln.target_uri
|
39
|
+
solns.distinct.each { |soln|
|
40
|
+
result << soln.target_uri
|
41
41
|
}
|
42
42
|
result
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
# add the passed statements to #graph
|
46
|
-
# @param [Array<RDF::Statement>] statements an array of RDF statements to be
|
47
|
-
|
46
|
+
# @param [Array<RDF::Statement>] statements an array of RDF statements to be
|
47
|
+
# loaded into the graph
|
48
|
+
def load_statements_into_graph(statements)
|
48
49
|
graph.insert(statements) if statements && statements.size > 0
|
49
50
|
end
|
50
51
|
|
51
52
|
end
|
52
|
-
end
|
53
|
+
end
|
@@ -27,8 +27,17 @@ module Triannon
|
|
27
27
|
# @param [String] id the unique id of the annotation. Can include base_uri prefix or omit it.
|
28
28
|
def initialize id = nil
|
29
29
|
@id = id
|
30
|
-
|
30
|
+
base_url = Triannon.config[:ldp]['url']
|
31
|
+
base_url.chop! if base_url.end_with?('/')
|
32
|
+
container_path = Triannon.config[:ldp]['uber_container']
|
33
|
+
if container_path
|
34
|
+
container_path.strip!
|
35
|
+
container_path = container_path[1..-1] if container_path.start_with?('/')
|
36
|
+
container_path.chop! if container_path.end_with?('/')
|
37
|
+
end
|
38
|
+
@base_uri = "#{base_url}/#{container_path}"
|
31
39
|
@ldp_annotation = Triannon::AnnotationLdp.new
|
40
|
+
|
32
41
|
end
|
33
42
|
|
34
43
|
# load annotation container object into @ldp_annotation's (our Triannon::AnnotationLdp object) graph
|
@@ -61,8 +70,9 @@ module Triannon
|
|
61
70
|
g = RDF::Graph.new
|
62
71
|
g.from_ttl root_ttl
|
63
72
|
root_uri = RDF::URI.new @base_uri
|
64
|
-
results = g.query [root_uri, RDF::LDP.contains, nil]
|
73
|
+
results = g.query [root_uri, RDF::Vocab::LDP.contains, nil]
|
65
74
|
results.each do |stmt|
|
75
|
+
# FIXME: can't be last with pair trees in fedora urls - leave broke as this method is deprecated
|
66
76
|
id = stmt.object.to_s.split('/').last
|
67
77
|
objs << Triannon::Annotation.new(:id => id)
|
68
78
|
end
|
@@ -86,7 +96,7 @@ module Triannon
|
|
86
96
|
req.headers['Accept'] = 'application/x-turtle'
|
87
97
|
end
|
88
98
|
if resp.status.between?(400, 600)
|
89
|
-
|
99
|
+
fail Triannon::LDPStorageError.new("error getting #{sub_path} from LDP", resp.status, resp.body)
|
90
100
|
else
|
91
101
|
resp.body
|
92
102
|
end
|
@@ -99,7 +109,7 @@ module Triannon
|
|
99
109
|
def statements_from_ttl_minus_fedora ttl
|
100
110
|
# RDF::Turtle::Reader.new(ttl).statements.to_a
|
101
111
|
g = RDF::Graph.new.from_ttl(ttl) if ttl
|
102
|
-
|
112
|
+
OA::Graph.remove_fedora_triples(g).statements if g
|
103
113
|
end
|
104
114
|
|
105
115
|
def conn
|
@@ -16,25 +16,34 @@ module Triannon
|
|
16
16
|
@ldp_anno = ldp_anno
|
17
17
|
@ldp_anno_graph = ldp_anno.stripped_graph
|
18
18
|
g = RDF::Graph.new
|
19
|
-
@oa_graph =
|
19
|
+
@oa_graph = OA::Graph.new g
|
20
20
|
end
|
21
21
|
|
22
22
|
def extract_base
|
23
|
-
root_subject_solns = @ldp_anno_graph.query
|
23
|
+
root_subject_solns = @ldp_anno_graph.query OA::Graph.anno_query
|
24
24
|
if root_subject_solns.count == 1
|
25
|
-
|
25
|
+
stored_url = Triannon.config[:ldp]['url'].strip
|
26
|
+
stored_url.chop! if stored_url.end_with?('/')
|
27
|
+
container_path = Triannon.config[:ldp]['uber_container']
|
28
|
+
if container_path
|
29
|
+
container_path.strip!
|
30
|
+
container_path = container_path[1..-1] if container_path.start_with?('/')
|
31
|
+
container_path.chop! if container_path.end_with?('/')
|
32
|
+
stored_url = "#{stored_url}/#{container_path}"
|
33
|
+
end
|
34
|
+
@id = root_subject_solns[0].s.to_s.split("#{stored_url}/").last
|
26
35
|
base_url = Triannon.config[:triannon_base_url]
|
27
36
|
base_url.strip!
|
28
37
|
base_url.chop! if base_url[-1] == '/'
|
29
38
|
@root_uri = RDF::URI.new(base_url + "/#{@id}")
|
30
39
|
end
|
31
|
-
|
40
|
+
|
32
41
|
@ldp_anno_graph.each_statement do |stmnt|
|
33
|
-
if stmnt.predicate == RDF.type && stmnt.object == RDF::
|
34
|
-
@oa_graph << [@root_uri, RDF.type, RDF::
|
35
|
-
elsif stmnt.predicate == RDF::
|
42
|
+
if stmnt.predicate == RDF.type && stmnt.object == RDF::Vocab::OA.Annotation
|
43
|
+
@oa_graph << [@root_uri, RDF.type, RDF::Vocab::OA.Annotation]
|
44
|
+
elsif stmnt.predicate == RDF::Vocab::OA.motivatedBy
|
36
45
|
@oa_graph << [@root_uri, stmnt.predicate, stmnt.object]
|
37
|
-
elsif stmnt.predicate == RDF::
|
46
|
+
elsif stmnt.predicate == RDF::Vocab::OA.annotatedAt
|
38
47
|
@oa_graph << [@root_uri, stmnt.predicate, stmnt.object]
|
39
48
|
end
|
40
49
|
end
|
@@ -42,28 +51,28 @@ module Triannon
|
|
42
51
|
|
43
52
|
def extract_bodies
|
44
53
|
@ldp_anno.body_uris.each { |body_uri|
|
45
|
-
if !map_external_ref(body_uri, RDF::
|
46
|
-
!map_content_as_text(body_uri, RDF::
|
47
|
-
!map_specific_resource(body_uri, RDF::
|
48
|
-
map_choice(body_uri, RDF::
|
54
|
+
if !map_external_ref(body_uri, RDF::Vocab::OA.hasBody) &&
|
55
|
+
!map_content_as_text(body_uri, RDF::Vocab::OA.hasBody) &&
|
56
|
+
!map_specific_resource(body_uri, RDF::Vocab::OA.hasBody)
|
57
|
+
map_choice(body_uri, RDF::Vocab::OA.hasBody)
|
49
58
|
end
|
50
59
|
}
|
51
60
|
end
|
52
61
|
|
53
62
|
def extract_targets
|
54
|
-
@ldp_anno.target_uris.each { |target_uri|
|
55
|
-
if !map_external_ref(target_uri, RDF::
|
56
|
-
!map_specific_resource(target_uri, RDF::
|
57
|
-
map_choice(target_uri, RDF::
|
63
|
+
@ldp_anno.target_uris.each { |target_uri|
|
64
|
+
if !map_external_ref(target_uri, RDF::Vocab::OA.hasTarget) &&
|
65
|
+
!map_specific_resource(target_uri, RDF::Vocab::OA.hasTarget)
|
66
|
+
map_choice(target_uri, RDF::Vocab::OA.hasTarget)
|
58
67
|
end
|
59
68
|
}
|
60
69
|
end
|
61
|
-
|
70
|
+
|
62
71
|
# if uri_obj is the subject of a Triannon.externalReference then add appropriate
|
63
72
|
# statements to @oa_graph and return true
|
64
73
|
# @param [RDF::URI] uri_obj the object that may have RDF::Triannon.externalReference
|
65
74
|
# @param [RDF::URI] predicate the predicate for [subject_obj, predicate, (ext_url)] statement
|
66
|
-
# to be added to @oa_graph, e.g. RDF::
|
75
|
+
# to be added to @oa_graph, e.g. RDF::Vocab::OA.hasTarget
|
67
76
|
# @param [RDF::URI] subject_obj the subject object to get the predicate statement; defaults to @root_uri
|
68
77
|
# @return [Boolean] true if it adds statements to @oa_graph, false otherwise
|
69
78
|
def map_external_ref uri_obj, predicate, subject_obj = @root_uri
|
@@ -71,8 +80,8 @@ module Triannon
|
|
71
80
|
if solns.count > 0
|
72
81
|
external_uri = solns.first.object
|
73
82
|
@oa_graph << [subject_obj, predicate, external_uri]
|
74
|
-
|
75
|
-
|
83
|
+
|
84
|
+
OA::Graph.subject_statements(uri_obj, @ldp_anno_graph).each { |stmt|
|
76
85
|
if stmt.subject == uri_obj && stmt.predicate != RDF::Triannon.externalReference
|
77
86
|
@oa_graph << [external_uri, stmt.predicate, stmt.object]
|
78
87
|
else
|
@@ -84,21 +93,21 @@ module Triannon
|
|
84
93
|
false
|
85
94
|
end
|
86
95
|
end
|
87
|
-
|
88
|
-
# if uri_obj has a type of RDF::
|
96
|
+
|
97
|
+
# if uri_obj has a type of RDF::Vocab::CNT.ContentAsText, then this is a skolemized blank node;
|
89
98
|
# add appropriate statements to @oa_graph to represent the blank node and its contents and return true
|
90
|
-
# @param [RDF::URI] uri_obj the object that may type RDF::
|
99
|
+
# @param [RDF::URI] uri_obj the object that may type RDF::Vocab::CNT.ContentAsText
|
91
100
|
# @param [RDF::URI] predicate the predicate for [subject_obj, predicate, (ext_url)] statement
|
92
|
-
# to be added to @oa_graph, e.g. RDF::
|
101
|
+
# to be added to @oa_graph, e.g. RDF::Vocab::OA.hasTarget
|
93
102
|
# @param [RDF::URI] subject_obj the subject object to get the predicate statement; defaults to @root_uri
|
94
103
|
# @return [Boolean] true if it adds statements to @oa_graph, false otherwise
|
95
104
|
def map_content_as_text uri_obj, predicate, subject_obj = @root_uri
|
96
|
-
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::
|
105
|
+
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::Vocab::CNT.ContentAsText]
|
97
106
|
if solns.count > 0
|
98
107
|
blank_node = RDF::Node.new
|
99
108
|
@oa_graph << [subject_obj, predicate, blank_node]
|
100
|
-
|
101
|
-
|
109
|
+
|
110
|
+
OA::Graph.subject_statements(uri_obj, @ldp_anno_graph).each { |stmt|
|
102
111
|
if stmt.subject == uri_obj
|
103
112
|
@oa_graph << [blank_node, stmt.predicate, stmt.object]
|
104
113
|
else
|
@@ -111,45 +120,45 @@ module Triannon
|
|
111
120
|
false
|
112
121
|
end
|
113
122
|
end
|
114
|
-
|
115
|
-
# if uri_obj has a type of RDF::
|
123
|
+
|
124
|
+
# if uri_obj has a type of RDF::Vocab::OA.SpecificResource, then this is a skolemized blank node;
|
116
125
|
# add appropriate statements to @oa_graph to represent the blank node and its contents and return true
|
117
|
-
# @param [RDF::URI] uri_obj the object that may have type RDF::
|
126
|
+
# @param [RDF::URI] uri_obj the object that may have type RDF::Vocab::OA.SpecificResource
|
118
127
|
# @param [RDF::URI] predicate the predicate for [@root_uri, predicate, (sel_res)] statement
|
119
|
-
# to be added to @oa_graph, e.g. RDF::
|
128
|
+
# to be added to @oa_graph, e.g. RDF::Vocab::OA.hasTarget
|
120
129
|
# @return [Boolean] true if it adds statements to @oa_graph, false otherwise
|
121
130
|
def map_specific_resource uri_obj, predicate
|
122
|
-
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::
|
131
|
+
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::Vocab::OA.SpecificResource]
|
123
132
|
if solns.count > 0
|
124
133
|
blank_node = RDF::Node.new
|
125
134
|
@oa_graph << [@root_uri, predicate, blank_node]
|
126
|
-
|
135
|
+
|
127
136
|
source_obj = nil
|
128
137
|
selector_obj = nil
|
129
138
|
selector_blank_node = nil
|
130
|
-
specific_res_stmts =
|
139
|
+
specific_res_stmts = OA::Graph.subject_statements(uri_obj, @ldp_anno_graph)
|
131
140
|
specific_res_stmts.each { |stmt|
|
132
|
-
if stmt.predicate == RDF::
|
141
|
+
if stmt.predicate == RDF::Vocab::OA.hasSource
|
133
142
|
# expecting a hash URI
|
134
143
|
source_obj = stmt.object
|
135
|
-
if source_obj.to_s.match("#{uri_obj
|
136
|
-
source_has_ext_uri = map_external_ref source_obj, RDF::
|
144
|
+
if source_obj.to_s.match("#{uri_obj}#source")
|
145
|
+
source_has_ext_uri = map_external_ref source_obj, RDF::Vocab::OA.hasSource, blank_node
|
137
146
|
end
|
138
|
-
elsif stmt.predicate == RDF::
|
147
|
+
elsif stmt.predicate == RDF::Vocab::OA.hasSelector
|
139
148
|
# this becomes a blank node. Per http://www.openannotation.org/spec/core/specific.html#Selectors
|
140
149
|
# "Typically if all of the information needed to resolve the Selector (or other Specifier)
|
141
|
-
# is present within the graph, such as is the case for the
|
142
|
-
# FragmentSelector, TextQuoteSelector, TextPositionSelector and DataPositionSelector classes,
|
150
|
+
# is present within the graph, such as is the case for the
|
151
|
+
# FragmentSelector, TextQuoteSelector, TextPositionSelector and DataPositionSelector classes,
|
143
152
|
# then there is no need to have a resolvable resource that provides the same information."
|
144
153
|
selector_obj = stmt.object
|
145
154
|
selector_blank_node = RDF::Node.new
|
146
|
-
@oa_graph << [blank_node, RDF::
|
155
|
+
@oa_graph << [blank_node, RDF::Vocab::OA.hasSelector, selector_blank_node]
|
147
156
|
end
|
148
157
|
}
|
149
|
-
|
150
|
-
# We can't know we'll hit hasSource and hasSelector statements in graph first,
|
158
|
+
|
159
|
+
# We can't know we'll hit hasSource and hasSelector statements in graph first,
|
151
160
|
# so we must do another pass through the statements to get that information
|
152
|
-
specific_res_stmts.each { |stmt|
|
161
|
+
specific_res_stmts.each { |stmt|
|
153
162
|
if stmt.subject == uri_obj && stmt.object != source_obj && stmt.object != selector_obj
|
154
163
|
@oa_graph << [blank_node, stmt.predicate, stmt.object]
|
155
164
|
elsif stmt.subject != source_obj
|
@@ -165,40 +174,40 @@ module Triannon
|
|
165
174
|
end
|
166
175
|
end
|
167
176
|
|
168
|
-
# if uri_obj has a type of RDF::
|
177
|
+
# if uri_obj has a type of RDF::Vocab::OA.Choice, then this is a skolemized blank node;
|
169
178
|
# add appropriate statements to @oa_graph to represent the blank node and its contents and return true
|
170
|
-
# @param [RDF::URI] uri_obj the object that may have type RDF::
|
179
|
+
# @param [RDF::URI] uri_obj the object that may have type RDF::Vocab::OA.Choice
|
171
180
|
# @param [RDF::URI] predicate the predicate for [@root_uri, predicate, (choice)] statement
|
172
|
-
# to be added to @oa_graph, e.g. RDF::
|
181
|
+
# to be added to @oa_graph, e.g. RDF::Vocab::OA.hasTarget
|
173
182
|
# @return [Boolean] true if it adds statements to @oa_graph, false otherwise
|
174
183
|
def map_choice uri_obj, predicate
|
175
|
-
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::
|
184
|
+
solns = @ldp_anno_graph.query [uri_obj, RDF.type, RDF::Vocab::OA.Choice]
|
176
185
|
if solns.count > 0
|
177
186
|
blank_node = RDF::Node.new
|
178
187
|
@oa_graph << [@root_uri, predicate, blank_node]
|
179
|
-
|
188
|
+
|
180
189
|
default_obj = nil
|
181
190
|
item_objs = []
|
182
|
-
choice_stmts =
|
191
|
+
choice_stmts = OA::Graph.subject_statements(uri_obj, @ldp_anno_graph)
|
183
192
|
choice_stmts.each { |stmt|
|
184
|
-
if stmt.predicate == RDF::
|
193
|
+
if stmt.predicate == RDF::Vocab::OA.default
|
185
194
|
default_obj = stmt.object
|
186
195
|
# assume it is either ContentAsText or external ref
|
187
|
-
if !map_content_as_text(default_obj, RDF::
|
188
|
-
map_external_ref(default_obj, RDF::
|
196
|
+
if !map_content_as_text(default_obj, RDF::Vocab::OA.default, blank_node)
|
197
|
+
map_external_ref(default_obj, RDF::Vocab::OA.default, blank_node)
|
189
198
|
end
|
190
|
-
elsif stmt.predicate == RDF::
|
199
|
+
elsif stmt.predicate == RDF::Vocab::OA.item
|
191
200
|
item_objs << stmt.object
|
192
201
|
# assume it is either ContentAsText or external ref
|
193
|
-
if !map_content_as_text(stmt.object, RDF::
|
194
|
-
map_external_ref(stmt.object, RDF::
|
202
|
+
if !map_content_as_text(stmt.object, RDF::Vocab::OA.item, blank_node)
|
203
|
+
map_external_ref(stmt.object, RDF::Vocab::OA.item, blank_node)
|
195
204
|
end
|
196
205
|
end
|
197
206
|
}
|
198
|
-
|
199
|
-
# We can't know we'll hit item and default statements in graph first,
|
207
|
+
|
208
|
+
# We can't know we'll hit item and default statements in graph first,
|
200
209
|
# so we must do another pass through the statements to get that information
|
201
|
-
choice_stmts.each { |stmt|
|
210
|
+
choice_stmts.each { |stmt|
|
202
211
|
if stmt.subject == uri_obj && stmt.object != default_obj && !item_objs.include?(stmt.object)
|
203
212
|
@oa_graph << [blank_node, stmt.predicate, stmt.object]
|
204
213
|
# there shouldn't be any other unmapped statements present
|