triannon 1.1.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3fb1a2a5664cb23544e3809666e40fbeac50bf7
4
- data.tar.gz: 530b85774e11c73ad4ace71448e200babf0e2887
3
+ metadata.gz: 0a7836e167aa59510f75b69435f06de72d75a4c6
4
+ data.tar.gz: efc5bc0bff62bfc9347590b2a13c0e144688e2ed
5
5
  SHA512:
6
- metadata.gz: d053edac7a6da6482140dc9c9eb4fda5ea467f772b1cc94a5fc05f0b866e2b2575d81278db451d6101b4856fa9ed4974b9677df28f26801f7483f7be375cba95
7
- data.tar.gz: 88807450e57ec3e5a801b8be3480dee4c4b7f5d2b46401e0abb0cbfdcbcdfa21306933d1d6b0aa521d251602f86df55bb6545e3ed8a9f81bc76323dd2e20d90d
6
+ metadata.gz: 04a8c245627c35a0c1d099a40c1d71138e25964f91f8f329c36b628beddd13eca016ef86cfccac88ec98b8dde7d280c79d19a869062752e901e01146fa862918
7
+ data.tar.gz: 67c3f60fa650ddbcaf6763582f1faf634d4b8766d56ebd3ae505894e96397eab2604d578d92bdb57c6f40da794a55398bdbf3047a8cfb26aad18e7cc9fbbd6e9
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Triannon
4
4
 
5
- Store Open Annotation in Fedora4 to support the Linked Data for Libraries use cases.
5
+ Store Open Annotation RDF in Fedora4 to support the Linked Data for Libraries use cases.
6
6
 
7
- ## Installation into Your Rails Application
7
+ ## Installation into Your Existing Rails Application
8
8
 
9
9
  Add this line to your Rails application's Gemfile
10
10
 
@@ -12,12 +12,14 @@ Add this line to your Rails application's Gemfile
12
12
  gem 'triannon'
13
13
  ```
14
14
 
15
- Then execute:
15
+ Then install the gems:
16
+
16
17
  ```console
17
18
  $ bundle install
18
19
  ```
19
20
 
20
21
  Then run the triannon generator:
22
+
21
23
  ```console
22
24
  $ rails g triannon:install
23
25
  ```
@@ -27,16 +29,20 @@ Edit the `config/triannon.yml` file:
27
29
  * `ldp:` Properties of LDP server
28
30
  * `url:` the baseurl of LDP server
29
31
  * `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)
32
+ * `anno_containers:` (the names of LDP Basic Containers holding individual annos)
31
33
  * `solr_url:` Points to the baseurl of Solr instance configured for Triannon
32
34
  * `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
33
35
 
34
- Generate the uber root annotations container on your LDP server:
36
+ Generate the root annotations containers on your LDP server:
35
37
 
36
38
  ```console
37
- $ rake triannon:create_uber_root_container
39
+ $ rake triannon:create_root_containers
38
40
  ```
39
41
 
42
+ This will generate the uber_container and the anno_containers (aka 'root containers') under the uber_container.
43
+
44
+ NOTE: you MUST create the root containers before creating any annotations. All annotation MUST be created as a child of a root container.
45
+
40
46
  Set up caching for jsonld context documents:
41
47
 
42
48
  * by using Rack::Cache for RestClient:
@@ -49,9 +55,9 @@ gem 'rack-cache'
49
55
  gem 'rest-client-components'
50
56
  ```
51
57
 
52
- * bundle install
58
+ * bundle install
53
59
 
54
- * create a config/initializers/rest_client.rb
60
+ * create config/initializers/rest_client.rb
55
61
 
56
62
  ```ruby
57
63
  require 'restclient/components'
@@ -78,6 +84,19 @@ Search Parameters:
78
84
  * `bodyKeyword` - matches terms in body characters
79
85
  * `motivatedBy` - matches fragment part of motivation predicate URI, e.g. commenting, tagging, painting
80
86
 
87
+ * use HTTP `Accept` header with mime type to indicate desired format
88
+ * default: jsonld
89
+ * `Accept`: `application/ld+json`
90
+ * also supports turtle, rdfxml, json, html
91
+ * `Accept`: `application/x-turtle`
92
+
93
+ ### Get a list of annos in a particular root container
94
+ as a IIIF Annotation List (see http://iiif.io/api/presentation/2.0/#other-content-resources)
95
+
96
+ * `GET`: `http://(host)/annotations/(root container name)/search?targetUri=some.url.org`
97
+
98
+ Search Parameters as above.
99
+
81
100
  * use HTTP `Accept` header with mime type to indicate desired format
82
101
  * default: jsonld
83
102
  * `Accept`: `application/ld+json`
@@ -85,7 +104,9 @@ Search Parameters:
85
104
  * `Accept`: `application/x-turtle`
86
105
 
87
106
  ### Get a particular anno
88
- `GET`: `http://(host)/annotations/(anno_id)`
107
+ `GET`: `http://(host)/annotations/(root container)/(anno_id)`
108
+
109
+ NOTE: you may need to URL encode the anno_id (e.g. "6f%2F0e%2F79%2F92%2F6f0e7992-83f5-4f31-8bb7-94a23465fdfb" instead of "6f/0e/79/92/6f0e7992-83f5-4f31-8bb7-94a23465fdfb"), particularly from a web browser.
89
110
 
90
111
  * use HTTP `Accept` header with mime type to indicate desired format
91
112
  * default: jsonld
@@ -118,7 +139,7 @@ You can also use either of these methods (with the correct HTTP Accept header):
118
139
  Note that OA (Open Annotation) is the default context if none is specified.
119
140
 
120
141
  ### Create an anno
121
- `POST`: `http://(host)/annotations`
142
+ `POST`: `http://(host)/annotations/(root container)`
122
143
  * the body of the HTTP request should contain the annotation, as jsonld, turtle, or rdfxml
123
144
  * Wrap the annotation in an object, as such:
124
145
  * `{ "commit" => "Create Annotation", "annotation" => { "data" => oa_jsonld } }`
@@ -134,7 +155,9 @@ Note that OA (Open Annotation) is the default context if none is specified.
134
155
  * note that the "type" part is optional and refers to the type of the rel, which is the reference for all json-ld contexts.
135
156
 
136
157
  ### Delete an anno
137
- `DELETE`: `http://(host)/annotations/(anno_id)`
158
+ `DELETE`: `http://(host)/annotations/(root container)/(anno_id)`
159
+
160
+ NOTE: you may need to URL encode the anno_id (e.g. "6f%2F0e%2F79%2F92%2F6f0e7992-83f5-4f31-8bb7-94a23465fdfb" instead of "6f/0e/79/92/6f0e7992-83f5-4f31-8bb7-94a23465fdfb")
138
161
 
139
162
 
140
163
  # Running This Code in Development
@@ -143,71 +166,64 @@ There is a bundled rake task for running triannon in a test rails application, b
143
166
 
144
167
  ## One time setup
145
168
 
146
- ### Set up a local instance of Fedora4
147
- ```console
148
- $ rake jetty:download
149
- $ rake jetty:unzip
150
- $ rake jetty:environment
151
- $ rake triannon:jetty_setup
152
- ```
153
-
154
- triannon:jetty_setup task does the following:
155
- * turns off basic authorization in Fedora4
156
- * sets up a Triannon flavored Solr
157
-
158
169
  ### Set up the testing Rails app that uses triannon gem
170
+
159
171
  ```console
160
172
  $ rake engine_cart:generate # (first run only)
161
173
  ```
162
174
 
163
- ### Start jetty
175
+ ### Set up a local instance of Fedora4 and Solr
176
+
164
177
  ```console
165
- $ rake jetty:start
178
+ $ rake jetty:download
179
+ $ rake jetty:unzip
180
+ $ rake jetty:environment
181
+ $ rake triannon:jetty_config
166
182
  ```
167
183
 
168
- Note that jetty can be very sloooooooow to start up with Fedora and Solr.
169
-
170
- #### Check if Solr is up
171
- Go to http://localhost:8983/solr/#/triannon
172
- or to http://localhost:8983/solr/triannon/select
184
+ triannon:jetty_config task does the following:
185
+ * turns off basic authorization in Fedora4
186
+ * sets up a Triannon flavored Solr core
173
187
 
174
- If all is well, you will not get an error message; the triannon core exists in Solr. If all is not
175
- well, try:
188
+ ### Start jetty
176
189
 
177
190
  ```console
178
- $ rake jetty:stop
179
- $ rake triannon:jetty_setup
180
191
  $ rake jetty:start
181
192
  ```
182
193
 
183
- and then check again.
194
+ Note that jetty can be very sloooooooow (a couple of minutes) to start up with Fedora and Solr.
184
195
 
196
+ #### Check if Solr and Fedora are up
197
+ Go to
198
+ * http://localhost:8983/solr/#/triannon - Solr admin GUI page, you should not see any error text in your browser
199
+ * http://localhost:8983/solr/triannon/select - actual Solr query; should give http status other than 200 if there is a problem
185
200
 
186
- #### Check if Fedora4 is up
187
- Go to http://localhost:8983/fedora/rest/
201
+ Go to
202
+ * http://localhost:8983/fedora/rest/ - you should see a fedora object.
188
203
 
189
- If all is well, you will not get an error message. If all is not well, try:
204
+ If all is not well for Fedora or Solr, try:
190
205
 
191
206
  ```console
192
- $ rake jetty:stop
193
- $ rake jetty:clean
194
- $ rake triannon:jetty_startup
195
- $ rake jetty:start
207
+ $ rake triannon:jetty_reset
196
208
  ```
197
209
 
198
- and check for Solr and Fedora again.
210
+ This stops jetty, cleans out the jetty directory, recreates it anew from the download, configures jetty for Triannon, and starts jetty. It may take a long time (a couple of minutes) for jetty to restart.
211
+
212
+ Then check the Solr and Fedora urls again.
199
213
 
200
- #### Generate uber root annotations container
201
- After you ensure that Fedora4 is running:
214
+
215
+ #### Generate root annotations containers in Fedora
216
+ After you ensure that Fedora is running, you need to create the root anno containers using the configuration of test rails app created by engine_cart:
202
217
 
203
218
  ```console
204
219
  $ cd spec/internal
205
- $ rake triannon:create_uber_root_container
220
+ $ rake triannon:create_root_containers
206
221
  $ cd ../..
207
222
  ```
208
223
 
209
224
  #### Configure spec/internal/config/triannon.yml as specified above
210
- You probably won't need to change this file.
225
+ NOTE: You probably won't need to change this file - it will work with the jetty setup provided.
226
+
211
227
  ```console
212
228
  $ vi spec/internal/config/triannon.yml
213
229
  ```
@@ -221,7 +237,7 @@ $ <cntl + C> # to stop Rails application
221
237
  $ rake jetty:stop # to stop Fedora and Solr
222
238
  ```
223
239
 
224
- The app will be running at localhost:3000
240
+ The app will be running at localhost:3000, with root containers "foo" and "blah" available (and empty).
225
241
 
226
242
  # Running the Tests
227
243
 
@@ -24,11 +24,9 @@ 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
- # 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
27
+ # parse the Accept HTTP header for the value of profile if it is a request for jsonld or json.
28
+ # e.g. Accept: application/ld+json; profile="http://www.w3.org/ns/oa-context-20130208.json"
29
+ # @return [String] url for jsonld @context or nil if missing or non-jsonld/json format
32
30
  def context_url_from_accept
33
31
  if request.format == "jsonld" || request.format == "json"
34
32
  accept_str = request.accept
@@ -48,12 +46,10 @@ module RdfResponseFormats
48
46
  end
49
47
  end
50
48
 
51
- # parse the Accept HTTP Link for the value of rel if it is a request for
52
- # jsonld or json
53
- # e.g. Link: http://www.w3.org/ns/oa.json; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"
54
- # note that the "type" part is optional
55
- # @return [String] url for jsonld @context or nil if missing or
56
- # non-jsonld/json format
49
+ # parse the Accept HTTP Link for the value of rel if it is a request for jsonld or json
50
+ # e.g. Link: http://www.w3.org/ns/oa.json; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"
51
+ # note that the "type" part is optional
52
+ # @return [String] url for jsonld @context or nil if missing or non-jsonld/json format
57
53
  def context_url_from_link
58
54
  if request.format == "jsonld" || request.format == "json"
59
55
  link_str = request.headers["Link"]
@@ -5,6 +5,7 @@ module Triannon
5
5
  include RdfResponseFormats
6
6
 
7
7
  rescue_from Triannon::LDPStorageError, with: :ldp_storage_error
8
+ rescue_from Triannon::LDPContainerError, with: :ldp_container_error
8
9
  rescue_from Triannon::ExternalReferenceError, with: :ext_ref_error
9
10
  rescue_from Triannon::SearchError, with: :search_error
10
11
  before_action :default_format_jsonld, only: [:show]
@@ -12,7 +13,11 @@ module Triannon
12
13
 
13
14
  # GET /annotations
14
15
  def index
15
- redirect_to "/search"
16
+ if params[:anno_root].present?
17
+ redirect_to "/#{params[:anno_root]}#{search_path}"
18
+ else
19
+ redirect_to search_path
20
+ end
16
21
  end
17
22
 
18
23
  # GET /annotations/1
@@ -29,10 +34,10 @@ module Triannon
29
34
  }
30
35
  format.ttl {
31
36
  accept_return_type = mime_type_from_accept(["application/x-turtle", "text/turtle"])
32
- render :body => @annotation.graph.to_ttl, content_type: accept_return_type if accept_return_type }
37
+ render body: @annotation.graph.to_ttl, content_type: accept_return_type if accept_return_type }
33
38
  format.rdfxml {
34
39
  accept_return_type = mime_type_from_accept(["application/rdf+xml", "text/rdf+xml", "text/rdf"])
35
- render :body => @annotation.graph.to_rdfxml, content_type: accept_return_type if accept_return_type }
40
+ render body: @annotation.graph.to_rdfxml, content_type: accept_return_type if accept_return_type }
36
41
  format.json {
37
42
  accept_return_type = mime_type_from_accept(["application/json", "text/x-json", "application/jsonrequest"])
38
43
  context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
@@ -44,7 +49,7 @@ module Triannon
44
49
  }
45
50
  format.xml {
46
51
  accept_return_type = mime_type_from_accept(["application/xml", "text/xml", "application/x-xml"])
47
- render :xml => @annotation.graph.to_rdfxml, content_type: accept_return_type if accept_return_type }
52
+ render xml: @annotation.graph.to_rdfxml, content_type: accept_return_type if accept_return_type }
48
53
  format.html { render :show }
49
54
  end
50
55
  end
@@ -68,12 +73,12 @@ module Triannon
68
73
  # it's from app html form
69
74
  params.require(:annotation).permit(:data)
70
75
  if params["annotation"]["data"]
71
- @annotation = Annotation.new({:data => params["annotation"]["data"]})
76
+ @annotation = Annotation.new(data: params["annotation"]["data"], root_container: params[:anno_root])
72
77
  end
73
78
  else
74
79
  # it's a direct post request
75
80
  content_type = request.headers["Content-Type"]
76
- @annotation = Annotation.new({:data => request.body.read, :expected_content_type => content_type})
81
+ @annotation = Annotation.new(data: request.body.read, expected_content_type: content_type, root_container: params[:anno_root])
77
82
  end
78
83
 
79
84
  if @annotation.save
@@ -83,30 +88,30 @@ module Triannon
83
88
  format.jsonld {
84
89
  context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
85
90
  if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
86
- render :json => @annotation.jsonld_iiif, status: 201, content_type: "application/ld+json"
91
+ render json: @annotation.jsonld_iiif, status: 201, content_type: "application/ld+json"
87
92
  else
88
- render :json => @annotation.jsonld_oa, status: 201, content_type: "application/ld+json"
93
+ render json: @annotation.jsonld_oa, status: 201, content_type: "application/ld+json"
89
94
  end
90
95
  }
91
96
  format.ttl {
92
97
  accept_return_type = mime_type_from_accept(["application/x-turtle", "text/turtle"])
93
- render :body => @annotation.graph.to_ttl, status: 201, content_type: accept_return_type if accept_return_type }
98
+ render body: @annotation.graph.to_ttl, status: 201, content_type: accept_return_type if accept_return_type }
94
99
  format.rdfxml {
95
100
  accept_return_type = mime_type_from_accept(["application/rdf+xml", "text/rdf+xml", "text/rdf"])
96
- render :body => @annotation.graph.to_rdfxml, status: 201, content_type: accept_return_type if accept_return_type }
101
+ render body: @annotation.graph.to_rdfxml, status: 201, content_type: accept_return_type if accept_return_type }
97
102
  format.json {
98
103
  accept_return_type = mime_type_from_accept(["application/json", "text/x-json", "application/jsonrequest"])
99
104
  context_url = context_url_from_link ? context_url_from_link : context_url_from_accept
100
105
  if context_url && context_url == OA::Graph::IIIF_CONTEXT_URL
101
- render :json => @annotation.jsonld_iiif, status: 201, content_type: accept_return_type if accept_return_type
106
+ render json: @annotation.jsonld_iiif, status: 201, content_type: accept_return_type if accept_return_type
102
107
  else
103
- render :json => @annotation.jsonld_oa, status: 201, content_type: accept_return_type if accept_return_type
108
+ render json: @annotation.jsonld_oa, status: 201, content_type: accept_return_type if accept_return_type
104
109
  end
105
110
  }
106
111
  format.xml {
107
112
  accept_return_type = mime_type_from_accept(["application/xml", "text/xml", "application/x-xml"])
108
- render :body => @annotation.graph.to_rdfxml, status: 201, content_type: accept_return_type if accept_return_type }
109
- format.html { redirect_to @annotation }
113
+ render body: @annotation.graph.to_rdfxml, status: 201, content_type: accept_return_type if accept_return_type }
114
+ format.html { redirect_to annotations_path(anno_root: params[:anno_root], id: @annotation.id) }
110
115
  end
111
116
  else
112
117
  render :new, status: 400
@@ -126,13 +131,13 @@ module Triannon
126
131
  # DELETE /annotations/1
127
132
  def destroy
128
133
  @annotation.destroy
129
- redirect_to annotations_url, status: 204, notice: 'Annotation was successfully destroyed.'
134
+ redirect_to annotations_path(anno_root: params[:anno_root]), status: 204, notice: 'Annotation was successfully destroyed.'
130
135
  end
131
136
 
132
137
  private
133
138
 
134
139
  def set_annotation
135
- @annotation = Annotation.find(params[:id])
140
+ @annotation = Annotation.find(params[:anno_root], params[:id])
136
141
  end
137
142
 
138
143
  # render Triannon::ExternalReferenceError
@@ -140,14 +145,19 @@ private
140
145
  render plain: err.message, status: 403
141
146
  end
142
147
 
148
+ # render Triannon::LDPContainer error
149
+ def ldp_container_error(err)
150
+ render plain: err.message, status: 403
151
+ end
152
+
143
153
  # render Triannon::LDPStorage error
144
154
  def ldp_storage_error(err)
145
- render :body => "<h2>#{err.message}</h2>" + err.ldp_resp_body, status: err.ldp_resp_status, content_type: "text/html"
155
+ render body: "<h2>#{err.message}</h2>" + err.ldp_resp_body, status: err.ldp_resp_status, content_type: "text/html"
146
156
  end
147
157
 
148
158
  # render Triannon::SearchError
149
159
  def search_error(err)
150
- render :body => "<h2>#{err.message}</h2>" + (err.search_resp_body ? err.search_resp_body : ""),
160
+ render body: "<h2>#{err.message}</h2>" + (err.search_resp_body ? err.search_resp_body : ""),
151
161
  status: err.search_resp_status ? err.search_resp_status : 400,
152
162
  content_type: "text/html"
153
163
  end
@@ -159,21 +169,21 @@ private
159
169
  case req_context
160
170
  when "iiif", "IIIF"
161
171
  if mime_type
162
- render :json => @annotation.jsonld_iiif, content_type: mime_type
172
+ render json: @annotation.jsonld_iiif, content_type: mime_type
163
173
  else
164
- render :json => @annotation.jsonld_iiif
174
+ render json: @annotation.jsonld_iiif
165
175
  end
166
176
  when "oa", "OA"
167
177
  if mime_type
168
- render :json => @annotation.jsonld_oa, content_type: mime_type
178
+ render json: @annotation.jsonld_oa, content_type: mime_type
169
179
  else
170
- render :json => @annotation.jsonld_oa
180
+ render json: @annotation.jsonld_oa
171
181
  end
172
182
  else
173
183
  if mime_type
174
- render :json => @annotation.jsonld_oa, content_type: mime_type
184
+ render json: @annotation.jsonld_oa, content_type: mime_type
175
185
  else
176
- render :json => @annotation.jsonld_oa
186
+ render json: @annotation.jsonld_oa
177
187
  end
178
188
  end
179
189
  end
@@ -6,11 +6,11 @@ module Triannon
6
6
  after_save :solr_save
7
7
  after_destroy :solr_delete
8
8
 
9
- attr_accessor :id, :data, :expected_content_type
9
+ attr_accessor :id, :data, :expected_content_type, :root_container
10
10
 
11
- validates_each :data do |record, attr, value|
12
- record.errors.add attr, 'less than 30 chars' if value.to_s.length < 30
13
- end
11
+ validates :data, :root_container, presence: true
12
+ # TODO: ensure root container exists in LDP store?? seems too expensive
13
+ validates :data, length: {minimum: 30}
14
14
 
15
15
  # full validation should be optional?
16
16
  # minimal: a subject with the right type and a hasTarget? (see url)
@@ -26,36 +26,33 @@ module Triannon
26
26
  a
27
27
  end
28
28
 
29
+ # @param [String] root_container - LDP parent container for annotation
29
30
  # @param [String] id the unique id of the annotation. Can include base_uri prefix or omit it.
30
- def self.find(id)
31
- oa_graph = Triannon::LdpLoader.load id
31
+ def self.find(root_container, id)
32
+ oa_graph = Triannon::LdpLoader.load(root_container, id)
32
33
  anno = Triannon::Annotation.new
33
34
  anno.graph = oa_graph
34
35
  anno.id = id
36
+ anno.root_container = root_container
35
37
  anno
36
38
  end
37
39
 
38
- # @deprecated - was used by old annotations#index action, before redirect to search (2015-04)
39
- def self.all
40
- Triannon::LdpLoader.find_all
41
- end
42
-
43
40
  # Instance Methods ----------------------------------------------------------------
44
41
 
45
42
  def save
46
43
  _run_save_callbacks do
47
44
  # TODO: check if valid anno?
48
- @id = Triannon::LdpWriter.create_anno self if graph && graph.size > 2
45
+ @id = Triannon::LdpWriter.create_anno(self, root_container) if graph && graph.size > 2
49
46
  # reload from storage to get the anno id within the graph
50
47
  # TODO: do graph manipulation to add id instead?
51
- @graph = Triannon::LdpLoader.load id
48
+ @graph = Triannon::LdpLoader.load(root_container, id)
52
49
  id
53
50
  end
54
51
  end
55
52
 
56
53
  def destroy
57
54
  _run_destroy_callbacks do
58
- Triannon::LdpWriter.delete_anno @id
55
+ Triannon::LdpWriter.delete_anno "#{root_container}/#{id}"
59
56
  end
60
57
  end
61
58
 
@@ -103,12 +100,12 @@ protected
103
100
 
104
101
  # Add annotation to Solr as a Solr document
105
102
  def solr_save
106
- solr_writer.write(graph) if id_as_url && !id_as_url.empty?
103
+ solr_writer.write(graph, root_container) if id_as_url.present?
107
104
  end
108
105
 
109
106
  # Delete annotation from Solr
110
107
  def solr_delete
111
- solr_writer.delete(id) if id
108
+ solr_writer.delete("#{root_container}/#{id}") if id.present?
112
109
  end
113
110
 
114
111
  private