1 package org.apache.velocity.runtime.resource.loader;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.InputStream;
23
24 import org.apache.velocity.runtime.RuntimeServices;
25 import org.apache.velocity.runtime.log.Log;
26 import org.apache.velocity.runtime.resource.Resource;
27 import org.apache.velocity.runtime.resource.ResourceCacheImpl;
28 import org.apache.velocity.exception.ResourceNotFoundException;
29 import org.apache.velocity.exception.VelocityException;
30 import org.apache.commons.collections.ExtendedProperties;
31
32 /**
33 * This is abstract class the all text resource loaders should
34 * extend.
35 *
36 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
37 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
38 * @version $Id: ResourceLoader.java 687518 2008-08-21 00:18:03Z nbubna $
39 */
40 public abstract class ResourceLoader
41 {
42 /**
43 * Does this loader want templates produced with it
44 * cached in the Runtime.
45 */
46 protected boolean isCachingOn = false;
47
48 /**
49 * This property will be passed on to the templates
50 * that are created with this loader.
51 */
52 protected long modificationCheckInterval = 2;
53
54 /**
55 * Class name for this loader, for logging/debuggin
56 * purposes.
57 */
58 protected String className = null;
59
60 protected RuntimeServices rsvc = null;
61 protected Log log = null;
62
63 /**
64 * This initialization is used by all resource
65 * loaders and must be called to set up common
66 * properties shared by all resource loaders
67 * @param rs
68 * @param configuration
69 */
70 public void commonInit( RuntimeServices rs, ExtendedProperties configuration)
71 {
72 this.rsvc = rs;
73 this.log = rsvc.getLog();
74
75 /*
76 * these two properties are not required for all loaders.
77 * For example, for ClasspathLoader, what would cache mean?
78 * so adding default values which I think are the safest
79 *
80 * don't cache, and modCheckInterval irrelevant...
81 */
82
83 try
84 {
85 isCachingOn = configuration.getBoolean("cache", false);
86 }
87 catch (Exception e)
88 {
89 isCachingOn = false;
90 String msg = "Exception parsing cache setting: "+configuration.getString("cache");
91 log.error(msg, e);
92 throw new VelocityException(msg, e);
93 }
94 try
95 {
96 modificationCheckInterval = configuration.getLong("modificationCheckInterval", 0);
97 }
98 catch (Exception e)
99 {
100 modificationCheckInterval = 0;
101 String msg = "Exception parsing modificationCheckInterval setting: "+configuration.getString("modificationCheckInterval");
102 log.error(msg, e);
103 throw new VelocityException(msg, e);
104 }
105
106 /*
107 * this is a must!
108 */
109 className = ResourceCacheImpl.class.getName();
110 try
111 {
112 className = configuration.getString("class", className);
113 }
114 catch (Exception e)
115 {
116 String msg = "Exception retrieving resource cache class name";
117 log.error(msg, e);
118 throw new VelocityException(msg, e);
119 }
120 }
121
122 /**
123 * Initialize the template loader with a
124 * a resources class.
125 * @param configuration
126 */
127 public abstract void init( ExtendedProperties configuration);
128
129 /**
130 * Get the InputStream that the Runtime will parse
131 * to create a template.
132 * @param source
133 * @return The input stream for the requested resource.
134 * @throws ResourceNotFoundException
135 */
136 public abstract InputStream getResourceStream( String source )
137 throws ResourceNotFoundException;
138
139 /**
140 * Given a template, check to see if the source of InputStream
141 * has been modified.
142 * @param resource
143 * @return True if the resource has been modified.
144 */
145 public abstract boolean isSourceModified(Resource resource);
146
147 /**
148 * Get the last modified time of the InputStream source
149 * that was used to create the template. We need the template
150 * here because we have to extract the name of the template
151 * in order to locate the InputStream source.
152 * @param resource
153 * @return Time in millis when the resource has been modified.
154 */
155 public abstract long getLastModified(Resource resource);
156
157 /**
158 * Return the class name of this resource Loader
159 * @return Class name of the resource loader.
160 */
161 public String getClassName()
162 {
163 return className;
164 }
165
166 /**
167 * Set the caching state. If true, then this loader
168 * would like the Runtime to cache templates that
169 * have been created with InputStreams provided
170 * by this loader.
171 * @param value
172 */
173 public void setCachingOn(boolean value)
174 {
175 isCachingOn = value;
176 }
177
178 /**
179 * The Runtime uses this to find out whether this
180 * template loader wants the Runtime to cache
181 * templates created with InputStreams provided
182 * by this loader.
183 * @return True if this resource loader caches.
184 */
185 public boolean isCachingOn()
186 {
187 return isCachingOn;
188 }
189
190 /**
191 * Set the interval at which the InputStream source
192 * should be checked for modifications.
193 * @param modificationCheckInterval
194 */
195 public void setModificationCheckInterval(long modificationCheckInterval)
196 {
197 this.modificationCheckInterval = modificationCheckInterval;
198 }
199
200 /**
201 * Get the interval at which the InputStream source
202 * should be checked for modifications.
203 * @return The modification check interval.
204 */
205 public long getModificationCheckInterval()
206 {
207 return modificationCheckInterval;
208 }
209
210 /**
211 * Check whether any given resource exists. This is not really
212 * a very efficient test and it can and should be overridden in the
213 * subclasses extending ResourceLoader.
214 *
215 * @param resourceName The name of a resource.
216 * @return true if a resource exists and can be accessed.
217 * @since 1.6
218 */
219 public boolean resourceExists(final String resourceName)
220 {
221 InputStream is = null;
222 try
223 {
224 is = getResourceStream(resourceName);
225 }
226 catch (ResourceNotFoundException e)
227 {
228 if (log.isDebugEnabled())
229 {
230 log.debug("Could not load resource '" + resourceName
231 + "' from ResourceLoader " + this.getClass().getName()
232 + ": ", e);
233 }
234 }
235 finally
236 {
237 try
238 {
239 if (is != null)
240 {
241 is.close();
242 }
243 }
244 catch (Exception e)
245 {
246 if (log.isErrorEnabled())
247 {
248 String msg = "While closing InputStream for resource '" + resourceName
249 + "' from ResourceLoader "+this.getClass().getName();
250 log.error(msg, e);
251 throw new VelocityException(msg, e);
252 }
253 }
254 }
255 return (is != null);
256 }
257 }