1 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 ; 25 import org.w3c.dom.NodeList ; 26 27 import javax.xml.parsers.DocumentBuilder ; 28 import javax.xml.parsers.DocumentBuilderFactory ; 29 import javax.xml.parsers.ParserConfigurationException ; 30 import java.io.File ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.net.MalformedURLException ; 34 import java.net.URL ; 35 import java.util.ArrayList ; 36 import java.util.StringTokenizer ; 37 import java.util.jar.JarEntry ; 38 import java.util.jar.JarFile ; 39 40 49 public class StandardFileSystemManager 50 extends DefaultFileSystemManager 51 { 52 private Log log = LogFactory.getLog(StandardFileSystemManager.class); 53 54 private static final String CONFIG_RESOURCE = "providers.xml"; 55 private static final String PLUGIN_CONFIG_RESOURCE = "META-INF/vfs-providers.xml"; 56 57 private URL configUri; 58 private ClassLoader classLoader; 59 60 63 public void setConfiguration(final String configUri) 64 { 65 try 66 { 67 setConfiguration(new URL (configUri)); 68 } 69 catch (MalformedURLException e) 70 { 71 log.warn(e.getLocalizedMessage(), e); 72 } 73 } 74 75 78 public void setConfiguration(final URL configUri) 79 { 80 this.configUri = configUri; 81 } 82 83 87 public void setClassLoader(final ClassLoader classLoader) 88 { 89 this.classLoader = classLoader; 90 } 91 92 95 public void init() throws FileSystemException 96 { 97 final DefaultFileReplicator replicator = createDefaultFileReplicator(); 99 setReplicator(new PrivilegedFileReplicator(replicator)); 100 setTemporaryFileStore(replicator); 101 102 if (classLoader == null) 103 { 104 classLoader = getClass().getClassLoader(); 106 } 107 if (configUri == null) 108 { 109 final URL 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(configUri); 120 121 configurePlugins(); 123 124 super.init(); 126 } 127 128 132 protected void configurePlugins() throws FileSystemException 133 { 134 String classpath = System.getProperty("java.class.path"); 135 if (classpath == null) 136 { 137 return; 139 } 140 141 StringTokenizer st = new StringTokenizer (classpath, File.pathSeparator, false); 142 while (st.hasMoreTokens()) 143 { 144 String path = st.nextToken(); 145 146 if (path.length() > 4 && path.substring(path.length()-4).toLowerCase().equals(".jar")) 147 { 148 try 149 { 150 JarFile jarFile = new JarFile (path); 151 JarEntry jarEntry = jarFile.getJarEntry(PLUGIN_CONFIG_RESOURCE); 152 if (jarEntry != null) 153 { 154 InputStream 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 throw e; 174 } 175 catch (IOException e) 176 { 177 log.warn(e.getLocalizedMessage() + " " + path, e); 179 } 180 } 181 else 182 { 183 File config = new File (path, PLUGIN_CONFIG_RESOURCE); 184 if (config.exists() && config.canRead()) 185 { 186 try 187 { 188 configure(config.toURL()); 189 } 190 catch (MalformedURLException 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 207 private void configure(final URL configUri) throws FileSystemException 208 { 209 InputStream configStream = null; 210 try 211 { 212 final DocumentBuilder builder = createDocumentBuilder(); 215 configStream = configUri.openStream(); 216 final Element config = builder.parse(configStream).getDocumentElement(); 217 218 configure(config); 219 } 220 catch (final Exception 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 e) 233 { 234 log.warn(e.getLocalizedMessage(), e); 235 } 236 } 237 } 238 } 239 240 243 private void configure(final String configUri, final InputStream configStream) throws FileSystemException 244 { 245 try 246 { 247 final DocumentBuilder builder = createDocumentBuilder(); 250 final Element config = builder.parse(configStream).getDocumentElement(); 251 252 configure(config); 253 254 } 255 catch (final Exception e) 256 { 257 throw new FileSystemException("vfs.impl/load-config.error", configUri, e); 258 } 259 } 260 261 264 private DocumentBuilder createDocumentBuilder() throws ParserConfigurationException 265 { 266 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 267 factory.setIgnoringElementContentWhitespace(true); 268 factory.setIgnoringComments(true); 269 factory.setExpandEntityReferences(true); 270 final DocumentBuilder builder = factory.newDocumentBuilder(); 271 return builder; 272 } 273 274 277 private void configure(final Element config) throws FileSystemException 278 { 279 final NodeList providers = config.getElementsByTagName("provider"); 281 final int count = providers.getLength(); 282 for (int i = 0; i < count; i++) 283 { 284 final Element provider = (Element ) providers.item(i); 285 addProvider(provider, false); 286 } 287 288 final NodeList defProviders = config.getElementsByTagName("default-provider"); 290 if (defProviders.getLength() > 0) 291 { 292 final Element provider = (Element ) defProviders.item(0); 293 addProvider(provider, true); 294 } 295 296 final NodeList mimeTypes = config.getElementsByTagName("mime-type-map"); 298 for (int i = 0; i < mimeTypes.getLength(); i++) 299 { 300 final Element map = (Element ) mimeTypes.item(i); 301 addMimeTypeMap(map); 302 } 303 304 final NodeList extensions = config.getElementsByTagName("extension-map"); 306 for (int i = 0; i < extensions.getLength(); i++) 307 { 308 final Element map = (Element ) extensions.item(i); 309 addExtensionMap(map); 310 } 311 } 312 313 316 private void addExtensionMap(final Element map) 317 { 318 final String extension = map.getAttribute("extension"); 319 final String scheme = map.getAttribute("scheme"); 320 if (scheme != null && scheme.length() > 0) 321 { 322 addExtensionMap(extension, scheme); 323 } 324 } 325 326 329 private void addMimeTypeMap(final Element map) 330 { 331 final String mimeType = map.getAttribute("mime-type"); 332 final String scheme = map.getAttribute("scheme"); 333 addMimeTypeMap(mimeType, scheme); 334 } 335 336 339 private void addProvider(final Element providerDef, final boolean isDefault) 340 throws FileSystemException 341 { 342 final String classname = providerDef.getAttribute("class-name"); 343 344 final String [] requiredSchemes = getRequiredSchemes(providerDef); 346 for (int i = 0; i < requiredSchemes.length; i++) 347 { 348 final String requiredScheme = requiredSchemes[i]; 349 if (!hasProvider(requiredScheme)) 350 { 351 final String msg = Messages.getString("vfs.impl/skipping-provider-scheme.debug", 352 new String []{classname, requiredScheme}); 353 VfsLog.debug(getLogger(), log, msg); 354 return; 355 } 356 } 357 358 final String [] requiredClasses = getRequiredClasses(providerDef); 360 for (int i = 0; i < requiredClasses.length; i++) 361 { 362 final String requiredClass = requiredClasses[i]; 363 if (!findClass(requiredClass)) 364 { 365 final String msg = Messages.getString("vfs.impl/skipping-provider.debug", 366 new String []{classname, requiredClass}); 367 VfsLog.debug(getLogger(), log, msg); 368 return; 369 } 370 } 371 372 final FileProvider provider = createProvider(classname); 374 final String [] schemas = getSchemas(providerDef); 375 if (schemas.length > 0) 376 { 377 addProvider(schemas, provider); 378 } 379 380 if (isDefault) 382 { 383 setDefaultProvider(provider); 384 } 385 } 386 387 390 private boolean findClass(final String className) 391 { 392 try 393 { 394 classLoader.loadClass(className); 395 return true; 396 } 397 catch (final ClassNotFoundException e) 398 { 399 return false; 400 } 401 } 402 403 406 private String [] getRequiredClasses(final Element providerDef) 407 { 408 final ArrayList classes = new ArrayList (); 409 final NodeList deps = providerDef.getElementsByTagName("if-available"); 410 final int count = deps.getLength(); 411 for (int i = 0; i < count; i++) 412 { 413 final Element dep = (Element ) deps.item(i); 414 String className = dep.getAttribute("class-name"); 415 if (className != null && className.length() > 0) 416 { 417 classes.add(className); 418 } 419 } 420 return (String []) classes.toArray(new String [classes.size()]); 421 } 422 423 426 private String [] getRequiredSchemes(final Element providerDef) 427 { 428 final ArrayList schemes = new ArrayList (); 429 final NodeList deps = providerDef.getElementsByTagName("if-available"); 430 final int count = deps.getLength(); 431 for (int i = 0; i < count; i++) 432 { 433 final Element dep = (Element ) deps.item(i); 434 String scheme = dep.getAttribute("scheme"); 435 if (scheme != null && scheme.length() > 0) 436 { 437 schemes.add(scheme); 438 } 439 } 440 return (String []) schemes.toArray(new String [schemes.size()]); 441 } 442 443 446 private String [] getSchemas(final Element provider) 447 { 448 final ArrayList schemas = new ArrayList (); 449 final NodeList schemaElements = provider.getElementsByTagName("scheme"); 450 final int count = schemaElements.getLength(); 451 for (int i = 0; i < count; i++) 452 { 453 final Element scheme = (Element ) schemaElements.item(i); 454 schemas.add(scheme.getAttribute("name")); 455 } 456 return (String []) schemas.toArray(new String [schemas.size()]); 457 } 458 459 462 private FileProvider createProvider(final String providerClassName) 463 throws FileSystemException 464 { 465 try 466 { 467 final Class providerClass = classLoader.loadClass(providerClassName); 468 return (FileProvider) providerClass.newInstance(); 469 } 470 catch (final Exception e) 471 { 472 throw new FileSystemException("vfs.impl/create-provider.error", providerClassName, e); 473 } 474 } 475 } | Popular Tags |