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