1 package org.apache.velocity.tools.view;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.InputStream;
24 import java.util.HashMap;
25 import javax.servlet.ServletContext;
26 import org.apache.commons.collections.ExtendedProperties;
27 import org.apache.velocity.exception.ResourceNotFoundException;
28 import org.apache.velocity.runtime.resource.Resource;
29 import org.apache.velocity.runtime.resource.loader.ResourceLoader;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class WebappResourceLoader extends ResourceLoader
55 {
56
57 protected String[] paths = null;
58 protected HashMap templatePaths = null;
59 protected ServletContext servletContext = null;
60
61
62
63
64
65
66
67
68
69
70
71
72 public void init(ExtendedProperties configuration)
73 {
74 log.trace("WebappResourceLoader: initialization starting.");
75
76
77 paths = configuration.getStringArray("path");
78 if (paths == null || paths.length == 0)
79 {
80 paths = new String[1];
81 paths[0] = "/";
82 }
83 else
84 {
85
86 for (int i=0; i < paths.length; i++)
87 {
88 if (!paths[i].endsWith("/"))
89 {
90 paths[i] += '/';
91 }
92 log.info("WebappResourceLoader: added template path - '" + paths[i] + "'");
93 }
94 }
95
96
97 Object obj = rsvc.getApplicationAttribute(ServletContext.class.getName());
98 if (obj instanceof ServletContext)
99 {
100 servletContext = (ServletContext)obj;
101 }
102 else
103 {
104 log.error("WebappResourceLoader: unable to retrieve ServletContext");
105 }
106
107
108 templatePaths = new HashMap();
109
110 log.trace("WebappResourceLoader: initialization complete.");
111 }
112
113
114
115
116
117
118
119
120
121
122 public synchronized InputStream getResourceStream(String name)
123 throws ResourceNotFoundException
124 {
125 InputStream result = null;
126
127 if (name == null || name.length() == 0)
128 {
129 throw new ResourceNotFoundException("WebappResourceLoader: No template name provided");
130 }
131
132
133
134 while (name.startsWith("/"))
135 {
136 name = name.substring(1);
137 }
138
139 Exception exception = null;
140 for (int i = 0; i < paths.length; i++)
141 {
142 String path = paths[i] + name;
143 try
144 {
145 result = servletContext.getResourceAsStream(path);
146
147
148 if (result != null)
149 {
150 templatePaths.put(name, paths[i]);
151 break;
152 }
153 }
154 catch (NullPointerException npe)
155 {
156
157 throw npe;
158 }
159 catch (Exception e)
160 {
161
162 if (exception == null)
163 {
164 if (log.isDebugEnabled())
165 {
166 log.debug("WebappResourceLoader: Could not load "+path, e);
167 }
168 exception = e;
169 }
170 }
171 }
172
173
174 if (result == null)
175 {
176 String msg = "WebappResourceLoader: Resource '" + name + "' not found.";
177
178
179 if (exception == null)
180 {
181 throw new ResourceNotFoundException(msg);
182 }
183 else
184 {
185 msg += " Due to: " + exception;
186 throw new ResourceNotFoundException(msg, exception);
187 }
188 }
189 return result;
190 }
191
192 private File getCachedFile(String rootPath, String fileName)
193 {
194
195
196 while (fileName.startsWith("/"))
197 {
198 fileName = fileName.substring(1);
199 }
200
201 String savedPath = (String)templatePaths.get(fileName);
202 return new File(rootPath + savedPath, fileName);
203 }
204
205
206
207
208
209
210
211
212 public boolean isSourceModified(Resource resource)
213 {
214 String rootPath = servletContext.getRealPath("/");
215 if (rootPath == null) {
216
217
218
219 return false;
220 }
221
222
223 String fileName = resource.getName();
224 File cachedFile = getCachedFile(rootPath, fileName);
225 if (!cachedFile.exists())
226 {
227
228 return true;
229 }
230
231
232
233 File currentFile = null;
234 for (int i = 0; i < paths.length; i++)
235 {
236 currentFile = new File(rootPath + paths[i], fileName);
237 if (currentFile.canRead())
238 {
239
240
241 break;
242 }
243 }
244
245
246 if (cachedFile.equals(currentFile) && cachedFile.canRead())
247 {
248
249 return (cachedFile.lastModified() != resource.getLastModified());
250 }
251 else
252 {
253
254
255 return true;
256 }
257 }
258
259
260
261
262
263
264
265 public long getLastModified(Resource resource)
266 {
267 String rootPath = servletContext.getRealPath("/");
268 if (rootPath == null) {
269
270
271
272 return 0;
273 }
274
275 File cachedFile = getCachedFile(rootPath, resource.getName());
276 if (cachedFile.canRead())
277 {
278 return cachedFile.lastModified();
279 }
280 else
281 {
282 return 0;
283 }
284 }
285 }