1 package com.atlassian.plugin.webresource;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.elements.ResourceDescriptor;
5 import com.atlassian.plugin.servlet.BaseFileServerServlet;
6 import org.apache.commons.collections.set.ListOrderedSet;
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9
10 import java.io.IOException;
11 import java.io.Writer;
12 import java.util.*;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public class WebResourceManagerImpl implements WebResourceManager
29 {
30 private static final Log log = LogFactory.getLog(WebResourceManagerImpl.class);
31
32 static final String STATIC_RESOURCE_PREFIX = "s";
33 static final String STATIC_RESOURCE_SUFFIX = "_";
34
35 private static final String REQUEST_CACHE_RESOURCE_KEY = "plugin.webresource.names";
36 private static final String REQUEST_CACHE_MODE_KEY = "plugin.webresource.mode";
37
38 private static final IncludeMode DEFAULT_INCLUDE_MODE = WebResourceManager.DELAYED_INCLUDE_MODE;
39 private static final WebResourceFormatter[] WEB_RESOURCE_FORMATTERS = new WebResourceFormatter[] {
40 new CssWebResourceFormatter(),
41 new JavascriptWebResourceFormatter(),
42 };
43
44 private final WebResourceIntegration webResourceIntegration;
45
46 public WebResourceManagerImpl(WebResourceIntegration webResourceIntegration)
47 {
48 this.webResourceIntegration = webResourceIntegration;
49 }
50
51 public void requireResource(String resourceName)
52 {
53 if (WebResourceManager.DELAYED_INCLUDE_MODE.equals(getIncludeMode()))
54 {
55 requireDelayedResource(resourceName);
56 }
57 else
58 {
59 throw new IllegalStateException("Require Writer for Inline mode.");
60 }
61 }
62
63 public void requireResource(String resourceName, Writer writer)
64 {
65 if (WebResourceManager.DELAYED_INCLUDE_MODE.equals(getIncludeMode()))
66 {
67 requireDelayedResource(resourceName);
68 }
69 else
70 {
71 try
72 {
73 includeResource(resourceName, writer);
74 }
75 catch (IOException e)
76 {
77 log.error(e);
78 }
79 }
80 }
81
82 private void requireDelayedResource(String resourceName)
83 {
84 Map cache = webResourceIntegration.getRequestCache();
85 Collection webResourceNames = (Collection) cache.get(REQUEST_CACHE_RESOURCE_KEY);
86 if (webResourceNames == null)
87 {
88 webResourceNames = new ListOrderedSet();
89 }
90
91 webResourceNames.add(resourceName);
92 cache.put(REQUEST_CACHE_RESOURCE_KEY, webResourceNames);
93 }
94
95 public void includeResources(Writer writer)
96 {
97 try
98 {
99 if (WebResourceManager.DELAYED_INCLUDE_MODE.equals(getIncludeMode()))
100 {
101 includeDelayedResources(writer);
102 }
103 }
104 catch (IOException e)
105 {
106 log.error(e);
107 }
108
109 }
110
111 private void includeDelayedResources(Writer writer) throws IOException
112 {
113 Collection webResourceNames = (Collection) webResourceIntegration.getRequestCache().get(REQUEST_CACHE_RESOURCE_KEY);
114 if (webResourceNames == null || webResourceNames.isEmpty())
115 {
116 return;
117 }
118
119 for (Iterator iterator = webResourceNames.iterator(); iterator.hasNext();)
120 {
121 String resourceName = (String) iterator.next();
122 includeResource(resourceName, writer);
123 }
124 }
125
126 private void includeResource(String resourceName, Writer writer) throws IOException
127 {
128 ModuleDescriptor descriptor = webResourceIntegration.getPluginAccessor().getEnabledPluginModule(resourceName);
129 if (descriptor == null)
130 {
131 writer.write("<!-- Error loading resource \"" + resourceName + "\". Resource not found -->\n");
132 return;
133 }
134 else if (!(descriptor instanceof WebResourceModuleDescriptor))
135 {
136 writer.write("<!-- Error loading resource \"" + descriptor + "\". Resource is not a WebResourceModule -->\n");
137 return;
138 }
139
140 for (Iterator iterator1 = descriptor.getResourceDescriptors().iterator(); iterator1.hasNext();)
141 {
142 ResourceDescriptor resourceDescriptor = (ResourceDescriptor) iterator1.next();
143 String name = resourceDescriptor.getName();
144 final String linkToResource;
145 if ("false".equalsIgnoreCase(resourceDescriptor.getParameter("cache")))
146 {
147 linkToResource = webResourceIntegration.getBaseUrl() + getResourceUrl(descriptor, name);
148 }
149 else
150 {
151 linkToResource = getStaticPluginResource(descriptor, name);
152 }
153
154 WebResourceFormatter webResourceFormatter = getWebResourceFormatter(name);
155 if(webResourceFormatter != null)
156 {
157 writer.write(webResourceFormatter.formatResource(name, linkToResource, resourceDescriptor.getParameters()));
158 }
159 else
160 {
161 writer.write("<!-- Error loading resource \"" + descriptor + "\". Type " + resourceDescriptor.getType() + " is not handled -->\n");
162 }
163 }
164 }
165
166 private WebResourceFormatter getWebResourceFormatter(String name)
167 {
168 for (int i = 0; i < WEB_RESOURCE_FORMATTERS.length; i++)
169 {
170 WebResourceFormatter webResourceFormatter = WEB_RESOURCE_FORMATTERS[i];
171 if(webResourceFormatter.matches(name))
172 {
173 return webResourceFormatter;
174 }
175 }
176 return null;
177 }
178
179 public String getStaticResourcePrefix()
180 {
181
182 return webResourceIntegration.getBaseUrl() + "/" +
183 STATIC_RESOURCE_PREFIX + "/" +
184 webResourceIntegration.getSystemBuildNumber() + "/" +
185 webResourceIntegration.getSystemCounter() + "/" +
186 STATIC_RESOURCE_SUFFIX;
187 }
188
189 public String getStaticResourcePrefix(String resourceCounter)
190 {
191
192 return webResourceIntegration.getBaseUrl() + "/" +
193 STATIC_RESOURCE_PREFIX + "/" +
194 webResourceIntegration.getSystemBuildNumber() + "/" +
195 webResourceIntegration.getSystemCounter() + "/" +
196 resourceCounter + "/" +
197 STATIC_RESOURCE_SUFFIX;
198 }
199
200
201
202
203 public String getStaticPluginResourcePrefix(ModuleDescriptor moduleDescriptor, String resourceName)
204 {
205 return getStaticPluginResource(moduleDescriptor, resourceName);
206 }
207
208
209
210
211 public String getStaticPluginResource(ModuleDescriptor moduleDescriptor, String resourceName)
212 {
213
214 String prefix = getStaticResourcePrefix(moduleDescriptor.getPlugin().getPluginInformation().getVersion());
215
216
217 String suffix = getResourceUrl(moduleDescriptor, resourceName);
218 return prefix + suffix;
219 }
220
221
222 private String getResourceUrl(ModuleDescriptor moduleDescriptor, String resourceName)
223 {
224 return "/" + BaseFileServerServlet.SERVLET_PATH + "/" + BaseFileServerServlet.RESOURCE_URL_PREFIX + "/" + moduleDescriptor.getCompleteKey() + "/" + resourceName;
225 }
226
227 public String getStaticPluginResource(String pluginModuleKey, String resourceName)
228 {
229 return getStaticPluginResource(webResourceIntegration.getPluginAccessor().getEnabledPluginModule(pluginModuleKey), resourceName);
230 }
231
232 public void setIncludeMode(IncludeMode includeMode)
233 {
234 webResourceIntegration.getRequestCache().put(REQUEST_CACHE_MODE_KEY, includeMode);
235 }
236
237 IncludeMode getIncludeMode()
238 {
239 IncludeMode includeMode = (IncludeMode) webResourceIntegration.getRequestCache().get(REQUEST_CACHE_MODE_KEY);
240 if (includeMode == null)
241 {
242 includeMode = DEFAULT_INCLUDE_MODE;
243 }
244 return includeMode;
245 }
246
247
248 }