source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotations.java @ 63:9f8c9611848a

Last change on this file since 63:9f8c9611848a was 63:9f8c9611848a, checked in by casties, 11 years ago

fixed bug with new rectangle shapes. added limit, offset and sortBy parameters to annotator/ and annotator/search.

File size: 9.7 KB
Line 
1/**
2 * Implements the "annotations" uri of the Annotator API. see
3 * <https://github.com/okfn/annotator/wiki/Storage>
4 */
5package de.mpiwg.itgroup.annotations.restlet;
6
7import java.io.IOException;
8import java.util.ArrayList;
9import java.util.List;
10
11import org.json.JSONArray;
12import org.json.JSONException;
13import org.json.JSONObject;
14import org.restlet.data.Form;
15import org.restlet.data.Status;
16import org.restlet.ext.json.JsonRepresentation;
17import org.restlet.representation.Representation;
18import org.restlet.resource.Delete;
19import org.restlet.resource.Get;
20import org.restlet.resource.Post;
21import org.restlet.resource.Put;
22
23import de.mpiwg.itgroup.annotations.Annotation;
24import de.mpiwg.itgroup.annotations.Person;
25import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
26import de.mpiwg.itgroup.annotations.restlet.utils.JSONObjectComparator;
27
28/**
29 * Implements the "annotations" uri of the Annotator API. see
30 * <https://github.com/okfn/annotator/wiki/Storage>
31 *
32 * @author dwinter, casties
33 *
34 */
35public class AnnotatorAnnotations extends AnnotatorResourceImpl {
36
37    protected String getAllowedMethodsForHeader() {
38        return "OPTIONS,GET,POST,PUT,DELETE";
39    }
40
41    /**
42     * GET with JSON content-type.
43     *
44     * @param entity
45     * @return
46     */
47    @Get("json")
48    public Representation doGetJSON(Representation entity) {
49        logger.debug("AnnotatorAnnotations doGetJSON!");
50        setCorsHeaders();
51        // id from URI /annotations/{id}
52        String jsonId = (String) getRequest().getAttributes().get("id");
53        String id = decodeJsonId(jsonId);
54        logger.debug("annotation-id=" + id);
55
56        // do authentication
57        Person authUser = Person.createPersonWithId(this.checkAuthToken(entity));
58        logger.debug("request authenticated=" + authUser);
59
60        if (id == null) {
61            // no id -- send all annotations
62            Form form = getRequest().getResourceRef().getQueryAsForm();
63            int limit = getInt(form.getFirstValue("limit"));
64            int offset = getInt(form.getFirstValue("offset"));
65            String sortBy = form.getFirstValue("sortBy");
66            return getAllAnnotations(authUser, limit, offset, sortBy);
67        }
68
69        // send annotation with id
70        AnnotationStore store = getAnnotationStore();
71        Annotation annot = store.getAnnotationById(id);
72        if (annot != null) {
73            if (!annot.isActionAllowed("read", authUser, store)) {
74                setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!");
75                return null;
76            }
77            JSONObject result = createAnnotatorJson(annot, (authUser == null));
78            return new JsonRepresentation(result);
79        } else {
80            // not found
81            setStatus(Status.CLIENT_ERROR_NOT_FOUND);
82            return null;
83        }
84    }
85
86    private Representation getAllAnnotations(Person authUser, int limit, int offset, String sortBy) {
87        AnnotationStore store = getAnnotationStore();
88        ArrayList<JSONObject> results = new ArrayList<JSONObject>();
89       
90        // read all annotations
91        List<Annotation> annotations = store.getAnnotations(null, null);
92        for (Annotation annotation : annotations) {
93            // check permission
94            if (!annotation.isActionAllowed("read", authUser, store)) continue;
95            // add annotation to list
96            JSONObject jo = createAnnotatorJson(annotation, false);
97            results.add(jo);
98        }
99
100        // sort if necessary
101        if (sortBy != null) {
102            JSONObjectComparator.sortAnnotations(results, sortBy);
103        }
104       
105        // put in JSON list
106        JSONArray rows = new JSONArray();
107        int cnt = 0;
108        for (JSONObject result : results) {
109            cnt += 1;
110            if (offset > 0 && cnt < offset) continue;
111            rows.put(result);
112            if (limit > 0 && cnt >= limit) break;
113        }
114
115        // assemble result object
116        JSONObject result = new JSONObject();
117        try {
118            result.put("rows", rows);
119            result.put("total", rows.length());
120        } catch (JSONException e) {
121            setStatus(Status.SERVER_ERROR_INTERNAL, "JSON Error");
122            return null;
123        }
124        return new JsonRepresentation(result);
125    }
126
127    /**
128     * POST with JSON content-type. Creates a new Annotation.
129     *
130     * @return
131     */
132    @Post("json")
133    public Representation doPostJson(Representation entity) {
134        logger.debug("AnnotatorAnnotations doPostJSON!");
135        // set headers
136        setCorsHeaders();
137
138        // do authentication TODO: who's allowed to create?
139        Person authUser = Person.createPersonWithId(this.checkAuthToken(entity));
140        logger.debug("request authenticated=" + authUser);
141        if (authUser == null) {
142            setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!");
143            return null;
144        }
145
146        Annotation annot = null;
147        try {
148            JsonRepresentation jrep = new JsonRepresentation(entity);
149            JSONObject jo = jrep.getJsonObject();
150            if (jo == null) {
151                setStatus(Status.SERVER_ERROR_INTERNAL);
152                return null;
153            }
154            // make sure id is not set for POST
155            jo.remove("id");
156            // get Annotation object from posted JSON
157            annot = createAnnotation(jo, entity);
158        } catch (IOException e1) {
159            setStatus(Status.SERVER_ERROR_INTERNAL);
160            return null;
161        } catch (JSONException e) {
162            setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
163            return null;
164        }
165        if (annot == null) {
166            setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
167            return null;
168        }
169        Annotation storedAnnot;
170        // store Annotation
171        storedAnnot = getAnnotationStore().storeAnnotation(annot);
172        /*
173         * according to https://github.com/okfn/annotator/wiki/Storage we should
174         * return 303: see other. For now we return the annotation.
175         */
176        JSONObject jo = createAnnotatorJson(storedAnnot, (authUser == null));
177        JsonRepresentation retRep = new JsonRepresentation(jo);
178        return retRep;
179    }
180
181    /**
182     * PUT with JSON content-type. Modifies an Annotation.
183     *
184     * @param entity
185     * @return
186     */
187    @Put("json")
188    public Representation doPutJSON(Representation entity) {
189        logger.debug("AnnotatorAnnotations doPutJSON!");
190        setCorsHeaders();
191        // id from URI /annotations/{id}
192        String jsonId = (String) getRequest().getAttributes().get("id");
193        String id = decodeJsonId(jsonId);
194        logger.debug("annotation-id=" + id);
195
196        // do authentication
197        Person authUser = Person.createPersonWithId(this.checkAuthToken(entity));
198        logger.debug("request authenticated=" + authUser);
199
200        Annotation annot = null;
201        AnnotationStore store = getAnnotationStore();
202        try {
203            JsonRepresentation jrep = new JsonRepresentation(entity);
204            JSONObject jo = jrep.getJsonObject();
205            if (jo == null) {
206                setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
207                return null;
208            }
209            // get stored Annotation
210            Annotation storedAnnot = store.getAnnotationById(id);
211            if (storedAnnot == null) {
212                setStatus(Status.CLIENT_ERROR_NOT_FOUND);
213                return null;
214            }
215            if (!storedAnnot.isActionAllowed("update", authUser, store)) {
216                setStatus(Status.CLIENT_ERROR_FORBIDDEN);
217                return null;
218            }
219            // update from posted JSON
220            annot = updateAnnotation(storedAnnot, jo, entity);
221            // store Annotation
222            storedAnnot = store.storeAnnotation(annot);
223            /*
224             * according to https://github.com/okfn/annotator/wiki/Storage we
225             * should return 303: see other. but the client doesn't like it
226             * setStatus(Status.REDIRECTION_SEE_OTHER); // go to same URL as
227             * this one Reference thisUrl = this.getReference();
228             * this.getResponse().setLocationRef(thisUrl);
229             */
230            // return new annotation
231            jo = createAnnotatorJson(storedAnnot, (authUser == null));
232            JsonRepresentation retRep = new JsonRepresentation(jo);
233            return retRep;
234        } catch (JSONException e) {
235            logger.error("Error in doPutJSON", e);
236            setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
237        } catch (IOException e) {
238            logger.error("Error in doPutJSON", e);
239            setStatus(Status.SERVER_ERROR_INTERNAL, "Other Error");
240        }
241        return null;
242    }
243
244    /**
245     * DELETE with JSON content-type. Deletes an Annotation.
246     *
247     * @param entity
248     * @return
249     */
250    @Delete("json")
251    public Representation doDeleteJSON(Representation entity) {
252        logger.debug("AnnotatorAnnotations doDeleteJSON!");
253        setCorsHeaders();
254        // id from URI /annotations/{id}
255        String jsonId = (String) getRequest().getAttributes().get("id");
256        String id = decodeJsonId(jsonId);
257        logger.debug("annotation-id=" + id);
258
259        // do authentication
260        Person authUser = Person.createPersonWithId(this.checkAuthToken(entity));
261        logger.debug("request authenticated=" + authUser);
262        AnnotationStore store = getAnnotationStore();
263        Annotation annot = store.getAnnotationById(id);
264        if (annot != null) {
265            if (!annot.isActionAllowed("delete", authUser, store)) {
266                setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Not Authorized!");
267                return null;
268            }
269        }
270        // delete annotation
271        store.deleteAnnotationById(id);
272        setStatus(Status.SUCCESS_NO_CONTENT);
273        return null;
274    }
275
276}
Note: See TracBrowser for help on using the repository browser.