1 package com.atlassian.plugin.servlet;
2
3 import com.atlassian.plugin.webresource.PluginResourceLocator;
4
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.http.HttpServletResponse;
7 import java.io.IOException;
8 import java.net.URLDecoder;
9 import java.util.Map;
10 import java.util.TreeMap;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class PluginResourceDownload implements DownloadStrategy
28 {
29 private static final Logger log = LoggerFactory.getLogger(PluginResourceDownload.class);
30 private String characterEncoding = "UTF-8";
31 private PluginResourceLocator pluginResourceLocator;
32 private ContentTypeResolver contentTypeResolver;
33
34 public PluginResourceDownload()
35 {
36 }
37
38 public PluginResourceDownload(PluginResourceLocator pluginResourceLocator, ContentTypeResolver contentTypeResolver, String characterEncoding)
39 {
40 this.characterEncoding = characterEncoding;
41 this.pluginResourceLocator = pluginResourceLocator;
42 this.contentTypeResolver = contentTypeResolver;
43 }
44
45 public boolean matches(String urlPath)
46 {
47 return pluginResourceLocator.matches(urlPath);
48 }
49
50 public void serveFile(HttpServletRequest request, HttpServletResponse response) throws DownloadException
51 {
52 try
53 {
54 String requestUri = URLDecoder.decode(request.getRequestURI(), characterEncoding);
55 DownloadableResource downloadableResource = pluginResourceLocator.getDownloadableResource(requestUri, getQueryParameters(request));
56
57 if (downloadableResource == null)
58 {
59 log.info("Could not locate resource: " + request.getRequestURI());
60 response.sendError(HttpServletResponse.SC_NOT_FOUND);
61 return;
62 }
63
64 if(downloadableResource.isResourceModified(request, response))
65 {
66 log.info("Plugin Resource has been modified since plugin was loaded. Skipping: " + requestUri);
67 return;
68 }
69
70 String contentType = getContentType(requestUri, downloadableResource);
71 if (contentType != null)
72 {
73 response.setContentType(contentType);
74 }
75 downloadableResource.serveResource(request, response);
76 }
77 catch(IOException e)
78 {
79 throw new DownloadException(e);
80 }
81 }
82
83 public void setCharacterEncoding(String characterEncoding)
84 {
85 this.characterEncoding = characterEncoding;
86 }
87
88 public void setContentTypeResolver(ContentTypeResolver contentTypeResolver)
89 {
90 this.contentTypeResolver = contentTypeResolver;
91 }
92
93 public void setPluginResourceLocator(PluginResourceLocator pluginResourceLocator)
94 {
95 this.pluginResourceLocator = pluginResourceLocator;
96 }
97
98
99
100
101
102 private String getContentType(String requestUri, DownloadableResource downloadableResource)
103 {
104 String contentType = downloadableResource.getContentType();
105 if(contentType == null)
106 {
107 return contentTypeResolver.getContentType(requestUri);
108 }
109
110 return contentType;
111 }
112
113
114
115
116
117
118
119 private Map<String, String> getQueryParameters(HttpServletRequest request)
120 {
121 Map<String, String> result = new TreeMap<String, String>();
122 Map<String, String[]> parameters = request.getParameterMap();
123
124 for (Map.Entry<String, String[]> entry : parameters.entrySet())
125 {
126 if(entry.getValue() != null && entry.getValue().length > 0)
127 result.put(entry.getKey(), entry.getValue()[0]);
128 }
129
130 return result;
131 }
132 }
133