1 package com.atlassian.plugins.rest.module.filter;
2
3 import com.sun.jersey.spi.container.ContainerRequest;
4 import com.sun.jersey.spi.container.ContainerRequestFilter;
5 import org.apache.commons.lang.StringUtils;
6 import org.apache.commons.lang.Validate;
7
8 import javax.ws.rs.core.HttpHeaders;
9 import static javax.ws.rs.core.MediaType.*;
10 import javax.ws.rs.core.UriBuilder;
11 import javax.ws.rs.ext.Provider;
12 import java.net.URI;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.LinkedList;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.regex.Pattern;
19
20
21
22
23
24
25
26
27
28 @Provider
29 public class ExtensionJerseyFilter implements ContainerRequestFilter
30 {
31 private static final String DOT = ".";
32
33 private final Collection<Pattern> pathExcludePatterns;
34
35
36 public ExtensionJerseyFilter(Collection<String> pathExcludePatterns)
37 {
38 Validate.notNull(pathExcludePatterns);
39 this.pathExcludePatterns = compilePatterns(pathExcludePatterns);
40 }
41
42 final static Map<String, String> EXTENSION_TO_ACCEPT_HEADER = new HashMap<String, String>()
43 {{
44 put("txt", TEXT_PLAIN);
45 put("htm", TEXT_HTML);
46 put("html", TEXT_HTML);
47 put("json", APPLICATION_JSON);
48 put("xml", APPLICATION_XML);
49 put("atom", APPLICATION_ATOM_XML);
50 }};
51
52 public ContainerRequest filter(ContainerRequest request)
53 {
54
55 final String absolutePath = request.getAbsolutePath().toString();
56
57 final String extension = StringUtils.substringAfterLast(absolutePath, DOT);
58 if (shouldFilter("/" + StringUtils.difference(request.getBaseUri().toString(), absolutePath), extension))
59 {
60 request.getRequestHeaders().putSingle(HttpHeaders.ACCEPT, EXTENSION_TO_ACCEPT_HEADER.get(extension));
61 final String absolutePathWithoutExtension = StringUtils.substringBeforeLast(absolutePath, DOT);
62 request.setUris(request.getBaseUri(), getRequestUri(absolutePathWithoutExtension, request.getQueryParameters()));
63 }
64 return request;
65 }
66
67 private boolean shouldFilter(String restPath, String extension)
68 {
69 for (Pattern pattern : pathExcludePatterns)
70 {
71 if (pattern.matcher(restPath).matches())
72 {
73 return false;
74 }
75 }
76 return EXTENSION_TO_ACCEPT_HEADER.containsKey(extension);
77 }
78
79 private URI getRequestUri(String absolutePathWithoutExtension, Map<String, List<String>> queryParams)
80 {
81 final UriBuilder requestUriBuilder = UriBuilder.fromPath(absolutePathWithoutExtension);
82 for (Map.Entry<String, List<String>> queryParamEntry : queryParams.entrySet())
83 {
84 for (String value : queryParamEntry.getValue())
85 {
86 requestUriBuilder.queryParam(queryParamEntry.getKey(), value);
87 }
88 }
89 return requestUriBuilder.build();
90 }
91
92 private Collection<Pattern> compilePatterns(Collection<String> pathExcludePatterns)
93 {
94 final Collection<Pattern> patterns = new LinkedList<Pattern>();
95 for (String pattern : pathExcludePatterns)
96 {
97 patterns.add(Pattern.compile(pattern));
98 }
99 return patterns;
100 }
101 }