1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.annotation.rest.internal

File AnnotationsRESTResource.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart3.png
80% of files have more coverage

Code metrics

8
47
3
1
207
117
11
0.23
15.67
3
3.67

Classes

Class Line # Actions
AnnotationsRESTResource 65 47 0% 11 42
0.2758620727.6%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.annotation.rest.internal;
21   
22    import java.util.ArrayList;
23    import java.util.Arrays;
24    import java.util.Date;
25    import java.util.HashMap;
26    import java.util.List;
27    import java.util.Map;
28    import java.util.logging.Level;
29   
30    import javax.inject.Inject;
31    import javax.inject.Named;
32    import javax.inject.Singleton;
33    import javax.ws.rs.GET;
34    import javax.ws.rs.POST;
35    import javax.ws.rs.Path;
36    import javax.ws.rs.PathParam;
37    import javax.ws.rs.WebApplicationException;
38    import javax.ws.rs.core.Response;
39    import javax.ws.rs.core.Response.Status;
40   
41    import org.apache.commons.lang.StringUtils;
42    import org.restlet.Request;
43    import org.restlet.data.Form;
44    import org.xwiki.annotation.AnnotationServiceException;
45    import org.xwiki.annotation.rest.model.jaxb.AnnotationAddRequest;
46    import org.xwiki.annotation.rest.model.jaxb.AnnotationField;
47    import org.xwiki.annotation.rest.model.jaxb.AnnotationFieldCollection;
48    import org.xwiki.annotation.rest.model.jaxb.AnnotationRequest;
49    import org.xwiki.annotation.rest.model.jaxb.AnnotationResponse;
50    import org.xwiki.component.annotation.Component;
51    import org.xwiki.model.reference.DocumentReference;
52    import org.xwiki.model.reference.EntityReferenceSerializer;
53    import org.xwiki.rest.XWikiRestException;
54   
55    import com.xpn.xwiki.XWikiException;
56   
57    /**
58    * @version $Id: e73c09fe6b80ad6a99de065fdc16a84f06997eea $
59    * @since 2.3M1
60    */
61    @Component
62    @Named("org.xwiki.annotation.rest.internal.AnnotationsRESTResource")
63    @Path("/wikis/{wikiName}/spaces/{spaceName: .+}/pages/{pageName}/annotations")
64    @Singleton
 
65    public class AnnotationsRESTResource extends AbstractAnnotationRESTResource
66    {
67    /**
68    * Request parameter to request a field in an annotation request.
69    */
70    private static final String ANNOTATION_REQUEST_REQUESTED_FIELD_PARAMETER = "request_field";
71   
72    /**
73    * Request parameter prefix for a filter in an annotation request.
74    */
75   
76    private static final String ANNOTATION_REQUEST_FILTER_PARAMETER_PREFIX = "filter_";
77   
78    /**
79    * Entity reference serializer used to get reference to the document to perform annotation operation on.
80    */
81    @Inject
82    private EntityReferenceSerializer<String> referenceSerializer;
83   
84    /**
85    * @param wiki the wiki of the document to get annotations for
86    * @param space the space of the document to get annotations for
87    * @param page the name of the document to get annotation for
88    * @return annotations of a given XWiki page. Note that we're returning a response holding the AnnotatedContent
89    * instead of an AnnotatedContent object because we need to be able to set custom expire fields to prevent
90    * IE from caching this resource.
91    * @throws XWikiRestException when failing to parse space
92    */
 
93  0 toggle @GET
94    public Response doGetAnnotatedContent(@PathParam("spaceName") String space, @PathParam("pageName") String page,
95    @PathParam("wikiName") String wiki) throws XWikiRestException
96    {
97  0 try {
98  0 DocumentReference documentReference = new DocumentReference(wiki, parseSpaceSegments(space), page);
99   
100    // Initialize the context with the correct value.
101  0 updateContext(documentReference);
102   
103  0 String documentName = referenceSerializer.serialize(documentReference);
104   
105    // check access to this function
106  0 if (!annotationRightService.canViewAnnotatedTarget(documentName, getXWikiUser())) {
107  0 throw new WebApplicationException(Status.UNAUTHORIZED);
108    }
109   
110    // Manually construct the Annotation request entity
111    // Historically it used to be passed as method argument, but this only worked because of a bug in
112    // earlier version of Restlet (1.1.x) ; the JAX-RS specification explicitly states that such entity
113    // parameters "[are] mapped from the request entity body.", and thus cannot be passed to a GET resource.
114    // See paragraph 3.3.2.1 "Entity Parameters" of JAX-RS 1.1 specification.
115  0 Form form = Request.getCurrent().getResourceRef().getQueryAsForm();
116  0 AnnotationRequest request = new AnnotationRequest();
117  0 AnnotationFieldCollection fields = new AnnotationFieldCollection();
118  0 List<AnnotationField> annotationFields = new ArrayList<AnnotationField>();
119  0 AnnotationRequest.Request requestedFields = new AnnotationRequest.Request();
120  0 for (String name : form.getNames()) {
121  0 if (StringUtils.startsWith(name, ANNOTATION_REQUEST_FILTER_PARAMETER_PREFIX)) {
122  0 for (String value : form.getValuesArray(name)) {
123  0 AnnotationField field = new AnnotationField();
124  0 field.setName(StringUtils.substringAfter(name, ANNOTATION_REQUEST_FILTER_PARAMETER_PREFIX));
125  0 field.setValue(value);
126  0 annotationFields.add(field);
127    }
128  0 } else if (StringUtils.equals(name, ANNOTATION_REQUEST_REQUESTED_FIELD_PARAMETER)) {
129  0 requestedFields.getFields().addAll(Arrays.asList(form.getValuesArray(name)));
130    }
131    }
132  0 request.setRequest(requestedFields);
133  0 fields.getFields().addAll(annotationFields);
134  0 request.setFilter(fields);
135   
136  0 AnnotationResponse response = getSuccessResponseWithAnnotatedContent(documentName, request);
137    // make this content expire now because cacheControl is not implemented in this version of restlet
138  0 return Response.ok(response).expires(new Date()).build();
139    } catch (AnnotationServiceException e) {
140  0 logger.log(Level.SEVERE, e.getMessage(), e);
141  0 return Response.ok(getErrorResponse(e)).build();
142    } catch (XWikiException e) {
143  0 logger.log(Level.SEVERE, e.getMessage(), e);
144  0 return Response.ok(getErrorResponse(e)).build();
145    }
146    }
147   
148    /**
149    * Add annotation to a given page.
150    *
151    * @param wiki the wiki of the document to add annotation on
152    * @param space the space of the document to add annotation on
153    * @param page the name of the document to add annotation on
154    * @param request the request object with the annotation to be added
155    * @return AnnotationRequestResponse, responseCode = 0 if no error
156    * @throws XWikiRestException when failing to parse space
157    */
 
158  4 toggle @POST
159    public AnnotationResponse doPostAnnotation(@PathParam("wikiName") String wiki,
160    @PathParam("spaceName") String space, @PathParam("pageName") String page, AnnotationAddRequest request)
161    throws XWikiRestException
162    {
163  4 try {
164  4 DocumentReference documentReference = new DocumentReference(wiki, parseSpaceSegments(space), page);
165   
166    // Initialize the context with the correct value.
167  4 updateContext(documentReference);
168   
169  4 String documentName = referenceSerializer.serialize(documentReference);
170   
171    // check access to this function
172  4 if (!annotationRightService.canAddAnnotation(documentName, getXWikiUser())) {
173  0 throw new WebApplicationException(Status.UNAUTHORIZED);
174    }
175   
176    // add the annotation
177  4 Map<String, Object> annotationMetadata = getMap(request.getAnnotation());
178  4 annotationService.addAnnotation(documentName, request.getSelection(), request.getSelectionContext(),
179    request.getSelectionOffset(), getXWikiUser(), annotationMetadata);
180    // and then return the annotated content, as specified by the annotation request
181  4 AnnotationResponse response = getSuccessResponseWithAnnotatedContent(documentName, request);
182  4 return response;
183    } catch (AnnotationServiceException e) {
184  0 logger.log(Level.SEVERE, e.getMessage(), e);
185  0 return getErrorResponse(e);
186    } catch (XWikiException e) {
187  0 logger.log(Level.SEVERE, e.getMessage(), e);
188  0 return getErrorResponse(e);
189    }
190    }
191   
192    /**
193    * Builds a simple map from a field collection.
194    *
195    * @param fields the collection of fields to build a map for
196    * @return a map of the fields, as string key and Object value pair
197    */
 
198  4 toggle protected Map<String, Object> getMap(AnnotationFieldCollection fields)
199    {
200  4 Map<String, Object> metadataMap = new HashMap<String, Object>();
201  4 for (AnnotationField f : fields.getFields()) {
202  12 metadataMap.put(f.getName(), f.getValue());
203    }
204   
205  4 return metadataMap;
206    }
207    }