1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.freemarker;
35
36 import java.beans.PropertyDescriptor;
37 import java.io.File;
38 import java.io.FileInputStream;
39 import java.io.FileNotFoundException;
40 import java.io.InputStream;
41 import java.io.UnsupportedEncodingException;
42 import java.net.MalformedURLException;
43 import java.net.URL;
44 import java.net.URLClassLoader;
45 import java.net.URLDecoder;
46 import java.util.Enumeration;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Set;
50
51 import javax.servlet.RequestDispatcher;
52 import javax.servlet.Servlet;
53 import javax.servlet.ServletContext;
54 import javax.servlet.ServletException;
55
56 import org.apache.commons.io.FileUtils;
57 import org.apache.commons.lang.StringUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67 public class FreemarkerServletContextWrapper implements ServletContext {
68
69 private ServletContext parentContext;
70
71
72
73
74 private static Logger log = LoggerFactory.getLogger(FreemarkerServletContextWrapper.class);
75
76 public FreemarkerServletContextWrapper(ServletContext parentServletContext) {
77
78 this.parentContext = parentServletContext;
79 }
80
81 @Override
82 public URL getResource(String path) throws MalformedURLException {
83
84 URL result = parentContext.getResource(path);
85 if (result == null) {
86
87 File file = new File(path);
88 if ((file.exists()) && (file.isFile())) {
89 result = file.toURI().toURL();
90 }
91 }
92 return result;
93 }
94
95 @Override
96 public InputStream getResourceAsStream(String path) {
97 InputStream is = parentContext.getResourceAsStream(path);
98 if (is == null) {
99
100 File file = new File(path);
101 if ((file.exists()) && (file.isFile())) {
102 try {
103 return new FileInputStream(file);
104 }
105 catch (FileNotFoundException e) {
106
107 }
108 }
109 }
110 return is;
111 }
112
113 @Override
114 @SuppressWarnings({"unchecked", "rawtypes"})
115 public Set getResourcePaths(String path) {
116 if (StringUtils.equals(path, "/WEB-INF/lib")) {
117 log.debug("returning resources from classpath");
118
119 final Set<String> resources = new HashSet<String>();
120 final ClassLoader cl = Thread.currentThread().getContextClassLoader();
121
122
123 if (cl instanceof URLClassLoader) {
124 final URLClassLoader urlClassLoader = (URLClassLoader) cl;
125 final URL[] urls = urlClassLoader.getURLs();
126 for (int j = 0; j < urls.length; j++) {
127 final File tofile = sanitizeToFile(urls[j]);
128 if (tofile.isDirectory()) {
129 for (File file : ((List<File>) FileUtils.listFiles(tofile, null, true))) {
130 resources.add(file.getAbsolutePath());
131 }
132 }
133 else {
134 resources.add(tofile.getAbsolutePath());
135 }
136 }
137
138 return resources;
139 }
140 try {
141
142
143
144
145
146
147 PropertyDescriptor pd = new PropertyDescriptor("classPath", cl.getClass());
148 if (pd != null && pd.getReadMethod() != null) {
149 String classpath = (String) pd.getReadMethod().invoke(cl, new Object[]{});
150 if (StringUtils.isNotBlank(classpath)) {
151 String[] paths = StringUtils.split(classpath, File.pathSeparator);
152 for (int j = 0; j < paths.length; j++) {
153 final File tofile = new File(paths[j]);
154
155 if (tofile.exists()) {
156 if (tofile.isDirectory()) {
157 for (File file : ((List<File>) FileUtils.listFiles(tofile, null, true))) {
158 resources.add(file.getAbsolutePath());
159 }
160 }
161 else {
162 resources.add(tofile.getAbsolutePath());
163 }
164 }
165 }
166 return resources;
167 }
168 }
169 }
170 catch (Throwable e) {
171
172 }
173
174
175 }
176 return parentContext.getResourcePaths(path);
177 }
178
179
180
181
182
183
184 private File sanitizeToFile(URL url) {
185 try {
186 String fileUrl = url.getFile();
187
188 fileUrl = URLDecoder.decode(fileUrl, "UTF-8");
189
190
191 fileUrl = StringUtils.removeStart(fileUrl, "file:");
192 fileUrl = StringUtils.removeEnd(fileUrl, "!/");
193 return new File(fileUrl);
194 }
195 catch (UnsupportedEncodingException e) {
196 throw new RuntimeException(e);
197 }
198 }
199
200
201 @Override
202 public Object getAttribute(String name) {
203 return parentContext.getAttribute(name);
204 }
205
206 @SuppressWarnings("rawtypes")
207 @Override
208 public Enumeration getAttributeNames() {
209 return parentContext.getAttributeNames();
210 }
211
212 @Override
213 public ServletContext getContext(String uripath) {
214 return parentContext.getContext(uripath);
215 }
216
217 @Override
218 public String getContextPath() {
219 return parentContext.getContextPath();
220 }
221
222 @Override
223 public String getInitParameter(String name) {
224 return parentContext.getInitParameter(name);
225 }
226
227 @SuppressWarnings("rawtypes")
228 @Override
229 public Enumeration getInitParameterNames() {
230 return parentContext.getInitParameterNames();
231 }
232
233 @Override
234 public int getMajorVersion() {
235 return parentContext.getMajorVersion();
236 }
237
238 @Override
239 public String getMimeType(String file) {
240 return parentContext.getMimeType(file);
241 }
242
243 @Override
244 public int getMinorVersion() {
245 return parentContext.getMinorVersion();
246 }
247
248 @Override
249 public RequestDispatcher getNamedDispatcher(String name) {
250 return parentContext.getNamedDispatcher(name);
251 }
252
253 @Override
254 public String getRealPath(String path) {
255 return parentContext.getRealPath(path);
256 }
257
258 @Override
259 public RequestDispatcher getRequestDispatcher(String path) {
260 return parentContext.getRequestDispatcher(path);
261 }
262
263 @Override
264 public String getServerInfo() {
265 return parentContext.getServerInfo();
266 }
267
268 @SuppressWarnings("deprecation")
269 @Override
270 public Servlet getServlet(String name) throws ServletException {
271 return parentContext.getServlet(name);
272 }
273
274 @Override
275 public String getServletContextName() {
276 return parentContext.getServletContextName();
277 }
278
279 @SuppressWarnings({"rawtypes", "deprecation"})
280 @Override
281 public Enumeration getServletNames() {
282 return parentContext.getServletNames();
283 }
284
285 @SuppressWarnings({"rawtypes", "deprecation"})
286 @Override
287 public Enumeration getServlets() {
288 return parentContext.getServlets();
289 }
290
291 @Override
292 public void log(String msg) {
293 parentContext.log(msg);
294 }
295
296 @SuppressWarnings("deprecation")
297 @Override
298 public void log(Exception exception, String msg) {
299 parentContext.log(exception, msg);
300 }
301
302 @Override
303 public void log(String message, Throwable throwable) {
304 parentContext.log(message, throwable);
305 }
306
307 @Override
308 public void removeAttribute(String name) {
309 parentContext.removeAttribute(name);
310 }
311
312 @Override
313 public void setAttribute(String name, Object object) {
314 parentContext.setAttribute(name, object);
315 }
316 }