Mercurial > hg > AnnotationManager
changeset 33:e5f5848892a2
new annotation model basically works.
line wrap: on
line diff
--- a/.settings/org.eclipse.wst.common.component Thu May 31 11:57:50 2012 +0200 +++ b/.settings/org.eclipse.wst.common.component Thu May 31 19:08:48 2012 +0200 @@ -7,6 +7,9 @@ <dependent-module archiveName="jsontoken-1.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/jsontoken/jsontoken"> <dependency-type>uses</dependency-type> </dependent-module> + <dependent-module archiveName="TripleStoreManager.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/TripleStoreManager/TripleStoreManager"> + <dependency-type>uses</dependency-type> + </dependent-module> <property name="context-root" value="AnnotationManager"/> <property name="java-output-path" value="/AnnotationManager/build/classes"/> </wb-module>
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/Constants/NS.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/Constants/NS.java Thu May 31 19:08:48 2012 +0200 @@ -10,5 +10,6 @@ public static final String RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; public static final String MPIWG_ANNOT_NS = "http://ontologies.mpiwg-berlin.mpg.de/annotations/"; public static final String MPIWG_ANNOT_URL = "http://entities.mpiwg-berlin.mpg.de/annotations/"; + public static final String MPIWG_ANNOT_CTX = "file:///annotations2"; }
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java Thu May 31 19:08:48 2012 +0200 @@ -22,7 +22,7 @@ */ public class Convert { - private String context = "file:///annotations"; + private String context = NS.MPIWG_ANNOT_CTX; private static Logger logger = Logger.getRootLogger(); private String urlBase = "http://entities.mpiwg-berlin.mpg.de/annotations/"; // TODO should go into config @@ -89,6 +89,11 @@ retQuad.add(new Quadruple(annot.xpointer, NS.RDF_NS + "type", NS.OAC_NS + "Target", context)); // is target of annotation retQuad.add(new Quadruple(annotationUrl, NS.OAC_NS + "hasTarget", annot.xpointer, context)); + if (annot.xpointer.contains("#")) { + // isPartOf base resource (without xpointer/fragment) + String baseUri = annot.xpointer.substring(0, annot.xpointer.indexOf("#")); + retQuad.add(new Quadruple(annot.xpointer, NS.DCTERMS_NS + "isPartOf", baseUri, context)); + } } else { /* * ConstrainedTarget with page number
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/RDFHandling/RDFSearcher.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/RDFHandling/RDFSearcher.java Thu May 31 19:08:48 2012 +0200 @@ -7,6 +7,7 @@ import org.openrdf.query.BindingSet; import org.openrdf.query.TupleQueryResult; +import de.mpiwg.itgroup.annotationManager.Constants.NS; import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; import de.mpiwg.itgroup.triplestoremanager.exceptions.TripleStoreHandlerException; import de.mpiwg.itgroup.triplestoremanager.owl.TripleStoreHandler; @@ -38,23 +39,27 @@ TripleStoreHandler th = TripleStoreConnection.newTripleStoreHandler(); String queryString = ""; // query for tuples with id as subject - StringBuilder whereString = new StringBuilder(String.format("<%s> ?p <http://www.w3.org/2000/10/annotationType#Comment>.", id)); - whereString.append(String.format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/annotatesDocuviewerText> ?uri.", id)); - whereString.append(String.format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/textSelection> ?xpointer.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#body> ?annotText.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#author> ?author.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#created> ?created.", id)); - whereString.append(" OPTIONAL {?annotText <http://ontologies.mpiwg-berlin.mpg.de/annotations/containsText> ?text.}"); + StringBuilder whereString = new StringBuilder(); + whereString.append(String.format("<%s> <http://www.openannotation.org/ns/hasTarget> ?target.", id)); + whereString.append("?target <http://www.purl.org/dc/terms/isPartOf> ?uri."); + whereString.append(String.format("<%s> <http://www.openannotation.org/ns/hasBody> ?body.", id)); + whereString.append("?body <http://www.w3.org/2011/content#chars> ?bodyText."); + whereString.append(String.format("<%s> <http://www.purl.org/dc/terms/creator> ?userUrl.", id)); + whereString.append(String.format("<%s> <http://www.purl.org/dc/terms/created> ?creationDate", id)); + + /* + * StringBuilder whereString = new + * StringBuilder(String.format("<%s> ?p <http://www.w3.org/2000/10/annotationType#Comment>.", id)); + * whereString.append(String + * .format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/annotatesDocuviewerText> ?uri.", id)); + * whereString.append(String.format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/textSelection> ?xpointer.", + * id)); whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#body> ?annotText.", id)); + * whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#author> ?author.", id)); + * whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#created> ?created.", id)); + * whereString.append(" OPTIONAL {?annotText <http://ontologies.mpiwg-berlin.mpg.de/annotations/containsText> ?text.}"); + */ - /* StringBuilder whereString = new StringBuilder(String.format("<%s> ?p <http://www.w3.org/2000/10/annotationType#Comment>.", id)); - whereString.append(String.format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/annotatesDocuviewerText> ?uri.", id)); - whereString.append(String.format("<%s> <http://ontologies.mpiwg-berlin.mpg.de/annotations/textSelection> ?xpointer.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#body> ?annotText.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#author> ?author.", id)); - whereString.append(String.format("<%s> <http://www.w3.org/2000/10/annotation-ns#created> ?created.", id)); - whereString.append(" OPTIONAL {?annotText <http://ontologies.mpiwg-berlin.mpg.de/annotations/containsText> ?text.}"); */ - - queryString = String.format("select distinct * where {%s}", whereString); + queryString = String.format("select * from <%s> where {%s}", context, whereString); logger.debug("RDFSearcher:" + queryString); @@ -63,15 +68,14 @@ while (results.hasNext()) { BindingSet result = results.next(); String annotUri = result.getBinding("uri").getValue().stringValue(); - String annotUser = result.getBinding("author").getValue().stringValue(); + String annotUser = result.getBinding("userUrl").getValue().stringValue(); String textString = ""; - if (result.getBinding("text") != null) { - textString = result.getBinding("text").getValue().stringValue(); + if (result.getBinding("bodyText") != null) { + textString = result.getBinding("bodyText").getValue().stringValue(); } - - String xpointer = result.getBinding("xpointer").getValue().stringValue(); - String created = result - .getBinding("created").getValue().stringValue(); + + String xpointer = result.getBinding("target").getValue().stringValue(); + String created = result.getBinding("creationDate").getValue().stringValue(); Annotation annot = new Annotation(xpointer, annotUser, created, textString, null, annotUri, id); retAnnots.add(annot); } @@ -79,10 +83,122 @@ e.printStackTrace(); throw new TripleStoreSearchError(); } + return retAnnots; + } + + /** + * Sucht im Triplestore nach Annotationen + * + * select * from <file:///annotations2> where { ?target <http://www.purl.org/dc/terms/isPartOf> + * <file:///Volumes/Schlachteplatte/Users/casties/Library/Eclipse/annotator/dev.html>. ?ann + * <http://www.openannotation.org/ns/hasTarget> ?target. ?ann <http://www.openannotation.org/ns/hasBody> ?body. ?body + * <http://www.w3.org/2011/content#chars> ?bodyText. } + * + * @param uri + * Adresse der Annotierten Ressource, in der Regel nicht mit dem xpointer, sonder die URI der kompletten Ressource + * oder NULL oder leer + * @param user + * Author der Annotationen, entweder als uri der Person oder ein Username, je nachdem wie die Annotatinen angelegt + * wurden. + * @param limit + * @param offset + * @return + * @throws TripleStoreHandlerException + * @throws TripleStoreSearchError + */ + public List<Annotation> searchByUriUser(String uri, String user, String limit, String offset) + throws TripleStoreHandlerException, TripleStoreSearchError { + + List<Annotation> retAnnots = new ArrayList<Annotation>(); + TripleStoreHandler th = TripleStoreConnection.newTripleStoreHandler(); + String queryString = ""; + + String whereString = "?s ?p <http://www.w3.org/2000/10/annotationType#Comment>."; + // whereString +="?s <http://ontologies.mpiwg-berlin.mpg.de/annotations/docuviewerText> ?link."; + + if (uri != null && !uri.equals("")) { + whereString = String.format("?target <http://www.purl.org/dc/terms/isPartOf> <%s>.", uri); + } else { + whereString = "?target <http://www.purl.org/dc/terms/isPartOf> ?uri."; + } + whereString += "?annotation <http://www.openannotation.org/ns/hasTarget> ?target."; + whereString += "?annotation <http://www.openannotation.org/ns/hasBody> ?body."; + whereString += "?body <http://www.w3.org/2011/content#chars> ?bodyText."; + + if (user != null && !user.equals("")) { + if (user.startsWith("http")) { + whereString += String.format("?annotation <http://www.purl.org/dc/terms/creator> <%s>", user); + } else { + whereString += String.format("?annotation <http://www.purl.org/dc/terms/creator> \"%s\".", user); + } + } else { + whereString += "?annotation <http://www.purl.org/dc/terms/creator> ?userUrl."; + } + + whereString += "?annotation <http://www.purl.org/dc/terms/created> ?creationDate"; + + queryString = String.format("select * from <%s> where {%s}", context, whereString); + + logger.debug("RDFSearcher:" + queryString); + + try { + TupleQueryResult results = th.querySPARQL(queryString); + + while (results.hasNext()) { + BindingSet result = results.next(); + String annotatedUri; + if (uri != null && !uri.equals("")) { + annotatedUri = uri; + } else { + annotatedUri = result.getBinding("uri").getValue().stringValue(); + } + + String annotUser; + if (user != null && !user.equals("")) { + annotUser = user; + } else { + annotUser = result.getBinding("userUrl").getValue().stringValue(); + } + + String textString = ""; + if (result.getBinding("bodyText") != null) { + textString = result.getBinding("bodyText").getValue().stringValue(); + } + String xpointer = result.getBinding("target").getValue().stringValue(); + String time = result.getBinding("creationDate").getValue().stringValue(); + String annotationUri = result.getBinding("annotation").getValue().stringValue(); + Annotation annot = new Annotation(xpointer, annotUser, time, textString, null, annotatedUri, annotationUri); + retAnnots.add(annot); + } + } catch (Exception e) { + e.printStackTrace(); + throw new TripleStoreSearchError(); + } // TODO Auto-generated method stub return retAnnots; } + public void deleteById(String id) throws TripleStoreHandlerException, TripleStoreSearchError { + if (id == null) { + return; + } + TripleStoreHandler th = TripleStoreConnection.newTripleStoreHandler(); + // delete triples with id as subject + /* + * wish Virtuoso would speak SparQL1.1... String queryString = + * String.format("WITH <%s> DELETE { <%s> ?p ?o } WHERE { <%s> ?p ?o }", context, id, id); + */ + String queryString = String.format("DELETE FROM <%s> { <%s> ?p ?o } WHERE { <%s> ?p ?o }", context, id, id); + + logger.debug("RDFSearcher:" + queryString); + + try { + th.querySPARQL(queryString); + } catch (Exception e) { + e.printStackTrace(); + throw new TripleStoreSearchError(); + } + } /** * Sucht im Triplestore nach Annotationen * @@ -98,7 +214,7 @@ * @throws TripleStoreHandlerException * @throws TripleStoreSearchError */ - public List<Annotation> searchByUriUser(String uri, String user, String limit, String offset) + public List<Annotation> searchByUriUserAlt(String uri, String user, String limit, String offset) throws TripleStoreHandlerException, TripleStoreSearchError { List<Annotation> retAnnots = new ArrayList<Annotation>(); @@ -172,24 +288,4 @@ return retAnnots; } - public void deleteById(String id) throws TripleStoreHandlerException, TripleStoreSearchError { - if (id == null) { - return; - } - TripleStoreHandler th = TripleStoreConnection.newTripleStoreHandler(); - // delete triples with id as subject - /* wish Virtuoso would speak SparQL1.1... - String queryString = String.format("WITH <%s> DELETE { <%s> ?p ?o } WHERE { <%s> ?p ?o }", context, id, id); - */ - String queryString = String.format("DELETE FROM <%s> { <%s> ?p ?o } WHERE { <%s> ?p ?o }", context, id, id); - - logger.debug("RDFSearcher:" + queryString); - - try { - th.querySPARQL(queryString); - } catch (Exception e) { - e.printStackTrace(); - throw new TripleStoreSearchError(); - } - } }
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AddAndReadAnnotations.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AddAndReadAnnotations.java Thu May 31 19:08:48 2012 +0200 @@ -93,7 +93,7 @@ } // - RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); //TODO should ge into config file String retString="<html><body><table>"; String lineFormat="<tr><td><a href=\"%s\">%s</a></td>" + @@ -195,7 +195,7 @@ // - RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); //TODO should ge into config file JSONArray ja; try { @@ -440,7 +440,7 @@ try { - return new Convert("file:///annotations").storeAnnotation(annot); + return new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); } catch (TripleStoreStoreError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error");
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorAnnotations.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorAnnotations.java Thu May 31 19:08:48 2012 +0200 @@ -68,7 +68,7 @@ boolean authenticated = isAuthenticated(entity); logger.debug("request authenticated=" + authenticated); - RDFSearcher searcher = new RDFSearcher("file:///annotations"); // TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file try { List<Annotation> annots = searcher.searchById(id); @@ -145,7 +145,7 @@ Annotation storedAnnot; try { // store Annotation - storedAnnot = new Convert("file:///annotations").storeAnnotation(annot); + storedAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); } catch (TripleStoreStoreError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); @@ -179,7 +179,7 @@ Annotation retValAnnot; try { - retValAnnot = new Convert("file:///annotations").storeAnnotation(annot); + retValAnnot = new Convert(NS.MPIWG_ANNOT_CTX).storeAnnotation(annot); } catch (TripleStoreStoreError e) { e.printStackTrace(); setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error"); @@ -314,7 +314,7 @@ setStatus(Status.CLIENT_ERROR_BAD_REQUEST); return null; } - RDFSearcher searcher = new RDFSearcher("file:///annotations"); // TODO should ge into config file + 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) { @@ -327,7 +327,7 @@ // update from posted JSON annot = updateAnnotation(storedAnnot, jo, entity); // store Annotation - storedAnnot = new Convert("file:///annotations").storeAnnotation(annot); + 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 @@ -378,7 +378,7 @@ return null; } - RDFSearcher searcher = new RDFSearcher("file:///annotations"); // TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should ge into config file try { // delete annotation
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java Thu May 31 19:08:48 2012 +0200 @@ -114,8 +114,7 @@ } /** - * checks Annotator Auth plugin authentication information from headers. - * returns userId if successful. + * checks Annotator Auth plugin authentication information from headers. returns userId if successful. * * @param entity * @return @@ -201,7 +200,15 @@ xpointers.add(xpointerString); } } - jo.put("ranges", transformToRanges(xpointers)); + if (!xpointers.isEmpty()) { + // we only look at the first xpointer + String xt = getXpointerType(xpointers.get(0)); + if (xt == "range") { + jo.put("ranges", transformToRanges(xpointers)); + } else if (xt == "area") { + jo.put("areas", transformToAreas(xpointers)); + } + } // encode Annotation URL (=id) in base64 String annotUrl = annot.getAnnotationUri(); String annotId = encodeJsonId(annotUrl); @@ -214,7 +221,6 @@ return null; } - private String getXpointerType(String xpointer) { if (xpointer.contains("#xpointer")) { return "range"; @@ -223,7 +229,7 @@ } return null; } - + private JSONArray transformToRanges(List<String> xpointers) { JSONArray ja = new JSONArray(); @@ -267,14 +273,46 @@ return ja; } + private JSONArray transformToAreas(List<String> xpointers) { + + JSONArray ja = new JSONArray(); + + Pattern rg = Pattern.compile("#xywh=(\\w*:)([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)"); + + try { + for (String xpointer : xpointers) { + String decoded = URLDecoder.decode(xpointer, "utf-8"); + Matcher m = rg.matcher(decoded); + + if (m.find()) { + { + JSONObject jo = new JSONObject(); + String unit = m.group(1); + jo.put("x", m.group(2)); + jo.put("y", m.group(3)); + jo.put("width", m.group(4)); + jo.put("height", m.group(5)); + ja.put(jo); + } + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return ja; + } + /** * creates an Annotation object with data from JSON. * - * uses the specification from the annotator project: {@link https - * ://github.com/okfn/annotator/wiki/Annotation-format} + * uses the specification from the annotator project: {@link https ://github.com/okfn/annotator/wiki/Annotation-format} * - * The username will be transformed to an URI if not given already as URI, - * if not it will set to the MPIWG namespace defined in + * The username will be transformed to an URI if not given already as URI, if not it will set to the MPIWG namespace defined in * de.mpiwg.itgroup.annotationManager.Constants.NS * * @param jo @@ -365,7 +403,7 @@ if (jo.has("areas")) { JSONObject area = jo.getJSONArray("areas").getJSONObject(0); String x = area.getString("x"); - String y = area.getString("end"); + String y = area.getString("y"); String width = "0"; String height = "0"; if (area.has("width")) {
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java Thu May 31 19:08:48 2012 +0200 @@ -19,6 +19,7 @@ import org.restlet.representation.StringRepresentation; import org.restlet.resource.Get; +import de.mpiwg.itgroup.annotationManager.Constants.NS; import de.mpiwg.itgroup.annotationManager.Errors.TripleStoreSearchError; import de.mpiwg.itgroup.annotationManager.RDFHandling.Annotation; import de.mpiwg.itgroup.annotationManager.RDFHandling.RDFSearcher; @@ -59,7 +60,7 @@ String limit = form.getFirstValue("limit"); String offset = form.getFirstValue("offset"); - RDFSearcher searcher = new RDFSearcher("file:///annotations"); // TODO should go into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO should go into config file JSONArray ja; try { @@ -128,7 +129,7 @@ return null; } - RDFSearcher searcher = new RDFSearcher("file:///annotations"); // TODO + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); // TODO // should // ge // into
--- a/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/SearchAnnotations.java Thu May 31 11:57:50 2012 +0200 +++ b/src/main/java/de/mpiwg/itgroup/annotationManager/restlet/SearchAnnotations.java Thu May 31 19:08:48 2012 +0200 @@ -89,7 +89,7 @@ return null; } - RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); //TODO should ge into config file String retString="<html><body><table>"; String lineFormat="<tr><td><a href=\"%s\">%s</a></td>" + @@ -190,7 +190,7 @@ // - RDFSearcher searcher = new RDFSearcher("file:///annotations"); //TODO should ge into config file + RDFSearcher searcher = new RDFSearcher(NS.MPIWG_ANNOT_CTX); //TODO should ge into config file JSONArray ja; try {