Mercurial > hg > AnnotationManagerN4J
comparison src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java @ 4:3599b29c393f
store seems to work now :-)
author | casties |
---|---|
date | Mon, 02 Jul 2012 22:39:46 +0200 |
parents | 47b53ae385d1 |
children | 629e15b345aa |
comparison
equal
deleted
inserted
replaced
3:47b53ae385d1 | 4:3599b29c393f |
---|---|
3 * <https://github.com/okfn/annotator/wiki/Storage> | 3 * <https://github.com/okfn/annotator/wiki/Storage> |
4 */ | 4 */ |
5 package de.mpiwg.itgroup.annotations.restlet; | 5 package de.mpiwg.itgroup.annotations.restlet; |
6 | 6 |
7 import java.io.IOException; | 7 import java.io.IOException; |
8 import java.util.ArrayList; | |
9 import java.util.List; | |
10 | 8 |
11 import org.json.JSONArray; | 9 import org.json.JSONArray; |
12 import org.json.JSONException; | 10 import org.json.JSONException; |
13 import org.json.JSONObject; | 11 import org.json.JSONObject; |
14 import org.restlet.Context; | |
15 import org.restlet.data.Form; | |
16 import org.restlet.data.MediaType; | |
17 import org.restlet.data.Reference; | |
18 import org.restlet.data.Status; | 12 import org.restlet.data.Status; |
19 import org.restlet.ext.json.JsonRepresentation; | 13 import org.restlet.ext.json.JsonRepresentation; |
20 import org.restlet.representation.Representation; | 14 import org.restlet.representation.Representation; |
21 import org.restlet.representation.StringRepresentation; | |
22 import org.restlet.resource.Delete; | 15 import org.restlet.resource.Delete; |
23 import org.restlet.resource.Get; | 16 import org.restlet.resource.Get; |
24 import org.restlet.resource.Post; | 17 import org.restlet.resource.Post; |
25 import org.restlet.resource.Put; | 18 import org.restlet.resource.Put; |
26 import org.restlet.security.User; | 19 |
27 | 20 import de.mpiwg.itgroup.annotations.Annotation; |
28 import de.mpiwg.itgroup.annotationManager.Constants.NS; | 21 import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore; |
29 import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; | |
30 import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreStoreError; | |
31 import de.mpiwg.itgroup.annotationManager.RDFHandling.Annotation; | |
32 import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert; | |
33 import de.mpiwg.itgroup.annotationManager.RDFHandling.RDFSearcher; | |
34 import de.mpiwg.itgroup.annotationManager.drupal.AnnotationHandler; | |
35 import de.mpiwg.itgroup.annotationManager.drupal.UnknowUserException; | |
36 import de.mpiwg.itgroup.triplestoremanager.exceptions.TripleStoreHandlerException; | |
37 | 22 |
38 /** | 23 /** |
39 * Implements the "annotations" uri of the Annotator API. see <https://github.com/okfn/annotator/wiki/Storage> | 24 * Implements the "annotations" uri of the Annotator API. see |
25 * <https://github.com/okfn/annotator/wiki/Storage> | |
40 * | 26 * |
41 * @author dwinter, casties | 27 * @author dwinter, casties |
42 * | 28 * |
43 */ | 29 */ |
44 public class AnnotatorAnnotations extends AnnotatorResourceImpl { | 30 public class AnnotatorAnnotations extends AnnotatorResourceImpl { |
66 | 52 |
67 // TODO: what to do with authentication? | 53 // TODO: what to do with authentication? |
68 boolean authenticated = isAuthenticated(entity); | 54 boolean authenticated = isAuthenticated(entity); |
69 logger.debug("request authenticated=" + authenticated); | 55 logger.debug("request authenticated=" + authenticated); |
70 | 56 |
71 RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file | 57 Annotation annots = getAnnotationStore().getAnnotationById(id); |
72 | 58 if (annots != null) { |
73 try { | 59 // there should be only one |
74 List<Annotation> annots = searcher.searchById(id); | 60 JSONObject result = createAnnotatorJson(annots); |
75 if (annots.size() == 1) { | 61 logger.debug("sending:"); |
76 // there should be only one | 62 logger.debug(result); |
77 JSONObject result = createAnnotatorJson(annots.get(0)); | 63 return new JsonRepresentation(result); |
78 logger.debug("sending:"); | 64 } else { |
79 logger.debug(result); | 65 JSONArray results = new JSONArray(); |
80 return new JsonRepresentation(result); | 66 // annotator read request returns a list of annotation objects |
81 } else { | 67 logger.debug("sending:"); |
82 JSONArray results; | 68 logger.debug(results); |
83 results = new JSONArray(); | 69 return new JsonRepresentation(results); |
84 for (Annotation annot : annots) { | |
85 JSONObject jo = createAnnotatorJson(annot); | |
86 if (jo != null) { | |
87 results.put(createAnnotatorJson(annot)); | |
88 } else { | |
89 setStatus(Status.SERVER_ERROR_INTERNAL, "JSon Error"); | |
90 return null; | |
91 } | |
92 } | |
93 // annotator read request returns a list of annotation objects | |
94 logger.debug("sending:"); | |
95 logger.debug(results); | |
96 return new JsonRepresentation(results); | |
97 } | |
98 } catch (TripleStoreHandlerException e) { | |
99 e.printStackTrace(); | |
100 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); | |
101 return null; | |
102 } catch (TripleStoreSearchError e) { | |
103 e.printStackTrace(); | |
104 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); | |
105 return null; | |
106 } | 70 } |
107 } | 71 } |
108 | 72 |
109 /** | 73 /** |
110 * POST with JSON content-type. | 74 * POST with JSON content-type. |
111 * | 75 * |
112 * json hash: username: name des users xpointer: xpointer auf den Ausschnitt (incl. der URL des Dokumentes) text: text der | 76 * json hash: username: name des users xpointer: xpointer auf den Ausschnitt |
113 * annotation annoturl: url auf eine Annotation falls extern | 77 * (incl. der URL des Dokumentes) text: text der annotation annoturl: url |
78 * auf eine Annotation falls extern | |
114 * | 79 * |
115 * @return | 80 * @return |
116 */ | 81 */ |
117 @Post("json") | 82 @Post("json") |
118 public Representation doPostJson(Representation entity) { | 83 public Representation doPostJson(Representation entity) { |
136 return null; | 101 return null; |
137 } catch (JSONException e) { | 102 } catch (JSONException e) { |
138 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); | 103 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); |
139 return null; | 104 return null; |
140 } | 105 } |
141 if (annot == null || annot.xpointer == null || annot.creator == null) { | 106 if (annot == null) { |
142 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); | 107 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); |
143 return null; | 108 return null; |
144 } | 109 } |
145 Annotation storedAnnot; | 110 Annotation storedAnnot; |
146 try { | 111 // store Annotation |
147 // store Annotation | 112 storedAnnot = getAnnotationStore().storeAnnotation(annot); |
148 storedAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); | 113 /* |
149 } catch (TripleStoreStoreError e) { | 114 * according to https://github.com/okfn/annotator/wiki/Storage we should |
150 e.printStackTrace(); | 115 * return 303: see other. For now we return the annotation. |
151 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); | |
152 return null; | |
153 } | |
154 /* according to https://github.com/okfn/annotator/wiki/Storage | |
155 * we should return 303: see other. | |
156 * For now we return the annotation. | |
157 */ | 116 */ |
158 JSONObject jo = createAnnotatorJson(storedAnnot); | 117 JSONObject jo = createAnnotatorJson(storedAnnot); |
159 JsonRepresentation retRep = new JsonRepresentation(jo); | 118 JsonRepresentation retRep = new JsonRepresentation(jo); |
160 return retRep; | 119 return retRep; |
161 } | 120 } |
162 | |
163 /** | |
164 * POST with HTML content-type. | |
165 * | |
166 * @param entity | |
167 * @return | |
168 */ | |
169 @Post("html") | |
170 public Representation doPostHtml(Representation entity) { | |
171 logger.debug("AnnotatorAnnotations doPostHtml!"); | |
172 Annotation annot; | |
173 annot = handleForm(entity); | |
174 if (annot.xpointer == null || annot.creator == null) { | |
175 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); | |
176 | |
177 return null; | |
178 } | |
179 | |
180 Annotation retValAnnot; | |
181 try { | |
182 retValAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); | |
183 } catch (TripleStoreStoreError e) { | |
184 e.printStackTrace(); | |
185 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); | |
186 return null; | |
187 } | |
188 if (retValAnnot == null) { | |
189 return null; | |
190 } | |
191 String retVal = retValAnnot.getAnnotationUri(); | |
192 if (retVal == null) { | |
193 return null; | |
194 } | |
195 | |
196 String text = String.format("<html><body><a href=\"%s\">%s</a></body></html>", retVal.replace(">", "").replace("<", ""), | |
197 retVal.replace(">", ">").replace("<", "<")); | |
198 Representation retRep = new StringRepresentation(text, MediaType.TEXT_HTML); | |
199 return retRep; | |
200 } | |
201 | |
202 /** | |
203 * | |
204 * @param entity | |
205 * should contain a form with the parameters "username", "password", "xpointer","text","uri","type" | |
206 * | |
207 * username,password is optional, if not given BasicAuthentification is used. | |
208 * | |
209 * If username given as a URI, the username will be transformed to an URI, username will be added to the MPIWG | |
210 * namespace defined in de.mpiwg.itgroup.annotationManager.Constants.NS | |
211 * | |
212 * @return | |
213 */ | |
214 protected Annotation handleForm(Representation entity) { | |
215 Annotation annot; | |
216 Form form = new Form(entity); | |
217 String username = form.getValues("username"); | |
218 String mode = form.getValues("mode"); | |
219 String password = form.getValues("password"); | |
220 String xpointer = form.getValues("xpointer"); | |
221 String text = form.getValues("text"); | |
222 String title = form.getValues("title"); | |
223 String url = form.getValues("url"); | |
224 String type = form.getValues("type"); | |
225 RestServer restServer = (RestServer) getApplication(); | |
226 | |
227 // falls user and password nicht null sind: | |
228 User userFromForm = null; | |
229 if (username != null && password != null) { | |
230 if (restServer.authenticate(username, password, getRequest())) { | |
231 userFromForm = new User(username); | |
232 } | |
233 } | |
234 User authUser = null; | |
235 | |
236 if (userFromForm == null) { | |
237 authUser = getHttpAuthUser(entity); | |
238 } | |
239 | |
240 // weder BasicAuth noch FormAuth | |
241 if (authUser == null && userFromForm == null) { | |
242 setStatus(Status.CLIENT_ERROR_FORBIDDEN); | |
243 return null; | |
244 } | |
245 | |
246 if (userFromForm != null) { | |
247 username = userFromForm.getIdentifier(); | |
248 } else { | |
249 username = authUser.getIdentifier(); | |
250 } | |
251 | |
252 // username should be a URI, if not it will set to the MPIWG namespace defined in | |
253 // de.mpiwg.itgroup.annotationManager.Constants.NS | |
254 String usernameOrig = username; | |
255 if (!username.startsWith("http")) | |
256 username = NS.MPIWG_PERSONS_URL + username; | |
257 | |
258 if (mode.equals("complexAnnotation")) {// Annotation mit text in externer ressource | |
259 | |
260 Context context = getContext(); | |
261 String drupalPath = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.drupalServer"); | |
262 | |
263 AnnotationHandler ah = new AnnotationHandler(drupalPath); | |
264 JSONObject newAnnot; | |
265 try { | |
266 newAnnot = ah.createAnnotation(title, text, usernameOrig, password); | |
267 } catch (UnknowUserException e1) { | |
268 setStatus(Status.CLIENT_ERROR_FORBIDDEN); | |
269 e1.printStackTrace(); | |
270 return null; | |
271 } | |
272 try { | |
273 annot = new Annotation(xpointer, username, null, text, type, newAnnot.getString("node_uri")); | |
274 } catch (JSONException e) { | |
275 // TODO Auto-generated catch block | |
276 e.printStackTrace(); | |
277 setStatus(Status.SERVER_ERROR_INTERNAL); | |
278 return null; | |
279 } | |
280 } else | |
281 annot = new Annotation(xpointer, username, null, text, type, url); | |
282 return annot; | |
283 } | |
284 | |
285 | 121 |
286 /** | 122 /** |
287 * PUT with JSON content-type. | 123 * PUT with JSON content-type. |
288 * | 124 * |
289 * @param entity | 125 * @param entity |
301 // TODO: what to do with authentication? we should check the owner | 137 // TODO: what to do with authentication? we should check the owner |
302 boolean authenticated = isAuthenticated(entity); | 138 boolean authenticated = isAuthenticated(entity); |
303 logger.debug("request authenticated=" + authenticated); | 139 logger.debug("request authenticated=" + authenticated); |
304 if (!authenticated) { | 140 if (!authenticated) { |
305 setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); | 141 setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); |
306 return null; | 142 return null; |
307 } | 143 } |
308 | 144 |
309 Annotation annot = null; | 145 Annotation annot = null; |
146 AnnotationStore store = getAnnotationStore(); | |
310 try { | 147 try { |
311 JsonRepresentation jrep = new JsonRepresentation(entity); | 148 JsonRepresentation jrep = new JsonRepresentation(entity); |
312 JSONObject jo = jrep.getJsonObject(); | 149 JSONObject jo = jrep.getJsonObject(); |
313 if (jo == null) { | 150 if (jo == null) { |
314 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); | 151 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); |
315 return null; | 152 return null; |
316 } | 153 } |
317 RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file | |
318 // get stored Annotation | 154 // get stored Annotation |
319 List<Annotation> annots = searcher.searchById(id); | 155 Annotation storedAnnot = store.getAnnotationById(id); |
320 if (annots.size() < 1) { | 156 if (storedAnnot == null) { |
321 setStatus(Status.CLIENT_ERROR_NOT_FOUND); | 157 setStatus(Status.CLIENT_ERROR_NOT_FOUND); |
322 return null; | 158 return null; |
323 } | 159 } |
324 Annotation storedAnnot = annots.get(0); | |
325 // delete | |
326 searcher.deleteById(id); | |
327 // update from posted JSON | 160 // update from posted JSON |
328 annot = updateAnnotation(storedAnnot, jo, entity); | 161 annot = updateAnnotation(storedAnnot, jo, entity); |
329 // store Annotation | 162 // store Annotation |
330 storedAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); | 163 storedAnnot = store.storeAnnotation(annot); |
331 /* according to https://github.com/okfn/annotator/wiki/Storage | 164 /* |
332 * we should return 303: see other. | 165 * according to https://github.com/okfn/annotator/wiki/Storage we |
333 * but the client doesn't like it | 166 * should return 303: see other. but the client doesn't like it |
334 setStatus(Status.REDIRECTION_SEE_OTHER); | 167 * setStatus(Status.REDIRECTION_SEE_OTHER); // go to same URL as |
335 // go to same URL as this one | 168 * this one Reference thisUrl = this.getReference(); |
336 Reference thisUrl = this.getReference(); | 169 * this.getResponse().setLocationRef(thisUrl); |
337 this.getResponse().setLocationRef(thisUrl); */ | 170 */ |
338 // return new annotation | 171 // return new annotation |
339 jo = createAnnotatorJson(storedAnnot); | 172 jo = createAnnotatorJson(storedAnnot); |
340 JsonRepresentation retRep = new JsonRepresentation(jo); | 173 JsonRepresentation retRep = new JsonRepresentation(jo); |
341 return retRep; | 174 return retRep; |
342 } catch (TripleStoreHandlerException e) { | |
343 e.printStackTrace(); | |
344 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); | |
345 } catch (TripleStoreSearchError e) { | |
346 e.printStackTrace(); | |
347 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); | |
348 } catch (JSONException e) { | 175 } catch (JSONException e) { |
349 e.printStackTrace(); | 176 e.printStackTrace(); |
350 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); | 177 setStatus(Status.CLIENT_ERROR_BAD_REQUEST); |
351 } catch (IOException e) { | 178 } catch (IOException e) { |
352 e.printStackTrace(); | 179 e.printStackTrace(); |
373 // TODO: what to do with authentication? we should check the owner | 200 // TODO: what to do with authentication? we should check the owner |
374 boolean authenticated = isAuthenticated(entity); | 201 boolean authenticated = isAuthenticated(entity); |
375 logger.debug("request authenticated=" + authenticated); | 202 logger.debug("request authenticated=" + authenticated); |
376 if (!authenticated) { | 203 if (!authenticated) { |
377 setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); | 204 setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); |
378 return null; | 205 return null; |
379 } | 206 } |
380 | 207 |
381 RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file | 208 // delete annotation |
382 | 209 getAnnotationStore().deleteById(id); |
383 try { | 210 setStatus(Status.SUCCESS_NO_CONTENT); |
384 // delete annotation | |
385 searcher.deleteById(id); | |
386 setStatus(Status.SUCCESS_NO_CONTENT); | |
387 } catch (TripleStoreHandlerException e) { | |
388 e.printStackTrace(); | |
389 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); | |
390 } catch (TripleStoreSearchError e) { | |
391 e.printStackTrace(); | |
392 setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); | |
393 } | |
394 return null; | 211 return null; |
395 } | 212 } |
396 | |
397 | 213 |
398 } | 214 } |