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     */
017    package org.apache.commons.configuration;
018    
019    import org.apache.commons.logging.Log;
020    import org.apache.commons.logging.LogFactory;
021    import org.apache.commons.logging.impl.NoOpLog;
022    
023    import java.io.InputStream;
024    import java.io.OutputStream;
025    import java.io.File;
026    import java.net.URL;
027    import java.net.MalformedURLException;
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     */
035    public abstract class FileSystem
036    {
037        /** The name of the system property that can be used to set the file system class name */
038        private static final String FILE_SYSTEM = "org.apache.commons.configuration.filesystem";
039    
040        /** The default file system */
041        private static FileSystem fileSystem;
042    
043        /** The Logger */
044        private Log log;
045    
046        /** FileSystem options provider */
047        private FileOptionsProvider optionsProvider;
048    
049        public FileSystem()
050        {
051            setLogger(null);
052        }
053    
054        /**
055         * Returns the logger used by this FileSystem.
056         *
057         * @return the logger
058         */
059        public Log getLogger()
060        {
061            return log;
062        }
063    
064        /**
065         * Allows to set the logger to be used by this FileSystem. This
066         * method makes it possible for clients to exactly control logging behavior.
067         * Per default a logger is set that will ignore all log messages. Derived
068         * classes that want to enable logging should call this method during their
069         * initialization with the logger to be used.
070         *
071         * @param log the new logger
072         */
073        public void setLogger(Log log)
074        {
075            this.log = (log != null) ? log : new NoOpLog();
076        }
077    
078        static
079        {
080            String fsClassName = System.getProperty(FILE_SYSTEM);
081            if (fsClassName != null)
082            {
083                Log log = LogFactory.getLog(FileSystem.class);
084    
085                try
086                {
087                    Class clazz = Class.forName(fsClassName);
088                    if (FileSystem.class.isAssignableFrom(clazz))
089                    {
090                        fileSystem = (FileSystem) clazz.newInstance();
091                        if (log.isDebugEnabled())
092                        {
093                            log.debug("Using " + fsClassName);
094                        }
095                    }
096                }
097                catch (InstantiationException ex)
098                {
099                    log.error("Unable to create " + fsClassName, ex);
100                }
101                catch (IllegalAccessException ex)
102                {
103                    log.error("Unable to create " + fsClassName, ex);
104                }
105                catch (ClassNotFoundException ex)
106                {
107                    log.error("Unable to create " + fsClassName, ex);
108                }
109            }
110    
111            if (fileSystem == null)
112            {
113                fileSystem = new DefaultFileSystem();
114            }
115        }
116    
117        /**
118         * Set the FileSystem to use.
119         * @param fs The FileSystem
120         * @throws NullPointerException if the FileSystem parameter is null.
121         */
122        public static void setDefaultFileSystem(FileSystem fs) throws NullPointerException
123        {
124            if (fs == null)
125            {
126                throw new NullPointerException("A FileSystem implementation is required");
127            }
128            fileSystem = fs;
129        }
130    
131        /**
132         * Reset the FileSystem to the default.
133         */
134        public static void resetDefaultFileSystem()
135        {
136            fileSystem = new DefaultFileSystem();
137        }
138    
139        /**
140         * Retrieve the FileSystem being used.
141         * @return The FileSystem.
142         */
143        public static FileSystem getDefaultFileSystem()
144        {
145            return fileSystem;
146        }
147    
148        /**
149         * Set the FileOptionsProvider
150         * @param provider The FileOptionsProvider
151         */
152        public void setFileOptionsProvider(FileOptionsProvider provider)
153        {
154            this.optionsProvider = provider;
155        }
156    
157        public FileOptionsProvider getFileOptionsProvider()
158        {
159            return this.optionsProvider;
160        }
161    
162        public abstract InputStream getInputStream(String basePath, String fileName)
163                throws ConfigurationException;
164    
165        public abstract InputStream getInputStream(URL url) throws ConfigurationException;
166    
167        public abstract OutputStream getOutputStream(URL url) throws ConfigurationException;
168    
169        public abstract OutputStream getOutputStream(File file) throws ConfigurationException;
170    
171        public abstract String getPath(File file, URL url, String basePath, String fileName);
172    
173        public abstract String getBasePath(String path);
174    
175        public abstract String getFileName(String path);
176    
177        public abstract URL locateFromURL(String basePath, String fileName);
178    
179        public abstract URL getURL(String basePath, String fileName) throws MalformedURLException;
180    }