triannon 1.0.1 → 1.1.0
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.
- 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
|