diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtNode.java index d9ce314ae7..5afb64fef8 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByExtNode.java @@ -48,7 +48,7 @@ public class FileTypesByExtNode extends DisplayableItemNode { * something to provide a sub-node. */ FileTypesByExtNode(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter) { - super(Children.create(new FileTypesChildren(skCase, filter, null), true), Lookups.singleton(filter == null ? FNAME : filter.getName())); + super(Children.create(new FileTypesByExtChildren(skCase, filter, null), true), Lookups.singleton(filter == null ? FNAME : filter.getName())); this.filter = filter; init(); } @@ -61,7 +61,7 @@ public class FileTypesByExtNode extends DisplayableItemNode { * provides updates on events */ private FileTypesByExtNode(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) { - super(Children.create(new FileTypesChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName())); + super(Children.create(new FileTypesByExtChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName())); this.filter = filter; init(); } @@ -122,7 +122,7 @@ public class FileTypesByExtNode extends DisplayableItemNode { /** * */ - static class FileTypesChildren extends ChildFactory { + static class FileTypesByExtChildren extends ChildFactory { private SleuthkitCase skCase; private FileTypeExtensionFilters.RootFilter filter; @@ -135,12 +135,12 @@ public class FileTypesByExtNode extends DisplayableItemNode { * @param o Observable that provides updates based on events being * fired (or null if one needs to be created) */ - public FileTypesChildren(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) { + public FileTypesByExtChildren(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) { super(); this.skCase = skCase; this.filter = filter; if (o == null) { - this.notifier = new FileTypesChildrenObservable(); + this.notifier = new FileTypesByExtChildrenObservable(); } else { this.notifier = o; } @@ -150,9 +150,9 @@ public class FileTypesByExtNode extends DisplayableItemNode { * Listens for case and ingest invest. Updates observers when events are * fired. FileType and FileTypes nodes are all listening to this. */ - private final class FileTypesChildrenObservable extends Observable { + private final class FileTypesByExtChildrenObservable extends Observable { - FileTypesChildrenObservable() { + FileTypesByExtChildrenObservable() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); Case.addPropertyChangeListener(pcl); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java index 05a55f9bfb..892a34b653 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesByMimeType.java @@ -57,9 +57,9 @@ import org.sleuthkit.datamodel.TskData; * Listener which is checking for changes in IngestJobEvent Completed or * Cancelled and IngestModuleEvent Content Changed. */ -class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { +public class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { - static SleuthkitCase skCase; + private static SleuthkitCase skCase; /** * The nodes of this tree will be determined dynamically by the mimetypes * which exist in the database. This hashmap will store them with the media @@ -175,15 +175,15 @@ class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { * when the file detection module has not been run and MIME type is * currently unknown. */ - class FileTypesByMimeTypeNode extends DisplayableItemNode { + public class FileTypesByMimeTypeNode extends DisplayableItemNode { @NbBundle.Messages("FileTypesByMimeType.name.text=By MIME Type") final String NAME = Bundle.FileTypesByMimeType_name_text(); FileTypesByMimeTypeNode(SleuthkitCase sleuthkitCase) { super(Children.create(new FileTypesByMimeTypeNodeChildren(), true)); - setName(NAME); - setDisplayName(NAME); + super.setName(NAME); + super.setDisplayName(NAME); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png"); } @@ -202,6 +202,10 @@ class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { return getClass().getName(); } + public boolean isEmpty() { + return existingMimeTypes.isEmpty(); + } + } /** @@ -225,12 +229,7 @@ class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { @Override protected Node createNodeForKey(String key) { - if (!existingMimeTypes.isEmpty()) { - return new MediaTypeNode(key); - } else { - return null; - } - + return new MediaTypeNode(key); } @Override @@ -468,4 +467,47 @@ class FileTypesByMimeType extends Observable implements AutopsyVisitableItem { } } + + /** + * EmptyNode Class made for edge case where no mime exist in the database + * yet. Creates a node to display information on why the tree is empty. + * + * Swapped for the FileTypesByMimeType node in + * DirectoryTreeTopComponent.respondSelection + */ + static public class EmptyNode extends AbstractNode { + + public EmptyNode() { + super(Children.create(new EmptyChildFactory(), true)); + + } + + static class EmptyChildFactory extends ChildFactory { + + String FILE_ID_MSG = "Data not available. Run file type identification module."; //NON-NLS + + @Override + protected boolean createKeys(List list) { + list.add(FILE_ID_MSG); + return true; + } + + @Override + protected Node createNodeForKey(String key) { + return new MessageNode(key); + } + + } + + static class MessageNode extends AbstractNode { + + MessageNode(String name) { + super(Children.LEAF); + super.setName(name); + setName(name); + setDisplayName(name); + } + } + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java index 7e73f37bec..a2c09299d1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java @@ -36,7 +36,6 @@ public class ViewsNode extends DisplayableItemNode { public ViewsNode(SleuthkitCase sleuthkitCase) { super(new RootContentChildren(Arrays.asList( - // new FileTypeExtensionFilters(sleuthkitCase), new FileTypes(sleuthkitCase), // June '15: Recent Files was removed because it was not useful w/out filtering // add it back in if we can filter the results to a more managable size. diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 8f63752a27..c0c5ac3cd4 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -61,7 +61,9 @@ import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.DataSources; import org.sleuthkit.autopsy.datamodel.DataSourcesNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.FileTypesByMimeType.EmptyNode; import org.sleuthkit.autopsy.datamodel.ExtractedContent; +import org.sleuthkit.autopsy.datamodel.FileTypesByMimeType; import org.sleuthkit.autopsy.datamodel.KeywordHits; import org.sleuthkit.autopsy.datamodel.KnownFileFilterNode; import org.sleuthkit.autopsy.datamodel.Reports; @@ -361,7 +363,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat items.add(new Tags()); items.add(new Reports()); contentChildren = new RootContentChildren(items); - + Node root = new AbstractNode(contentChildren) { /** * to override the right click action in the white blank @@ -632,6 +634,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat if (origin == null) { return; } + Node originNode = origin.getNode(); //set node, wrap in filter node first to filter out children @@ -639,7 +642,15 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat Node kffn = new KnownFileFilterNode(drfn, KnownFileFilterNode.getSelectionContext(originNode)); // Create a TableFilterNode with knowledge of the node's type to allow for column order settings - if (originNode instanceof DisplayableItemNode) { + //Special case for when File Type Identification has not yet been run and + //there are no mime types to populate Files by Mime Type Tree + if (originNode instanceof FileTypesByMimeType.FileTypesByMimeTypeNode + && ((FileTypesByMimeType.FileTypesByMimeTypeNode) originNode).isEmpty()) { + EmptyNode emptyNode = new EmptyNode(); + Node emptyDrfn = new DataResultFilterNode(emptyNode, DirectoryTreeTopComponent.this.em); + Node emptyKffn = new KnownFileFilterNode(emptyDrfn, KnownFileFilterNode.getSelectionContext(emptyNode)); + dataResult.setNode(new TableFilterNode(emptyKffn, true, "This Node Is Empty")); + } else if (originNode instanceof DisplayableItemNode) { dataResult.setNode(new TableFilterNode(kffn, true, ((DisplayableItemNode) originNode).getItemType())); } else { dataResult.setNode(new TableFilterNode(kffn, true)); @@ -783,8 +794,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * Set the selected node using a path to a previously selected node. * * @param previouslySelectedNodePath Path to a previously selected node. - * @param rootNodeName Name of the root node to match, may be - * null. + * @param rootNodeName Name of the root node to match, may be null. */ private void setSelectedNode(final String[] previouslySelectedNodePath, final String rootNodeName) { if (previouslySelectedNodePath == null) {