KickJava   Java API By Example, From Geeks To Geeks.

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


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.InputStream JavaDoc;
20
21 import java.util.Hashtable JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 import org.apache.velocity.util.StringUtils;
25 import org.apache.velocity.runtime.resource.Resource;
26 import org.apache.velocity.exception.ResourceNotFoundException;
27 import 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  */

59 public 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 JavaDoc entryDirectory = new Hashtable JavaDoc(559);
67     
68     /**
69      * Maps JAR URLs to the actual JAR
70      * Key = the JAR URL
71      * Value = the JAR
72      */

73     private Hashtable JavaDoc jarfiles = new Hashtable JavaDoc(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 JavaDoc 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 JavaDoc)paths.get(i) );
105         }
106         
107         rsvc.info("JarResourceLoader : initialization complete.");
108     }
109     
110     private void loadJar( String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc getResourceStream( String JavaDoc source )
173         throws ResourceNotFoundException
174     {
175         InputStream JavaDoc results = null;
176
177         if ( source == null || source.length() == 0)
178         {
179             throw new ResourceNotFoundException("Need to have a resource!");
180         }
181         
182         String JavaDoc normalizedPath = StringUtils.normalizePath( source );
183         
184         if ( normalizedPath == null || normalizedPath.length() == 0 )
185         {
186             String JavaDoc 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 JavaDoc jarurl = (String JavaDoc)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
243
Popular Tags