KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > resource > loader > FileResourceLoader


1 package org.apache.velocity.runtime.resource.loader;
2
3 /*
4  * Copyright 2001,2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.File JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24
25 import java.util.Hashtable JavaDoc;
26 import java.util.Vector JavaDoc;
27
28 import org.apache.velocity.util.StringUtils;
29
30 import org.apache.velocity.runtime.resource.Resource;
31
32 import org.apache.velocity.exception.ResourceNotFoundException;
33
34 import org.apache.commons.collections.ExtendedProperties;
35
36 /**
37  * A loader for templates stored on the file system.
38  *
39  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
40  * @version $Id: FileResourceLoader.java,v 1.19.4.1 2004/03/03 23:23:02 geirm Exp $
41  */

42 public class FileResourceLoader extends ResourceLoader
43 {
44     /**
45      * The paths to search for templates.
46      */

47     private Vector JavaDoc paths = null;
48
49     /**
50      * Used to map the path that a template was found on
51      * so that we can properly check the modification
52      * times of the files.
53      */

54     private Hashtable JavaDoc templatePaths = new Hashtable JavaDoc();
55
56     public void init( ExtendedProperties configuration)
57     {
58         rsvc.info("FileResourceLoader : initialization starting.");
59         
60         paths = configuration.getVector("path");
61         
62         /*
63          * lets tell people what paths we will be using
64          */

65
66         int sz = paths.size();
67
68         for( int i=0; i < sz; i++)
69         {
70             rsvc.info("FileResourceLoader : adding path '" + (String JavaDoc) paths.get(i) + "'");
71         }
72
73         rsvc.info("FileResourceLoader : initialization complete.");
74     }
75
76     /**
77      * Get an InputStream so that the Runtime can build a
78      * template with it.
79      *
80      * @param name name of template to get
81      * @return InputStream containing the template
82      * @throws ResourceNotFoundException if template not found
83      * in the file template path.
84      */

85     public synchronized InputStream JavaDoc getResourceStream(String JavaDoc templateName)
86         throws ResourceNotFoundException
87     {
88         /*
89          * Make sure we have a valid templateName.
90          */

91         if (templateName == null || templateName.length() == 0)
92         {
93             /*
94              * If we don't get a properly formed templateName then
95              * there's not much we can do. So we'll forget about
96              * trying to search any more paths for the template.
97              */

98             throw new ResourceNotFoundException(
99                 "Need to specify a file name or file path!");
100         }
101
102         String JavaDoc template = StringUtils.normalizePath(templateName);
103         if ( template == null || template.length() == 0 )
104         {
105             String JavaDoc msg = "File resource error : argument " + template +
106                 " contains .. and may be trying to access " +
107                 "content outside of template root. Rejected.";
108
109             rsvc.error( "FileResourceLoader : " + msg );
110       
111             throw new ResourceNotFoundException ( msg );
112         }
113
114         /*
115          * if a / leads off, then just nip that :)
116          */

117         if (template.startsWith("/"))
118         {
119             template = template.substring(1);
120         }
121
122         int size = paths.size();
123         for (int i = 0; i < size; i++)
124         {
125             String JavaDoc path = (String JavaDoc) paths.get(i);
126             InputStream JavaDoc inputStream = findTemplate(path, template);
127             
128             if (inputStream != null)
129             {
130                 /*
131                  * Store the path that this template came
132                  * from so that we can check its modification
133                  * time.
134                  */

135
136                 templatePaths.put(templateName, path);
137                 return inputStream;
138             }
139         }
140     
141         /*
142          * We have now searched all the paths for
143          * templates and we didn't find anything so
144          * throw an exception.
145          */

146          String JavaDoc msg = "FileResourceLoader Error: cannot find resource " +
147           template;
148     
149          throw new ResourceNotFoundException( msg );
150     }
151     
152     /**
153      * Try to find a template given a normalized path.
154      *
155      * @param String a normalized path
156      * @return InputStream input stream that will be parsed
157      *
158      */

159     private InputStream JavaDoc findTemplate(String JavaDoc path, String JavaDoc template)
160     {
161         try
162         {
163             File JavaDoc file = new File JavaDoc( path, template );
164         
165             if ( file.canRead() )
166             {
167                 return new BufferedInputStream JavaDoc(
168                     new FileInputStream JavaDoc(file.getAbsolutePath()));
169             }
170             else
171             {
172                 return null;
173             }
174         }
175         catch( FileNotFoundException JavaDoc fnfe )
176         {
177             /*
178              * log and convert to a general Velocity ResourceNotFoundException
179              */

180             return null;
181         }
182     }
183     
184     /**
185      * How to keep track of all the modified times
186      * across the paths. Note that a file might have
187      * appeared in a directory which is earlier in the
188      * path; so we should search the path and see if
189      * the file we find that way is the same as the one
190      * that we have cached.
191      */

192     public boolean isSourceModified(Resource resource)
193     {
194         /*
195          * we assume that the file needs to be reloaded;
196          * if we find the original file and it's unchanged,
197          * then we'll flip this.
198          */

199         boolean modified = true;
200
201         String JavaDoc fileName = resource.getName();
202         String JavaDoc path = (String JavaDoc) templatePaths.get(fileName);
203         File JavaDoc currentFile = null;
204
205         for (int i = 0; currentFile == null && i < paths.size(); i++)
206         {
207             String JavaDoc testPath = (String JavaDoc) paths.get(i);
208             File JavaDoc testFile = new File JavaDoc(testPath, fileName);
209             if (testFile.canRead())
210             {
211                 currentFile = testFile;
212             }
213         }
214         File JavaDoc file = new File JavaDoc(path, fileName);
215         if (currentFile == null || !file.exists())
216         {
217             /*
218              * noop: if the file is missing now (either the cached
219              * file is gone, or the file can no longer be found)
220              * then we leave modified alone (it's set to true); a
221              * reload attempt will be done, which will either use
222              * a new template or fail with an appropriate message
223              * about how the file couldn't be found.
224              */

225         }
226         else if (currentFile.equals(file) && file.canRead())
227         {
228             /*
229              * if only if currentFile is the same as file and
230              * file.lastModified() is the same as
231              * resource.getLastModified(), then we should use the
232              * cached version.
233              */

234             modified = (file.lastModified() != resource.getLastModified());
235         }
236
237         /*
238          * rsvc.debug("isSourceModified for " + fileName + ": " + modified);
239          */

240         return modified;
241     }
242
243     public long getLastModified(Resource resource)
244     {
245         String JavaDoc path = (String JavaDoc) templatePaths.get(resource.getName());
246         File JavaDoc file = new File JavaDoc(path, resource.getName());
247
248         if (file.canRead())
249         {
250             return file.lastModified();
251         }
252         else
253         {
254             return 0;
255         }
256     }
257 }
258
Popular Tags