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;
}
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;
}
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));
}
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;
}
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));
}
}
Aggregations