1 package com.atlassian.plugins.rest.module.json;
2
3 import com.sun.jersey.spi.container.ContainerRequest;
4 import com.sun.jersey.spi.container.ContainerResponse;
5 import com.sun.jersey.spi.container.ContainerResponseFilter;
6 import org.apache.commons.lang.StringUtils;
7 import org.apache.commons.lang.Validate;
8
9 import static javax.ws.rs.core.HttpHeaders.*;
10 import javax.ws.rs.core.MediaType;
11 import javax.ws.rs.core.MultivaluedMap;
12 import javax.ws.rs.ext.Provider;
13
14 @Provider
15 public class JsonWithPaddingResponseFilter implements ContainerResponseFilter
16 {
17 private final String callbackFunctionParameterName;
18
19 public JsonWithPaddingResponseFilter()
20 {
21 this("jsonp-callback");
22 }
23
24 public JsonWithPaddingResponseFilter(String callbackFunctionParameterName)
25 {
26 Validate.notEmpty(callbackFunctionParameterName);
27 this.callbackFunctionParameterName = callbackFunctionParameterName;
28 }
29
30 public ContainerResponse filter(ContainerRequest request, ContainerResponse response)
31 {
32 if (isJsonWithPadding(request, response))
33 {
34 response.setContainerResponseWriter(new JsonWithPaddingResponseAdapter(getCallbackFunction(request), response.getContainerResponseWriter()));
35 }
36 return response;
37 }
38
39 private boolean isJsonWithPadding(ContainerRequest request, ContainerResponse response)
40 {
41 return isJsonResponse(response) && isCallbackRequest(request);
42 }
43
44 private boolean isCallbackRequest(ContainerRequest request)
45 {
46 return StringUtils.isNotBlank(getCallbackFunction(request));
47 }
48
49 private String getCallbackFunction(ContainerRequest request)
50 {
51 return request.getQueryParameters().getFirst(callbackFunctionParameterName);
52 }
53
54 private boolean isJsonResponse(ContainerResponse response)
55 {
56 final MultivaluedMap<String, Object> httpHeaders = response.getHttpHeaders();
57 return httpHeaders.containsKey(CONTENT_TYPE) && httpHeaders.getFirst(CONTENT_TYPE).equals(MediaType.APPLICATION_JSON_TYPE);
58 }
59 }