/** * Implements the "annotations" uri of the Annotator API. see * */ package de.mpiwg.itgroup.annotations.restlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.restlet.data.Form; import org.restlet.data.Parameter; import org.restlet.data.Status; import org.restlet.ext.json.JsonRepresentation; import org.restlet.representation.Representation; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; import org.restlet.resource.Put; import de.mpiwg.itgroup.annotations.Annotation; import de.mpiwg.itgroup.annotations.Person; import de.mpiwg.itgroup.annotations.Tag; import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore; import de.mpiwg.itgroup.annotations.restlet.utils.JSONObjectComparator; /** * Implements the "annotations" uri of the Annotator API. see * * * @author dwinter, casties * */ public class AnnotatorAnnotations extends AnnotatorResourceImpl { protected String getAllowedMethodsForHeader() { return "OPTIONS,GET,POST,PUT,DELETE"; } /** * GET with JSON content-type. * * @param entity * @return */ @Get("json") public Representation doGetJSON(Representation entity) { logger.debug("AnnotatorAnnotations doGetJSON!"); setCorsHeaders(); // id from URI /annotations/{id} String jsonId = (String) getRequest().getAttributes().get("id"); String id = decodeJsonId(jsonId); logger.debug("annotation-id=" + id); // do authentication Person authUser = Person.createPersonWithId(this.checkAuthToken(entity)); logger.debug("request authenticated=" + authUser); if (id == null) { return getAllAnnotations(authUser); } AnnotationStore store = getAnnotationStore(); Annotation annot = store.getAnnotationById(id); if (annot != null) { if (! annot.isActionAllowed("read", authUser, store)) { setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); return null; } JSONObject result = createAnnotatorJson(annot, (authUser == null)); logger.debug("sending:"); logger.debug(result); return new JsonRepresentation(result); } else { // not found setStatus(Status.CLIENT_ERROR_NOT_FOUND); return null; } } private Representation getAllAnnotations(Person authUser) { Form form = getRequest().getResourceRef().getQueryAsForm(); String sortBy=null; for (Parameter parameter : form) { if (parameter.getName().equals("sortBy")){ sortBy = parameter.getValue(); } } AnnotationStore store = getAnnotationStore(); ArrayList results = new ArrayList(); List annotations = store.getAnnotations(null, null); for (Annotation annotation : annotations) { //check permission if (!annotation.isActionAllowed("read", authUser, store)) continue; JSONObject jo = createAnnotatorJson(annotation,false); results.add(jo); } if (sortBy!=null){ JSONObjectComparator.sortAnnotations(results,sortBy); } JSONArray resultsJa = new JSONArray(); for (JSONObject result:results){ resultsJa.put(result); } // assemble result object JSONObject result = new JSONObject(); try { result.put("rows", resultsJa); result.put("total", resultsJa.length()); } catch (JSONException e) { setStatus(Status.SERVER_ERROR_INTERNAL, "JSON Error"); return null; } logger.debug("sending:"); logger.debug(result); return new JsonRepresentation(result); } /** * POST with JSON content-type. Creates a new Annotation. * * @return */ @Post("json") public Representation doPostJson(Representation entity) { logger.debug("AnnotatorAnnotations doPostJSON!"); // set headers setCorsHeaders(); // do authentication TODO: who's allowed to create? Person authUser = Person.createPersonWithId(this.checkAuthToken(entity)); logger.debug("request authenticated=" + authUser); if (authUser == null) { setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); return null; } Annotation annot = null; try { JsonRepresentation jrep = new JsonRepresentation(entity); JSONObject jo = jrep.getJsonObject(); if (jo == null) { setStatus(Status.SERVER_ERROR_INTERNAL); return null; } // make sure id is not set for POST jo.remove("id"); // get Annotation object from posted JSON annot = createAnnotation(jo, entity); } catch (IOException e1) { setStatus(Status.SERVER_ERROR_INTERNAL); return null; } catch (JSONException e) { setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } if (annot == null) { setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } Annotation storedAnnot; // store Annotation storedAnnot = getAnnotationStore().storeAnnotation(annot); /* * according to https://github.com/okfn/annotator/wiki/Storage we should * return 303: see other. For now we return the annotation. */ JSONObject jo = createAnnotatorJson(storedAnnot, (authUser == null)); JsonRepresentation retRep = new JsonRepresentation(jo); return retRep; } /** * PUT with JSON content-type. Modifies an Annotation. * * @param entity * @return */ @Put("json") public Representation doPutJSON(Representation entity) { logger.debug("AnnotatorAnnotations doPutJSON!"); setCorsHeaders(); // id from URI /annotations/{id} String jsonId = (String) getRequest().getAttributes().get("id"); String id = decodeJsonId(jsonId); logger.debug("annotation-id=" + id); // do authentication Person authUser = Person.createPersonWithId(this.checkAuthToken(entity)); logger.debug("request authenticated=" + authUser); Annotation annot = null; AnnotationStore store = getAnnotationStore(); try { JsonRepresentation jrep = new JsonRepresentation(entity); JSONObject jo = jrep.getJsonObject(); if (jo == null) { setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } // get stored Annotation Annotation storedAnnot = store.getAnnotationById(id); if (storedAnnot == null) { setStatus(Status.CLIENT_ERROR_NOT_FOUND); return null; } if (! storedAnnot.isActionAllowed("update", authUser, store)) { setStatus(Status.CLIENT_ERROR_FORBIDDEN); return null; } // update from posted JSON annot = updateAnnotation(storedAnnot, jo, entity); // store Annotation storedAnnot = store.storeAnnotation(annot); /* * according to https://github.com/okfn/annotator/wiki/Storage we * should return 303: see other. but the client doesn't like it * setStatus(Status.REDIRECTION_SEE_OTHER); // go to same URL as * this one Reference thisUrl = this.getReference(); * this.getResponse().setLocationRef(thisUrl); */ // return new annotation jo = createAnnotatorJson(storedAnnot, (authUser == null)); JsonRepresentation retRep = new JsonRepresentation(jo); return retRep; } catch (JSONException e) { e.printStackTrace(); setStatus(Status.CLIENT_ERROR_BAD_REQUEST); } catch (IOException e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "Other Error"); } return null; } /** * DELETE with JSON content-type. Deletes an Annotation. * * @param entity * @return */ @Delete("json") public Representation doDeleteJSON(Representation entity) { logger.debug("AnnotatorAnnotations doDeleteJSON!"); setCorsHeaders(); // id from URI /annotations/{id} String jsonId = (String) getRequest().getAttributes().get("id"); String id = decodeJsonId(jsonId); logger.debug("annotation-id=" + id); // do authentication Person authUser = Person.createPersonWithId(this.checkAuthToken(entity)); logger.debug("request authenticated=" + authUser); AnnotationStore store = getAnnotationStore(); Annotation annot = store.getAnnotationById(id); if (annot != null) { if (! annot.isActionAllowed("delete", authUser, store)) { setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); return null; } } // delete annotation store.deleteAnnotationById(id); setStatus(Status.SUCCESS_NO_CONTENT); return null; } }