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

Last change on this file since 4028 was 4028, checked in by olhsha, 11 years ago

updating body of the annotation. Testing Get methods and verifying their produced xml-s. Ok.

File size: 19.7 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.dao.DBIntegrityService;
22import eu.dasish.annotation.schema.Annotation;
23import eu.dasish.annotation.schema.AnnotationActionName;
24import eu.dasish.annotation.schema.AnnotationInfoList;
25import eu.dasish.annotation.schema.Action;
26import eu.dasish.annotation.schema.ActionList;
27import eu.dasish.annotation.schema.AnnotationBody;
28import eu.dasish.annotation.schema.ObjectFactory;
29import eu.dasish.annotation.schema.Permission;
30import eu.dasish.annotation.schema.PermissionActionName;
31import eu.dasish.annotation.schema.UserWithPermissionList;
32import eu.dasish.annotation.schema.ReferenceList;
33import eu.dasish.annotation.schema.ResponseBody;
34import java.io.IOException;
35import java.sql.Timestamp;
36import java.util.ArrayList;
37import java.util.List;
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.GET;
44import javax.ws.rs.POST;
45import javax.ws.rs.PUT;
46import javax.ws.rs.Path;
47import javax.ws.rs.PathParam;
48import javax.ws.rs.Produces;
49import javax.ws.rs.QueryParam;
50import javax.ws.rs.core.Context;
51import javax.ws.rs.core.MediaType;
52import javax.ws.rs.core.UriInfo;
53import javax.ws.rs.ext.Providers;
54import javax.xml.bind.JAXBElement;
55import org.springframework.beans.factory.annotation.Autowired;
56import org.springframework.security.access.annotation.Secured;
57import org.springframework.stereotype.Component;
58import org.slf4j.Logger;
59import org.slf4j.LoggerFactory;
60
61/**
62 *
63 * @author olhsha
64 */
65@Component
66@Path("/annotations")
67public class AnnotationResource {
68
69    @Autowired
70    private DBIntegrityService dbIntegrityService;
71    @Context
72    private HttpServletRequest httpServletRequest;
73    @Context
74    private HttpServletResponse httpServletResponse;
75    @Context
76    private UriInfo uriInfo;
77    @Context
78    private Providers providers;
79    final String default_permission = "reader";
80    private static final Logger logger = LoggerFactory.getLogger(AnnotationResource.class);
81
82    public void setUriInfo(UriInfo uriInfo) {
83        this.uriInfo = uriInfo;
84    }
85
86    public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
87        this.httpServletResponse = httpServletResponse;
88    }
89
90    public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
91        this.httpServletRequest = httpServletRequest;
92    }
93
94    public void setProviders(Providers providers) {
95        this.providers = providers;
96    }
97
98    public AnnotationResource() {
99    }
100
101    @GET
102    @Produces(MediaType.TEXT_XML)
103    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
104    @Secured("ROLE_USER")
105    public JAXBElement<Annotation> getAnnotation(@PathParam("annotationid") String ExternalIdentifier) {
106        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
107        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(ExternalIdentifier));
108        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
109        if (canRead(userID, annotationID)) {
110            final Annotation annotation = dbIntegrityService.getAnnotation(annotationID);
111            JAXBElement<Annotation> rootElement = new ObjectFactory().createAnnotation(annotation);
112            logger.info("getAnnotation method: OK");
113            return rootElement;
114        } else {
115            try {
116                logger.error("FORBIDDEN-access attempt");
117                httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
118            } catch (IOException ioe) {
119                logger.error("IOException: Cannot send server respond about unaithorized access.");
120            }
121            return null;
122        }
123
124    }
125
126    //TODO: unit test
127    @GET
128    @Produces(MediaType.TEXT_XML)
129    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/targets")
130    @Secured("ROLE_USER")
131    public JAXBElement<ReferenceList> getAnnotationTargets(@PathParam("annotationid") String ExternalIdentifier) {
132        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
133        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(ExternalIdentifier));
134        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
135        if (canRead(userID, annotationID)) {
136            final ReferenceList TargetList = dbIntegrityService.getAnnotationTargets(annotationID);
137            logger.info("getAnnotationTargets method: OK");
138            return new ObjectFactory().createTargetList(TargetList);
139        } else {
140            try {
141                logger.error("FORBIDDEN-access attempt");
142                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
143            } catch (IOException ioe) {
144                logger.error("IOException: Cannot send server respond about unaithorized access.");
145            }
146            return null;
147        }
148    }
149
150    // TODO Unit test
151    @GET
152    @Produces(MediaType.TEXT_XML)
153    @Path("")
154    @Secured("ROLE_USER")
155    public JAXBElement<AnnotationInfoList> getFilteredAnnotations(@QueryParam("link") String link,
156            @QueryParam("text") String text,
157            @QueryParam("access") String permission,
158            @QueryParam("namespace") String namespace,
159            @QueryParam("owner") String ownerExternalId,
160            @QueryParam("after") Timestamp after,
161            @QueryParam("before") Timestamp before) {
162
163        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
164        Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
165        UUID ownerExternalUUID = (ownerExternalId != null) ? UUID.fromString(ownerExternalId) : null;
166        String access = (permission != null) ? permission : default_permission;
167        final AnnotationInfoList annotationInfoList = dbIntegrityService.getFilteredAnnotationInfos(link, text, userID, access, namespace, ownerExternalUUID, after, before);
168        logger.info("getFilteredAnnotations method: OK");
169        return new ObjectFactory().createAnnotationInfoList(annotationInfoList);
170    }
171
172    // TODO Unit test   
173    @GET
174    @Produces(MediaType.TEXT_XML)
175    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions")
176    @Secured("ROLE_USER")
177    public JAXBElement<UserWithPermissionList> getAnnotationPermissions(@PathParam("annotationid") String ExternalIdentifier) {
178        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
179        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(ExternalIdentifier));
180        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
181        if (canRead(userID, annotationID)) {
182            final UserWithPermissionList permissionList = dbIntegrityService.getPermissionsForAnnotation(annotationID);
183            logger.info("getAnnotationPermissions method: OK");
184            return new ObjectFactory().createPermissionList(permissionList);
185        } else {
186            try {
187                logger.error("FORBIDDEN-access attempt");
188                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
189            } catch (IOException ioe) {
190                logger.error("IOException: Cannot send server respond about unaithorized access.");
191            }
192            return null;
193        }
194
195    }
196
197    ///////////////////////////////////////////////////////
198    // TODO: how to return the status code?
199    @DELETE
200    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
201    @Secured("ROLE_USER")
202    public String deleteAnnotation(@PathParam("annotationid") String externalIdentifier) {
203        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
204        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(externalIdentifier));
205        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
206        if (isOwner(userID, annotationID)) {
207            int[] resultDelete = dbIntegrityService.deleteAnnotation(annotationID);
208            String result = Integer.toString(resultDelete[0]);
209            logger.info("deleteAnnotation method: OK");
210            return result + " annotation(s) deleted.";
211        } else {
212            logger.error("FORBIDDEN-access attempt. Only the owner can delete an annotation.");
213            try {
214                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
215            } catch (IOException ioe) {
216                logger.error("IOException: Cannot send server respond about unaithorized access.");
217            }
218            return null;
219        }
220
221    }
222
223    ///////////////////////////////////////////////////////
224    @POST
225    @Consumes(MediaType.APPLICATION_XML)
226    @Produces(MediaType.APPLICATION_XML)
227    @Path("")
228    @Secured("ROLE_USER")
229    public JAXBElement<ResponseBody> createAnnotation(Annotation annotation) {
230        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
231        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
232        Number annotationID = dbIntegrityService.addUsersAnnotation(userID, annotation);
233        logger.info("createAnnotation method: OK");
234        return new ObjectFactory().createResponseBody(makeAnnotationResponseEnvelope(annotationID));
235    }
236
237    ///////////////////////////////////////////////////////
238    // TODO: unit test
239    @PUT
240    @Consumes(MediaType.APPLICATION_XML)
241    @Produces(MediaType.APPLICATION_XML)
242    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}")
243    @Secured("ROLE_USER")
244    public JAXBElement<ResponseBody> updateAnnotation(@PathParam("annotationid") String externalIdentifier, Annotation annotation) {
245        String path = uriInfo.getBaseUri().toString();
246        dbIntegrityService.setServiceURI(path);
247        String annotationURI = annotation.getURI();
248        if (!(path + "annotations/" + externalIdentifier).equals(annotationURI)) {
249            logger.error("Wrong request: the external annotation ID and the annotation ID from the request body do not match.");
250            logger.error("Will do nothing.");
251            return null;
252        }
253        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(externalIdentifier));
254        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
255        if (canWrite(userID, annotationID)) {
256            int updatedRows = dbIntegrityService.updateUsersAnnotation(userID, annotation);
257            logger.info("updateAnnotation method: OK");
258            return new ObjectFactory().createResponseBody(makeAnnotationResponseEnvelope(annotationID));
259
260        } else {
261            logger.error("FORBIDDEN-access attempt.");
262            logger.error("The logged-in user is not authorised to alter this annotation. ");
263            try {
264                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
265            } catch (IOException ioe) {
266                logger.error("IOException: Cannot send server respond about unaithorized access.");
267            }
268            return null;
269        }
270
271    }
272   
273    @PUT
274    @Consumes(MediaType.APPLICATION_XML)
275    @Produces(MediaType.APPLICATION_XML)
276    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/body")
277    @Secured("ROLE_USER")
278    public JAXBElement<ResponseBody> updateAnnotationBody(@PathParam("annotationid") String externalIdentifier, AnnotationBody annotationBody) {
279        String path = uriInfo.getBaseUri().toString();
280        dbIntegrityService.setServiceURI(path);
281       
282        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(externalIdentifier));
283        final Number userID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
284        if (canWrite(userID, annotationID)) {
285            int updatedRows = dbIntegrityService.updateAnnotationBody(annotationID, annotationBody);
286            logger.info("updateAnnotationBody method: OK");
287            return new ObjectFactory().createResponseBody(makeAnnotationResponseEnvelope(annotationID));
288
289        } else {
290            logger.error("FORBIDDEN-access attempt.");
291            logger.error("The logged-in user is not authorised to alter this annotation. ");
292            try {
293                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
294            } catch (IOException ioe) {
295                logger.error("IOException: Cannot send server respond about unaithorized access.");
296            }
297            return null;
298        }
299
300    }
301
302    @PUT
303    @Consumes(MediaType.APPLICATION_XML)
304    @Produces(MediaType.APPLICATION_XML)
305    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/{userid: " + BackendConstants.regExpIdentifier + "}")
306    @Secured("ROLE_USER")
307    public String updatePermission(@PathParam("annotationid") String annotationExternalId, @PathParam("userid") String userExternalId, Permission permission) {
308        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
309        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(annotationExternalId));
310        final Number remoteUserID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
311        final Number userID = dbIntegrityService.getUserInternalIdentifier(UUID.fromString(userExternalId));
312        if (isOwner(remoteUserID, annotationID)) {
313            int result = (dbIntegrityService.getPermission(annotationID, userID) != null)
314                    ? dbIntegrityService.updateAnnotationPrincipalPermission(annotationID, userID, permission)
315                    : dbIntegrityService.addAnnotationPrincipalPermission(annotationID, userID, permission);
316            logger.info("updatePermission method: OK");
317            return result + " rows are updated/added";
318
319        } else {
320            logger.error("FORBIDDEN-access attempt");
321            logger.error("The logged-in user is not authorised to alter this annotation. ");
322            try {
323                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
324            } catch (IOException ioe) {
325                logger.error("IOException: Cannot send server respond about unaithorized access.");
326            }
327            return null;
328        }
329    }
330
331    @PUT
332    @Consumes(MediaType.APPLICATION_XML)
333    @Produces(MediaType.APPLICATION_XML)
334    @Path("{annotationid: " + BackendConstants.regExpIdentifier + "}/permissions/")
335    @Secured("ROLE_USER")
336    public JAXBElement<ResponseBody> updatePermissions(@PathParam("annotationid") String annotationExternalId, UserWithPermissionList permissions) {
337        dbIntegrityService.setServiceURI(uriInfo.getBaseUri().toString());
338        final Number annotationID = dbIntegrityService.getAnnotationInternalIdentifier(UUID.fromString(annotationExternalId));
339        final Number remoteUserID = dbIntegrityService.getUserInternalIDFromRemoteID(httpServletRequest.getRemoteUser());
340        if (isOwner(remoteUserID, annotationID)) {
341            int updatedRows = dbIntegrityService.updatePermissions(annotationID, permissions);
342            logger.info("updatePermissions method: OK");
343            return new ObjectFactory().createResponseBody(makePermissionResponseEnvelope(annotationID));
344        } else {
345            logger.error("FORBIDDEN-access attempt");
346            logger.error("The logged-in user is not authorised to alter this annotation. ");
347            try {
348                httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
349            } catch (IOException ioe) {
350                logger.error("IOException: Cannot send server respond about unaithorized access.");
351            }
352            return null;
353        }
354    }
355
356    /////////////////////////////////////////
357    private ResponseBody makeAnnotationResponseEnvelope(Number annotationID) {
358        ResponseBody result = new ResponseBody();
359        result.setPermissions(null);
360        Annotation annotation = dbIntegrityService.getAnnotation(annotationID);
361        result.setAnnotation(annotation);
362        List<String> targetsNoCached = dbIntegrityService.getTargetsWithNoCachedRepresentation(annotationID);
363        ActionList actionList = new ActionList();
364        result.setActionList(actionList);
365        actionList.getAction().addAll(makeActionList(targetsNoCached, AnnotationActionName.CREATE_CACHED_REPRESENTATION.value()));
366        return result;
367    }
368
369    /////////////////////////////////////////
370    private ResponseBody makePermissionResponseEnvelope(Number annotationID) {
371        ResponseBody result = new ResponseBody();
372        result.setAnnotation(null);
373        UserWithPermissionList permissions = dbIntegrityService.getPermissionsForAnnotation(annotationID);
374        result.setPermissions(permissions);
375        List<String> usersWithNoInfo = dbIntegrityService.getUsersWithNoInfo(annotationID);
376        ActionList actionList = new ActionList();
377        result.setActionList(actionList);
378        actionList.getAction().addAll(makeActionList(usersWithNoInfo, PermissionActionName.PROVIDE_USER_INFO.value()));
379        return result;
380    }
381
382    private List<Action> makeActionList(List<String> resourceURIs, String message) {
383        if (resourceURIs != null) {
384            if (resourceURIs.isEmpty()) {
385                return (new ArrayList<Action>());
386            } else {
387                List<Action> result = new ArrayList<Action>();
388                for (String resourceURI : resourceURIs) {
389                    Action action = new Action();
390                    result.add(action);
391                    action.setMessage(message);
392                    action.setObject(resourceURI);
393                }
394                return result;
395            }
396        } else {
397            return null;
398        }
399    }
400
401    private boolean canRead(Number userID, Number annotationID) {
402        final Permission permission = dbIntegrityService.getPermission(annotationID, userID);
403        if (permission != null) {
404            return (permission.value() == Permission.OWNER.value() || permission.value() == Permission.WRITER.value() || permission.value() == Permission.READER.value());
405        } else {
406            return false;
407        }
408    }
409
410    private boolean canWrite(Number userID, Number annotationID) {
411        final Permission permission = dbIntegrityService.getPermission(annotationID, userID);
412        if (permission != null) {
413            return (permission.value() == Permission.OWNER.value() || permission.value() == Permission.WRITER.value());
414        } else {
415            return false;
416        }
417    }
418
419    private boolean isOwner(Number userID, Number annotationID) {
420        final Permission permission = dbIntegrityService.getPermission(annotationID, userID);
421        if (permission != null) {
422            return (permission.value() == Permission.OWNER.value());
423        } else {
424            return false;
425        }
426    }
427}
Note: See TracBrowser for help on using the repository browser.