KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > vfs > impl > StandardFileSystemManager


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

16 package org.apache.commons.vfs.impl;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.apache.commons.vfs.FileSystemException;
21 import org.apache.commons.vfs.VfsLog;
22 import org.apache.commons.vfs.provider.FileProvider;
23 import org.apache.commons.vfs.util.Messages;
24 import org.w3c.dom.Element JavaDoc;
25 import org.w3c.dom.NodeList JavaDoc;
26
27 import javax.xml.parsers.DocumentBuilder JavaDoc;
28 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
29 import javax.xml.parsers.ParserConfigurationException JavaDoc;
30 import java.io.File JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33 import java.net.MalformedURLException JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37 import java.util.jar.JarEntry JavaDoc;
38 import java.util.jar.JarFile JavaDoc;
39
40 /**
41  * A {@link org.apache.commons.vfs.FileSystemManager} that configures itself
42  * from an XML (Default: providers.xml) configuration file.<br>
43  * Certain providers are only loaded and available if the dependend library is in your
44  * classpath. You have to configure your debugging facility to log "debug" messages to see
45  * if a provider was skipped due to "unresolved externals".
46  *
47  * @author <a HREF="mailto:adammurdoch@apache.org">Adam Murdoch</a>
48  */

49 public class StandardFileSystemManager
50     extends DefaultFileSystemManager
51 {
52     private Log log = LogFactory.getLog(StandardFileSystemManager.class);
53
54     private static final String JavaDoc CONFIG_RESOURCE = "providers.xml";
55     private static final String JavaDoc PLUGIN_CONFIG_RESOURCE = "META-INF/vfs-providers.xml";
56
57     private URL JavaDoc configUri;
58     private ClassLoader JavaDoc classLoader;
59
60     /**
61      * Sets the configuration file for this manager.
62      */

63     public void setConfiguration(final String JavaDoc configUri)
64     {
65         try
66         {
67             setConfiguration(new URL JavaDoc(configUri));
68         }
69         catch (MalformedURLException JavaDoc e)
70         {
71             log.warn(e.getLocalizedMessage(), e);
72         }
73     }
74
75     /**
76      * Sets the configuration file for this manager.
77      */

78     public void setConfiguration(final URL JavaDoc configUri)
79     {
80         this.configUri = configUri;
81     }
82
83     /**
84      * Sets the ClassLoader to use to load the providers. Default is to
85      * use the ClassLoader that loaded this class.
86      */

87     public void setClassLoader(final ClassLoader JavaDoc classLoader)
88     {
89         this.classLoader = classLoader;
90     }
91
92     /**
93      * Initializes this manager. Adds the providers and replicator.
94      */

95     public void init() throws FileSystemException
96     {
97         // Set the replicator and temporary file store (use the same component)
98
final DefaultFileReplicator replicator = createDefaultFileReplicator();
99         setReplicator(new PrivilegedFileReplicator(replicator));
100         setTemporaryFileStore(replicator);
101
102         if (classLoader == null)
103         {
104             // Use default classloader
105
classLoader = getClass().getClassLoader();
106         }
107         if (configUri == null)
108         {
109             // Use default config
110
final URL JavaDoc url = getClass().getResource(CONFIG_RESOURCE);
111             if (url == null)
112             {
113                 throw new FileSystemException("vfs.impl/find-config-file.error", CONFIG_RESOURCE);
114             }
115             configUri = url;
116         }
117
118         // Configure
119
configure(configUri);
120
121         // Configure Plugins
122
configurePlugins();
123
124         // Initialise super-class
125
super.init();
126     }
127
128     /**
129      * Scans the classpath to find any droped plugin.<br />
130      * The plugin-description has to be in /META-INF/vfs-providers.xml
131      */

132     protected void configurePlugins() throws FileSystemException
133     {
134         String JavaDoc classpath = System.getProperty("java.class.path");
135         if (classpath == null)
136         {
137             // huh? why should that be?
138
return;
139         }
140
141         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(classpath, File.pathSeparator, false);
142         while (st.hasMoreTokens())
143         {
144             String JavaDoc path = st.nextToken();
145
146             if (path.length() > 4 && path.substring(path.length()-4).toLowerCase().equals(".jar"))
147             {
148                 try
149                 {
150                     JarFile JavaDoc jarFile = new JarFile JavaDoc(path);
151                     JarEntry JavaDoc jarEntry = jarFile.getJarEntry(PLUGIN_CONFIG_RESOURCE);
152                     if (jarEntry != null)
153                     {
154                         InputStream JavaDoc configStream = null;
155                         try
156                         {
157                             configStream = jarFile.getInputStream(jarEntry);
158                             configure(jarEntry.getName(), configStream);
159                         }
160                         finally
161                         {
162                             if (configStream != null)
163                             {
164                                 configStream.close();
165                             }
166                         }
167                     }
168                 }
169                 catch (FileSystemException e)
170                 {
171                     // VFS exception - rethrow
172
// Need to do this as FileSystemException extends IOException
173
throw e;
174                 }
175                 catch (IOException JavaDoc e)
176                 {
177                     // Maybe a damaged jar? Complain about but continue ...
178
log.warn(e.getLocalizedMessage() + " " + path, e);
179                 }
180             }
181             else
182             {
183                 File JavaDoc config = new File JavaDoc(path, PLUGIN_CONFIG_RESOURCE);
184                 if (config.exists() && config.canRead())
185                 {
186                     try
187                     {
188                       configure(config.toURL());
189                     }
190                     catch (MalformedURLException JavaDoc e)
191                     {
192                       log.warn(e.getLocalizedMessage(), e);
193                     }
194                 }
195             }
196         }
197     }
198
199     protected DefaultFileReplicator createDefaultFileReplicator()
200     {
201         return new DefaultFileReplicator();
202     }
203
204     /**
205      * Configures this manager from an XML configuration file.
206      */

207     private void configure(final URL JavaDoc configUri) throws FileSystemException
208     {
209         InputStream JavaDoc configStream = null;
210         try
211         {
212             // Load up the config
213
// TODO - validate
214
final DocumentBuilder JavaDoc builder = createDocumentBuilder();
215             configStream = configUri.openStream();
216             final Element JavaDoc config = builder.parse(configStream).getDocumentElement();
217
218             configure(config);
219         }
220         catch (final Exception JavaDoc e)
221         {
222             throw new FileSystemException("vfs.impl/load-config.error", configUri.toString(), e);
223         }
224         finally
225         {
226             if (configStream != null)
227             {
228                 try
229                 {
230                     configStream.close();
231                 }
232                 catch (IOException JavaDoc e)
233                 {
234                     log.warn(e.getLocalizedMessage(), e);
235                 }
236             }
237         }
238     }
239
240     /**
241      * Configures this manager from an XML configuration file.
242      */

243     private void configure(final String JavaDoc configUri, final InputStream JavaDoc configStream) throws FileSystemException
244     {
245         try
246         {
247             // Load up the config
248
// TODO - validate
249
final DocumentBuilder JavaDoc builder = createDocumentBuilder();
250             final Element JavaDoc config = builder.parse(configStream).getDocumentElement();
251
252             configure(config);
253
254         }
255         catch (final Exception JavaDoc e)
256         {
257             throw new FileSystemException("vfs.impl/load-config.error", configUri, e);
258         }
259     }
260
261     /**
262      * Configure and create a DocumentBuilder
263      */

264     private DocumentBuilder JavaDoc createDocumentBuilder() throws ParserConfigurationException JavaDoc
265     {
266         final DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
267         factory.setIgnoringElementContentWhitespace(true);
268         factory.setIgnoringComments(true);
269         factory.setExpandEntityReferences(true);
270         final DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
271         return builder;
272     }
273
274     /**
275      * Configures this manager from an parsed XML configuration file
276      */

277     private void configure(final Element JavaDoc config) throws FileSystemException
278     {
279         // Add the providers
280
final NodeList JavaDoc providers = config.getElementsByTagName("provider");
281         final int count = providers.getLength();
282         for (int i = 0; i < count; i++)
283         {
284             final Element JavaDoc provider = (Element JavaDoc) providers.item(i);
285             addProvider(provider, false);
286         }
287
288         // Add the default provider
289
final NodeList JavaDoc defProviders = config.getElementsByTagName("default-provider");
290         if (defProviders.getLength() > 0)
291         {
292             final Element JavaDoc provider = (Element JavaDoc) defProviders.item(0);
293             addProvider(provider, true);
294         }
295
296         // Add the mime-type maps
297
final NodeList JavaDoc mimeTypes = config.getElementsByTagName("mime-type-map");
298         for (int i = 0; i < mimeTypes.getLength(); i++)
299         {
300             final Element JavaDoc map = (Element JavaDoc) mimeTypes.item(i);
301             addMimeTypeMap(map);
302         }
303
304         // Add the extension maps
305
final NodeList JavaDoc extensions = config.getElementsByTagName("extension-map");
306         for (int i = 0; i < extensions.getLength(); i++)
307         {
308             final Element JavaDoc map = (Element JavaDoc) extensions.item(i);
309             addExtensionMap(map);
310         }
311     }
312
313     /**
314      * Adds an extension map.
315      */

316     private void addExtensionMap(final Element JavaDoc map)
317     {
318         final String JavaDoc extension = map.getAttribute("extension");
319         final String JavaDoc scheme = map.getAttribute("scheme");
320         if (scheme != null && scheme.length() > 0)
321         {
322             addExtensionMap(extension, scheme);
323         }
324     }
325
326     /**
327      * Adds a mime-type map.
328      */

329     private void addMimeTypeMap(final Element JavaDoc map)
330     {
331         final String JavaDoc mimeType = map.getAttribute("mime-type");
332         final String JavaDoc scheme = map.getAttribute("scheme");
333         addMimeTypeMap(mimeType, scheme);
334     }
335
336     /**
337      * Adds a provider from a provider definition.
338      */

339     private void addProvider(final Element JavaDoc providerDef, final boolean isDefault)
340         throws FileSystemException
341     {
342         final String JavaDoc classname = providerDef.getAttribute("class-name");
343
344         // Make sure all required schemes are available
345
final String JavaDoc[] requiredSchemes = getRequiredSchemes(providerDef);
346         for (int i = 0; i < requiredSchemes.length; i++)
347         {
348             final String JavaDoc requiredScheme = requiredSchemes[i];
349             if (!hasProvider(requiredScheme))
350             {
351                 final String JavaDoc msg = Messages.getString("vfs.impl/skipping-provider-scheme.debug",
352                     new String JavaDoc[]{classname, requiredScheme});
353                 VfsLog.debug(getLogger(), log, msg);
354                 return;
355             }
356         }
357
358         // Make sure all required classes are in classpath
359
final String JavaDoc[] requiredClasses = getRequiredClasses(providerDef);
360         for (int i = 0; i < requiredClasses.length; i++)
361         {
362             final String JavaDoc requiredClass = requiredClasses[i];
363             if (!findClass(requiredClass))
364             {
365                 final String JavaDoc msg = Messages.getString("vfs.impl/skipping-provider.debug",
366                     new String JavaDoc[]{classname, requiredClass});
367                 VfsLog.debug(getLogger(), log, msg);
368                 return;
369             }
370         }
371
372         // Create and register the provider
373
final FileProvider provider = createProvider(classname);
374         final String JavaDoc[] schemas = getSchemas(providerDef);
375         if (schemas.length > 0)
376         {
377             addProvider(schemas, provider);
378         }
379
380         // Set as default, if required
381
if (isDefault)
382         {
383             setDefaultProvider(provider);
384         }
385     }
386
387     /**
388      * Tests if a class is available.
389      */

390     private boolean findClass(final String JavaDoc className)
391     {
392         try
393         {
394             classLoader.loadClass(className);
395             return true;
396         }
397         catch (final ClassNotFoundException JavaDoc e)
398         {
399             return false;
400         }
401     }
402
403     /**
404      * Extracts the required classes from a provider definition.
405      */

406     private String JavaDoc[] getRequiredClasses(final Element JavaDoc providerDef)
407     {
408         final ArrayList JavaDoc classes = new ArrayList JavaDoc();
409         final NodeList JavaDoc deps = providerDef.getElementsByTagName("if-available");
410         final int count = deps.getLength();
411         for (int i = 0; i < count; i++)
412         {
413             final Element JavaDoc dep = (Element JavaDoc) deps.item(i);
414             String JavaDoc className = dep.getAttribute("class-name");
415             if (className != null && className.length() > 0)
416             {
417                 classes.add(className);
418             }
419         }
420         return (String JavaDoc[]) classes.toArray(new String JavaDoc[classes.size()]);
421     }
422
423     /**
424      * Extracts the required schemes from a provider definition.
425      */

426     private String JavaDoc[] getRequiredSchemes(final Element JavaDoc providerDef)
427     {
428         final ArrayList JavaDoc schemes = new ArrayList JavaDoc();
429         final NodeList JavaDoc deps = providerDef.getElementsByTagName("if-available");
430         final int count = deps.getLength();
431         for (int i = 0; i < count; i++)
432         {
433             final Element JavaDoc dep = (Element JavaDoc) deps.item(i);
434             String JavaDoc scheme = dep.getAttribute("scheme");
435             if (scheme != null && scheme.length() > 0)
436             {
437                 schemes.add(scheme);
438             }
439         }
440         return (String JavaDoc[]) schemes.toArray(new String JavaDoc[schemes.size()]);
441     }
442
443     /**
444      * Extracts the schema names from a provider definition.
445      */

446     private String JavaDoc[] getSchemas(final Element JavaDoc provider)
447     {
448         final ArrayList JavaDoc schemas = new ArrayList JavaDoc();
449         final NodeList JavaDoc schemaElements = provider.getElementsByTagName("scheme");
450         final int count = schemaElements.getLength();
451         for (int i = 0; i < count; i++)
452         {
453             final Element JavaDoc scheme = (Element JavaDoc) schemaElements.item(i);
454             schemas.add(scheme.getAttribute("name"));
455         }
456         return (String JavaDoc[]) schemas.toArray(new String JavaDoc[schemas.size()]);
457     }
458
459     /**
460      * Creates a provider.
461      */

462     private FileProvider createProvider(final String JavaDoc providerClassName)
463         throws FileSystemException
464     {
465         try
466         {
467             final Class JavaDoc providerClass = classLoader.loadClass(providerClassName);
468             return (FileProvider) providerClass.newInstance();
469         }
470         catch (final Exception JavaDoc e)
471         {
472             throw new FileSystemException("vfs.impl/create-provider.error", providerClassName, e);
473         }
474     }
475 }
Popular Tags