Mercurial > hg > AnnotationManagerN4J
view src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java @ 3:47b53ae385d1
merging old code
author | casties |
---|---|
date | Fri, 29 Jun 2012 20:38:27 +0200 |
parents | |
children | 3599b29c393f |
line wrap: on
line source
/** * Implements the "annotations" uri of the Annotator API. see * <https://github.com/okfn/annotator/wiki/Storage> */ 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.Context; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.data.Reference; import org.restlet.data.Status; import org.restlet.ext.json.JsonRepresentation; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; import org.restlet.resource.Put; import org.restlet.security.User; import de.mpiwg.itgroup.annotationManager.Constants.NS; import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreStoreError; import de.mpiwg.itgroup.annotationManager.RDFHandling.Annotation; import de.mpiwg.itgroup.annotationManager.RDFHandling.Convert; import de.mpiwg.itgroup.annotationManager.RDFHandling.RDFSearcher; import de.mpiwg.itgroup.annotationManager.drupal.AnnotationHandler; import de.mpiwg.itgroup.annotationManager.drupal.UnknowUserException; import de.mpiwg.itgroup.triplestoremanager.exceptions.TripleStoreHandlerException; /** * Implements the "annotations" uri of the Annotator API. see <https://github.com/okfn/annotator/wiki/Storage> * * @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); // TODO: what to return without id - list of all annotations? // TODO: what to do with authentication? boolean authenticated = isAuthenticated(entity); logger.debug("request authenticated=" + authenticated); RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file try { List<Annotation> annots = searcher.searchById(id); if (annots.size() == 1) { // there should be only one JSONObject result = createAnnotatorJson(annots.get(0)); logger.debug("sending:"); logger.debug(result); return new JsonRepresentation(result); } else { JSONArray results; results = new JSONArray(); for (Annotation annot : annots) { JSONObject jo = createAnnotatorJson(annot); if (jo != null) { results.put(createAnnotatorJson(annot)); } else { setStatus(Status.SERVER_ERROR_INTERNAL, "JSon Error"); return null; } } // annotator read request returns a list of annotation objects logger.debug("sending:"); logger.debug(results); return new JsonRepresentation(results); } } catch (TripleStoreHandlerException e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); return null; } catch (TripleStoreSearchError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); return null; } } /** * POST with JSON content-type. * * json hash: username: name des users xpointer: xpointer auf den Ausschnitt (incl. der URL des Dokumentes) text: text der * annotation annoturl: url auf eine Annotation falls extern * * @return */ @Post("json") public Representation doPostJson(Representation entity) { logger.debug("AnnotatorAnnotations doPostJSON!"); // set headers setCorsHeaders(); 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 || annot.xpointer == null || annot.creator == null) { setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } Annotation storedAnnot; try { // store Annotation storedAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); } catch (TripleStoreStoreError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); return null; } /* 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); JsonRepresentation retRep = new JsonRepresentation(jo); return retRep; } /** * POST with HTML content-type. * * @param entity * @return */ @Post("html") public Representation doPostHtml(Representation entity) { logger.debug("AnnotatorAnnotations doPostHtml!"); Annotation annot; annot = handleForm(entity); if (annot.xpointer == null || annot.creator == null) { setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } Annotation retValAnnot; try { retValAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); } catch (TripleStoreStoreError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); return null; } if (retValAnnot == null) { return null; } String retVal = retValAnnot.getAnnotationUri(); if (retVal == null) { return null; } String text = String.format("<html><body><a href=\"%s\">%s</a></body></html>", retVal.replace(">", "").replace("<", ""), retVal.replace(">", ">").replace("<", "<")); Representation retRep = new StringRepresentation(text, MediaType.TEXT_HTML); return retRep; } /** * * @param entity * should contain a form with the parameters "username", "password", "xpointer","text","uri","type" * * username,password is optional, if not given BasicAuthentification is used. * * If username given as a URI, the username will be transformed to an URI, username will be added to the MPIWG * namespace defined in de.mpiwg.itgroup.annotationManager.Constants.NS * * @return */ protected Annotation handleForm(Representation entity) { Annotation annot; Form form = new Form(entity); String username = form.getValues("username"); String mode = form.getValues("mode"); String password = form.getValues("password"); String xpointer = form.getValues("xpointer"); String text = form.getValues("text"); String title = form.getValues("title"); String url = form.getValues("url"); String type = form.getValues("type"); RestServer restServer = (RestServer) getApplication(); // falls user and password nicht null sind: User userFromForm = null; if (username != null && password != null) { if (restServer.authenticate(username, password, getRequest())) { userFromForm = new User(username); } } User authUser = null; if (userFromForm == null) { authUser = getHttpAuthUser(entity); } // weder BasicAuth noch FormAuth if (authUser == null && userFromForm == null) { setStatus(Status.CLIENT_ERROR_FORBIDDEN); return null; } if (userFromForm != null) { username = userFromForm.getIdentifier(); } else { username = authUser.getIdentifier(); } // username should be a URI, if not it will set to the MPIWG namespace defined in // de.mpiwg.itgroup.annotationManager.Constants.NS String usernameOrig = username; if (!username.startsWith("http")) username = NS.MPIWG_PERSONS_URL + username; if (mode.equals("complexAnnotation")) {// Annotation mit text in externer ressource Context context = getContext(); String drupalPath = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.drupalServer"); AnnotationHandler ah = new AnnotationHandler(drupalPath); JSONObject newAnnot; try { newAnnot = ah.createAnnotation(title, text, usernameOrig, password); } catch (UnknowUserException e1) { setStatus(Status.CLIENT_ERROR_FORBIDDEN); e1.printStackTrace(); return null; } try { annot = new Annotation(xpointer, username, null, text, type, newAnnot.getString("node_uri")); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL); return null; } } else annot = new Annotation(xpointer, username, null, text, type, url); return annot; } /** * PUT with JSON content-type. * * @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); // TODO: what to do with authentication? we should check the owner boolean authenticated = isAuthenticated(entity); logger.debug("request authenticated=" + authenticated); if (!authenticated) { 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.CLIENT_ERROR_BAD_REQUEST); return null; } RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file // get stored Annotation List<Annotation> annots = searcher.searchById(id); if (annots.size() < 1) { setStatus(Status.CLIENT_ERROR_NOT_FOUND); return null; } Annotation storedAnnot = annots.get(0); // delete searcher.deleteById(id); // update from posted JSON annot = updateAnnotation(storedAnnot, jo, entity); // store Annotation storedAnnot = new Convert(NS.MPIWG_ANNOT_CTX).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); JsonRepresentation retRep = new JsonRepresentation(jo); return retRep; } catch (TripleStoreHandlerException e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); } catch (TripleStoreSearchError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); } 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. * * @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); // TODO: what to do with authentication? we should check the owner boolean authenticated = isAuthenticated(entity); logger.debug("request authenticated=" + authenticated); if (!authenticated) { setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!"); return null; } RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file try { // delete annotation searcher.deleteById(id); setStatus(Status.SUCCESS_NO_CONTENT); } catch (TripleStoreHandlerException e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreHandler Error"); } catch (TripleStoreSearchError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStoreSearch Error"); } return null; } }