annotate src/main/java/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java @ 23:a3e324009990

now Mavenified! removed tiny-mce javascript from html frontend. still needs TripleStoreManager project in Eclipse. jsontoken 1.1 has to be built manually.
author casties
date Tue, 03 Apr 2012 13:05:05 +0200
parents src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java@0f4428febcc6
children d9809412b67f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
1 /**
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
2 * Base class for Annotator resource classes.
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
3 */
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
4 package de.mpiwg.itgroup.annotationManager.restlet;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
5
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
6 import java.io.UnsupportedEncodingException;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
7 import java.net.URLDecoder;
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
8 import java.net.URLEncoder;
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
9 import java.security.InvalidKeyException;
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
10 import java.security.SignatureException;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
11 import java.util.ArrayList;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
12 import java.util.List;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
13 import java.util.regex.Matcher;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
14 import java.util.regex.Pattern;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
15
14
0f64de5fff5a try to use javax.xml.bind.DatatypeConverter
casties
parents: 13
diff changeset
16 import javax.xml.bind.DatatypeConverter;
0f64de5fff5a try to use javax.xml.bind.DatatypeConverter
casties
parents: 13
diff changeset
17
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
18 import net.oauth.jsontoken.Checker;
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
19 import net.oauth.jsontoken.JsonToken;
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
20 import net.oauth.jsontoken.JsonTokenParser;
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
21 import net.oauth.jsontoken.SystemClock;
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
22 import net.oauth.jsontoken.crypto.HmacSHA256Verifier;
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
23 import net.oauth.jsontoken.crypto.Verifier;
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
24
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
25 import org.apache.log4j.Logger;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
26 import org.json.JSONArray;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
27 import org.json.JSONException;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
28 import org.json.JSONObject;
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
29 import org.restlet.data.ClientInfo;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
30 import org.restlet.data.Form;
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
31 import org.restlet.data.Status;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
32 import org.restlet.representation.Representation;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
33 import org.restlet.resource.Options;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
34 import org.restlet.resource.ServerResource;
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
35 import org.restlet.security.User;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
36
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
37 import de.mpiwg.itgroup.annotationManager.Constants.NS;
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
38 import de.mpiwg.itgroup.annotationManager.RDFHandling.Annotation;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
39
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
40 /**
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
41 * Base class for Annotator resource classes.
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
42 *
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
43 * @author dwinter, casties
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
44 *
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
45 */
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
46 public abstract class AnnotatorResourceImpl extends ServerResource {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
47
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
48 protected Logger logger = Logger.getRootLogger();
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
49
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
50 protected String getAllowedMethodsForHeader() {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
51 return "OPTIONS,GET,POST";
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
52 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
53
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
54 public String encodeJsonId(String id) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
55 try {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
56 return DatatypeConverter.printBase64Binary(id.getBytes("UTF-8"));
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
57 } catch (UnsupportedEncodingException e) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
58 return null;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
59 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
60 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
61
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
62 public String decodeJsonId(String id) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
63 try {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
64 return new String(DatatypeConverter.parseBase64Binary(id), "UTF-8");
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
65 } catch (UnsupportedEncodingException e) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
66 return null;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
67 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
68 }
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
69
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
70 /**
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
71 * Handle options request to allow CORS for AJAX.
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
72 *
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
73 * @param entity
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
74 */
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
75 @Options
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
76 public void doOptions(Representation entity) {
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
77 logger.debug("AnnotatorResourceImpl doOptions!");
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
78 setCorsHeaders();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
79 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
80
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
81 /**
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
82 * set headers to allow CORS for AJAX.
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
83 */
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
84 protected void setCorsHeaders() {
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
85 Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
86 if (responseHeaders == null) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
87 responseHeaders = new Form();
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
88 getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
89 }
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
90 responseHeaders.add("Access-Control-Allow-Methods", getAllowedMethodsForHeader());
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
91 // echo back Origin and Request-Headers
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
92 Form requestHeaders = (Form) getRequest().getAttributes().get("org.restlet.http.headers");
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
93 String origin = requestHeaders.getFirstValue("Origin", true);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
94 if (origin == null) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
95 responseHeaders.add("Access-Control-Allow-Origin", "*");
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
96 } else {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
97 responseHeaders.add("Access-Control-Allow-Origin", origin);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
98 }
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
99 String allowHeaders = requestHeaders.getFirstValue("Access-Control-Request-Headers", true);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
100 if (allowHeaders != null) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
101 responseHeaders.add("Access-Control-Allow-Headers", allowHeaders);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
102 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
103 responseHeaders.add("Access-Control-Allow-Credentials", "true");
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
104 responseHeaders.add("Access-Control-Max-Age", "60");
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
105 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
106
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
107 /**
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
108 * returns if authentication information from headers is valid.
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
109 *
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
110 * @param entity
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
111 * @return
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
112 */
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
113 public boolean isAuthenticated(Representation entity) {
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
114 return (checkAuthToken(entity) != null);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
115 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
116
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
117 /**
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
118 * checks Annotator Auth plugin authentication information from headers. returns userId if successful.
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
119 *
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
120 * @param entity
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
121 * @return
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
122 */
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
123 public String checkAuthToken(Representation entity) {
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
124 Form requestHeaders = (Form) getRequest().getAttributes().get("org.restlet.http.headers");
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
125 String authToken = requestHeaders.getFirstValue("x-annotator-auth-token", true);
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
126 // decode token first to get consumer key
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
127 JsonToken token = new JsonTokenParser(null, null).deserialize(authToken);
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
128 String userId = token.getParamAsPrimitive("userId").getAsString();
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
129 String consumerKey = token.getParamAsPrimitive("consumerKey").getAsString();
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
130 // get stored consumer secret for key
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
131 RestServer restServer = (RestServer) getApplication();
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
132 String consumerSecret = restServer.getConsumerSecret(consumerKey);
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
133 logger.debug("requested consumer key=" + consumerKey + " secret=" + consumerSecret);
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
134 if (consumerSecret == null) {
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
135 return null;
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
136 }
21
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
137 //logger.debug(String.format("token=%s tokenString=%s signatureAlgorithm=%s",token,token.getTokenString(),token.getSignatureAlgorithm()));
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
138 try {
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
139 List<Verifier> verifiers = new ArrayList<Verifier>();
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
140 // we only do HS256 yet
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
141 verifiers.add(new HmacSHA256Verifier(consumerSecret.getBytes("UTF-8")));
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
142 // verify token signature(should really be static...)
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
143 new JsonTokenParser(new SystemClock(), null, (Checker[]) null).verify(token, verifiers);
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
144 } catch (SignatureException e) {
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
145 // TODO Auto-generated catch block
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
146 e.printStackTrace();
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
147 } catch (InvalidKeyException e) {
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
148 // TODO Auto-generated catch block
0cd1e7608d25 works with new JWT-Auth now!
casties
parents: 20
diff changeset
149 e.printStackTrace();
20
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
150 } catch (UnsupportedEncodingException e) {
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
151 // TODO Auto-generated catch block
6629e8422760 half baked version for new JWT auth :-(
casties
parents: 17
diff changeset
152 e.printStackTrace();
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
153 }
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
154 // must be ok then
15
6c7c4140630d on the way to updating annotations.
casties
parents: 14
diff changeset
155 logger.debug("auth OK! user="+userId);
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
156 return userId;
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
157 }
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
158
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
159 /**
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
160 * creates Annotator-JSON from an Annotation object.
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
161 *
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
162 * @param annot
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
163 * @return
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
164 */
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
165 public JSONObject createAnnotatorJson(Annotation annot) {
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
166 boolean makeUserObject = true;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
167 JSONObject jo = new JSONObject();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
168 try {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
169 jo.put("text", annot.text);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
170 jo.put("uri", annot.url);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
171
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
172 if (makeUserObject) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
173 // create user object
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
174 JSONObject userObject = new JSONObject();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
175 // save creator as uri
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
176 userObject.put("uri", annot.creator);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
177 // make short user id
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
178 String userID = annot.creator;
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
179 if (userID.startsWith(NS.MPIWG_PERSONS)) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
180 userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne NAMESPACE
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
181 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
182 // save as id
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
183 userObject.put("id", userID);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
184 // get full name
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
185 RestServer restServer = (RestServer) getApplication();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
186 String userName = restServer.getUserNameFromLdap(userID);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
187 userObject.put("name", userName);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
188 // save user object
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
189 jo.put("user", userObject);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
190 } else {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
191 // save user as string
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
192 jo.put("user", annot.creator);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
193 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
194
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
195 List<String> xpointers = new ArrayList<String>();
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
196 if (annot.xpointers == null || annot.xpointers.size() == 0)
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
197 xpointers.add(annot.xpointer);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
198 else {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
199 for (String xpointerString : annot.xpointers) {
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
200 xpointers.add(xpointerString);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
201 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
202 }
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
203 jo.put("ranges", transformToRanges(xpointers));
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
204 // encode Annotation URL (=id) in base64
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
205 String annotUrl = annot.getAnnotationUri();
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
206 String annotId = encodeJsonId(annotUrl);
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
207 jo.put("id", annotId);
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
208 return jo;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
209 } catch (JSONException e) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
210 // TODO Auto-generated catch block
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
211 e.printStackTrace();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
212 }
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
213 return null;
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
214 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
215
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
216 private JSONArray transformToRanges(List<String> xpointers) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
217
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
218 JSONArray ja = new JSONArray();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
219
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
220 Pattern rg = Pattern
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
221 .compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)");
10
0bdfe01e30b5 checking auth token works now.
casties
parents: 8
diff changeset
222 Pattern rg1 = Pattern.compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)");
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
223
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
224 try {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
225 for (String xpointer : xpointers) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
226 String decoded = URLDecoder.decode(xpointer, "utf-8");
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
227 Matcher m = rg.matcher(decoded);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
228
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
229 if (m.find()) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
230 {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
231 JSONObject jo = new JSONObject();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
232 jo.put("start", m.group(1));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
233 jo.put("startOffset", m.group(2));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
234 jo.put("end", m.group(3));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
235 jo.put("endOffset", m.group(4));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
236 ja.put(jo);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
237 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
238 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
239 m = rg1.matcher(xpointer);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
240 if (m.find()) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
241 JSONObject jo = new JSONObject();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
242 jo.put("start", m.group(1));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
243 jo.put("startOffset", m.group(2));
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
244
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
245 ja.put(jo);
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
246 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
247 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
248 } catch (JSONException e) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
249 // TODO Auto-generated catch block
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
250 e.printStackTrace();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
251 } catch (UnsupportedEncodingException e) {
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
252 // TODO Auto-generated catch block
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
253 e.printStackTrace();
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
254 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
255
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
256 return ja;
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
257 }
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
258
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
259 /**
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
260 * creates an Annotation object with data from JSON.
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
261 *
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
262 * uses the specification from the annotator project: {@link https://github.com/okfn/annotator/wiki/Annotation-format}
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
263 *
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
264 * 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
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
265 * de.mpiwg.itgroup.annotationManager.Constants.NS
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
266 *
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
267 * @param jo
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
268 * @return
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
269 * @throws JSONException
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
270 */
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
271 public Annotation createAnnotation(JSONObject jo, Representation entity) throws JSONException {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
272 return updateAnnotation(new Annotation(), jo, entity);
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
273 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
274
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
275 public Annotation updateAnnotation(Annotation annot, JSONObject jo, Representation entity) throws JSONException {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
276 // annotated uri
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
277 String url = annot.url;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
278 if (jo.has("uri")) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
279 url = jo.getString("uri");
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
280 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
281 // annotation text
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
282 String text = annot.text;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
283 if (jo.has("text")) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
284 text = jo.getString("text");
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
285 }
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
286 // check authentication
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
287 String authUser = checkAuthToken(entity);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
288 if (authUser == null) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
289 // try http auth
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
290 User httpUser = getHttpAuthUser(entity);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
291 if (httpUser == null) {
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
292 setStatus(Status.CLIENT_ERROR_FORBIDDEN);
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
293 return null;
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
294 }
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
295 authUser = httpUser.getIdentifier();
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
296 }
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
297 // username not required, if no username given authuser will be used
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
298 String username = null;
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
299 String userUri = annot.creator;
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
300 if (jo.has("user")) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
301 if (jo.get("user") instanceof String) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
302 // user is just a String
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
303 username = jo.getString("user");
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
304 // TODO: what if username and authUser are different?
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
305 } else {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
306 // user is an object
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
307 JSONObject user = jo.getJSONObject("user");
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
308 if (user.has("id")) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
309 username = user.getString("id");
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
310 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
311 if (user.has("uri")) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
312 userUri = user.getString("uri");
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
313 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
314 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
315 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
316 if (username == null) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
317 username = authUser;
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
318 }
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
319 // username should be a URI, if not it will set to the MPIWG namespace defined in
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
320 // de.mpiwg.itgroup.annotationManager.Constants.NS
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
321 if (userUri == null) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
322 if (username.startsWith("http")) {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
323 userUri = username;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
324 } else {
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
325 userUri = NS.MPIWG_PERSONS + username;
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
326 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
327 }
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
328 // TODO: should we overwrite the creator?
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
329
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
330 // create xpointer
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
331 String xpointer = annot.xpointer;
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
332 if (jo.has("ranges")) {
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
333 JSONObject ranges = jo.getJSONArray("ranges").getJSONObject(0);
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
334 String start = ranges.getString("start");
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
335 String end = ranges.getString("end");
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
336 String startOffset = ranges.getString("startOffset");
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
337 String endOffset = ranges.getString("endOffset");
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
338
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
339 try {
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
340 xpointer = url
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
341 + "#"
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
342 + URLEncoder.encode(String.format(
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
343 "xpointer(start-point(string-range(\"%s\",%s,1))/range-to(end-point(string-range(\"%s\",%s,1))))",
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
344 start, startOffset, end, endOffset), "utf-8");
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
345 } catch (UnsupportedEncodingException e) {
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
346 e.printStackTrace();
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
347 setStatus(Status.SERVER_ERROR_INTERNAL);
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
348 return null;
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
349 }
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
350 }
17
b0ef5c860464 updating and deleting annotations works now!
casties
parents: 15
diff changeset
351 return new Annotation(xpointer, userUri, annot.time, text, annot.type);
13
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
352 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
353
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
354 /**
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
355 * returns the logged in User.
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
356 *
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
357 * @param entity
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
358 * @return
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
359 */
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
360 protected User getHttpAuthUser(Representation entity) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
361 RestServer restServer = (RestServer) getApplication();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
362 if (!restServer.authenticate(getRequest(), getResponse())) {
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
363 // Not authenticated
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
364 return null;
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
365 }
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
366
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
367 ClientInfo ci = getRequest().getClientInfo();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
368 logger.debug(ci);
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
369 return getRequest().getClientInfo().getUser();
9393c9c9b916 saves annotations now!
casties
parents: 12
diff changeset
370
11
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
371 }
2f8c72ae4c43 working on create and read api for annotator.
casties
parents: 10
diff changeset
372
8
11baadcdd2c8 start of new Annotator API implementation.
casties
parents:
diff changeset
373 }