Search in sources :

Example 26 with AbstractFile

use of com.mucommander.commons.file.AbstractFile in project mucommander by mucommander.

the class PathUtils method resolveDestination.

/**
 * Resolves a destination path entered by the user and returns a {@link ResolvedDestination} object that
 * that contains a {@link AbstractFile} instance corresponding to the path and a type that describes the kind of
 * destination that was resolved. <code>null</code> is returned if the path is not a valid destination (see below)
 * or could not be resolved, for example becuase of I/O or authentication error.
 * <p>
 * The given path may be either absolute or relative to the specified base folder. If the base folder argument is
 * <code>null</code> and the path is relative, <code>null</code> will always be returned.
 * The path may contain '.', '..' and '~' tokens which will be left for the corresponding
 * {@link com.mucommander.commons.file.SchemeParser} to canonize.
 * </p>
 * <p>
 * The path may refer to the following listed destination types. In all cases, the destination's parent folder must
 * exist, if it doesn't <code>null</code> will always be returned. For example, <code>/non_existing_folder/file</code>
 * is not a valid destination (provided that '/non_existing_folder' does not exist).
 * <dl>
 *  <dt>{@link ResolvedDestination#EXISTING_FOLDER}</dt><dd>if the path denotes a folder, either a directory or a
 * browsable archive.</dd>
 *  <dt>{@link ResolvedDestination#EXISTING_FILE}</dt><dd>if the path denotes a regular file. The file may be a browsable archive,
 * see below.</dd>
 *  <dt>{@link ResolvedDestination#NEW_FILE}</dt><dd>if the path denotes a non-existing file whose parent exists.</dd>
 * </dl>
 * Paths to browsable archives are considered as denoting a folder only if they end with a trailing separator
 * character. If they don't, they're considered as denoting a regular file. For example,
 * <code>/existing_folder/existing_archive.zip/</code> refers to the archive as a folder where as
 * <code>/existing_folder/existing_archive.zip</code> refers to the archive as a regular file.
 * </p>
 *
 * @param destPath the destination path to resolve
 * @param baseFolder the base folder used for relative paths, <code>null</code> to accept only absolute paths
 * @param parent the parent of destPath
 * @return the object that that contains a {@link AbstractFile} instance corresponding to the path and a type that
 * describes the kind of destination that was resolved
 */
public static ResolvedDestination resolveDestination(String destPath, AbstractFile baseFolder, AbstractFile parent) {
    FileURL destURL;
    // Try to resolve the path as a URL
    try {
        destURL = FileURL.getFileURL(destPath);
    // destPath is absolute
    } catch (MalformedURLException e) {
        // Abort now if there is no base folder
        if (baseFolder == null)
            return null;
        String separator = baseFolder.getSeparator();
        // Start by cloning the base folder's URL, including credentials and properties
        FileURL baseFolderURL = baseFolder.getURL();
        destURL = (FileURL) baseFolderURL.clone();
        String basePath = destURL.getPath();
        if (!destPath.equals(""))
            destURL.setPath(basePath + (basePath.endsWith(separator) ? "" : separator) + destPath);
        // => parse the URL from scratch to have the SchemeParser canonize them.
        try {
            destURL = FileURL.getFileURL(destURL.toString(false));
            // Import credentials separately, so that login and passwords that contain URI-unsafe characters
            // such as '/' are properly parsed.
            destURL.setCredentials(baseFolderURL.getCredentials());
            destURL.importProperties(baseFolderURL);
        } catch (MalformedURLException e2) {
            return null;
        }
    }
    // No point in going any further if the URL cannot be resolved into a file
    AbstractFile destFile = FileFactory.getFile(destURL);
    if (destFile == null) {
        LOGGER.info("could not resolve a file for {}", destURL);
        return null;
    }
    // Test if the destination file exists
    boolean destFileExists = destFile.exists();
    if (destFileExists) {
        // if they don't, they'll refer to the archive as a file.
        if (destFile.isDirectory() || (destPath.endsWith(destFile.getSeparator()) && destFile.isBrowsable()))
            return new ResolvedDestination(destFile, DestinationType.EXISTING_FOLDER, destFile);
    }
    if (Objects.equals(parent, destFile.getParent())) {
        destFile.setParent(parent);
    }
    // Test if the destination's parent exists, if not the path is not a valid destination
    AbstractFile destParent = destFile.getParent();
    if (destParent == null || !destParent.exists())
        return null;
    return new ResolvedDestination(destFile, destFileExists ? DestinationType.EXISTING_FILE : DestinationType.NEW_FILE, destParent);
}
Also used : FileURL(com.mucommander.commons.file.FileURL) MalformedURLException(java.net.MalformedURLException) AbstractFile(com.mucommander.commons.file.AbstractFile)

Example 27 with AbstractFile

use of com.mucommander.commons.file.AbstractFile in project mucommander by mucommander.

the class LocalFile method getVolumes.

/**
 * Resolves and returns all local volumes:
 * <ul>
 * <li>On UNIX-based OSes, these are the mount points declared in <code>/etc/ftab</code>.</li>
 * <li>On the Windows platform, these are the drives displayed in Explorer. Some of the returned volumes may
 * correspond to removable drives and thus may not always be available -- if they aren't, {@link #exists()} will
 * return <code>false</code>.</li>
 * </ul>
 * <p>
 * The return list of volumes is purposively not cached so that new volumes will be returned as soon as they are
 * mounted.
 * </p>
 *
 * @return all local volumes
 */
public static AbstractFile[] getVolumes() {
    Vector<AbstractFile> volumesV = new Vector<AbstractFile>();
    // (like 'Hard drive' or whatever silly name the user gave his primary hard disk) to /
    if (OsFamily.MAC_OS.isCurrent()) {
        addMacOSXVolumes(volumesV);
    } else {
        // Add java.io.File's root folders
        addJavaIoFileRoots(volumesV);
        // Add /proc/mounts folders under UNIX-based systems.
        if (OsFamily.getCurrent().isUnixBased())
            addMountEntries(volumesV);
    }
    // Add home folder, if it is not already present in the list
    AbstractFile homeFolder = getUserHome();
    if (!(homeFolder == null || volumesV.contains(homeFolder)))
        volumesV.add(homeFolder);
    addDesktopEntry(volumesV, homeFolder);
    AbstractFile[] volumes = new AbstractFile[volumesV.size()];
    volumesV.toArray(volumes);
    return volumes;
}
Also used : AbstractFile(com.mucommander.commons.file.AbstractFile) Vector(java.util.Vector)

Example 28 with AbstractFile

use of com.mucommander.commons.file.AbstractFile in project mucommander by mucommander.

the class LocalFile method ls.

@Override
public AbstractFile[] ls(FilenameFilter filenameFilter) throws IOException {
    File[] files = file.listFiles(filenameFilter == null ? null : new LocalFilenameFilter(filenameFilter));
    if (files == null)
        throw new IOException();
    int nbFiles = files.length;
    AbstractFile[] children = new AbstractFile[nbFiles];
    for (int i = 0; i < nbFiles; i++) {
        // Clone the FileURL of this file and set the child's path, this is more efficient than creating a new
        // FileURL instance from scratch.
        FileURL childURL = (FileURL) fileURL.clone();
        childURL.setPath(absPath + SEPARATOR + files[i].getName());
        // Retrieves an AbstractFile (LocalFile or AbstractArchiveFile) instance that's potentially already in
        // the cache, reuse this file as the file's parent, and the already-created java.io.File instance.
        children[i] = FileFactory.getFile(childURL, this, Collections.singletonMap("createdFile", files[i]));
    }
    return children;
}
Also used : FileURL(com.mucommander.commons.file.FileURL) AbstractFile(com.mucommander.commons.file.AbstractFile) IOException(java.io.IOException) RandomAccessFile(java.io.RandomAccessFile) MonitoredFile(com.mucommander.commons.file.MonitoredFile) ProtocolFile(com.mucommander.commons.file.protocol.ProtocolFile) File(java.io.File) AbstractFile(com.mucommander.commons.file.AbstractFile)

Example 29 with AbstractFile

use of com.mucommander.commons.file.AbstractFile in project mucommander by mucommander.

the class LocalFile method getVolume.

/**
 * Overridden to return the local volume on which this file is located. The returned volume is one of the volumes
 * returned by {@link #getVolumes()}.
 */
@Override
public AbstractFile getVolume() {
    AbstractFile[] volumes = LocalFile.getVolumes();
    // Looks for the volume that best matches this file, i.e. the volume that is the deepest parent of this file.
    // If this file is itself a volume, return it.
    int bestDepth = -1;
    AbstractFile bestMatch = null;
    String thisPath = getAbsolutePath(true);
    for (AbstractFile volume : volumes) {
        String volumePath = volume.getAbsolutePath(true);
        if (thisPath.equals(volumePath)) {
            return this;
        } else if (thisPath.startsWith(volumePath)) {
            int depth = PathUtils.getDepth(volumePath, volume.getSeparator());
            if (depth > bestDepth) {
                bestDepth = depth;
                bestMatch = volume;
            }
        }
    }
    if (bestMatch != null)
        return bestMatch;
    // If no volume matched this file (shouldn't normally happen), return the root folder
    return getRoot();
}
Also used : AbstractFile(com.mucommander.commons.file.AbstractFile)

Example 30 with AbstractFile

use of com.mucommander.commons.file.AbstractFile in project mucommander by mucommander.

the class UNCFile method renameTo.

@Override
public void renameTo(AbstractFile destFile) throws IOException, UnsupportedFileOperationException {
    // Throw an exception if the file cannot be renamed to the specified destination.
    // Fail in some situations where java.io.File#renameTo() doesn't.
    // Note that java.io.File#renameTo()'s implementation is system-dependant, so it's always a good idea to
    // perform all those checks even if some are not necessary on this or that platform.
    checkRenamePrerequisites(destFile, true, false);
    // The behavior of java.io.File#renameTo() when the destination file already exists is not consistent
    // across platforms:
    // - Under UNIX, it succeeds and return true
    // - Under Windows, it fails and return false
    // This ticket goes in great details about the issue: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4017593
    // 
    // => Since this method is required to succeed when the destination file exists, the Windows platform needs
    // special treatment.
    destFile = destFile.getTopAncestor();
    File destJavaIoFile = ((UNCFile) destFile).file;
    // Note that Windows UNC paths are handled by checkRenamePrerequisites() when comparing hosts for equality.
    if (!getRoot().equals(destFile.getRoot()))
        throw new IOException();
    if (Kernel32.isAvailable()) {
        // call #exists() on the destination file which has a cost.
        if (!Kernel32.getInstance().MoveFileEx(absPath, destFile.getAbsolutePath(), Kernel32API.MOVEFILE_REPLACE_EXISTING | Kernel32API.MOVEFILE_WRITE_THROUGH)) {
            String errorMessage = Integer.toString(Kernel32.getInstance().GetLastError());
            // TODO: use Kernel32.FormatMessage
            throw new IOException("Rename using Kernel32 API failed: " + errorMessage);
        } else {
            // move successful
            return;
        }
    }
    if (!file.renameTo(destJavaIoFile))
        throw new IOException();
}
Also used : IOException(java.io.IOException) RandomAccessFile(java.io.RandomAccessFile) ProtocolFile(com.mucommander.commons.file.protocol.ProtocolFile) File(java.io.File) AbstractFile(com.mucommander.commons.file.AbstractFile)

Aggregations

AbstractFile (com.mucommander.commons.file.AbstractFile)150 IOException (java.io.IOException)49 FileURL (com.mucommander.commons.file.FileURL)19 FileSet (com.mucommander.commons.file.util.FileSet)11 FileTable (com.mucommander.ui.main.table.FileTable)11 DialogAction (com.mucommander.ui.dialog.DialogAction)10 File (java.io.File)9 List (java.util.List)8 MainFrame (com.mucommander.ui.main.MainFrame)6 InputStream (java.io.InputStream)6 Vector (java.util.Vector)6 AbstractArchiveEntryFile (com.mucommander.commons.file.archive.AbstractArchiveEntryFile)5 ProtocolFile (com.mucommander.commons.file.protocol.ProtocolFile)5 LocalFile (com.mucommander.commons.file.protocol.local.LocalFile)5 ProgressDialog (com.mucommander.ui.dialog.file.ProgressDialog)5 FolderPanel (com.mucommander.ui.main.FolderPanel)5 FileTableModel (com.mucommander.ui.main.table.FileTableModel)5 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 UnsupportedFileOperationException (com.mucommander.commons.file.UnsupportedFileOperationException)4