mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Recursive local file support in FileManager and dir tree
This commit is contained in:
parent
e5c83bc9ce
commit
ce4ee992ea
@ -25,7 +25,8 @@ package org.sleuthkit.autopsy.casemodule.services;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.DerivedFile;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
@ -33,6 +34,7 @@ import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.LocalFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||
|
||||
/**
|
||||
* Abstraction to facilitate access to files and directories.
|
||||
@ -40,6 +42,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
public class FileManager implements Closeable {
|
||||
|
||||
private SleuthkitCase tskCase;
|
||||
private static final Logger logger = Logger.getLogger(FileManager.class.getName());
|
||||
|
||||
public FileManager(SleuthkitCase tskCase) {
|
||||
this.tskCase = tskCase;
|
||||
@ -138,6 +141,90 @@ public class FileManager implements Closeable {
|
||||
isFile, parentFile, rederiveDetails, toolName, toolVersion, otherDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper (internal) to add child of local dir recursively
|
||||
* @param parentVd
|
||||
* @param childLocalFile
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private void addLocalDirectoryRecInt(VirtualDirectory parentVd,
|
||||
java.io.File childLocalFile) throws TskCoreException {
|
||||
|
||||
final boolean isDir = childLocalFile.isDirectory();
|
||||
|
||||
if (isDir) {
|
||||
//create virtual folder
|
||||
final VirtualDirectory childVd = tskCase.addVirtualDirectory(parentVd.getId(), childLocalFile.getName());
|
||||
//add children recursively
|
||||
for (java.io.File childChild : childLocalFile.listFiles()) {
|
||||
addLocalDirectoryRecInt(childVd, childChild);
|
||||
}
|
||||
} else {
|
||||
//add leaf file, base case
|
||||
this.addLocalFileSingle(childLocalFile.getAbsolutePath(), parentVd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a local directory and its children recursively.
|
||||
*
|
||||
*
|
||||
* @param localAbsPath local absolute path of root folder whose children are
|
||||
* to be added recursively
|
||||
* @return parent virtual directory folder created representing the
|
||||
* localAbsPath node
|
||||
* @throws TskCoreException exception thrown if the object creation failed
|
||||
* due to a critical system error or of the file manager has already been
|
||||
* closed, or if the localAbsPath could not be accessed
|
||||
*/
|
||||
public synchronized VirtualDirectory addLocalDir(String localAbsPath) throws TskCoreException {
|
||||
if (tskCase == null) {
|
||||
throw new TskCoreException("Attempted to use FileManager after it was closed.");
|
||||
}
|
||||
|
||||
java.io.File localDir = new java.io.File(localAbsPath);
|
||||
if (!localDir.exists()) {
|
||||
throw new TskCoreException("Attempted to add a local dir that does not exist: " + localAbsPath);
|
||||
}
|
||||
if (!localDir.canRead()) {
|
||||
throw new TskCoreException("Attempted to add a local dir that is not readable: " + localAbsPath);
|
||||
}
|
||||
|
||||
if (!localDir.isDirectory()) {
|
||||
throw new TskCoreException("Attempted to add a local dir that is not a directory: " + localAbsPath);
|
||||
}
|
||||
|
||||
final String rootVdName = localDir.getName();
|
||||
|
||||
VirtualDirectory rootVd = null;
|
||||
try {
|
||||
final long localFilesRootId = tskCase.getLocalFilesRootDirectoryId();
|
||||
rootVd = tskCase.addVirtualDirectory(localFilesRootId, rootVdName);
|
||||
} catch (TskCoreException e) {
|
||||
//log and rethrow
|
||||
final String msg = "Error creating root dir for local dir to be added, can't addLocalDir: " + localDir;
|
||||
logger.log(Level.SEVERE, msg, e);
|
||||
throw new TskCoreException(msg);
|
||||
}
|
||||
|
||||
try {
|
||||
java.io.File[] localChildren = localDir.listFiles();
|
||||
for (java.io.File localChild : localChildren) {
|
||||
//add childrnen recursively, at a time in separate transaction
|
||||
//consider a single transaction for everything
|
||||
addLocalDirectoryRecInt(rootVd, localChild);
|
||||
}
|
||||
} catch (TskCoreException e) {
|
||||
final String msg = "Error creating local children for local dir to be added, can't fully add addLocalDir: " + localDir;
|
||||
logger.log(Level.SEVERE, msg, e);
|
||||
throw new TskCoreException(msg);
|
||||
}
|
||||
|
||||
|
||||
return rootVd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single local file under $LocalFiles for the case, adds it to
|
||||
* the database and returns it.
|
||||
@ -147,7 +234,7 @@ public class FileManager implements Closeable {
|
||||
* @return newly created local file object added to the database
|
||||
* @throws TskCoreException exception thrown if the object creation failed
|
||||
* due to a critical system error or of the file manager has already been
|
||||
* closed
|
||||
* closed, or if the localAbsPath could not be accessed
|
||||
*
|
||||
*/
|
||||
public synchronized LocalFile addLocalFileSingle(String localAbsPath) throws TskCoreException {
|
||||
@ -203,8 +290,8 @@ public class FileManager implements Closeable {
|
||||
isFile, parentFile);
|
||||
|
||||
//refresh the content tree
|
||||
//TODO decouple, use Node autorefresh once implemented
|
||||
DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
|
||||
//TODO decouple at least using events, and later use Node autorefresh once implemented
|
||||
//DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
|
||||
|
||||
return lf;
|
||||
}
|
||||
|
@ -25,11 +25,13 @@ import org.openide.nodes.Children;
|
||||
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.datamodel.LocalFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.LayoutFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.LocalFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
|
||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
@ -37,6 +39,7 @@ import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||
import org.sleuthkit.datamodel.Volume;
|
||||
|
||||
/**
|
||||
@ -123,7 +126,11 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
|
||||
try {
|
||||
for (Content c : vol.getChildren()) {
|
||||
if (!(c instanceof LayoutFile)) {
|
||||
if (!(c instanceof LayoutFile
|
||||
|| c instanceof VirtualDirectory
|
||||
)
|
||||
|
||||
) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
@ -173,14 +180,13 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
return isLeafDirectory(dn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(FileNode fn) {
|
||||
private Boolean visitDeep(AbstractAbstractFileNode node) {
|
||||
//is a leaf if has no children, or children are files not dirs
|
||||
boolean hasChildren = fn.hasContentChildren();
|
||||
boolean hasChildren = node.hasContentChildren();
|
||||
if (!hasChildren) {
|
||||
return true;
|
||||
}
|
||||
List<Content> derivedChildren = fn.getContentChildren();
|
||||
List<Content> derivedChildren = node.getContentChildren();
|
||||
//child of a file, must be a (derived) file too
|
||||
for (Content childContent : derivedChildren) {
|
||||
if (((AbstractFile) childContent).isDir()) {
|
||||
@ -200,34 +206,32 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(LocalFileNode dfn) {
|
||||
//is a leaf if has no children, or children are files not dirs
|
||||
boolean hasChildren = dfn.hasContentChildren();
|
||||
if (!hasChildren) {
|
||||
return true;
|
||||
}
|
||||
List<Content> derivedChildren = dfn.getContentChildren();
|
||||
//child of a file, must be a (derived) file too
|
||||
for (Content childContent : derivedChildren) {
|
||||
if (((AbstractFile) childContent).isDir()) {
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
if (childContent.hasChildren()) {
|
||||
return false;
|
||||
}
|
||||
} catch (TskCoreException e) {
|
||||
logger.log(Level.SEVERE, "Error checking if derived file node is leaf.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
public Boolean visit(FileNode fn) {
|
||||
return visitDeep(fn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean visit(LocalFileNode lfn) {
|
||||
return visitDeep(lfn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(LayoutFileNode fn) {
|
||||
return visitDeep(fn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean visit(VolumeNode vn) {
|
||||
return isLeafVolume(vn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(VirtualDirectoryNode vdn) {
|
||||
//return visitDeep(vdn);
|
||||
return ! vdn.hasContentChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShowItemVisitor extends DisplayableItemNodeVisitor.Default<Boolean> {
|
||||
@ -251,13 +255,18 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(LocalFileNode dfn) {
|
||||
return dfn.hasContentChildren();
|
||||
public Boolean visit(LocalFileNode lfn) {
|
||||
return lfn.hasContentChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(LayoutFileNode ln) {
|
||||
return false;
|
||||
return ln.hasContentChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(VirtualDirectoryNode vdn) {
|
||||
return vdn.hasContentChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user