1 package com.atlassian.plugin.webresource;
2
3 import static com.atlassian.plugin.servlet.AbstractFileServerServlet.PATH_SEPARATOR;
4 import static com.atlassian.plugin.servlet.AbstractFileServerServlet.SERVLET_PATH;
5
6 import com.atlassian.plugin.servlet.DownloadException;
7 import com.atlassian.plugin.servlet.DownloadableResource;
8 import com.atlassian.plugin.Plugin;
9
10 import java.io.IOException;
11 import java.io.OutputStream;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Map;
16
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23
24
25
26
27
28
29
30
31
32
33 public class BatchPluginResource implements DownloadableResource, PluginResource, BatchResource
34 {
35 private static final Logger log = LoggerFactory.getLogger(BatchPluginResource.class);
36
37
38
39
40 static final String URL_PREFIX = PATH_SEPARATOR + SERVLET_PATH + PATH_SEPARATOR + "batch";
41
42 final private String type;
43 final private String moduleCompleteKey;
44 final private Map<String, String> params;
45 final private String resourceName;
46 final private List<DownloadableResource> resources;
47
48
49
50
51
52
53
54 public BatchPluginResource(final String moduleCompleteKey, final String type, final Map<String, String> params)
55 {
56 this(moduleCompleteKey + "." + type, moduleCompleteKey, type, params);
57 }
58
59
60
61
62
63 private BatchPluginResource(final String resourceName, final String moduleCompleteKey, final String type, final Map<String, String> params)
64 {
65 this.resourceName = resourceName;
66 this.moduleCompleteKey = moduleCompleteKey;
67 this.type = type;
68 this.params = params;
69 resources = new ArrayList<DownloadableResource>();
70 }
71
72
73
74
75 public boolean isEmpty()
76 {
77 return resources.isEmpty();
78 }
79
80 public void add(final DownloadableResource resource)
81 {
82 resources.add(resource);
83 }
84
85 public boolean isResourceModified(final HttpServletRequest request, final HttpServletResponse response)
86 {
87 for (final DownloadableResource resource : resources)
88 {
89 if (resource.isResourceModified(request, response))
90 {
91 return true;
92 }
93 }
94 return false;
95 }
96
97 public void serveResource(final HttpServletRequest request, final HttpServletResponse response) throws DownloadException
98 {
99 log.debug("Start to serve batch " + toString());
100 for (final DownloadableResource resource : resources)
101 {
102 resource.serveResource(request, response);
103 writeNewLine(response);
104 }
105 }
106
107 public void streamResource(final OutputStream out) throws DownloadException
108 {
109 for (final DownloadableResource resource : resources)
110 {
111 resource.streamResource(out);
112 writeNewLine(out);
113 }
114 }
115
116
117
118
119
120
121
122
123
124 private void writeNewLine(final HttpServletResponse response) throws DownloadException
125 {
126 try
127 {
128 writeNewLine(response.getOutputStream());
129 }
130 catch (final IOException e)
131 {
132 throw new DownloadException(e);
133 }
134 }
135
136 private void writeNewLine(final OutputStream out) throws DownloadException
137 {
138 try
139 {
140 out.write('\n');
141 }
142 catch (final IOException e)
143 {
144 throw new DownloadException(e);
145 }
146 }
147
148 public String getContentType()
149 {
150 final String contentType = params.get("content-type");
151 if (contentType != null)
152 {
153 return contentType;
154 }
155 return null;
156 }
157
158
159
160
161
162
163
164
165
166 public static BatchPluginResource parse(String url, final Map<String, String> queryParams) throws UrlParseException
167 {
168 final int startIndex = url.indexOf(URL_PREFIX) + URL_PREFIX.length() + 1;
169
170 if (url.indexOf('?') != -1)
171 {
172 url = url.substring(0, url.indexOf('?'));
173 }
174
175 final String typeAndModuleKey = url.substring(startIndex);
176 final String[] parts = typeAndModuleKey.split("/", 2);
177
178 if (parts.length < 2)
179 {
180 throw new UrlParseException("Could not parse invalid batch resource url: " + url);
181 }
182
183 final String moduleKey = parts[0];
184 final String resourceName = parts[1];
185 final String type = resourceName.substring(resourceName.lastIndexOf('.') + 1);
186
187 return new BatchPluginResource(resourceName, moduleKey, type, queryParams);
188 }
189
190 public static boolean matches(final String url)
191 {
192 return url.indexOf(URL_PREFIX) != -1;
193 }
194
195
196
197
198
199
200
201
202
203
204
205 public String getUrl()
206 {
207 final StringBuilder sb = new StringBuilder();
208 sb.append(URL_PREFIX).append(PATH_SEPARATOR).append(moduleCompleteKey).append(PATH_SEPARATOR).append(resourceName);
209
210 addParamsToUrl(sb, params);
211
212 return sb.toString();
213 }
214
215 protected void addParamsToUrl(StringBuilder sb, Map<String, String> params)
216 {
217 if (params.size() > 0)
218 {
219 sb.append("?");
220 int count = 0;
221
222 for (final Map.Entry<String, String> entry : params.entrySet())
223 {
224 sb.append(entry.getKey()).append("=").append(entry.getValue());
225
226 if (++count < params.size())
227 {
228 sb.append("&");
229 }
230 }
231 }
232 }
233
234 public String getResourceName()
235 {
236 return resourceName;
237 }
238
239 public Map<String, String> getParams()
240 {
241 return Collections.unmodifiableMap(params);
242 }
243
244 public String getVersion(WebResourceIntegration integration)
245 {
246 final Plugin plugin = integration.getPluginAccessor().getEnabledPluginModule(getModuleCompleteKey()).getPlugin();
247 return plugin.getPluginInformation().getVersion();
248 }
249
250 public String getModuleCompleteKey()
251 {
252 return moduleCompleteKey;
253 }
254
255 public boolean isCacheSupported()
256 {
257 return !"false".equals(params.get("cache"));
258 }
259
260 public String getType()
261 {
262 return type;
263 }
264
265 @Override
266 public boolean equals(final Object o)
267 {
268 if (this == o)
269 {
270 return true;
271 }
272 if ((o == null) || (getClass() != o.getClass()))
273 {
274 return false;
275 }
276
277 final BatchPluginResource that = (BatchPluginResource) o;
278
279 if (moduleCompleteKey != null ? !moduleCompleteKey.equals(that.moduleCompleteKey) : that.moduleCompleteKey != null)
280 {
281 return false;
282 }
283 if (params != null ? !params.equals(that.params) : that.params != null)
284 {
285 return false;
286 }
287 if (type != null ? !type.equals(that.type) : that.type != null)
288 {
289 return false;
290 }
291
292 return true;
293 }
294
295 @Override
296 public int hashCode()
297 {
298 int result;
299 result = (type != null ? type.hashCode() : 0);
300 result = 31 * result + (moduleCompleteKey != null ? moduleCompleteKey.hashCode() : 0);
301 result = 31 * result + (params != null ? params.hashCode() : 0);
302 return result;
303 }
304
305 @Override
306 public String toString()
307 {
308 return "[moduleCompleteKey=" + moduleCompleteKey + ", type=" + type + ", params=" + params + "]";
309 }
310 }