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

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

adding two html forms and two services for updating user-annotation access and public access of an annotation

File size: 22.3 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.NotInDataBaseException;
22import eu.dasish.annotation.backend.Resource;
23import eu.dasish.annotation.backend.ResourceAction;
24import eu.dasish.annotation.backend.dao.ILambda;
25import eu.dasish.annotation.schema.Annotation;
26import eu.dasish.annotation.schema.AnnotationBody;
27import eu.dasish.annotation.schema.AnnotationInfoList;
28import eu.dasish.annotation.schema.ObjectFactory;
29import eu.dasish.annotation.schema.Access;
30import eu.dasish.annotation.schema.PermissionList;
31import eu.dasish.annotation.schema.ReferenceList;
32import eu.dasish.annotation.schema.ResponseBody;
33import java.io.IOException;
34import java.util.Arrays;
35import java.util.HashMap;
36import java.util.List;
37import java.util.Map;
38import java.util.UUID;
39import javax.servlet.http.HttpServletRequest;
40import javax.servlet.http.HttpServletResponse;
41import javax.ws.rs.Consumes;
42import javax.ws.rs.DELETE;
43import javax.ws.rs.FormParam;
44import javax.ws.rs.GET;
45import javax.ws.rs.POST;
46import javax.ws.rs.PUT;
47import javax.ws.rs.Path;
48import javax.ws.rs.PathParam;
49import javax.ws.rs.Produces;
50import javax.ws.rs.QueryParam;
51import javax.ws.rs.core.MediaType;
52import javax.ws.rs.ext.Providers;
53import javax.xml.bind.JAXBElement;
54import org.springframework.stereotype.Component;
55import org.springframework.transaction.annotation.Transactional;
56
57/**
58 *
59 * @author olhsha
60 */
61@Component
62@Path("/annotations")
63@Transactional(rollbackFor = {Exception.class})
64public class AnnotationResource extends ResourceResource {
65
66    public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
67        this.httpServletResponse = httpServletResponse;
68    }
69
70    public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
71        this.httpServletRequest = httpServletRequest;
72    }
73
74    public void setProviders(Providers providers) {
75        this.providers = providers;
76    }
77
78    public AnnotationResource() {
79    }
80
81    @GET
82    @Produces(MediaType.TEXT_XML)
83    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
84    @Transactional(readOnly = true)
85    public JAXBElement<Annotation> getAnnotation(@PathParam("annotationid") String externalIdentifier) throws IOException {
86        Map params = new HashMap();
87        Annotation result = (Annotation) (new RequestWrappers(this)).wrapRequestResource(params, new GetAnnotation(), Resource.ANNOTATION, ResourceAction.READ, externalIdentifier);
88        if (result != null) {
89            return (new ObjectFactory()).createAnnotation(result);
90        } else {
91            return (new ObjectFactory()).createAnnotation(new Annotation());
92        }
93    }
94
95    private class GetAnnotation implements ILambda<Map, Annotation> {
96
97        @Override
98        public Annotation apply(Map params) throws NotInDataBaseException {
99            return dbDispatcher.getAnnotation((Number) params.get("internalID"));
100        }
101    }
102
103    //////////////////////////////////////////////////
104    @GET
105    @Produces(MediaType.TEXT_XML)
106    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/targets")
107    @Transactional(readOnly = true)
108    public JAXBElement<ReferenceList> getAnnotationTargets(@PathParam("annotationid") String externalIdentifier) throws IOException {
109        Map params = new HashMap();
110        ReferenceList result = (ReferenceList) (new RequestWrappers(this)).wrapRequestResource(params, new GetTargetList(), Resource.ANNOTATION, ResourceAction.READ, externalIdentifier);
111        if (result != null) {
112            return (new ObjectFactory()).createTargetList(result);
113        } else {
114            return (new ObjectFactory()).createTargetList(new ReferenceList());
115        }
116    }
117
118    private class GetTargetList implements ILambda<Map, ReferenceList> {
119
120        @Override
121        public ReferenceList apply(Map params) throws NotInDataBaseException {
122            return dbDispatcher.getAnnotationTargets((Number) params.get("internalID"));
123        }
124    }
125// TODO Unit test
126
127    @GET
128    @Produces(MediaType.TEXT_XML)
129    @Path("")
130    @Transactional(readOnly = true)
131    public JAXBElement<AnnotationInfoList> getFilteredAnnotations(@QueryParam("link") String link,
132            @QueryParam("text") String text,
133            @QueryParam("access") String access,
134            @QueryParam("namespace") String namespace,
135            @QueryParam("owner") String ownerExternalId,
136            @QueryParam("after") String after,
137            @QueryParam("before") String before) throws IOException {
138
139        Number principalID = this.getPrincipalID();
140        if (principalID == null) {
141            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
142        }
143
144        UUID ownerExternalUUID = (ownerExternalId != null) ? UUID.fromString(ownerExternalId) : null;
145        if (access == null) {
146            access = defaultAccess;
147        }
148        if (!Arrays.asList(admissibleAccess).contains(access)) {
149            this.INVALID_ACCESS_MODE(access);
150            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "ivalide mode acess " + access);
151            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
152        }
153        try {
154            final AnnotationInfoList annotationInfoList = dbDispatcher.getFilteredAnnotationInfos(ownerExternalUUID, link, text, principalID, access, namespace, after, before);
155            return new ObjectFactory().createAnnotationInfoList(annotationInfoList);
156        } catch (NotInDataBaseException e) {
157            loggerServer.debug(e.toString());
158            httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
159            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
160        }
161    }
162// TODO Unit test   
163
164    @GET
165    @Produces(MediaType.TEXT_XML)
166    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions")
167    @Transactional(readOnly = true)
168    public JAXBElement<PermissionList> getAnnotationPermissions(@PathParam("annotationid") String externalIdentifier) throws IOException {
169        Map params = new HashMap();
170        PermissionList result = (PermissionList) (new RequestWrappers(this)).wrapRequestResource(params, new GetPermissionList(), Resource.ANNOTATION, ResourceAction.READ, externalIdentifier);
171        if (result != null) {
172            return (new ObjectFactory()).createPermissionList(result);
173        } else {
174            return (new ObjectFactory()).createPermissionList(new PermissionList());
175        }
176    }
177
178    private class GetPermissionList implements ILambda<Map, PermissionList> {
179
180        @Override
181        public PermissionList apply(Map params) throws NotInDataBaseException {
182            return dbDispatcher.getPermissions((Number) params.get("internalID"), (Resource) params.get("resourceType"));
183        }
184    }
185///////////////////////////////////////////////////////
186
187    @DELETE
188    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
189    public String deleteAnnotation(@PathParam("annotationid") String externalIdentifier) throws IOException {
190        Map params = new HashMap();
191        int[] result = (int[]) (new RequestWrappers(this)).wrapRequestResource(params, new DeleteAnnotation(), Resource.ANNOTATION, ResourceAction.DELETE, externalIdentifier);
192        if (result != null) {
193            return result[0] + " annotation(s) is(are) deleted.";
194        } else {
195            return "Nothing is deleted.";
196        }
197    }
198
199    private class DeleteAnnotation implements ILambda<Map, int[]> {
200
201        @Override
202        public int[] apply(Map params) throws NotInDataBaseException {
203            return dbDispatcher.deleteAnnotation((Number) params.get("internalID"));
204        }
205    }
206
207///////////////////////////////////////////////////////
208    @POST
209    @Consumes(MediaType.APPLICATION_XML)
210    @Produces(MediaType.APPLICATION_XML)
211    @Path("")
212    public JAXBElement<ResponseBody> createAnnotation(Annotation annotation) throws IOException {
213
214        Map params = new HashMap();
215        params.put("annotation", annotation);
216        ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new AddAnnotation());
217        if (result != null) {
218            return (new ObjectFactory()).createResponseBody(result);
219        } else {
220            return (new ObjectFactory()).createResponseBody(new ResponseBody());
221        }
222    }
223
224    private class AddAnnotation implements ILambda<Map, ResponseBody> {
225
226        @Override
227        public ResponseBody apply(Map params) throws NotInDataBaseException {
228            Number principalID = (Number) params.get("principalID");
229            Annotation annotation = (Annotation) params.get("annotation");
230            Number annotationID = dbDispatcher.addPrincipalsAnnotation(principalID, annotation);
231            return dbDispatcher.makeAnnotationResponseEnvelope(annotationID);
232        }
233    }
234
235///////////////////////////////////////////////////////
236// TODO: unit test
237    @PUT
238    @Consumes(MediaType.APPLICATION_XML)
239    @Produces(MediaType.APPLICATION_XML)
240    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
241    public JAXBElement<ResponseBody> updateAnnotation(@PathParam("annotationid") String externalId, Annotation annotation) throws IOException {
242
243        String annotationExtId = annotation.getId();
244        if (!(externalId).equals(annotationExtId)) {
245            loggerServer.debug("Wrong request: the annotation identifier   " + externalId + " and the annotation (notebook) ID from the request body do not match.");
246            httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
247            return null;
248        }
249        Map params = new HashMap();
250        params.put("annotation", annotation);
251        ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotation(), Resource.ANNOTATION, ResourceAction.WRITE_W_METAINFO, externalId);
252        if (result != null) {
253            return (new ObjectFactory()).createResponseBody(result);
254        } else {
255            return (new ObjectFactory()).createResponseBody(new ResponseBody());
256        }
257
258
259    }
260
261    ///////////////////////////////////////////////////////////
262    private class UpdateAnnotation implements ILambda<Map, ResponseBody> {
263
264        @Override
265        public ResponseBody apply(Map params) throws NotInDataBaseException {
266            Annotation annotation = (Annotation) params.get("annotation");
267            Number annotationID = (Number) params.get("internalID");
268            int updatedRows = dbDispatcher.updateAnnotation(annotation);
269            return dbDispatcher.makeAnnotationResponseEnvelope(annotationID);
270        }
271    }
272    ///////////////////////////////////////////////////////////////////////////////
273
274    @PUT
275    @Consumes(MediaType.APPLICATION_XML)
276    @Produces(MediaType.APPLICATION_XML)
277    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/body")
278    public JAXBElement<ResponseBody> updateAnnotationBody(@PathParam("annotationid") String externalIdentifier, AnnotationBody annotationBody) throws IOException {
279        Map params = new HashMap();
280        params.put("annotationBody", annotationBody);
281        ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotationBody(), Resource.ANNOTATION, ResourceAction.WRITE, externalIdentifier);
282        if (result != null) {
283            return (new ObjectFactory()).createResponseBody(result);
284        } else {
285            return (new ObjectFactory()).createResponseBody(new ResponseBody());
286        }
287
288    }
289
290    ///////////////////////////////////////////////////////////
291    private class UpdateAnnotationBody implements ILambda<Map, ResponseBody> {
292
293        @Override
294        public ResponseBody apply(Map params) throws NotInDataBaseException {
295            Number resourceID = (Number) params.get("internalID");
296            AnnotationBody annotationBody = (AnnotationBody) params.get("annotationBody");
297            int updatedRows = dbDispatcher.updateAnnotationBody(resourceID, annotationBody);
298            return dbDispatcher.makeAnnotationResponseEnvelope(resourceID);
299        }
300    }
301
302    @PUT
303    @Consumes(MediaType.TEXT_PLAIN)
304    @Produces(MediaType.APPLICATION_XML)
305    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/headline")
306    public JAXBElement<ResponseBody> updateAnnotationHeadline(@PathParam("annotationid") String externalIdentifier, String newHeadline) throws IOException {
307        Map params = new HashMap();
308        params.put("headline", newHeadline);
309        ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdateAnnotationHeadline(), Resource.ANNOTATION, ResourceAction.WRITE, externalIdentifier);
310        if (result != null) {
311            return (new ObjectFactory()).createResponseBody(result);
312        } else {
313            return (new ObjectFactory()).createResponseBody(new ResponseBody());
314        }
315
316    }
317
318    ///////////////////////////////////////////////////////////
319    private class UpdateAnnotationHeadline implements ILambda<Map, ResponseBody> {
320
321        @Override
322        public ResponseBody apply(Map params) throws NotInDataBaseException {
323            Number resourceID = (Number) params.get("internalID");
324            String newHeadline = (String) params.get("headline");
325            int updatedRows = dbDispatcher.updateAnnotationHeadline(resourceID, newHeadline);
326            return dbDispatcher.makeAnnotationResponseEnvelope(resourceID);
327        }
328    }
329   
330    //////////////////////////////////////////
331   
332     //////////////////////////////////////////////
333    @POST
334    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
335    @Produces(MediaType.TEXT_PLAIN)
336    @Path("publicaccessform")
337    public String updatePubliAccessFromForm(
338            @FormParam("annotationId") String annotationDatabaseId,
339            @FormParam("annotationHeadline") String annotationHeadline,
340            @FormParam("access") String access)
341            throws IOException {
342       
343        if (access.trim().equals("")) {
344            access = "none";
345        }
346       
347        Access accessTyped = Access.fromValue(access);
348        int updatedAnnotations = 0;
349       
350        if (annotationDatabaseId == null || annotationDatabaseId.trim().equals("")) {
351            List<Number> annotationIDs = dbDispatcher.getAnnotationInternalIDsFromHeadline(annotationHeadline);
352            if (annotationIDs == null || annotationIDs.isEmpty()) {
353                return "No annotations with this headline have been found";
354            };
355            int count = 0;
356            for (Number annotationID : annotationIDs) {
357                count = dbDispatcher.updatePublicAttribute(annotationID, accessTyped);;
358                updatedAnnotations = updatedAnnotations+count;
359            }           
360            return (updatedAnnotations + " row(s) are updated");
361        } else {
362            try {
363            Number annotationID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString(annotationDatabaseId), Resource.ANNOTATION);
364            updatedAnnotations= dbDispatcher.updatePublicAttribute(annotationID, accessTyped);
365            } catch (NotInDataBaseException e) {
366              httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.toString());   
367            }
368        }
369        return (updatedAnnotations + " annotation(s) are updated.");
370    }
371   
372    ////////////////////////////////////////////////////
373
374    @PUT
375    @Consumes(MediaType.APPLICATION_XML)
376    @Produces(MediaType.APPLICATION_XML)
377    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/{principalid: " + BackendConstants.regExpIdentifier + "}")
378    public String updateAccess(@PathParam("annotationid") String annotationExternalId,
379            @PathParam("principalid") String principalExternalId, Access access) throws IOException {
380        return this.genericUpdateDeleteAccess(annotationExternalId, principalExternalId, access);
381    }
382   
383
384
385    //////////////////////////////////////////////
386    @POST
387    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
388    @Produces(MediaType.TEXT_PLAIN)
389    @Path("permissionform")
390    public String updatePermissionFromForm(@FormParam("login") String remoteID,
391            @FormParam("fullName") String fullName,
392            @FormParam("userId") String principalDatabaseId,
393            @FormParam("annotationId") String annotationDatabaseId,
394            @FormParam("annotationHeadline") String annotationHeadline,
395            @FormParam("access") String access)
396            throws IOException {
397       
398        if (access.trim().equals("")) {
399            access = null;
400        }
401       
402        try {
403            if (principalDatabaseId == null || principalDatabaseId.trim().equals("")) {
404                if (remoteID != null && !remoteID.trim().equals("")) {
405                    principalDatabaseId = dbDispatcher.getPrincipalExternalIDFromRemoteID(remoteID).toString();
406                } else {
407                    if (fullName != null) {
408                        principalDatabaseId = dbDispatcher.getPrincipalExternalIdFromName(fullName).toString();
409                    } else {
410                        httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "No user information is given");
411                    }
412                }
413            }
414        } catch (NotInDataBaseException e) {
415            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.toString()); 
416        }
417
418        if (annotationDatabaseId == null || annotationDatabaseId.trim().equals("")) {
419            List<UUID> annotationIds = dbDispatcher.getAnnotationExternalIdsFromHeadline(annotationHeadline);
420            if (annotationIds == null || annotationIds.isEmpty()) {
421                return "No annotations with this headline found";
422            };
423            int count = 0;
424            String tmp = null;
425            for (UUID annotationId : annotationIds) {
426                tmp = this.genericUpdateDeleteAccess(annotationId.toString(), principalDatabaseId, Access.fromValue(access));
427                if (!tmp.startsWith("0")) {
428                    count++;
429                }
430            }           
431            return (count + " row(s) are updated");
432        } else {
433            return this.genericUpdateDeleteAccess(annotationDatabaseId, principalDatabaseId, Access.fromValue(access));
434        }
435    }
436
437    ////////////////////////////////////////////
438    private String genericUpdateDeleteAccess(String annotationId, String principalId, Access access) throws IOException {
439        Map params = new HashMap();
440        params.put("access", access);
441        try {
442            final Number inputPrincipalID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString(principalId), Resource.PRINCIPAL);
443            params.put("inputPrincipalID", inputPrincipalID);
444            Integer result = (Integer) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePrincipalAccess(), Resource.ANNOTATION, ResourceAction.WRITE_W_METAINFO, annotationId);
445            if (result != null) {
446                return result + " row(s) is(are) updated.";
447            } else {
448                return "Nothing is updated.";
449            }
450
451        } catch (NotInDataBaseException e2) {
452            loggerServer.debug(e2.toString());
453            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e2.toString());
454            return "Nothing is deleted.";
455        }
456    }
457
458    private class UpdatePrincipalAccess implements ILambda<Map, Integer> {
459
460        @Override
461        public Integer apply(Map params) throws NotInDataBaseException {
462            Number annotationID = (Number) params.get("internalID");
463            Number principalID = (Number) params.get("inputPrincipalID");
464            Access access = (Access) params.get("access");
465            return dbDispatcher.updateAnnotationPrincipalAccess(annotationID, principalID, access);
466        }
467    }
468    ///////////////////////////////////////////
469
470    @PUT
471    @Consumes(MediaType.APPLICATION_XML)
472    @Produces(MediaType.APPLICATION_XML)
473    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/")
474    public JAXBElement<ResponseBody> updatePermissions(@PathParam("annotationid") String annotationExternalId, PermissionList permissions) throws IOException {
475
476        Map params = new HashMap();
477        params.put("permissions", permissions);
478
479        ResponseBody result = (ResponseBody) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePermissions(), Resource.ANNOTATION, ResourceAction.WRITE_W_METAINFO, annotationExternalId);
480        if (result != null) {
481            return new ObjectFactory().createResponseBody(result);
482        } else {
483            return new ObjectFactory().createResponseBody(new ResponseBody());
484        }
485
486
487    }
488
489    ////////////////////////////////////////////
490    private class UpdatePermissions implements ILambda<Map, ResponseBody> {
491
492        @Override
493        public ResponseBody apply(Map params) throws NotInDataBaseException {
494            Number annotationID = (Number) params.get("internalID");
495            PermissionList permissions = (PermissionList) params.get("permissions");
496            int updatedRows = dbDispatcher.updatePermissions(annotationID, permissions);
497            return dbDispatcher.makeAccessResponseEnvelope(annotationID, Resource.ANNOTATION);
498        }
499    }
500
501    ////////////////////////////////////////////////////////////
502    @DELETE
503    @Produces(MediaType.TEXT_PLAIN)
504    @Path("{annotationId: " + BackendConstants.regExpIdentifier + "}/principal/{principalId}/delete")
505    public String deletePrincipalsAccess(@PathParam("annotationId") String annotationId,
506            @PathParam("principalId") String principalId) throws IOException {
507        return this.genericUpdateDeleteAccess(annotationId, principalId, null);
508    }
509}
Note: See TracBrowser for help on using the repository browser.