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.vfs2;
018
019import java.lang.reflect.InvocationTargetException;
020import java.lang.reflect.Method;
021
022import org.apache.commons.lang3.reflect.MethodUtils;
023import org.apache.commons.vfs2.provider.AbstractFileSystem;
024
025/**
026 * The main entry point for the VFS. Used to create {@link FileSystemManager} instances.
027 */
028public final class VFS {
029
030    /** The FileSystemManager */
031    private static FileSystemManager instance;
032
033    /** The URI style */
034    private static Boolean uriStyle;
035
036    /**
037     * Closes the default {@link FileSystemManager} instance.
038     * <p>
039     * Warning, if you close the default instance, a new one will be created by {@link #getManager()}.
040     * </p>
041     *
042     * @since 2.8.0
043     */
044    public static synchronized void close() {
045        if (instance != null) {
046            instance.close();
047            instance = null;
048        }
049    }
050
051    /**
052     * Creates a file system manager instance.
053     *
054     * @param managerClassName The specific manager implementation class name.
055     * @return The FileSystemManager.
056     * @throws FileSystemException if an error occurs creating the manager.
057     */
058    private static FileSystemManager createFileSystemManager(final String managerClassName) throws FileSystemException {
059        try {
060            // Create instance
061            final Class<FileSystemManager> clazz = (Class<FileSystemManager>) Class.forName(managerClassName);
062            final FileSystemManager manager = clazz.getConstructor().newInstance();
063            // Initialize
064            if (manager instanceof AbstractFileSystem) {
065                ((AbstractFileSystem) manager).init();
066            } else {
067                final Method method = MethodUtils.getMatchingMethod(clazz, "init");
068                if (method != null) {
069                    method.invoke(manager, (Object[]) null);
070                }
071            }
072            return manager;
073        } catch (final InvocationTargetException e) {
074            throw new FileSystemException("vfs/create-manager.error", managerClassName, e.getTargetException());
075        } catch (final Exception e) {
076            throw new FileSystemException("vfs/create-manager.error", managerClassName, e);
077        }
078    }
079
080    /**
081     * Gets the default {@link FileSystemManager} instance.
082     * <p>
083     * Warning, if you close this instance you may affect all current and future users of this manager singleton.
084     * </p>
085     *
086     * @return The FileSystemManager.
087     * @throws FileSystemException if an error occurs creating the manager.
088     */
089    public static synchronized FileSystemManager getManager() throws FileSystemException {
090        if (instance == null) {
091            instance = reset();
092        }
093        return instance;
094    }
095
096    /**
097     * TODO.
098     *
099     * @return TODO.
100     */
101    public static boolean isUriStyle() {
102        if (uriStyle == null) {
103            uriStyle = Boolean.FALSE;
104        }
105        return uriStyle.booleanValue();
106    }
107
108    /**
109     * Resets the FileSystemManager to the default.
110     *
111     * @return the new FileSystemManager.
112     * @throws FileSystemException if an error occurs creating the manager.
113     * @since 2.5.0
114     */
115    public static synchronized FileSystemManager reset() throws FileSystemException {
116        close();
117        return instance = createFileSystemManager("org.apache.commons.vfs2.impl.StandardFileSystemManager");
118    }
119
120    /**
121     * Sets the file system manager.
122     *
123     * @param manager the file system manager
124     * @since 2.2
125     */
126    public static synchronized void setManager(final FileSystemManager manager) {
127        instance = manager;
128    }
129
130    /**
131     * TODO.
132     *
133     * @param uriStyle TODO.
134     */
135    public static void setUriStyle(final boolean uriStyle) {
136        if (VFS.uriStyle != null && VFS.uriStyle.booleanValue() != uriStyle) {
137            throw new IllegalStateException("VFS.uriStyle was already set differently.");
138        }
139        VFS.uriStyle = Boolean.valueOf(uriStyle);
140    }
141
142    private VFS() {
143        // no public instantiation.
144    }
145}