1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package edu.internet2.middleware.shibboleth.common.util;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.InputStream;
24 import java.io.UnsupportedEncodingException;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import org.apache.commons.collections.ExtendedProperties;
30 import org.apache.commons.lang.StringUtils;
31 import org.apache.velocity.exception.ResourceNotFoundException;
32 import org.apache.velocity.exception.VelocityException;
33 import org.apache.velocity.runtime.resource.Resource;
34 import org.apache.velocity.runtime.resource.loader.ResourceLoader;
35 import org.apache.velocity.runtime.resource.util.StringResource;
36 import org.apache.velocity.runtime.resource.util.StringResourceRepository;
37 import org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl;
38 import org.apache.velocity.util.ClassUtils;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public class StringResourceLoader extends ResourceLoader {
127
128 public static final String REPOSITORY_STATIC = "repository.static";
129
130
131 public static final boolean REPOSITORY_STATIC_DEFAULT = true;
132
133
134 public static final String REPOSITORY_CLASS = "repository.class";
135
136
137 public static final String REPOSITORY_CLASS_DEFAULT = StringResourceRepositoryImpl.class.getName();
138
139
140 public static final String REPOSITORY_NAME = "repository.name";
141
142
143
144
145
146 public static final String REPOSITORY_NAME_DEFAULT = StringResourceRepository.class.getName();
147
148
149 public static final String REPOSITORY_ENCODING = "repository.encoding";
150
151
152 public static final String REPOSITORY_ENCODING_DEFAULT = "UTF-8";
153
154 protected static final Map STATIC_REPOSITORIES = Collections.synchronizedMap(new HashMap());
155
156
157
158
159 public static StringResourceRepository getRepository() {
160 return getRepository(REPOSITORY_NAME_DEFAULT);
161 }
162
163
164
165
166 public static StringResourceRepository getRepository(String name) {
167 return (StringResourceRepository) STATIC_REPOSITORIES.get(name);
168 }
169
170
171
172
173 public static void setRepository(String name, StringResourceRepository repo) {
174 STATIC_REPOSITORIES.put(name, repo);
175 }
176
177
178
179
180 public static StringResourceRepository removeRepository(String name) {
181 return (StringResourceRepository) STATIC_REPOSITORIES.remove(name);
182 }
183
184
185
186
187 public static void clearRepositories() {
188 STATIC_REPOSITORIES.clear();
189 }
190
191
192 protected StringResourceRepository repository;
193
194
195
196
197 public void init(final ExtendedProperties configuration) {
198 log.trace("StringResourceLoader : initialization starting.");
199
200
201 String repoClass = configuration.getString(REPOSITORY_CLASS, REPOSITORY_CLASS_DEFAULT);
202 String repoName = configuration.getString(REPOSITORY_NAME, REPOSITORY_NAME_DEFAULT);
203 boolean isStatic = configuration.getBoolean(REPOSITORY_STATIC, REPOSITORY_STATIC_DEFAULT);
204 String encoding = configuration.getString(REPOSITORY_ENCODING);
205
206
207 if (isStatic) {
208 this.repository = getRepository(repoName);
209 if (repository != null && log.isDebugEnabled()) {
210 log.debug("Loaded repository '" + repoName + "' from static repo store");
211 }
212 } else {
213 this.repository = (StringResourceRepository) rsvc.getApplicationAttribute(repoName);
214 if (repository != null && log.isDebugEnabled()) {
215 log.debug("Loaded repository '" + repoName + "' from application attributes");
216 }
217 }
218
219 if (this.repository == null) {
220
221 this.repository = createRepository(repoClass, encoding);
222
223
224 if (isStatic) {
225 setRepository(repoName, this.repository);
226 } else {
227 rsvc.setApplicationAttribute(repoName, this.repository);
228 }
229 } else {
230
231
232 if (!this.repository.getClass().getName().equals(repoClass)) {
233 log.warn("Cannot change class of string repository '" + repoName + "' from "
234 + this.repository.getClass().getName() + " to " + repoClass);
235 }
236
237
238 if (encoding != null && !this.repository.getEncoding().equals(encoding)) {
239 if (log.isInfoEnabled()) {
240 log.info("Changing the default encoding of string repository '" + repoName + "' from "
241 + this.repository.getEncoding() + " to " + encoding);
242 }
243 this.repository.setEncoding(encoding);
244 }
245 }
246
247 log.trace("StringResourceLoader : initialization complete.");
248 }
249
250 public StringResourceRepository createRepository(final String className, final String encoding) {
251 if (log.isDebugEnabled()) {
252 log.debug("Creating string repository using class " + className + "...");
253 }
254
255 StringResourceRepository repo;
256 try {
257 repo = (StringResourceRepository) ClassUtils.getNewInstance(className);
258 } catch (ClassNotFoundException cnfe) {
259 throw new VelocityException("Could not find '" + className + "'", cnfe);
260 } catch (IllegalAccessException iae) {
261 throw new VelocityException("Could not access '" + className + "'", iae);
262 } catch (InstantiationException ie) {
263 throw new VelocityException("Could not instantiate '" + className + "'", ie);
264 }
265
266 if (encoding != null) {
267 repo.setEncoding(encoding);
268 } else {
269 repo.setEncoding(REPOSITORY_ENCODING_DEFAULT);
270 }
271
272 if (log.isDebugEnabled()) {
273 log.debug("Default repository encoding is " + repo.getEncoding());
274 }
275 return repo;
276 }
277
278
279
280
281
282
283
284
285 public InputStream getResourceStream(final String name) throws ResourceNotFoundException {
286 if (StringUtils.isEmpty(name)) {
287 throw new ResourceNotFoundException("No template name provided");
288 }
289
290 StringResource resource = this.repository.getStringResource(name);
291
292 if (resource == null) {
293 throw new ResourceNotFoundException("Could not locate resource '" + name + "'");
294 }
295
296 byte[] byteArray = null;
297
298 try {
299 byteArray = resource.getBody().getBytes(resource.getEncoding());
300 return new ByteArrayInputStream(byteArray);
301 } catch (UnsupportedEncodingException ue) {
302 throw new VelocityException("Could not convert String using encoding " + resource.getEncoding(), ue);
303 }
304 }
305
306
307
308
309 public boolean isSourceModified(final Resource resource) {
310 StringResource original = null;
311 boolean result = true;
312
313 original = this.repository.getStringResource(resource.getName());
314
315 if (original != null) {
316 result = original.getLastModified() != resource.getLastModified();
317 }
318
319 return result;
320 }
321
322
323
324
325 public long getLastModified(final Resource resource) {
326 StringResource original = null;
327
328 original = this.repository.getStringResource(resource.getName());
329
330 return (original != null) ? original.getLastModified() : 0;
331 }
332
333 }