EMMA Coverage Report (generated Tue May 18 22:13:27 CDT 2004)
[all classes][org.apache.velocity.runtime.resource.loader]

COVERAGE SUMMARY FOR SOURCE FILE [FileResourceLoader.java]

nameclass, %method, %block, %line, %
FileResourceLoader.java100% (1/1)83%  (5/6)59%  (160/271)59%  (32/54)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FileResourceLoader100% (1/1)83%  (5/6)59%  (160/271)59%  (32/54)
isSourceModified (Resource): boolean 0%   (0/1)0%   (0/72)0%   (0/15)
getResourceStream (String): InputStream 100% (1/1)66%  (67/101)78%  (14/18)
findTemplate (String, String): InputStream 100% (1/1)87%  (20/23)67%  (4/6)
getLastModified (Resource): long 100% (1/1)91%  (20/22)80%  (4/5)
FileResourceLoader (): void 100% (1/1)100% (11/11)100% (3/3)
init (ExtendedProperties): void 100% (1/1)100% (42/42)100% (7/7)

1package 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 
19import java.io.File;
20import java.io.InputStream;
21import java.io.FileInputStream;
22import java.io.BufferedInputStream;
23import java.io.FileNotFoundException;
24 
25import java.util.Hashtable;
26import java.util.Vector;
27 
28import org.apache.velocity.util.StringUtils;
29 
30import org.apache.velocity.runtime.resource.Resource;
31 
32import org.apache.velocity.exception.ResourceNotFoundException;
33 
34import 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 */
42public class FileResourceLoader extends ResourceLoader
43{
44    /**
45     * The paths to search for templates.
46     */
47    private Vector 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 templatePaths = new Hashtable();
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) 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 getResourceStream(String 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 template = StringUtils.normalizePath(templateName);
103        if ( template == null || template.length() == 0 )
104        {
105            String 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 path = (String) paths.get(i);
126            InputStream 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 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 findTemplate(String path, String template)
160    {
161        try 
162        {
163            File file = new File( path, template );   
164        
165            if ( file.canRead() )
166            {
167                return new BufferedInputStream(
168                    new FileInputStream(file.getAbsolutePath()));
169            }
170            else
171            {                
172                return null;
173            }                
174        }
175        catch( FileNotFoundException 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 fileName = resource.getName();
202        String path = (String) templatePaths.get(fileName);
203        File currentFile = null;
204 
205        for (int i = 0; currentFile == null && i < paths.size(); i++)
206        {
207            String testPath = (String) paths.get(i);
208            File testFile = new File(testPath, fileName);
209            if (testFile.canRead())
210            {
211                currentFile = testFile;
212            }
213        }
214        File file = new File(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 path = (String) templatePaths.get(resource.getName());
246        File file = new File(path, resource.getName());
247 
248        if (file.canRead())
249        {
250            return file.lastModified();
251        }            
252        else
253        {
254            return 0;
255        }            
256    }
257}

[all classes][org.apache.velocity.runtime.resource.loader]
EMMA 2.0.4015 (stable) (C) Vladimir Roubtsov