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 [JarResourceLoader.java]

nameclass, %method, %block, %line, %
JarResourceLoader.java100% (1/1)88%  (7/8)74%  (187/252)76%  (39/51)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JarResourceLoader100% (1/1)88%  (7/8)74%  (187/252)76%  (39/51)
isSourceModified (Resource): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
closeJar (String): void 100% (1/1)43%  (6/14)50%  (2/4)
getResourceStream (String): InputStream 100% (1/1)65%  (63/97)76%  (13/17)
init (ExtendedProperties): void 100% (1/1)77%  (44/57)73%  (8/11)
loadJar (String): void 100% (1/1)87%  (52/60)83%  (10/12)
JarResourceLoader (): void 100% (1/1)100% (15/15)100% (3/3)
addEntries (Hashtable): void 100% (1/1)100% (5/5)100% (2/2)
getLastModified (Resource): long 100% (1/1)100% (2/2)100% (1/1)

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.InputStream;
20 
21import java.util.Hashtable;
22import java.util.Vector;
23 
24import org.apache.velocity.util.StringUtils;
25import org.apache.velocity.runtime.resource.Resource;
26import org.apache.velocity.exception.ResourceNotFoundException;
27import org.apache.commons.collections.ExtendedProperties;
28 
29/**
30 * <p>
31 * ResourceLoader to load templates from multiple Jar files.
32 * </p>
33 * <p>
34 * The configuration of the JarResourceLoader is straightforward -
35 * You simply add the JarResourceLoader to the configuration via
36 * </p>
37 * <p><pre>
38 *    resource.loader = jar
39 *    jar.resource.loader.class = org.apache.velocity.runtime.resource.loader.JarResourceLoader
40 *    jar.resource.loader.path = list of JAR &lt;URL&gt;s
41 * </pre></p>
42 *
43 * <p> So for example, if you had a jar file on your local filesystem, you could simply do
44 *    <pre>
45 *    jar.resource.loader.path = jar:file:/opt/myfiles/jar1.jar
46 *    </pre>
47 * </p>
48 * <p> Note that jar specification for the <code>.path</code> configuration property
49 * conforms to the same rules for the java.net.JarUrlConnection class.
50 * </p>
51 *
52 * <p> For a working example, see the unit test case, 
53 *  org.apache.velocity.test.MultiLoaderTestCase class
54 * </p>
55 * 
56 * @author <a href="mailto:daveb@miceda-data.com">Dave Bryson</a>
57 * @version $Id: JarResourceLoader.java,v 1.16.4.1 2004/03/03 23:23:02 geirm Exp $
58 */
59public class JarResourceLoader extends ResourceLoader
60{
61    /**
62     * Maps entries to the parent JAR File
63     * Key = the entry *excluding* plain directories
64     * Value = the JAR URL
65     */
66    private Hashtable entryDirectory = new Hashtable(559);
67    
68    /**
69     * Maps JAR URLs to the actual JAR
70     * Key = the JAR URL
71     * Value = the JAR
72     */
73    private Hashtable jarfiles = new Hashtable(89);
74   
75    /**
76     * Called by Velocity to initialize the loader
77     */
78    public void init( ExtendedProperties configuration)
79    {
80        rsvc.info("JarResourceLoader : initialization starting.");
81 
82        Vector paths = configuration.getVector("path");
83 
84        /*
85         *  support the old version but deprecate with a log message
86         */
87 
88        if( paths == null || paths.size() == 0)
89        {
90            paths = configuration.getVector("resource.path");
91 
92            if (paths != null && paths.size() > 0)
93            {
94                rsvc.warn("JarResourceLoader : you are using a deprecated configuration"
95                             + " property for the JarResourceLoader -> '<name>.resource.loader.resource.path'."
96                             + " Please change to the conventional '<name>.resource.loader.path'.");
97            }
98        }
99                             
100        rsvc.info("JarResourceLoader # of paths : " + paths.size() );
101        
102        for ( int i=0; i<paths.size(); i++ )
103        {
104            loadJar( (String)paths.get(i) );
105        }
106        
107        rsvc.info("JarResourceLoader : initialization complete.");
108    }
109    
110    private void loadJar( String path )
111    {
112        rsvc.info("JarResourceLoader : trying to load: " + path);
113 
114        // Check path information
115        if ( path == null )
116        {
117            rsvc.error("JarResourceLoader : can not load JAR - JAR path is null");
118        }
119        if ( !path.startsWith("jar:") )
120        {
121            rsvc.error("JarResourceLoader : JAR path must start with jar: -> " +
122                "see java.net.JarURLConnection for information");
123        }
124        if ( !path.endsWith("!/") )
125        {
126            path += "!/";
127        }
128        
129        // Close the jar if it's already open
130        // this is useful for a reload
131        closeJar( path );
132        
133        // Create a new JarHolder
134        JarHolder temp = new JarHolder( rsvc,  path );
135        // Add it's entries to the entryCollection
136        addEntries( temp.getEntries() );
137        // Add it to the Jar table
138        jarfiles.put( temp.getUrlPath(), temp );
139    }
140 
141    /**
142     * Closes a Jar file and set its URLConnection 
143     * to null.
144     */
145    private void closeJar( String path )
146    {
147        if ( jarfiles.containsKey(path) )
148        {
149            JarHolder theJar = (JarHolder)jarfiles.get(path);
150            theJar.close();
151        }
152    }
153    
154    /**
155     * Copy all the entries into the entryDirectory
156     * It will overwrite any duplicate keys.
157     */
158    private synchronized void addEntries( Hashtable entries )
159    {
160        entryDirectory.putAll( entries );
161    }
162    
163    /**
164     * Get an InputStream so that the Runtime can build a
165     * template with it.
166     *
167     * @param name name of template to get
168     * @return InputStream containing the template
169     * @throws ResourceNotFoundException if template not found
170     *         in the file template path.
171     */
172    public synchronized InputStream getResourceStream( String source )
173        throws ResourceNotFoundException
174    {
175        InputStream results = null;
176 
177        if ( source == null || source.length() == 0)
178        {
179            throw new ResourceNotFoundException("Need to have a resource!");
180        }
181        
182        String normalizedPath = StringUtils.normalizePath( source );
183        
184        if ( normalizedPath == null || normalizedPath.length() == 0 )
185        {
186            String msg = "JAR resource error : argument " + normalizedPath + 
187                " contains .. and may be trying to access " + 
188                "content outside of template root.  Rejected.";
189            
190            rsvc.error( "JarResourceLoader : " + msg );
191            
192            throw new ResourceNotFoundException ( msg );
193        }
194        
195        /*
196         *  if a / leads off, then just nip that :)
197         */
198        if ( normalizedPath.startsWith("/") )
199        {
200            normalizedPath = normalizedPath.substring(1);
201        }
202    
203        if ( entryDirectory.containsKey( normalizedPath ) )
204        {
205            String jarurl  = (String)entryDirectory.get( normalizedPath );
206            
207            if ( jarfiles.containsKey( jarurl ) )
208            {
209                JarHolder holder = (JarHolder)jarfiles.get( jarurl );
210                results =  holder.getResource( normalizedPath );
211                return results;
212            }
213        }
214        
215        throw new ResourceNotFoundException( "JarResourceLoader Error: cannot find resource " +
216          source );
217 
218    }
219        
220        
221    // TO DO BELOW 
222    // SHOULD BE DELEGATED TO THE JARHOLDER
223    public boolean isSourceModified(Resource resource)
224    {
225        return true;
226    }
227 
228    public long getLastModified(Resource resource)
229    {
230        return 0;
231    }
232}
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 

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