日期:2014-05-16  浏览次数:21099 次

apache commons-vfs源码赏析(二)
在上篇中说到了第一个比较重要的类是VFS类.在那个类中说到StandardFileSystemManager这个类.因此在这里我们引申出vfs中第二个比较重要的类:StandardFileSystemManager.这个类集成一个父类DefaultFileSystemManager

在上篇中说道VFS会初始化一个StandardFileSystemManager对象,并调用其init方法.因此我们便去看看这个类的init方法.

因为这个类的比较大,所以在说的时候我只列出我认为比较重要的代码.
    public void init() throws FileSystemException
    {
        // Set the replicator and temporary file store (use the same component)
        final DefaultFileReplicator replicator = createDefaultFileReplicator();
        setReplicator(new PrivilegedFileReplicator(replicator));
        setTemporaryFileStore(replicator);

        /* replaced by findClassLoader
        if (classLoader == null)
        {
            // Use default classloader
            classLoader = getClass().getClassLoader();
        }
        */

        if (configUri == null)
        {
            // Use default config
            final URL url = getClass().getResource(CONFIG_RESOURCE);
            if (url == null)
            {
                throw new FileSystemException("vfs.impl/find-config-file.error", CONFIG_RESOURCE);
            }
            configUri = url;
        }

        // Configure
        configure(configUri);

        // Configure Plugins
        configurePlugins();

        // Initialise super-class
        super.init();
    }

我们可以看到这个init方法做了很多事,首先是设置临时文件并复制和存储,然后做了一些配置,配置插件并调用其父类的init方法.
在这个方法中用到一个常量CONFIG_RESOURCE和一个变量configUri,
在类的开头已经定义.
  private static final String CONFIG_RESOURCE = "providers.xml";
  private URL configUri;

说的意思就是我们可以通过configUri去自定义配置文件.如果没有的话就使用默认的providers.xml.

我们重点要看的就是init方法要调用configure(Url url)和configurePlugins()方法

首先看看configure(Url url)方法,这个方法主要做的是根据url去Load一个配置文件.然后里面在去调用configure(Element config)方法.

这个方法的部分代码
InputStream configStream = null;
        try
        {
            // Load up the config
            // TODO - validate
            final DocumentBuilder builder = createDocumentBuilder();
            configStream = configUri.openStream();
            final Element config = builder.parse(configStream).getDocumentElement();

            configure(config);
        }
        catch (final Exception e)
        {
            throw new FileSystemException("vfs.impl/load-config.error", configUri.toString(), e);
        }


因此重点要看的就是看看configure(Element config)方法里面做了什么事情.这个比较关键.
private void configure(final Element config) throws FileSystemException
    {
        // Add the providers
        final NodeList providers = config.getElementsByTagName("provider");
        final int count = providers.getLength();
        for (int i = 0; i < count; i++)
        {
            final Element provider = (Element) providers.item(i);
            addProvider(provider, false);
        }

        // Add the operation providers
        final NodeList operationProviders = config.getElementsByTagName("operationProvider");
        for (int i = 0; i < operationProviders.getLength(); i++)
        {
            final Element operationProvider = (Element) operationProviders.item(i);
            addOperationProvider(operationProvider);
        }

        // Add the default provider
        final NodeList defProviders = config.getElementsByTagName("default-provider");
        if (defProviders.getLength() > 0)
        {
            final Element provider = (Element) defProviders.item(0);
            addProvider(provider, true);
        }

        // Add the mime-type maps
        final NodeList mimeTypes = config.getElementsByTagName("mime-type-map");
        for (int i = 0; i < mimeTypes.getLength(); i++)
        {
            final Element map = (Element) mimeTypes.item(i);
            addMimeTypeMap(map);
        }

        // Add the extension maps
        final NodeList extensions = config.getElem