/** * This method is overridden to use the archive file's absolute path as the base path of this entry file. */ @Override public String getAbsolutePath() { // Use the archive file's absolute path and append the entry's relative path to it return archiveFile.getAbsolutePath(true)+getRelativeEntryPath(); }
/** * Creates and returns an {@link AbstractFile} instance corresponding to the given entry node. * This method recurses to resolve the entry's parent file. * * @param entryNode tree node corresponding to the entry for which to return a file * @return an {@link AbstractFile} instance corresponding to the given entry node */ protected AbstractFile getArchiveEntryFile(DefaultMutableTreeNode entryNode) throws IOException { DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)entryNode.getParent(); return getArchiveEntryFile( (ArchiveEntry)entryNode.getUserObject(), parentNode==entryTreeRoot ?this :getArchiveEntryFile(parentNode) ); }
/** * Delegates to the archive file's {@link AbstractArchiveFile#getEntryInputStream(ArchiveEntry,ArchiveEntryIterator)}} * method. * * @throws UnsupportedFileOperationException if the underlying archive file does not support * {@link FileOperation#READ_FILE} operations. */ @Override public InputStream getInputStream() throws IOException, UnsupportedFileOperationException { return archiveFile.getEntryInputStream(entry, null); }
/** * Checks if the entries tree exists and if this file hasn't been modified since the tree was last created. * If any of those 2 conditions isn't met, the entries tree is (re)created. * * @throws IOException if an error occurred while creating the tree * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ protected void checkEntriesTree() throws IOException, UnsupportedFileOperationException { if(this.entryTreeRoot==null || getDate()!=this.entryTreeDate) createEntriesTree(); }
/** * This method is overridden to list and return the topmost entries contained by this archive. * The returned files are {@link AbstractArchiveEntryFile} instances. * * @return the topmost entries contained by this archive * @throws IOException if the archive entries could not be listed * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ @Override public AbstractFile[] ls() throws IOException, UnsupportedFileOperationException { // Delegate to the ancestor if this file isn't actually an archive if(!isArchive()) return super.ls(); // Make sure the entries tree is created and up-to-date checkEntriesTree(); return ls(entryTreeRoot, this, null, null); }
iterator = archiveFile.getEntryIterator(); while((entry = iterator.nextEntry())!=null && getState() != FileJobState.INTERRUPTED) { entryPath = entry.getPath(); entryFile = archiveFile.getArchiveEntryFile(entryPath); showErrorDialog(errorDialogTitle, Translator.get("cannot_read_file", archiveFile.getName()));
@Override protected void jobCompleted() { super.jobCompleted(); // If the source files are located inside an archive, optimize the archive file AbstractArchiveFile archiveFile = getBaseSourceFolder().getParentArchive(); if(archiveFile!=null && archiveFile.isArchive() && archiveFile.isWritable()) { while(true) { try { archiveToOptimize = ((AbstractRWArchiveFile)archiveFile); isOptimizingArchive = true; archiveToOptimize.optimizeArchive(); break; } catch(IOException e) { if(showErrorDialog(errorDialogTitle, Translator.get("error_while_optimizing_archive", archiveFile.getName()))==FileJobAction.RETRY) continue; break; } } isOptimizingArchive = true; } }
String fileSeparator = getSeparator(); if(!fileSeparator.equals("/")) entryPath = entryPath.replace("/", fileSeparator); FileURL archiveURL = getURL(); FileURL entryURL = (FileURL)archiveURL.clone(); entryURL.setPath(addTrailingSeparator(archiveURL.getPath()) + entryPath);
@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); // If this job corresponds to a file renaming in the same directory, select the renamed file // 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)); } }
@Override protected void jobCompleted() { super.jobCompleted(); // If the destination files are located inside an archive, optimize the archive file AbstractArchiveFile archiveFile = baseDestFolder.getParentArchive(); if(archiveFile!=null && archiveFile.isArchive() && archiveFile.isWritable()) optimizeArchive((AbstractRWArchiveFile)archiveFile); // Unselect all files in the active table upon successful completion if(selectedEntries!=null) { ActionManager.performAction(UnmarkAllAction.Descriptor.ACTION_ID, getMainFrame()); } }
mainFrame, parentArchiveFile, PathUtils.getDepth(baseFolder.getAbsolutePath(), baseFolder.getSeparator()) - PathUtils.getDepth(parentArchiveFile.getAbsolutePath(), parentArchiveFile.getSeparator()), resolvedDest.getDestinationFolder(), newName,
checkEntriesTree(); parentFile = getArchiveEntryFile(parentPath); if(parentFile==null) // neither the entry nor the parent exist throw new IOException(); return getArchiveEntryFile(new ArchiveEntry(entryPath, false, 0, 0, false), parentFile); return getArchiveEntryFile(entryNode);
/** * Creates the entries tree, used by {@link #ls(AbstractArchiveEntryFile , com.mucommander.commons.file.filter.FilenameFilter, com.mucommander.commons.file.filter.FileFilter)} * to quickly list the contents of an archive's subfolder. * * @throws IOException if an error occured while retrieving this archive's entries * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ protected void createEntriesTree() throws IOException, UnsupportedFileOperationException { // TODO: this method is not thread-safe and needs to be synchronized ArchiveEntryTree treeRoot = new ArchiveEntryTree(); archiveEntryFiles = new WeakHashMap<ArchiveEntry, AbstractArchiveEntryFile>(); long start = System.currentTimeMillis(); ArchiveEntryIterator entries = getEntryIterator(); try { ArchiveEntry entry; while((entry=entries.nextEntry())!=null) treeRoot.addArchiveEntry(entry); LOGGER.info("entries tree created in "+(System.currentTimeMillis()-start)+" ms"); this.entryTreeRoot = treeRoot; declareEntriesTreeUpToDate(); } finally { try { entries.close(); } catch(IOException e) { // Not much we can do about it } } }
/** * This method is overridden to return the separator of the {@link #getArchiveFile() archive file} that contains * this entry. * * @return the separator of the archive file that contains this entry */ @Override public String getSeparator() { return archiveFile.getSeparator(); }
/** * Returns the contents of the specified folder entry. * * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ protected AbstractFile[] ls(AbstractArchiveEntryFile entryFile, FilenameFilter filenameFilter, FileFilter fileFilter) throws IOException, UnsupportedFileOperationException { // Make sure the entries tree is created and up-to-date checkEntriesTree(); if(!entryFile.isBrowsable()) throw new IOException(); DefaultMutableTreeNode matchNode = entryTreeRoot.findEntryNode(entryFile.getEntry().getPath()); if(matchNode==null) throw new IOException(); return ls(matchNode, entryFile, filenameFilter, fileFilter); }
/** * Adds the given {@link ArchiveEntry} to the entries tree. This method will create the tree if it doesn't already * exist, or re-create it if the archive file has changed since it was last created. * * @param entry the ArchiveEntry to add to the tree * @throws IOException if an error occurred while creating the entries tree * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ protected void addToEntriesTree(ArchiveEntry entry) throws IOException, UnsupportedFileOperationException { checkEntriesTree(); entryTreeRoot.addArchiveEntry(entry); }
/** * This method is overridden to list and return the topmost entries contained by this archive, filtering out * the ones that do not match the specified {@link FileFilter}. The returned files are {@link AbstractArchiveEntryFile} instances. * * @param filter the FilenameFilter to be used to filter files out from the list, may be <code>null</code> * @return the topmost entries contained by this archive * @throws IOException if the archive entries could not be listed * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ @Override public AbstractFile[] ls(FileFilter filter) throws IOException, UnsupportedFileOperationException { // Delegate to the ancestor if this file isn't actually an archive if(!isArchive()) return super.ls(filter); // Make sure the entries tree is created and up-to-date checkEntriesTree(); return ls(entryTreeRoot, this, null, filter); }
@Override protected void jobCompleted() { super.jobCompleted(); // If the destination files are located inside an archive, optimize the archive file AbstractArchiveFile archiveFile = baseDestFolder.getParentArchive(); if(archiveFile!=null && archiveFile.isArchive() && archiveFile.isWritable()) optimizeArchive((AbstractRWArchiveFile)archiveFile); // If this job corresponds to a 'local copy' of a single file and in the same directory, // select the copied file 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)); } }
/** * Removes the given {@link ArchiveEntry} from the entries tree. This method will create the tree if it doesn't * already exist, or re-create it if the archive file has changed since it was last created. * * @param entry the ArchiveEntry to remove from the tree * @throws IOException if an error occurred while creating the entries tree * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ protected void removeFromEntriesTree(ArchiveEntry entry) throws IOException, UnsupportedFileOperationException { checkEntriesTree(); DefaultMutableTreeNode entryNode = entryTreeRoot.findEntryNode(entry.getPath()); if(entryNode!=null) { DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)entryNode.getParent(); parentNode.remove(entryNode); } }
/** * This method is overridden to list and return the topmost entries contained by this archive, filtering out * the ones that do not match the specified {@link FilenameFilter}. The returned files are {@link AbstractArchiveEntryFile} * instances. * * @param filter the FilenameFilter to be used to filter files out from the list, may be <code>null</code> * @return the topmost entries contained by this archive * @throws IOException if the archive entries could not be listed * @throws UnsupportedFileOperationException if {@link FileOperation#READ_FILE} operations are not supported by the * underlying file protocol. */ @Override public AbstractFile[] ls(FilenameFilter filter) throws IOException, UnsupportedFileOperationException { // Delegate to the ancestor if this file isn't actually an archive if(!isArchive()) return super.ls(filter); // Make sure the entries tree is created and up-to-date checkEntriesTree(); return ls(entryTreeRoot, this, filter, null); }