changeset 13:9393c9c9b916

saves annotations now!
author casties
date Wed, 21 Mar 2012 15:23:57 +0100
parents 2e5d526079de
children 0f64de5fff5a
files .classpath WebContent/WEB-INF/web.xml.template src/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorAnnotations.java src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java
diffstat 7 files changed, 226 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/.classpath	Wed Mar 21 11:09:20 2012 +0100
+++ b/.classpath	Wed Mar 21 15:23:57 2012 +0100
@@ -42,7 +42,11 @@
 			<attribute name="owner.project.facets" value="jst.web"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
-	<classpathentry kind="lib" path="libs/joda-time-2.1.jar"/>
+	<classpathentry kind="lib" path="libs/joda-time-2.1.jar">
+		<attributes>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/JDK 1.6"/>
 	<classpathentry kind="output" path="build/classes"/>
 </classpath>
--- a/WebContent/WEB-INF/web.xml.template	Wed Mar 21 11:09:20 2012 +0100
+++ b/WebContent/WEB-INF/web.xml.template	Wed Mar 21 15:23:57 2012 +0100
@@ -4,38 +4,36 @@
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
-<display-name>RESTfulJavaWebServices-Restlet</display-name>
-<!-- Application classname -->
-<context-param>
-<param-name>org.restlet.application</param-name>
-<param-value>de.mpiwg.itgroup.annotationManager.restlet.RestServer</param-value>
-</context-param>
-
-<context-param>
-<param-name>de.mpiwg.itgroup.annotationManager.jaas.configFilePath</param-name>
-<param-value>file:///etc/jaasAuth.conf</param-value>
-</context-param>
-
-<context-param>
-<param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser</param-name>
-<param-value>USERNAME</param-value>
-</context-param>
-
-<context-param>
-<param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword</param-name>
-<param-value>PASSWORD</param-value>
-</context-param>
-<!-- Restletadapter -->
-<servlet>
-<servlet-name>RestletServlet</servlet-name>
-<servlet-class>
-org.restlet.ext.servlet.ServerServlet
-</servlet-class>
-</servlet>
-
-<!-- Catchallrequests -->
-<servlet-mapping>
-<servlet-name>RestletServlet</servlet-name>
-<url-pattern>/annotator/*</url-pattern>
-</servlet-mapping>
+    <display-name>RESTfulJavaWebServices-Restlet</display-name>
+    <!-- Application classname -->
+    <context-param>
+        <param-name>org.restlet.application</param-name>
+        <param-value>de.mpiwg.itgroup.annotationManager.restlet.RestServer</param-value>
+    </context-param>
+    <context-param>
+        <param-name>de.mpiwg.itgroup.annotationManager.jaas.configFilePath</param-name>
+        <param-value>file:///etc/jaasAuth.conf</param-value>
+    </context-param>
+    <context-param>
+        <param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser</param-name>
+        <param-value>USERNAME</param-value>
+    </context-param>
+    <context-param>
+        <param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword</param-name>
+        <param-value>PASSWORD</param-value>
+    </context-param>
+    <context-param>
+        <param-name>de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreConnectionURL</param-name>
+        <param-value>jdbc:virtuoso://virtuoso.mpiwg-berlin.mpg.de:1111</param-value>
+    </context-param>
+    <!-- Restletadapter -->
+    <servlet>
+        <servlet-name>RestletServlet</servlet-name>
+        <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
+    </servlet>
+    <!-- Catchallrequests -->
+    <servlet-mapping>
+        <servlet-name>RestletServlet</servlet-name>
+        <url-pattern>/annotator/*</url-pattern>
+    </servlet-mapping>
 </web-app>
\ No newline at end of file
--- a/src/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java	Wed Mar 21 11:09:20 2012 +0100
+++ b/src/de/mpiwg/itgroup/annotationManager/RDFHandling/Convert.java	Wed Mar 21 15:23:57 2012 +0100
@@ -298,7 +298,10 @@
 			String user = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUser");
 			String pw = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreUserPassword");
 			String connectionURL = context.getParameters().getFirstValue("de.mpiwg.itgroup.annotationManager.virtuoso.tripleStoreConnectionURL");
-			
+			if (user == null || pw == null || connectionURL == null) {
+			    logger.error(String.format("Missing triplestore parameters! (user=%s pw=%s url=%s)", user, pw, connectionURL));
+			    throw new TripleStoreStoreError();
+			}
 			//TripleStoreHandler th = new TripleStoreHandler("jdbc:virtuoso://virtuoso.mpiwg-berlin.mpg.de:1111", user, pw);
 			TripleStoreHandler th = new TripleStoreHandler(connectionURL, user, pw);
 				
--- a/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorAnnotations.java	Wed Mar 21 11:09:20 2012 +0100
+++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorAnnotations.java	Wed Mar 21 15:23:57 2012 +0100
@@ -51,7 +51,7 @@
      */
     @Get("json")
     public Representation doGetJSON(Representation entity) {
-
+        logger.debug("AnnotatorAnnotations doGetJSON!");
         doOptions(entity);
         // TODO: what to do with authentication?
         boolean authenticated = isAuthenticated(entity);
@@ -73,9 +73,9 @@
 
             results = new JSONArray();
             for (Convert.Annotation annot : annots) {
-                JSONObject jo = annot2AnnotatorJSON(annot);
+                JSONObject jo = createAnnotatorJson(annot);
                 if (jo != null) {
-                    results.put(annot2AnnotatorJSON(annot));
+                    results.put(createAnnotatorJson(annot));
                 } else {
                     setStatus(Status.SERVER_ERROR_INTERNAL, "JSon Error");
                     return null;
@@ -98,22 +98,27 @@
     }
 
     /**
-     * POST with JSON content-type. json hash: username: name des users xpointer: xpointer auf den Ausschnitt (incl. der URL des
+     * 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) {
-        JsonRepresentation jrep;
-        Annotation annot;
+        logger.debug("AnnotatorAnnotations doPostJSON!");
+        // set headers
+        setCorsHeaders();
+        Annotation annot = null;
         try {
-            jrep = new JsonRepresentation(entity);
+            JsonRepresentation jrep = new JsonRepresentation(entity);
             JSONObject jo = jrep.getJsonObject();
             if (jo == null) {
                 setStatus(Status.SERVER_ERROR_INTERNAL);
                 return null;
             }
+            // get Annotation object from posted JSON
             annot = createAnnotation(jo, entity);
         } catch (IOException e1) {
             setStatus(Status.SERVER_ERROR_INTERNAL);
@@ -122,19 +127,21 @@
             setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
             return null;
         }
-        if (annot.xpointer == null || annot.creator == null) {
+        if (annot == null || annot.xpointer == null || annot.creator == null) {
             setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
             return null;
         }
-        Annotation retVal;
+        Annotation storedAnnot;
         try {
-            retVal = new Convert("file:///annotations").storeAnnotation(annot);
+            // store Annotation
+            storedAnnot = new Convert("file:///annotations").storeAnnotation(annot);
         } catch (TripleStoreStoreError e) {
             e.printStackTrace();
             setStatus(Status.SERVER_ERROR_INTERNAL, "TripleStore Error");
             return null;
         }
-        JSONObject jo = annot2AnnotatorJSON(retVal);
+        // return stored annotation
+        JSONObject jo = createAnnotatorJson(storedAnnot);
         JsonRepresentation retRep = new JsonRepresentation(jo);
         return retRep;
     }
@@ -147,6 +154,7 @@
      */
     @Post("html")
     public Representation doPostHtml(Representation entity) {
+        logger.debug("AnnotatorAnnotations doPostHtml!");
         Convert.Annotation annot;
         annot = handleForm(entity);
         if (annot.xpointer == null || annot.creator == null) {
@@ -177,16 +185,15 @@
         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.
+     * @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
+     *            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
      */
@@ -213,7 +220,7 @@
         User authUser = null;
 
         if (userFromForm == null) {
-            authUser = handleBasicAuthentification(entity);
+            authUser = getHttpAuthUser(entity);
         }
 
         // weder BasicAuth noch FormAuth
@@ -228,17 +235,17 @@
             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;
+        // 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+username;
-        
-        if (mode.equals("complexAnnotation")){// Annotation mit text in externer ressource
-            
+            username = NS.MPIWG_PERSONS + 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 {
@@ -249,7 +256,7 @@
                 return null;
             }
             try {
-                annot= new Convert.Annotation(xpointer, username, null, text, type, newAnnot.getString("node_uri"));
+                annot = new Convert.Annotation(xpointer, username, null, text, type, newAnnot.getString("node_uri"));
             } catch (JSONException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
@@ -257,8 +264,7 @@
                 return null;
             }
         } else
-            annot = new Convert.Annotation(xpointer, username, null, text,
-                type, url);
+            annot = new Convert.Annotation(xpointer, username, null, text, type, url);
         return annot;
     }
 
--- a/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java	Wed Mar 21 11:09:20 2012 +0100
+++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java	Wed Mar 21 15:23:57 2012 +0100
@@ -20,6 +20,7 @@
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.restlet.data.ClientInfo;
 import org.restlet.data.Form;
 import org.restlet.data.Status;
 import org.restlet.representation.Representation;
@@ -45,12 +46,45 @@
     }
 
     /**
+     * returns a hex String of a SHA256 digest of text.
+     * 
+     * @param text
+     * @return
+     */
+    public String getSha256Digest(String text) {
+        String digest = null;
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-256");
+            md.update(text.getBytes("UTF-8"));
+            byte[] dg = md.digest();
+            StringBuffer sb = new StringBuffer();
+            for (byte b : dg) {
+                sb.append(String.format("%02x", b));
+            }
+            digest = sb.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return digest;
+    }
+
+    /**
      * Handle options request to allow CORS for AJAX.
      * 
      * @param entity
      */
     @Options
     public void doOptions(Representation entity) {
+        logger.debug("AnnotatorResourceImpl doOptions!");
+        setCorsHeaders();
+    }
+
+    /**
+     * set headers to allow CORS for AJAX.
+     */
+    protected void setCorsHeaders() {
         Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
         if (responseHeaders == null) {
             responseHeaders = new Form();
@@ -80,49 +114,42 @@
      * @return
      */
     public boolean isAuthenticated(Representation entity) {
-        // get authToken
+        return (checkAuthToken(entity) != null);
+    }
+
+    /**
+     * checks Annotator Auth plugin authentication information from headers. returns userId if successful.
+     * 
+     * @param entity
+     * @return
+     */
+    public String checkAuthToken(Representation entity) {
         Form requestHeaders = (Form) getRequest().getAttributes().get("org.restlet.http.headers");
         String consumerKey = requestHeaders.getFirstValue("x-annotator-consumer-key", true);
         if (consumerKey == null) {
-            return false;
+            return null;
         }
+        // get stored consumer secret for key
         RestServer restServer = (RestServer) getApplication();
         String consumerSecret = restServer.getConsumerSecret(consumerKey);
         logger.debug("requested consumer key=" + consumerKey + " secret=" + consumerSecret);
         if (consumerSecret == null) {
-            return false;
+            return null;
         }
         String userId = requestHeaders.getFirstValue("x-annotator-user-id", true);
         String issueTime = requestHeaders.getFirstValue("x-annotator-auth-token-issue-time", true);
         if (userId == null || issueTime == null) {
-            return false;
+            return null;
         }
         // compute hashed token based on the values we know
         // computed_token = hashlib.sha256(consumer.secret + user_id + issue_time).hexdigest()
-        String computedToken;
-        try {
-            MessageDigest md = MessageDigest.getInstance("SHA-256");
-            String computedString = consumerSecret + userId + issueTime;
-            md.update(computedString.getBytes("UTF-8"));
-            byte[] dg = md.digest();
-            StringBuffer sb = new StringBuffer();
-            for (byte b : dg) {
-                sb.append(String.format("%02x", b));
-            }
-            computedToken = sb.toString();
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return false;
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-            return false;
-        }
+        String computedToken = getSha256Digest(consumerSecret + userId + issueTime);
         // compare to the token we got
         String authToken = requestHeaders.getFirstValue("x-annotator-auth-token", true);
         logger.debug(String.format("got: authToken=%s consumerSecret=%s userId=%s issueTime=%s", authToken, consumerSecret, userId,
                 issueTime));
         if (!computedToken.equals(authToken)) {
-            return false;
+            return null;
         }
         // check token lifetime
         // validity = iso8601.parse_date(issue_time)
@@ -140,10 +167,10 @@
             e.printStackTrace();
         }
         if (tokenValidity == null || tokenValidity.isAfterNow() || tokenExpiry.isBeforeNow()) {
-            return false;
+            return null;
         }
         // must be ok then
-        return true;
+        return userId;
     }
 
     /**
@@ -152,36 +179,45 @@
      * @param annot
      * @return
      */
-    public JSONObject annot2AnnotatorJSON(Convert.Annotation annot) {
+    public JSONObject createAnnotatorJson(Convert.Annotation annot) {
+        boolean makeUserObject = true;
         JSONObject jo = new JSONObject();
         try {
             jo.put("text", annot.text);
             jo.put("uri", annot.url);
 
-            JSONObject userObject = new JSONObject();
-            userObject.put("id", annot.creator);
-
-            RestServer restServer = (RestServer) getApplication();
-
-            String userID = annot.creator;
-            if (userID.startsWith(NS.MPIWG_PERSONS)) {
-                userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne NAMESPACE
+            if (makeUserObject) {
+                // create user object
+                JSONObject userObject = new JSONObject();
+                // save creator as uri
+                userObject.put("uri", annot.creator);
+                // make short user id
+                String userID = annot.creator;
+                if (userID.startsWith(NS.MPIWG_PERSONS)) {
+                    userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne NAMESPACE
+                }
+                // save as id
+                userObject.put("id", userID);
+                // get full name
+                RestServer restServer = (RestServer) getApplication();
+                String userName = restServer.getUserNameFromLdap(userID);
+                userObject.put("name", userName);
+                // save user object
+                jo.put("user", userObject);
+            } else {
+                // save user as string
+                jo.put("user", annot.creator);
             }
-            String userName = restServer.getUserNameFromLdap(userID);
-            userObject.put("name", userName);
 
-            jo.put("user", userObject);
-
-            List<String> xpointer = new ArrayList<String>();
-
+            List<String> xpointers = new ArrayList<String>();
             if (annot.xpointers == null || annot.xpointers.size() == 0)
-                xpointer.add(annot.xpointer);
+                xpointers.add(annot.xpointer);
             else {
                 for (String xpointerString : annot.xpointers) {
-                    xpointer.add(xpointerString);
+                    xpointers.add(xpointerString);
                 }
             }
-            jo.put("ranges", transformToRanges(xpointer));
+            jo.put("ranges", transformToRanges(xpointers));
             jo.put("id", annot.annotationUri);
             return jo;
         } catch (JSONException e) {
@@ -235,56 +271,56 @@
     }
 
     /**
-     * creates an Annotation object with data from JSON.
-     * uses the specification from the annotator project.
+     * creates an Annotation object with data from JSON. 
+     * 
+     * uses the specification from the annotator project: {@link https://github.com/okfn/annotator/wiki/Annotation-format}
      * 
-     * @see{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
+     * de.mpiwg.itgroup.annotationManager.Constants.NS
      * 
-     * 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
      * @return
      * @throws JSONException
      */
     public Convert.Annotation createAnnotation(JSONObject jo, Representation entity) throws JSONException {
-        Convert.Annotation annot;
         String url = jo.getString("uri");
         String text = jo.getString("text");
-    
-        String username = null;
-        if (jo.has("user")) { 
-            // not required, if no username given authuser
-            // will be used otherwise username and password
-            // has to be submitted
-            JSONObject user = jo.getJSONObject("user");
-            if (user.has("id")) {
-                username = user.getString("id");
-                if (!user.has("password")) {
-                    User authUser = handleBasicAuthentification(entity);
-                    if (authUser == null) {
-                        setStatus(Status.CLIENT_ERROR_FORBIDDEN);
-                        return null;
-                    }
-                    username = authUser.getIdentifier();
-                } else {
-                    String password = user.getString("password");
-                    if (!((RestServer) getApplication()).authenticate(username, password, getRequest())) {
-                        setStatus(Status.CLIENT_ERROR_FORBIDDEN);
-                        return null;
-                    }
-                }
-            }
-    
-        } else {
-            User authUser = handleBasicAuthentification(entity);
-            if (authUser == null) {
+
+        // check authentication
+        String authUser = checkAuthToken(entity);
+        if (authUser == null) {
+            // try http auth
+            User httpUser = getHttpAuthUser(entity);
+            if (httpUser == null) {
                 setStatus(Status.CLIENT_ERROR_FORBIDDEN);
                 return null;
             }
-            username = authUser.getIdentifier();
+            authUser = httpUser.getIdentifier();
         }
-    
+        // username not required, if no username given authuser will be used
+        String username = null;
+        String userUri = null;
+        if (jo.has("user")) {
+            if (jo.get("user") instanceof String) {
+                // user is just a String
+                username = jo.getString("user");
+                // TODO: what if username and authUser are different?
+            } else {
+                // user is an object
+                JSONObject user = jo.getJSONObject("user");
+                if (user.has("id")) {
+                    username = user.getString("id");
+                }
+                if (user.has("uri")) {
+                    userUri = user.getString("uri");
+                }
+            }
+        }
+        if (username == null) {
+            username = authUser;
+        }
+        
+        // create xpointer
         String xpointer;
         if (jo.has("ranges")) {
             JSONObject ranges = jo.getJSONArray("ranges").getJSONObject(0);
@@ -292,7 +328,7 @@
             String end = ranges.getString("end");
             String startOffset = ranges.getString("startOffset");
             String endOffset = ranges.getString("endOffset");
-    
+
             try {
                 xpointer = url
                         + "#"
@@ -307,13 +343,36 @@
         } else {
             xpointer = url;
         }
-    
+
         // username should be a URI, if not it will set to the MPIWG namespace defined in
         // de.mpiwg.itgroup.annotationManager.Constants.NS
-        if (!username.startsWith("http"))
-            username = NS.MPIWG_PERSONS + username;
-    
-        return new Convert.Annotation(xpointer, username, null, text, null);
+        if (userUri == null) {
+            if (username.startsWith("http")) {
+                userUri = username;
+            } else {
+                userUri = NS.MPIWG_PERSONS + username;
+            }
+        }
+        return new Convert.Annotation(xpointer, userUri, null, text, null);
+    }
+
+    /**
+     * returns the logged in User.
+     * 
+     * @param entity
+     * @return
+     */
+    protected User getHttpAuthUser(Representation entity) {
+        RestServer restServer = (RestServer) getApplication();
+        if (!restServer.authenticate(getRequest(), getResponse())) {
+            // Not authenticated
+            return null;
+        }
+
+        ClientInfo ci = getRequest().getClientInfo();
+        logger.debug(ci);
+        return getRequest().getClientInfo().getUser();
+
     }
 
 }
--- a/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java	Wed Mar 21 11:09:20 2012 +0100
+++ b/src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorSearch.java	Wed Mar 21 15:23:57 2012 +0100
@@ -69,9 +69,9 @@
 
             ja = new JSONArray();
             for (Convert.Annotation annot : annots) {
-                JSONObject jo = annot2AnnotatorJSON(annot);
+                JSONObject jo = createAnnotatorJson(annot);
                 if (jo != null) {
-                    ja.put(annot2AnnotatorJSON(annot));
+                    ja.put(createAnnotatorJson(annot));
                 } else {
                     setStatus(Status.SERVER_ERROR_INTERNAL, "JSON Error");
                     return null;
--- a/src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java	Wed Mar 21 11:09:20 2012 +0100
+++ b/src/de/mpiwg/itgroup/annotationManager/restlet/RestServer.java	Wed Mar 21 15:23:57 2012 +0100
@@ -186,8 +186,8 @@
 
         Router router = new Router(getContext());
 
-        router.attach("/annotations", AddAndReadAnnotations.class);
-        router.attach("/search", AnnotatorSearch.class); // annotator api askes
+        router.attach("/annotator/annotations", AnnotatorAnnotations.class);
+        router.attach("/annotator/search", AnnotatorSearch.class); // annotator api askes
                                                          // for different uris
                                                          // for search and
                                                          // adding