001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.configuration;
018
019import java.io.File;
020import java.io.InputStream;
021import java.io.OutputStream;
022import java.net.MalformedURLException;
023import java.net.URL;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.apache.commons.logging.impl.NoOpLog;
028
029/**
030 * Abstract layer to allow various types of file systems.
031 * @since 1.7
032 * @author <a
033 * href="http://commons.apache.org/configuration/team-list.html">Commons Configuration team</a>
034 * @version $Id: FileSystem.html 901729 2014-03-15 20:24:09Z oheger $
035 */
036public abstract class FileSystem
037{
038    /** The name of the system property that can be used to set the file system class name */
039    private static final String FILE_SYSTEM = "org.apache.commons.configuration.filesystem";
040
041    /** The default file system */
042    private static FileSystem fileSystem;
043
044    /** The Logger */
045    private Log log;
046
047    /** FileSystem options provider */
048    private FileOptionsProvider optionsProvider;
049
050    public FileSystem()
051    {
052        setLogger(null);
053    }
054
055    /**
056     * Returns the logger used by this FileSystem.
057     *
058     * @return the logger
059     */
060    public Log getLogger()
061    {
062        return log;
063    }
064
065    /**
066     * Allows to set the logger to be used by this FileSystem. This
067     * method makes it possible for clients to exactly control logging behavior.
068     * Per default a logger is set that will ignore all log messages. Derived
069     * classes that want to enable logging should call this method during their
070     * initialization with the logger to be used.
071     *
072     * @param log the new logger
073     */
074    public void setLogger(Log log)
075    {
076        this.log = (log != null) ? log : new NoOpLog();
077    }
078
079    static
080    {
081        String fsClassName = System.getProperty(FILE_SYSTEM);
082        if (fsClassName != null)
083        {
084            Log log = LogFactory.getLog(FileSystem.class);
085
086            try
087            {
088                Class<?> clazz = Class.forName(fsClassName);
089                if (FileSystem.class.isAssignableFrom(clazz))
090                {
091                    fileSystem = (FileSystem) clazz.newInstance();
092                    if (log.isDebugEnabled())
093                    {
094                        log.debug("Using " + fsClassName);
095                    }
096                }
097            }
098            catch (InstantiationException ex)
099            {
100                log.error("Unable to create " + fsClassName, ex);
101            }
102            catch (IllegalAccessException ex)
103            {
104                log.error("Unable to create " + fsClassName, ex);
105            }
106            catch (ClassNotFoundException ex)
107            {
108                log.error("Unable to create " + fsClassName, ex);
109            }
110        }
111
112        if (fileSystem == null)
113        {
114            fileSystem = new DefaultFileSystem();
115        }
116    }
117
118    /**
119     * Set the FileSystem to use.
120     * @param fs The FileSystem
121     * @throws NullPointerException if the FileSystem parameter is null.
122     */
123    public static void setDefaultFileSystem(FileSystem fs) throws NullPointerException
124    {
125        if (fs == null)
126        {
127            throw new NullPointerException("A FileSystem implementation is required");
128        }
129        fileSystem = fs;
130    }
131
132    /**
133     * Reset the FileSystem to the default.
134     */
135    public static void resetDefaultFileSystem()
136    {
137        fileSystem = new DefaultFileSystem();
138    }
139
140    /**
141     * Retrieve the FileSystem being used.
142     * @return The FileSystem.
143     */
144    public static FileSystem getDefaultFileSystem()
145    {
146        return fileSystem;
147    }
148
149    /**
150     * Set the FileOptionsProvider
151     * @param provider The FileOptionsProvider
152     */
153    public void setFileOptionsProvider(FileOptionsProvider provider)
154    {
155        this.optionsProvider = provider;
156    }
157
158    public FileOptionsProvider getFileOptionsProvider()
159    {
160        return this.optionsProvider;
161    }
162
163    public abstract InputStream getInputStream(String basePath, String fileName)
164            throws ConfigurationException;
165
166    public abstract InputStream getInputStream(URL url) throws ConfigurationException;
167
168    public abstract OutputStream getOutputStream(URL url) throws ConfigurationException;
169
170    public abstract OutputStream getOutputStream(File file) throws ConfigurationException;
171
172    public abstract String getPath(File file, URL url, String basePath, String fileName);
173
174    public abstract String getBasePath(String path);
175
176    public abstract String getFileName(String path);
177
178    public abstract URL locateFromURL(String basePath, String fileName);
179
180    public abstract URL getURL(String basePath, String fileName) throws MalformedURLException;
181}