Search in sources :

Example 1 with AbstractArchiveFile

use of com.mucommander.commons.file.archive.AbstractArchiveFile in project mucommander by mucommander.

the class CopyDialog method createTransferFileJob.

// ////////////////////////////////////////////
// TransferDestinationDialog implementation //
// ////////////////////////////////////////////
@Override
protected TransferFileJob createTransferFileJob(ProgressDialog progressDialog, PathUtils.ResolvedDestination resolvedDest, int defaultFileExistsAction) {
    AbstractFile baseFolder = files.getBaseFolder();
    AbstractArchiveFile parentArchiveFile = baseFolder.getParentArchive();
    TransferFileJob job;
    String newName = resolvedDest.getDestinationType() == DestinationType.EXISTING_FOLDER ? null : resolvedDest.getDestinationFile().getName();
    // their natural order (more efficient)
    if (parentArchiveFile != null) {
        // Add all selected archive entries to a vector
        int nbFiles = files.size();
        List<ArchiveEntry> selectedEntries = new Vector<ArchiveEntry>();
        for (int i = 0; i < nbFiles; i++) {
            selectedEntries.add((ArchiveEntry) files.elementAt(i).getAncestor(AbstractArchiveEntryFile.class).getUnderlyingFileObject());
        }
        job = new UnpackJob(progressDialog, mainFrame, parentArchiveFile, PathUtils.getDepth(baseFolder.getAbsolutePath(), baseFolder.getSeparator()) - PathUtils.getDepth(parentArchiveFile.getAbsolutePath(), parentArchiveFile.getSeparator()), resolvedDest.getDestinationFolder(), newName, defaultFileExistsAction, selectedEntries);
    } else {
        job = new CopyJob(progressDialog, mainFrame, files, resolvedDest.getDestinationFolder(), newName, TransferMode.COPY, defaultFileExistsAction);
    }
    return job;
}
Also used : AbstractArchiveFile(com.mucommander.commons.file.archive.AbstractArchiveFile) AbstractArchiveEntryFile(com.mucommander.commons.file.archive.AbstractArchiveEntryFile) TransferFileJob(com.mucommander.job.impl.TransferFileJob) AbstractFile(com.mucommander.commons.file.AbstractFile) UnpackJob(com.mucommander.job.impl.UnpackJob) CopyJob(com.mucommander.job.impl.CopyJob) ArchiveEntry(com.mucommander.commons.file.archive.ArchiveEntry) Vector(java.util.Vector)

Example 2 with AbstractArchiveFile

use of com.mucommander.commons.file.archive.AbstractArchiveFile in project mucommander by mucommander.

the class FileFactory method getFile.

/**
 * Creates and returns an instance of AbstractFile for the given FileURL and uses the specified parent file (if any)
 * as the created file's parent.
 *
 * <p>Specifying the file parent if an instance already exists allows to recycle the AbstractFile instance
 * instead of creating a new one when the parent file is requested.
 *
 * @param fileURL the file URL representing the file to be created
 * @param authenticator used to authenticate the specified location if its protocol
 * {@link FileURL#getAuthenticationType() is authenticated} and the location contains no credentials already.
 * If the value is <code>null</code>, no {@link Authenticator} will be used, not even the default one.
 * @param parent the parent AbstractFile to use as the created file's parent, can be <code>null</code>
 * @return an instance of {@link AbstractFile} for the given {@link FileURL}.
 * @throws java.io.IOException if something went wrong during file creation.
 */
public static AbstractFile getFile(FileURL fileURL, AbstractFile parent, Authenticator authenticator, Map<String, Object> instantiationParams) throws IOException {
    String protocol = fileURL.getScheme();
    if (!isRegisteredProtocol(protocol))
        throw new IOException("Unsupported file protocol: " + protocol);
    // Lookup the pool for an existing AbstractFile instance, only if there are no instantiationParams.
    // If there are instantiationParams (the file was created by the AbstractFile implementation directly, that is
    // by ls()), any existing file in the pool must be replaced with a new, more up-to-date one.
    FilePool filePool = FILE_POOL_MAP.get(fileURL.getScheme().toLowerCase());
    if (filePool == null)
        filePool = new FilePool();
    if (instantiationParams.isEmpty()) {
        // Note: FileURL#equals(Object) and #hashCode() take into account credentials and properties and are
        // trailing slash insensitive (e.g. '/root' and '/root/' URLS are one and the same)
        AbstractFile file = filePool.get(fileURL);
        if (file != null)
            return file;
    }
    String filePath = fileURL.getPath();
    // For local paths under Windows (e.g. "/C:\temp"), remove the leading '/' character
    if (OsFamily.WINDOWS.isCurrent() && LocalFile.SCHEMA.equals(protocol))
        filePath = PathUtils.removeLeadingSeparator(filePath, "/");
    String pathSeparator = fileURL.getPathSeparator();
    PathTokenizer pt = new PathTokenizer(filePath, pathSeparator, false);
    AbstractFile currentFile = null;
    boolean lastFileResolved = false;
    // If it does, create the appropriate protocol file and wrap it with an archive file.
    while (pt.hasMoreFilenames()) {
        String filename = pt.nextFilename();
        if (SearchFile.SCHEMA.equals(protocol))
            continue;
        // Note that the archive can also be a directory with an archive extension.
        if (isArchiveFilename(filename)) {
            // Remove trailing separator of file, some file protocols such as SFTP don't like trailing separators.
            // On the contrary, directories without a trailing slash are fine.
            String currentPath = PathUtils.removeTrailingSeparator(pt.getCurrentPath(), pathSeparator);
            // protocol file
            if (currentFile == null || !currentFile.isArchive()) {
                // Create a fresh FileURL with the current path
                FileURL clonedURL = (FileURL) fileURL.clone();
                clonedURL.setPath(currentPath);
                // Look for a cached file instance before creating a new one
                currentFile = filePool.get(clonedURL);
                if (currentFile == null) {
                    currentFile = wrapArchive(createRawFile(clonedURL, authenticator, instantiationParams));
                    // Add the intermediate file instance to the cache
                    filePool.put(clonedURL, currentFile);
                }
                lastFileResolved = true;
            } else {
                // currentFile is an AbstractArchiveFile
                // Note: wrapArchive() is already called by AbstractArchiveFile#createArchiveEntryFile()
                AbstractFile tempEntryFile = ((AbstractArchiveFile) currentFile).getArchiveEntryFile(PathUtils.removeLeadingSeparator(currentPath.substring(currentFile.getURL().getPath().length(), currentPath.length()), pathSeparator));
                if (tempEntryFile.isArchive()) {
                    currentFile = tempEntryFile;
                    lastFileResolved = true;
                } else {
                    lastFileResolved = false;
                }
            // Note: don't cache the entry file
            }
        } else {
            lastFileResolved = false;
        }
    }
    // except that it doesn't wrap the file with an archive file
    if (!lastFileResolved) {
        // Note: DON'T strip out the trailing separator, as this would cause problems with root resources
        String currentPath = pt.getCurrentPath();
        if (currentFile == null || !currentFile.isArchive()) {
            FileURL clonedURL = (FileURL) fileURL.clone();
            clonedURL.setPath(currentPath);
            // Note: no need to look a cached file instance, we have already looked for it at the very beginning.
            currentFile = createRawFile(clonedURL, authenticator, instantiationParams);
            // Add the final file instance to the cache
            filePool.put(currentFile.getURL(), currentFile);
        } else {
            // currentFile is an AbstractArchiveFile
            currentFile = ((AbstractArchiveFile) currentFile).getArchiveEntryFile(PathUtils.removeLeadingSeparator(currentPath.substring(currentFile.getURL().getPath().length(), currentPath.length()), pathSeparator));
        // Note: don't cache the entry file
        }
    }
    // Reuse existing parent file instance if one was specified
    if (parent != null)
        currentFile.setParent(parent);
    return currentFile;
}
Also used : PathTokenizer(com.mucommander.commons.file.util.PathTokenizer) AbstractArchiveFile(com.mucommander.commons.file.archive.AbstractArchiveFile) FilePool(com.mucommander.commons.file.util.FilePool) IOException(java.io.IOException)

Example 3 with AbstractArchiveFile

use of com.mucommander.commons.file.archive.AbstractArchiveFile in project mucommander by mucommander.

the class ResourceLoader method getResourceAsFile.

/**
 * Finds the resource with the given path and returns an {@link AbstractFile} that gives full access to it,
 * or <code>null</code> if the resource couldn't be located. The given <code>ClassLoader</code> is used for locating
 * the resource.
 *
 * <p>The given resource path must be forward slash (<code>/</code>) separated. It may or may not start with a
 * leading forward slash character, this doesn't affect the way it is interpreted.</p>
 *
 * <p>It is worth noting that this method may be slower than {@link #getResourceAsStream(String)} if
 * the resource is located inside a JAR file, because the Zip file headers will have to be parsed the first time
 * the archive is accessed. Therefore, the latter approach should be favored if the file is simply used for
 * reading the resource.</p>
 *
 * <p>The <code>rootPackageFile</code> argument can be used to limit the scope of the search to a specific
 * location (JAR file or directory) in the classpath: resources located outside of this location will not be matched.
 * This avoids potential ambiguities that can arise if the specified resource path exists in several locations.
 * If this parameter is <code>null</code>, the resource is looked up in the whole class path. In that case and if
 * several resources with the specified path exist, the choice of the resource to return is arbitrary.</p>
 *
 * @param path forward slash-separated path to the resource to look for, relative to the parent classpath
 * location (directory or JAR file) that contains it.
 * @param classLoader the ClassLoader is used for locating the resource
 * @param rootPackageFile root package location (JAR file or directory) that limits the scope of the search,
 * <code>null</code> to look for the resource in the whole class path.
 * @return an AbstractFile that represents the resource, or <code>null</code> if the resource couldn't be located
 */
public static AbstractFile getResourceAsFile(String path, ClassLoader classLoader, AbstractFile rootPackageFile) {
    if (classLoader == null)
        classLoader = getDefaultClassLoader();
    path = removeLeadingSlash(path);
    URL aClassURL = getResourceAsURL(path, classLoader, rootPackageFile);
    if (aClassURL == null)
        // no resource under that path
        return null;
    if ("jar".equals(aClassURL.getProtocol())) {
        try {
            return ((AbstractArchiveFile) FileFactory.getFile(getJarFilePath(aClassURL))).getArchiveEntryFile(path);
        } catch (Exception e) {
            // Shouldn't normally happen, unless the JAR file is corrupt or cannot be parsed by the file API
            return null;
        }
    }
    return FileFactory.getFile(getLocalFilePath(aClassURL));
}
Also used : AbstractArchiveFile(com.mucommander.commons.file.archive.AbstractArchiveFile) URL(java.net.URL) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 4 with AbstractArchiveFile

use of com.mucommander.commons.file.archive.AbstractArchiveFile in project mucommander by mucommander.

the class CopyDialog method createTransferFileJob.

// ////////////////////////////////////////////
// TransferDestinationDialog implementation //
// ////////////////////////////////////////////
@Override
protected TransferFileJob createTransferFileJob(ProgressDialog progressDialog, PathUtils.ResolvedDestination resolvedDest, FileCollisionDialog.FileCollisionAction defaultFileExistsAction) {
    AbstractFile baseFolder = files.getBaseFolder();
    AbstractArchiveFile parentArchiveFile = baseFolder.getParentArchive();
    TransferFileJob job;
    String newName = resolvedDest.getDestinationType() == DestinationType.EXISTING_FOLDER ? null : resolvedDest.getDestinationFile().getName();
    // their natural order (more efficient)
    if (parentArchiveFile != null) {
        // Add all selected archive entries to a vector
        int nbFiles = files.size();
        List<ArchiveEntry> selectedEntries = new Vector<ArchiveEntry>();
        for (int i = 0; i < nbFiles; i++) {
            selectedEntries.add((ArchiveEntry) files.elementAt(i).getAncestor(AbstractArchiveEntryFile.class).getUnderlyingFileObject());
        }
        job = new UnpackJob(progressDialog, mainFrame, parentArchiveFile, PathUtils.getDepth(baseFolder.getAbsolutePath(), baseFolder.getSeparator()) - PathUtils.getDepth(parentArchiveFile.getAbsolutePath(), parentArchiveFile.getSeparator()), resolvedDest.getDestinationFolder(), newName, defaultFileExistsAction, selectedEntries);
    } else {
        job = new CopyJob(progressDialog, mainFrame, files, resolvedDest.getDestinationFolder(), newName, TransferMode.COPY, defaultFileExistsAction);
    }
    return job;
}
Also used : AbstractArchiveFile(com.mucommander.commons.file.archive.AbstractArchiveFile) AbstractArchiveEntryFile(com.mucommander.commons.file.archive.AbstractArchiveEntryFile) TransferFileJob(com.mucommander.job.impl.TransferFileJob) AbstractFile(com.mucommander.commons.file.AbstractFile) UnpackJob(com.mucommander.job.impl.UnpackJob) CopyJob(com.mucommander.job.impl.CopyJob) ArchiveEntry(com.mucommander.commons.file.archive.ArchiveEntry) Vector(java.util.Vector)

Example 5 with AbstractArchiveFile

use of com.mucommander.commons.file.archive.AbstractArchiveFile in project mucommander by mucommander.

the class MoveJob method jobCompleted.

// //////////////////////
// Overridden methods //
// //////////////////////
@Override
protected void jobCompleted() {
    super.jobCompleted();
    // If the source files are located inside an archive, optimize the archive file
    AbstractArchiveFile sourceArchiveFile = getBaseSourceFolder() == null ? null : getBaseSourceFolder().getParentArchive();
    if (sourceArchiveFile != null && sourceArchiveFile.isArchive() && sourceArchiveFile.isWritable())
        optimizeArchive((AbstractRWArchiveFile) sourceArchiveFile);
    // If the destination files are located inside an archive, optimize the archive file, only if the destination
    // archive is different from the source one
    AbstractArchiveFile destArchiveFile = baseDestFolder.getParentArchive();
    if (destArchiveFile != null && destArchiveFile.isArchive() && destArchiveFile.isWritable() && !(sourceArchiveFile != null && destArchiveFile.equalsCanonical(sourceArchiveFile)))
        optimizeArchive((AbstractRWArchiveFile) destArchiveFile);
    // in the active table after this job has finished (and hasn't been cancelled)
    if (files.size() == 1 && newName != null && baseDestFolder.equalsCanonical(files.elementAt(0).getParent())) {
        // Resolve new file instance now that it exists: some remote files do not immediately update file attributes
        // after creation, we need to get an instance that reflects the newly created file attributes
        selectFileWhenFinished(FileFactory.getFile(baseDestFolder.getAbsolutePath(true) + newName));
    }
}
Also used : AbstractArchiveFile(com.mucommander.commons.file.archive.AbstractArchiveFile) AbstractRWArchiveFile(com.mucommander.commons.file.archive.AbstractRWArchiveFile)

Aggregations

AbstractArchiveFile (com.mucommander.commons.file.archive.AbstractArchiveFile)9 AbstractRWArchiveFile (com.mucommander.commons.file.archive.AbstractRWArchiveFile)4 IOException (java.io.IOException)4 ArchiveEntry (com.mucommander.commons.file.archive.ArchiveEntry)3 AbstractFile (com.mucommander.commons.file.AbstractFile)2 AbstractArchiveEntryFile (com.mucommander.commons.file.archive.AbstractArchiveEntryFile)2 CopyJob (com.mucommander.job.impl.CopyJob)2 TransferFileJob (com.mucommander.job.impl.TransferFileJob)2 UnpackJob (com.mucommander.job.impl.UnpackJob)2 Vector (java.util.Vector)2 ArchiveEntryIterator (com.mucommander.commons.file.archive.ArchiveEntryIterator)1 FilePool (com.mucommander.commons.file.util.FilePool)1 PathTokenizer (com.mucommander.commons.file.util.PathTokenizer)1 DialogAction (com.mucommander.ui.dialog.DialogAction)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 URL (java.net.URL)1 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)1