changeset 61:b8ef15c8c4a5

implemented new shape format for image annotations. minor cleanups.
author casties
date Thu, 22 Nov 2012 17:38:53 +0100
parents 99d9afcfd04d
children 15569aa35d62
files src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResources.java
diffstat 3 files changed, 153 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java	Tue Nov 20 19:43:12 2012 +0100
+++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java	Thu Nov 22 17:38:53 2012 +0100
@@ -54,21 +54,18 @@
         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)) {
+            if (!annot.isActionAllowed("read", authUser, store)) {
                 setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!");
                 return null;
             }
@@ -84,37 +81,36 @@
     }
 
     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();
-             }
-           }
-        
+
+        Form form = getRequest().getResourceRef().getQueryAsForm();
+        String sortBy = null;
+        for (Parameter parameter : form) {
+            if (parameter.getName().equals("sortBy")) {
+                sortBy = parameter.getValue();
+            }
+        }
+
         AnnotationStore store = getAnnotationStore();
         ArrayList<JSONObject> results = new ArrayList<JSONObject>();
-       
-       	List<Annotation> annotations = store.getAnnotations(null, null);
+
+        List<Annotation> 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);
-    	}
-    	
+            // 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 {
@@ -129,11 +125,7 @@
         return new JsonRepresentation(result);
     }
 
-       	
-        
-	
-
-	/**
+    /**
      * POST with JSON content-type. Creates a new Annotation.
      * 
      * @return
@@ -143,8 +135,8 @@
         logger.debug("AnnotatorAnnotations doPostJSON!");
         // set headers
         setCorsHeaders();
-        
-        // do authentication TODO: who's allowed to create? 
+
+        // do authentication TODO: who's allowed to create?
         Person authUser = Person.createPersonWithId(this.checkAuthToken(entity));
         logger.debug("request authenticated=" + authUser);
         if (authUser == null) {
@@ -221,7 +213,7 @@
                 setStatus(Status.CLIENT_ERROR_NOT_FOUND);
                 return null;
             }
-            if (! storedAnnot.isActionAllowed("update", authUser, store)) {
+            if (!storedAnnot.isActionAllowed("update", authUser, store)) {
                 setStatus(Status.CLIENT_ERROR_FORBIDDEN);
                 return null;
             }
@@ -271,12 +263,12 @@
         AnnotationStore store = getAnnotationStore();
         Annotation annot = store.getAnnotationById(id);
         if (annot != null) {
-            if (! annot.isActionAllowed("delete", authUser, store)) {
+            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);
--- a/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java	Tue Nov 20 19:43:12 2012 +0100
+++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java	Thu Nov 22 17:38:53 2012 +0100
@@ -132,7 +132,8 @@
 
     /**
      * Checks Annotator Auth plugin authentication information from headers.
-     * Returns userId if successful. Returns "anonymous" in non-authorization mode.
+     * Returns userId if successful. Returns "anonymous" in non-authorization
+     * mode.
      * 
      * @param entity
      * @return
@@ -183,7 +184,8 @@
      * creates Annotator-JSON from an Annotation object.
      * 
      * @param annot
-     * @param forAnonymous TODO
+     * @param forAnonymous
+     *            TODO
      * @return
      */
     public JSONObject createAnnotatorJson(Annotation annot, boolean forAnonymous) {
@@ -235,10 +237,10 @@
                 if (xt == FragmentTypes.XPOINTER) {
                     jo.put("ranges", transformToRanges(fragments));
                 } else if (xt == FragmentTypes.AREA) {
-                    jo.put("areas", transformToAreas(fragments));
+                    jo.put("shapes", transformToShapes(fragments));
                 }
             }
-            
+
             /*
              * permissions
              */
@@ -281,11 +283,11 @@
             if (readPerm != null) {
                 readPerms.put(readPerm.getIdString());
             }
-            
+
             /*
              * tags
              */
-            Set<String> tagset = annot.getTags(); 
+            Set<String> tagset = annot.getTags();
             if (tagset != null) {
                 JSONArray tags = new JSONArray();
                 jo.put("tags", tags);
@@ -293,7 +295,7 @@
                     tags.put(tag);
                 }
             }
-            
+
             /*
              * id
              */
@@ -303,84 +305,99 @@
             jo.put("id", annotId);
             return jo;
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            logger.error("Unable to create AnnotatorJSON!", e);
         }
         return null;
     }
 
     private JSONArray transformToRanges(List<String> xpointers) {
-
         JSONArray ja = new JSONArray();
-
         Pattern rg = Pattern
                 .compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)");
         Pattern rg1 = Pattern.compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)");
-
         try {
             for (String xpointer : xpointers) {
                 // String decoded = URLDecoder.decode(xpointer, "utf-8");
                 String decoded = xpointer;
                 Matcher m = rg.matcher(decoded);
-
                 if (m.find()) {
-                    {
-                        JSONObject jo = new JSONObject();
-                        jo.put("start", m.group(1));
-                        jo.put("startOffset", m.group(2));
-                        jo.put("end", m.group(3));
-                        jo.put("endOffset", m.group(4));
-                        ja.put(jo);
-                    }
+                    JSONObject jo = new JSONObject();
+                    jo.put("start", m.group(1));
+                    jo.put("startOffset", m.group(2));
+                    jo.put("end", m.group(3));
+                    jo.put("endOffset", m.group(4));
+                    ja.put(jo);
                 }
                 m = rg1.matcher(xpointer);
                 if (m.find()) {
                     JSONObject jo = new JSONObject();
                     jo.put("start", m.group(1));
                     jo.put("startOffset", m.group(2));
-
                     ja.put(jo);
                 }
             }
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            logger.error("Unable to transform to ranges!", e);
         }
         return ja;
     }
 
-    private JSONArray transformToAreas(List<String> xpointers) {
-
+    private JSONArray transformToShapes(List<String> xpointers) {
         JSONArray ja = new JSONArray();
-
-        Pattern rg = Pattern.compile("xywh=(\\w*:)([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)");
-
+        Pattern rg = Pattern.compile("xywh=(\\w*):([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)");
         try {
             for (String xpointer : xpointers) {
-                // String decoded = URLDecoder.decode(xpointer, "utf-8");
                 String decoded = xpointer;
                 Matcher m = rg.matcher(decoded);
-
                 if (m.find()) {
-                    {
-                        JSONObject jo = new JSONObject();
-                        @SuppressWarnings("unused")
-                        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);
+                    String units = m.group(1);
+                    float x = getFloat(m.group(2));
+                    float y = getFloat(m.group(3));
+                    float width = getFloat(m.group(4));
+                    float height = getFloat(m.group(5));
+                    JSONObject shape = new JSONObject();
+                    JSONObject geom = new JSONObject();
+                    geom.put("units", units);
+                    geom.put("x", x);
+                    geom.put("y", y);
+                    if (width == 0 || height == 0) {
+                        shape.put("type", "point");
+                        shape.put("geometry", geom);
+                    } else {
+                        shape.put("type", "rectangle");
+                        geom.put("width", width);
+                        geom.put("height", height);
+                        shape.put("geometry", geom);
                     }
+                    ja.put(shape);
                 }
             }
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            logger.error("Unable to transform to shapes!", e);
         }
         return ja;
     }
 
+    protected String parseShape(JSONObject shape) throws JSONException {
+        String fragment = null;
+        String type = shape.getString("type");
+        JSONObject geom = shape.getJSONObject("geometry");
+        if (type.equalsIgnoreCase("point")) {
+            String x = geom.getString("x");
+            String y = geom.getString("y");
+            fragment = String.format("xywh=fraction:%s,%s,0,0", x, y);
+        } else if (type.equalsIgnoreCase("point")) {
+            String x = geom.getString("x");
+            String y = geom.getString("y");
+            String width = shape.getString("width");
+            String height = shape.getString("height");
+            fragment = String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height);
+        } else {
+            logger.error("Unable to parse this shape: " + shape);
+        }
+        return fragment;
+    }
+
     protected String parseArea(JSONObject area) throws JSONException {
         String x = area.getString("x");
         String y = area.getString("y");
@@ -538,7 +555,7 @@
         }
 
         /*
-         * create xpointer from the first range/area
+         * create fragment from the first range/area
          */
         try {
             if (jo.has("ranges")) {
@@ -551,6 +568,17 @@
             // nothing to do
         }
         try {
+            if (jo.has("shapes")) {
+                JSONObject shapes = jo.getJSONArray("shapes").getJSONObject(0);
+                annot.setFragmentType(FragmentTypes.AREA);
+                String fragment = parseShape(shapes);
+                annot.setTargetFragment(fragment);
+            }
+        } catch (JSONException e) {
+            // nothing to do
+        }
+        // deprecated areas type
+        try {
             if (jo.has("areas")) {
                 JSONObject area = jo.getJSONArray("areas").getJSONObject(0);
                 annot.setFragmentType(FragmentTypes.AREA);
@@ -600,11 +628,11 @@
             annot.setTags(tagset);
         }
 
-        
         return annot;
     }
 
-    @SuppressWarnings("unused") // i in for loop
+    @SuppressWarnings("unused")
+    // i in for loop
     protected Actor getActorFromPermissions(JSONArray perms) throws JSONException {
         Actor actor = null;
         for (int i = 0; i < perms.length(); ++i) {
@@ -621,4 +649,11 @@
         return actor;
     }
 
+    public float getFloat(String s) {
+        try {
+            return Float.parseFloat(s);
+        } catch (NumberFormatException e) {
+        }
+        return 0f;
+    }
 }
--- a/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResources.java	Tue Nov 20 19:43:12 2012 +0100
+++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResources.java	Thu Nov 22 17:38:53 2012 +0100
@@ -17,12 +17,11 @@
 import de.mpiwg.itgroup.annotations.Resource;
 import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
 
-
 /**
- * API for accessing tags in the Annotation store.
+ * API for accessing resource objects in the Annotation store.
  * 
  * @author dwinter
- *
+ * 
  */
 public class AnnotatorResources extends AnnotatorResourceImpl {
     protected String getAllowedMethodsForHeader() {
@@ -30,62 +29,58 @@
     }
 
     /**
-     * GET with JSON content-type.
-     * Parameters: 
-     *   user: short user name
-     *   uri: user uri
-     *   
+     * GET with JSON content-type. 
+     * Parameters: user: short user name uri: user uri
+     * 
      * @param entity
      * @return
      */
     @Get("json")
     public Representation doGetJSON(Representation entity) {
-        logger.debug("AnnotatorGroups doGetJSON!");
+        logger.debug("AnnotatorResources doGetJSON!");
         setCorsHeaders();
-       
+
         String jsonId = (String) getRequest().getAttributes().get("id");
         String uri = decodeJsonId(jsonId);
-        
+
         logger.debug("resources-id=" + uri);
 
-        if (uri==null){
-        return getAllResources();
+        if (uri == null) {
+            return getAllResources();
         } else {
-
-        	return getResource(uri);
+            return getResource(uri);
         }
     }
-    
-    protected Representation getResource(String uri){
-    	  AnnotationStore store = getAnnotationStore();
-    	  //String tagUri=NS.MPIWG_TAGS_URL+id;
-          Node tagNode = store.getResourceNodeByUri(uri);
-          Resource resource = store.createResourceFromNode(tagNode);
-          JSONObject jo = new JSONObject();
-          try {
-              jo.put("id", encodeJsonId(resource.getUri()));
-              jo.put("uri", resource.getUri());
-          } catch (JSONException e) {
-          }
-          
-          return new JsonRepresentation(jo);
+
+    protected Representation getResource(String uri) {
+        AnnotationStore store = getAnnotationStore();
+        Node resNode = store.getResourceNodeByUri(uri);
+        Resource resource = store.createResourceFromNode(resNode);
+        JSONObject jo = new JSONObject();
+        try {
+            jo.put("id", encodeJsonId(resource.getUri()));
+            jo.put("uri", resource.getUri());
+        } catch (JSONException e) {
+        }
+
+        return new JsonRepresentation(jo);
     }
-	protected Representation getAllResources() {
-		JSONArray results = new JSONArray();
+
+    protected Representation getAllResources() {
+        JSONArray results = new JSONArray();
         AnnotationStore store = getAnnotationStore();
-        
-       
-            List<Resource> resources = store.getResources(null, null);
-            for (Resource resource : resources) {
-                JSONObject jo = new JSONObject();
-                try {
-                	 jo.put("id", encodeJsonId(resource.getUri()));
-                     jo.put("uri", resource.getUri());
-                } catch (JSONException e) {
-                }
-                results.put(jo);
+
+        List<Resource> resources = store.getResources(null, null);
+        for (Resource resource : resources) {
+            JSONObject jo = new JSONObject();
+            try {
+                jo.put("id", encodeJsonId(resource.getUri()));
+                jo.put("uri", resource.getUri());
+            } catch (JSONException e) {
             }
-        
+            results.put(jo);
+        }
+
         // assemble result object
         JSONObject result = new JSONObject();
         try {
@@ -98,8 +93,6 @@
         logger.debug("sending:");
         logger.debug(result);
         return new JsonRepresentation(result);
-	}        	
-        
+    }
 
-    
 }