All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.vfsjfilechooser2.filechooser.AbstractVFSFileSystemView Maven / Gradle / Ivy

/*
 * The implementation using commons-vfs based on Swing FileSystemView
 *
 * Copyright (C) 2005-2008 Yves Zoundi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * under the License.
 */
package com.googlecode.vfsjfilechooser2.filechooser;

import com.googlecode.vfsjfilechooser2.utils.SwingCommonsUtilities;
import com.googlecode.vfsjfilechooser2.utils.VFSResources;
import com.googlecode.vfsjfilechooser2.utils.VFSUtils;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.text.MessageFormat;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.UIManager;
import javax.swing.filechooser.FileView;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.impl.DecoratedFileObject;
import org.apache.commons.vfs2.provider.local.LocalFile;

/**
 * The implementation using commons-vfs based on Swing FileSystemView
 * @author Yves Zoundi 
 * @version 0.0.1
 */
public abstract class AbstractVFSFileSystemView {

    //static FileSystemView macFileSystemView = null;
    static AbstractVFSFileSystemView genericFileSystemView = null;
    static boolean useSystemExtensionsHiding = false;
    FileObject[] localRoots = new FileObject[0];

    public static AbstractVFSFileSystemView getFileSystemView() {
        useSystemExtensionsHiding = UIManager.getDefaults()
                .getBoolean("FileChooser.useSystemExtensionHiding");
        UIManager.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent e) {
                if (e.getPropertyName().equals("lookAndFeel")) {
                    useSystemExtensionsHiding = UIManager.getDefaults()
                            .getBoolean("FileChooser.useSystemExtensionHiding");
                }
            }
        });

        if (genericFileSystemView == null) {
            genericFileSystemView = new GenericFileSystemView();
        }

        return genericFileSystemView;
    }

    /**
     * Determines if the given file is a root in the navigatable tree(s).
     * Examples: Windows 98 has one root, the Desktop folder. DOS has one root
     * per drive letter, C:\, D:\, etc. Unix has one root,
     * the "/" directory.
     *
     * The default implementation gets information from the ShellFolder class.
     *
     * @param f a File object representing a directory
     * @return true if f is a root in the navigatable tree.
     * @see #isFileSystemRoot
     */
    public boolean isRoot(FileObject f) {
        return VFSUtils.isRoot(f);
    }

    /**
     * Returns true if the file (directory) can be visited.
     * Returns false if the directory cannot be traversed.
     *
     * @param f the File
     * @return true if the file/directory can be traversed, otherwise false
     * @see JFileChooser#isTraversable
     * @see FileView#isTraversable
     * @since 1.4
     */
    public Boolean isTraversable(FileObject f) {
        return Boolean.valueOf(VFSUtils.isDirectory(f));
    }

    /**
     * Name of a file, directory, or folder as it would be displayed in
     * a system file browser. Example from Windows: the "M:\" directory
     * displays as "CD-ROM (M:)"
     *
     * The default implementation gets information from the ShellFolder class.
     *
     * @param f a File object
     * @return the file name as it would be displayed by a native file chooser
     * @see JFileChooser#getName
     * @since 1.4
     */
    public String getSystemDisplayName(FileObject f) {
        String name = null;

        if (f != null) {
            name = f.getName().getBaseName();

            if (!name.trim().equals("")) {
                name = VFSUtils.getFriendlyName(f.getName() + "");
            }
        }

        return name;
    }

    /**
     * Type description for a file, directory, or folder as it would be displayed in
     * a system file browser. Example from Windows: the "Desktop" folder
     * is desribed as "Desktop".
     *
     * Override for platforms with native ShellFolder implementations.
     *
     * @param f a File object
     * @return the file type description as it would be displayed by a native file chooser
     * or null if no native information is available.
     * @see JFileChooser#getTypeDescription
     * @since 1.4
     */
    public String getSystemTypeDescription(FileObject f) {
        return VFSUtils.getFriendlyName(f.getName().toString());
    }

    /**
     * Icon for a file, directory, or folder as it would be displayed in
     * a system file browser. Example from Windows: the "M:\" directory
     * displays a CD-ROM icon.
     *
     * The default implementation gets information from the ShellFolder class.
     *
     * @param f a File object
     * @return an icon as it would be displayed by a native file chooser
     * @see JFileChooser#getIcon
     * @since 1.4
     */
    public Icon getSystemIcon(FileObject f) {
        if (f != null) {
            return UIManager.getIcon(VFSUtils.isDirectory(f)
                    ? "FileView.directoryIcon" : "FileView.fileIcon");
        } else {
            return null;
        }
    }

    /**
     * On Windows, a file can appear in multiple folders, other than its
     * parent directory in the filesystem. Folder could for example be the
     * "Desktop" folder which is not the same as file.getParentFile().
     *
     * @param folder a File object repesenting a directory or special folder
     * @param file a File object
     * @return true if folder is a directory or special folder and contains file.
     * @since 1.4
     */
    public boolean isParent(FileObject folder, FileObject file) {
        return VFSUtils.isParent(folder, file);
    }

    /**
     *
     * @param parent a File object repesenting a directory or special folder
     * @param fileName a name of a file or folder which exists in parent
     * @return a File object. This is normally constructed with new
     * File(parent, fileName) except when parent and child are both
     * special folders, in which case the File is a wrapper containing
     * a ShellFolder object.
     * @since 1.4
     */
    public FileObject getChild(FileObject parent, String fileName) {
        return createFileObject(parent, fileName);
    }

    /**
     * Checks if f represents a real directory or file as opposed to a
     * special folder such as "Desktop". Used by UI classes to decide if
     * a folder is selectable when doing directory choosing.
     *
     * @param f a File object
     * @return true if f is a real file or directory.
     * @since 1.4
     */
    public boolean isFileSystem(FileObject f) {
        return true;
    }

    /**
     * Creates a new folder with a default folder name.
     * @param containingDir
     * @return
     * @throws org.apache.commons.vfs.FileSystemException
     */
    public abstract FileObject createNewFolder(FileObject containingDir)
            throws FileSystemException;

    /**
     * Returns whether a file is hidden or not.
     * @param f
     * @return
     */
    public boolean isHiddenFile(FileObject f) {
        return VFSUtils.isHiddenFile(f);
    }

    /**
     * Is dir the root of a tree in the file system, such as a drive
     * or partition. Example: Returns true for "C:\" on Windows 98.
     *
     * @param dir a File object representing a directory
     * @return true if f is a root of a filesystem
     * @see #isRoot
     * @since 1.4
     */
    public boolean isFileSystemRoot(FileObject dir) {
        return VFSUtils.isRoot(dir);
    }

    /**
     * Used by UI classes to decide whether to display a special icon
     * for drives or partitions, e.g. a "hard disk" icon.
     *
     * The default implementation has no way of knowing, so always returns false.
     *
     * @param dir a directory
     * @return false always
     * @since 1.4
     */
    public boolean isDrive(FileObject dir) {
        return VFSUtils.getParentDirectory(dir) == null;
    }

    /**
     * Used by UI classes to decide whether to display a special icon
     * for a floppy disk. Implies isDrive(dir).
     *
     * The default implementation has no way of knowing, so always returns false.
     *
     * @param dir a directory
     * @return false always
     * @since 1.4
     */
    public boolean isFloppyDrive(FileObject dir) {
        return false;
    }

    /**
     * Used by UI classes to decide whether to display a special icon
     * for a computer node, e.g. "My Computer" or a network server.
     *
     * The default implementation has no way of knowing, so always returns false.
     *
     * @param dir a directory
     * @return false always
     * @since 1.4
     */
    public boolean isComputerNode(FileObject dir) {
        return false;
    }

    /**
     * Returns all root partitions on this system. For example, on
     * Windows, this would be the "Desktop" folder, while on DOS this
     * would be the A: through Z: drives.
     * @param fo
     * @return
     */
    public FileObject[] getRoots(FileObject fo) {
        if (fo instanceof DecoratedFileObject) {
            fo = ((DecoratedFileObject) fo).getDecoratedFileObject();
        }

        if (fo instanceof LocalFile) {
            File[] roots = File.listRoots();
            final int count = roots.length;
            localRoots = new FileObject[roots.length];

            for (int i = 0; i < count; i++) {
                localRoots[i] = VFSUtils.toFileObject(roots[i]);
            }

            return localRoots.clone();
        } // Don't cache this array, because filesystem might change
        else {
            FileObject p = VFSUtils.getRootFileSystem(fo);

            return new FileObject[]{p};
        }
    }

    // Providing default implementations for the remaining methods
    // because most OS file systems will likely be able to use this
    // code. If a given OS can't, override these methods in its
    // implementation.
    /**
     *
     * @return
     */
    public FileObject getHomeDirectory() {
        return SwingCommonsUtilities.getVFSFileChooserDefaultDirectory();
    }

    /**
     * Return the user's default starting directory for the file chooser.
     *
     * @return a File object representing the default
     *         starting folder
     * @since 1.4
     */
    public FileObject getDefaultDirectory() {
        return createFileObject(System.getProperty("user.dir"));
    }

    /**
     * Returns a File object constructed in dir from the given filename.
     * @param dir
     * @param filename
     * @return
     */
    public FileObject createFileObject(FileObject dir, String filename) {
        if (dir == null) {
            return VFSUtils.createFileObject(filename);
        } else {
            return VFSUtils.resolveFileObject(dir, filename);
        }
    }

    /**
     * Returns a File object constructed from the given path string.
     * @param path
     * @return
     */
    public FileObject createFileObject(String path) {
        return VFSUtils.resolveFileObject(path);
    }

    /**
     * Gets the list of shown (i.e. not hidden) files.
     * @param dir
     * @param useFileHiding
     * @return
     */
    public FileObject[] getFiles(FileObject dir, boolean useFileHiding) {
        return VFSUtils.getFiles(dir, useFileHiding);
    }

    /**
     * Returns the parent directory of dir.
     * @param dir the File being queried
     * @return the parent directory of dir, or
     *   null if dir is null
     */
    public FileObject getParentDirectory(FileObject dir) {
        if ((dir != null) && VFSUtils.exists(dir)) {
            FileObject parentDir = VFSUtils.getParentDirectory(dir);

            if (parentDir == null) {
                return dir;
            } else {
                return parentDir;
            }
        }

        return null;
    }

    /**
     * Creates a new File object for f with correct
     * behavior for a file system root directory.
     *
     * @param f a File object representing a file system root
     *          directory, for example "/" on Unix or "C:\" on Windows.
     * @return a new File object
     * @since 1.4
     */
    protected FileObject createFileSystemRoot(FileObject f) {
        return VFSUtils.createFileSystemRoot(f);
    }

    /**
     * Fallthrough FileSystemView in case we can't determine the OS.
     */
    static class GenericFileSystemView extends AbstractVFSFileSystemView {

        private static final String newFolderString = VFSResources.getMessage(
                "VFSJFileChooser.other.newFolder");
        private static final String newFolderNextString = VFSResources.getMessage(
                "VFSJFileChooser.other.newFolder.subsequent");

        /**
         * Creates a new folder with a default folder name.
         */
        @Override
        public FileObject createNewFolder(FileObject containingDir)
                throws FileSystemException {
            if (containingDir == null) {
                throw new FileSystemException(
                        "Trying to create a new folder into a non existing folder");
            }

            FileObject newFolder = null;

            // Using NT's default folder name
            newFolder = createFileObject(containingDir, newFolderString);

            // avoid creating a folder called New Folder so we loop as in the 
            // Windows FileSystemView
            for (int i = 1; newFolder.exists(); i++) {
                newFolder = createFileObject(containingDir,
                        MessageFormat.format(newFolderNextString,
                                new Object[]{i}));
            }

            // if the folder already exists throw an exception
            if (newFolder.exists()) {
                throw new FileSystemException("Directory already exists:"
                        + newFolder.getName().getURI());
            } else {
                // create the folder 
                newFolder.createFolder();
            }

            // return the created folder if no exception is thrown
            return newFolder;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy