source: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/rest/AnnotationResource.java @ 5850

Last change on this file since 5850 was 5850, checked in by olhsha@mpi.nl, 10 years ago

when annotation update is received from a "Writer" then it is checked if it tries to change permissions. If so, 403 is the respond

File size: 31.2 KB
Line 
1/*
2 * Copyright (C) 2013 DASISH
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18package eu.dasish.annotation.backend.rest;
19
20import eu.dasish.annotation.backend.BackendConstants;
21import eu.dasish.annotation.backend.ForbiddenException;
22import eu.dasish.annotation.backend.MatchMode;
23import eu.dasish.annotation.backend.NotInDataBaseException;
24import eu.dasish.annotation.backend.Resource;
25import eu.dasish.annotation.backend.dao.ILambda;
26import eu.dasish.annotation.schema.Annotation;
27import eu.dasish.annotation.schema.AnnotationBody;
28import eu.dasish.annotation.schema.AnnotationInfoList;
29import eu.dasish.annotation.schema.ObjectFactory;
30import eu.dasish.annotation.schema.Access;
31import eu.dasish.annotation.schema.PermissionList;
32import eu.dasish.annotation.schema.ReferenceList;
33import eu.dasish.annotation.schema.ResponseBody;
34import java.io.IOException;
35import java.util.ArrayList;
36import java.util.Arrays;
37import java.util.HashMap;
38import java.util.List;
39import java.util.Map;
40import java.util.Random;
41import java.util.UUID;
42import javax.servlet.http.HttpServletRequest;
43import javax.servlet.http.HttpServletResponse;
44import javax.ws.rs.Consumes;
45import javax.ws.rs.DELETE;
46import javax.ws.rs.FormParam;
47import javax.ws.rs.GET;
48import javax.ws.rs.POST;
49import javax.ws.rs.PUT;
50import javax.ws.rs.Path;
51import javax.ws.rs.PathParam;
52import javax.ws.rs.Produces;
53import javax.ws.rs.QueryParam;
54import javax.ws.rs.core.MediaType;
55import javax.ws.rs.ext.Providers;
56import javax.xml.bind.JAXBElement;
57import org.springframework.stereotype.Component;
58import org.springframework.transaction.annotation.Transactional;
59
60/**
61 *
62 * @author olhsha
63 */
64@Component
65@Path("/annotations")
66@Transactional(rollbackFor = {Exception.class})
67public class AnnotationResource extends ResourceResource {
68   
69    final private String defaultMatchMode = "exact";
70    final private String[] admissibleMatchModes = {"exact", "starts_with", "ends_with", "contains"};
71
72    public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
73        this.httpServletResponse = httpServletResponse;
74    }
75
76    public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
77        this.httpServletRequest = httpServletRequest;
78    }
79
80    public void setProviders(Providers providers) {
81        this.providers = providers;
82    }
83
84    public AnnotationResource() {
85    }
86   
87
88    @GET
89    @Produces(MediaType.TEXT_XML)
90    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
91    @Transactional(readOnly = true)
92    public JAXBElement<Annotation> getAnnotation(@PathParam("annotationid") String externalIdentifier) throws IOException {
93        Map params = new HashMap();
94        try {
95            Annotation result = (Annotation) (new RequestWrappers(this)).wrapRequestResource(params, new GetAnnotation(), Resource.ANNOTATION, Access.READ, externalIdentifier);
96            if (result != null) {
97                return (new ObjectFactory()).createAnnotation(result);
98            } else {
99                return (new ObjectFactory()).createAnnotation(new Annotation());
100            }
101        } catch (NotInDataBaseException e1) {
102            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
103            return (new ObjectFactory()).createAnnotation(new Annotation());
104        } catch (ForbiddenException e2) {
105            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
106            return (new ObjectFactory()).createAnnotation(new Annotation());
107        }
108    }
109
110    private class GetAnnotation implements ILambda<Map, Annotation> {
111
112        @Override
113        public Annotation apply(Map params) throws NotInDataBaseException {
114            return dbDispatcher.getAnnotation((Number) params.get("internalID"));
115        }
116    }
117
118    //////////////////////////////////////////////////
119    @GET
120    @Produces(MediaType.TEXT_XML)
121    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/targets")
122    @Transactional(readOnly = true)
123    public JAXBElement<ReferenceList> getAnnotationTargets(@PathParam("annotationid") String externalIdentifier) throws IOException {
124        Map params = new HashMap();
125        try {
126            ReferenceList result = (ReferenceList) (new RequestWrappers(this)).wrapRequestResource(params, new GetTargetList(), Resource.ANNOTATION, Access.READ, externalIdentifier);
127            if (result != null) {
128                return (new ObjectFactory()).createTargetList(result);
129            } else {
130                return (new ObjectFactory()).createTargetList(new ReferenceList());
131            }
132        } catch (NotInDataBaseException e1) {
133            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
134            return (new ObjectFactory()).createReferenceList(new ReferenceList());
135        } catch (ForbiddenException e2) {
136            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
137            return (new ObjectFactory()).createReferenceList(new ReferenceList());
138        }
139    }
140
141    private class GetTargetList implements ILambda<Map, ReferenceList> {
142
143        @Override
144        public ReferenceList apply(Map params) throws NotInDataBaseException {
145            return dbDispatcher.getAnnotationTargets((Number) params.get("internalID"));
146        }
147    }
148// TODO Unit test
149
150    @GET
151    @Produces(MediaType.TEXT_XML)
152    @Path("")
153    @Transactional(readOnly = true)
154    public JAXBElement<AnnotationInfoList> getFilteredAnnotations(@QueryParam("link") String link,
155            @QueryParam("matchMode") String matchMode,
156            @QueryParam("text") String text,
157            @QueryParam("access") String access,
158            @QueryParam("namespace") String namespace,
159            @QueryParam("owner") String ownerExternalId,
160            @QueryParam("after") String after,
161            @QueryParam("before") String before) throws IOException {
162
163        Number principalID = this.getPrincipalID();
164        if (principalID == null) {
165            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
166        }
167       
168         if (matchMode == null) {
169            matchMode = defaultMatchMode;
170        }
171        if (!Arrays.asList(admissibleMatchModes).contains(matchMode)) {
172            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "ivalide match mode " + matchMode);
173            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
174        }
175
176        UUID ownerExternalUUID = (ownerExternalId != null) ? UUID.fromString(ownerExternalId) : null;
177       
178       
179        if (access == null) {
180            access = defaultAccess;
181        }
182        if (!Arrays.asList(admissibleAccess).contains(access)) {
183            this.INVALID_ACCESS_MODE(access);
184            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "ivalide mode acess " + access);
185            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
186        }
187       
188       
189        try {
190            final AnnotationInfoList annotationInfoList = dbDispatcher.getFilteredAnnotationInfos(ownerExternalUUID, link, MatchMode.valueOf(matchMode.toUpperCase()), text, principalID, access, namespace, after, before);
191            return new ObjectFactory().createAnnotationInfoList(annotationInfoList);
192        } catch (NotInDataBaseException e) {
193            loggerServer.debug(e.toString());
194            httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
195            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
196        }
197    }
198   
199    @GET
200    @Produces(MediaType.TEXT_PLAIN)
201    @Path("stressTest")
202    @Transactional(readOnly = true)
203    public String getAnnotationsMultithread(@QueryParam("n") int n) throws IOException, NotInDataBaseException {
204        Number remotePrincipalID = this.getPrincipalID();
205        if (remotePrincipalID == null) {
206            return "You are not logged in";
207        }
208        String typeOfAccount = dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID);
209        if (typeOfAccount.equals(admin) || typeOfAccount.equals(DebugResource.developer)) {
210           
211            System.out.print("Preparing the data: getting the list of all annotations, picking up "+n+" of them randomly, and initializing threads");           
212            final List<Number> annotationIDs = dbDispatcher.getFilteredAnnotationIDs(null, null, null, null, remotePrincipalID, "read", null, null, null);
213            final int size = annotationIDs.size();
214            List<GetThread> threads = new ArrayList<GetThread>(n);
215            Random rand = new Random();
216            for (int i=0; i<n; i++) {
217               int r = rand.nextInt(size);
218               String annotationExternalId = dbDispatcher.getResourceExternalIdentifier(annotationIDs.get(r), Resource.ANNOTATION).toString();
219               GetThread thread = new GetThread(this, annotationExternalId);
220               threads.add(thread);           
221            }
222                       
223            System.out.print("Running on getAnnotation(id) (no serialized output is shown to save time) on randomly selected annotation ids."); 
224            for (int i=0; i<n; i++) {
225               threads.get(i).run();           
226            }
227           
228            return "Stress-tested annotationrResource's getAnnotation(xxx): ok";
229        } else {
230            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
231            return "You cannot enjoy this priviledged service because youe are neither admin nor developer. Ask the admin for more priviledges";
232        }
233    }
234   
235   
236// TODO Unit test   
237
238    @GET
239    @Produces(MediaType.TEXT_XML)
240    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions")
241    @Transactional(readOnly = true)
242    public JAXBElement<PermissionList> getAnnotationPermissions(@PathParam("annotationid") String externalIdentifier) throws IOException {
243        Map params = new HashMap();
244        try {
245            PermissionList result = (PermissionList) (new RequestWrappers(this)).wrapRequestResource(params, new GetPermissionList(), Resource.ANNOTATION, Access.READ, externalIdentifier);
246            if (result != null) {
247                return (new ObjectFactory()).createPermissionList(result);
248            } else {
249                return (new ObjectFactory()).createPermissionList(new PermissionList());
250            }
251        } catch (NotInDataBaseException e1) {
252            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
253            return (new ObjectFactory()).createPermissionList(new PermissionList());
254        } catch (ForbiddenException e2) {
255            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
256            return (new ObjectFactory()).createPermissionList(new PermissionList());
257        }
258    }
259
260    private class GetPermissionList implements ILambda<Map, PermissionList> {
261
262        @Override
263        public PermissionList apply(Map params) throws NotInDataBaseException {
264            return dbDispatcher.getPermissions((Number) params.get("internalID"), (Resource) params.get("resourceType"));
265        }
266    }
267///////////////////////////////////////////////////////
268
269    @DELETE
270    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
271    public String deleteAnnotation(@PathParam("annotationid") String externalIdentifier) throws IOException {
272        Map params = new HashMap();
273        try {
274            int[] result = (int[]) (new RequestWrappers(this)).wrapRequestResource(params, new DeleteAnnotation(), Resource.ANNOTATION, Access.ALL, externalIdentifier);
275            if (result != null) {
276                return result[0] + " annotation(s) is(are) deleted.";
277            } else {
278                return "Nothing is deleted.";
279            }
280        } catch (NotInDataBaseException e1) {
281            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
282            return e1.getMessage();
283        } catch (ForbiddenException e2) {
284            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
285            return e2.getMessage();
286        }
287    }
288
289    private class DeleteAnnotation implements ILambda<Map, int[]> {
290
291        @Override
292        public int[] apply(Map params) throws NotInDataBaseException {
293            return dbDispatcher.deleteAnnotation((Number) params.get("internalID"));
294        }
295    }
296
297///////////////////////////////////////////////////////
298    @POST
299    @Consumes(MediaType.APPLICATION_XML)
300    @Produces(MediaType.APPLICATION_XML)
301    @Path("")
302    public JAXBElement<ResponseBody> createAnnotation(Annotation annotation) throws IOException {
303
304        Map params = new HashMap();
305        params.put("annotation", annotation);
306        try {
307            ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new AddAnnotation());
308            if (result != null) {
309                return (new ObjectFactory()).createResponseBody(result);
310            } else {
311                return (new ObjectFactory()).createResponseBody(new ResponseBody());
312            }
313        } catch (NotInDataBaseException e) {
314            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
315            return (new ObjectFactory()).createResponseBody(new ResponseBody());
316        } catch (ForbiddenException e2) {
317            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
318            return (new ObjectFactory()).createResponseBody(new ResponseBody());
319        }
320    }
321
322    private class AddAnnotation implements ILambda<Map, ResponseBody> {
323
324        @Override
325        public ResponseBody apply(Map params) throws NotInDataBaseException {
326            Number principalID = (Number) params.get("principalID");
327            Annotation annotation = (Annotation) params.get("annotation");
328            Number annotationID = dbDispatcher.addPrincipalsAnnotation(principalID, annotation);
329            return dbDispatcher.makeAnnotationResponseEnvelope(annotationID);
330        }
331    }
332
333///////////////////////////////////////////////////////
334// TODO: unit test
335    @PUT
336    @Consumes(MediaType.APPLICATION_XML)
337    @Produces(MediaType.APPLICATION_XML)
338    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
339    public JAXBElement<ResponseBody> updateAnnotation(@PathParam("annotationid") String externalId, Annotation annotation) throws IOException {
340
341        String annotationExtId = annotation.getId();
342        if (!(externalId).equals(annotationExtId)) {
343            loggerServer.debug("Wrong request: the annotation identifier   " + externalId + " and the annotation (notebook) ID from the request body do not match.");
344            httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
345            return null;
346        }
347        try {
348            Map params = new HashMap();           
349            params.put("annotation", annotation);
350            params.put("remoteUser",httpServletRequest.getRemoteUser()); 
351            ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotation(), Resource.ANNOTATION, Access.WRITE, externalId);
352            if (result != null) {
353                return (new ObjectFactory()).createResponseBody(result);
354            }
355            else {
356                return (new ObjectFactory()).createResponseBody(new ResponseBody());
357            }
358        } catch (NotInDataBaseException e1) {
359            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
360            return (new ObjectFactory()).createResponseBody(new ResponseBody());
361        } catch (ForbiddenException e2) {
362            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
363            return (new ObjectFactory()).createResponseBody(new ResponseBody());
364        }
365    }
366
367    ///////////////////////////////////////////////////////////
368    private class UpdateAnnotation implements ILambda<Map, ResponseBody> {
369
370        @Override 
371        public ResponseBody apply(Map params) throws NotInDataBaseException, ForbiddenException {
372            Annotation annotation = (Annotation) params.get("annotation");
373            Number annotationID = (Number) params.get("internalID");
374            String remoteUser = (String) params.get("remoteUser");
375            int updatedRows = dbDispatcher.updateAnnotation(annotation, remoteUser);
376            return dbDispatcher.makeAnnotationResponseEnvelope(annotationID);
377        }
378    }
379    ///////////////////////////////////////////////////////////////////////////////
380
381    @PUT
382    @Consumes(MediaType.APPLICATION_XML)
383    @Produces(MediaType.APPLICATION_XML)
384    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/body")
385    public JAXBElement<ResponseBody> updateAnnotationBody(@PathParam("annotationid") String externalIdentifier, AnnotationBody annotationBody) throws IOException {
386        Map params = new HashMap();
387        params.put("annotationBody", annotationBody);
388        try {
389            ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotationBody(), Resource.ANNOTATION, Access.WRITE, externalIdentifier);
390            if (result != null) {
391                return (new ObjectFactory()).createResponseBody(result);
392            } else {
393                return (new ObjectFactory()).createResponseBody(new ResponseBody());
394            }
395        } catch (NotInDataBaseException e1) {
396            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
397            return (new ObjectFactory()).createResponseBody(new ResponseBody());
398        } catch (ForbiddenException e2) {
399            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
400            return (new ObjectFactory()).createResponseBody(new ResponseBody());
401        }
402
403    }
404
405    ///////////////////////////////////////////////////////////
406    private class UpdateAnnotationBody implements ILambda<Map, ResponseBody> {
407
408        @Override
409        public ResponseBody apply(Map params) throws NotInDataBaseException {
410            Number resourceID = (Number) params.get("internalID");
411            AnnotationBody annotationBody = (AnnotationBody) params.get("annotationBody");
412            int updatedRows = dbDispatcher.updateAnnotationBody(resourceID, annotationBody);
413            return dbDispatcher.makeAnnotationResponseEnvelope(resourceID);
414        }
415    }
416
417    @PUT
418    @Consumes(MediaType.TEXT_PLAIN)
419    @Produces(MediaType.APPLICATION_XML)
420    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/headline")
421    public JAXBElement<ResponseBody> updateAnnotationHeadline(@PathParam("annotationid") String externalIdentifier, String newHeadline) throws IOException {
422        Map params = new HashMap();
423        params.put("headline", newHeadline);
424        try {
425            ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotationHeadline(), Resource.ANNOTATION, Access.WRITE, externalIdentifier);
426            if (result != null) {
427                return (new ObjectFactory()).createResponseBody(result);
428            } else {
429                return (new ObjectFactory()).createResponseBody(new ResponseBody());
430            }
431        } catch (NotInDataBaseException e1) {
432            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
433            return (new ObjectFactory()).createResponseBody(new ResponseBody());
434        } catch (ForbiddenException e2) {
435            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
436            return (new ObjectFactory()).createResponseBody(new ResponseBody());
437        }
438
439    }
440
441    ///////////////////////////////////////////////////////////
442    private class UpdateAnnotationHeadline implements ILambda<Map, ResponseBody> {
443
444        @Override
445        public ResponseBody apply(Map params) throws NotInDataBaseException {
446            Number resourceID = (Number) params.get("internalID");
447            String newHeadline = (String) params.get("headline");
448            int updatedRows = dbDispatcher.updateAnnotationHeadline(resourceID, newHeadline);
449            return dbDispatcher.makeAnnotationResponseEnvelope(resourceID);
450        }
451    }
452
453    //////////////////////////////////////////
454    //////////////////////////////////////////////
455    @POST
456    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
457    @Produces(MediaType.TEXT_PLAIN)
458    @Path("publicaccessform")
459    public String updatePubliAccessFromForm(
460            @FormParam("annotationId") String annotationDatabaseId,
461            @FormParam("annotationHeadline") String annotationHeadline,
462            @FormParam("access") String access)
463            throws IOException {
464
465        if (access.trim().equals("")) {
466            access = "none";
467        }
468
469        try {
470
471            Access accessTyped = Access.fromValue(access);
472            if (annotationDatabaseId == null || annotationDatabaseId.trim().equals("")) {
473                List<UUID> annotationIds = dbDispatcher.getAnnotationExternalIdsFromHeadline(annotationHeadline);
474                if (annotationIds == null || annotationIds.isEmpty()) {
475                    httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "No annotations with this headline have been found");
476                    return "No annotations with this headline have been found";
477                };
478                int updatedAnnotations = 0;           
479                for (UUID annotationId : annotationIds) {
480                    Map params = new HashMap();
481                    params.put("access", accessTyped);
482                    Integer result = (Integer) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePublicAccess(), Resource.ANNOTATION, Access.ALL, annotationId.toString());
483                    updatedAnnotations = (result != null) ? updatedAnnotations + result.intValue() : updatedAnnotations;
484                }
485                return (updatedAnnotations + " row(s) are updated");
486            } else {
487                Map params = new HashMap();
488                params.put("access", accessTyped);
489                Integer result = (Integer) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePublicAccess(), Resource.ANNOTATION, Access.ALL, annotationDatabaseId);
490                if (result != null) {
491                    return result + " row(s) is(are) updated.";
492                } else {
493                    return "0 rows are updated.";
494                }
495            }
496        } catch (NotInDataBaseException e1) {
497            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.toString());
498            return "0 rows are updated.";
499        } catch (ForbiddenException e2) {
500            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.toString());
501            return "0 rows are updated.";
502        }
503    }
504
505    private class UpdatePublicAccess implements ILambda<Map, Integer> {
506
507        @Override
508        public Integer apply(Map params) throws NotInDataBaseException {
509            Number annotationID = (Number) params.get("internalID");
510            Access access = (Access) params.get("access");
511            return dbDispatcher.updatePublicAttribute(annotationID, access);
512        }
513    }
514
515    ////////////////////////////////////////////////////
516    @PUT
517    @Consumes(MediaType.APPLICATION_XML)
518    @Produces(MediaType.APPLICATION_XML)
519    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/{principalid: " + BackendConstants.regExpIdentifier + "}")
520    public String updatePermission(@PathParam("annotationid") String annotationExternalId,
521            @PathParam("principalid") String principalExternalId, Access access) throws IOException {
522        try {
523            return this.genericUpdateDeletePermission(annotationExternalId, principalExternalId, access);
524        } catch (NotInDataBaseException e1) {
525            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
526            return e1.getMessage();
527        } catch (ForbiddenException e2) {
528            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
529            return e2.getMessage();
530        }
531    }
532
533    //////////////////////////////////////////////
534    @POST
535    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
536    @Produces(MediaType.TEXT_PLAIN)
537    @Path("permissionform")
538    public String updatePermissionFromForm(@FormParam("login") String remoteID,
539            @FormParam("fullName") String fullName,
540            @FormParam("userId") String principalDatabaseId,
541            @FormParam("annotationId") String annotationDatabaseId,
542            @FormParam("annotationHeadline") String annotationHeadline,
543            @FormParam("access") String access)
544            throws IOException {
545
546        try {
547
548            if (access.trim().equals("")) {
549                access = null;
550            }
551
552            if (principalDatabaseId == null || principalDatabaseId.trim().equals("")) {
553                if (remoteID != null && !remoteID.trim().equals("")) {
554                    principalDatabaseId = dbDispatcher.getPrincipalExternalIDFromRemoteID(remoteID).toString();
555                } else {
556                    if (fullName != null) {
557                        principalDatabaseId = dbDispatcher.getPrincipalExternalIdFromName(fullName).toString();
558                    } else {
559                        httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "No user information is given");
560                    }
561                }
562            }
563
564            if (annotationDatabaseId == null || annotationDatabaseId.trim().equals("")) {
565                List<UUID> annotationIds = dbDispatcher.getAnnotationExternalIdsFromHeadline(annotationHeadline);
566                if (annotationIds == null || annotationIds.isEmpty()) {
567                    return "No annotations with this headline found";
568                };
569                int count = 0;
570                String tmp = null;
571                for (UUID annotationId : annotationIds) {
572                    tmp = this.genericUpdateDeletePermission(annotationId.toString(), principalDatabaseId, Access.fromValue(access));
573                    if (!tmp.startsWith("0")) {
574                        count++;
575                    }
576                }
577                return (count + " row(s) are updated");
578            } else {
579                return this.genericUpdateDeletePermission(annotationDatabaseId, principalDatabaseId, Access.fromValue(access));
580            }
581
582        } catch (NotInDataBaseException e1) {
583            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
584            return e1.getMessage();
585        } catch (ForbiddenException e2) {
586            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
587            return e2.getMessage();
588        }
589    }
590
591    ////////////////////////////////////////////
592    private String genericUpdateDeletePermission(String annotationId, String principalId, Access access) throws IOException, NotInDataBaseException, ForbiddenException {
593        Map params = new HashMap();
594        params.put("access", access);
595        final Number inputPrincipalID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString(principalId), Resource.PRINCIPAL);
596        params.put("inputPrincipalID", inputPrincipalID);
597        Integer result = (Integer) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePermissionHelper(), Resource.ANNOTATION, Access.ALL, annotationId);
598        if (result != null) {
599            return result + " row(s) is(are) updated.";
600        } else {
601            return "0 rows are updated.";
602        }
603    }
604
605    private class UpdatePermissionHelper implements ILambda<Map, Integer> {
606
607        @Override
608        public Integer apply(Map params) throws NotInDataBaseException {
609            Number annotationID = (Number) params.get("internalID");
610            Number principalID = (Number) params.get("inputPrincipalID");
611            Access access = (Access) params.get("access");
612            return dbDispatcher.updatePermission(annotationID, principalID, access);
613        }
614    }
615    ///////////////////////////////////////////
616
617    @PUT
618    @Consumes(MediaType.APPLICATION_XML)
619    @Produces(MediaType.APPLICATION_XML)
620    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/")
621    public JAXBElement<ResponseBody> updatePermissions(@PathParam("annotationid") String annotationExternalId, PermissionList permissions) throws IOException {
622
623        Map params = new HashMap();
624        params.put("permissions", permissions);
625        try {
626            ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePermissions(), Resource.ANNOTATION, Access.ALL, annotationExternalId);
627            if (result != null) {
628                return new ObjectFactory().createResponseBody(result);
629            } else {
630                return new ObjectFactory().createResponseBody(new ResponseBody());
631            }
632        } catch (NotInDataBaseException e1) {
633            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
634            return new ObjectFactory().createResponseBody(new ResponseBody());
635        } catch (ForbiddenException e2) {
636            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
637            return new ObjectFactory().createResponseBody(new ResponseBody());
638        }
639
640    }
641
642    ////////////////////////////////////////////
643    private class UpdatePermissions implements ILambda<Map, ResponseBody> {
644
645        @Override
646        public ResponseBody apply(Map params) throws NotInDataBaseException {
647            Number annotationID = (Number) params.get("internalID");
648            PermissionList permissions = (PermissionList) params.get("permissions");
649            int updatedRows = dbDispatcher.updateOrAddPermissions(annotationID, permissions);
650            return dbDispatcher.makeAccessResponseEnvelope(annotationID, Resource.ANNOTATION);
651        }
652    }
653
654    ////////////////////////////////////////////////////////////
655    @DELETE
656    @Produces(MediaType.TEXT_PLAIN)
657    @Path("{annotationId: " + BackendConstants.regExpIdentifier + "}/principal/{principalId}/delete")
658    public String deletePermission(@PathParam("annotationId") String annotationId,
659            @PathParam("principalId") String principalId) throws IOException {
660        try {
661            return this.genericUpdateDeletePermission(annotationId, principalId, null);
662        } catch (NotInDataBaseException e1) {
663            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e1.getMessage());
664            return e1.getMessage();
665        } catch (ForbiddenException e2) {
666            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, e2.getMessage());
667            return e2.getMessage();
668        }
669    }
670   
671   
672}
Note: See TracBrowser for help on using the repository browser.