1917 made FileTypeByExtType a inner class of FileTypesByExtType

This commit is contained in:
William Schaefer 2016-12-01 16:51:13 -05:00
parent 038ce32767
commit d8c4ea9044
7 changed files with 583 additions and 614 deletions

View File

@ -118,12 +118,12 @@ FileSize.createSheet.filterType.displayName=Filter Type
FileSize.createSheet.filterType.desc=no description
FileSize.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0}
FileTypeChildren.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0}
FileTypeByExtNode.createSheet.filterType.name=Filter Type
FileTypeByExtNode.createSheet.filterType.displayName=Filter Type
FileTypeByExtNode.createSheet.filterType.desc=no description
FileTypeByExtNode.createSheet.fileExt.name=File Extensions
FileTypeByExtNode.createSheet.fileExt.displayName=File Extensions
FileTypeByExtNode.createSheet.fileExt.desc=no description
FileTypesByExtNode.createSheet.filterType.name=Filter Type
FileTypesByExtNode.createSheet.filterType.displayName=Filter Type
FileTypesByExtNode.createSheet.filterType.desc=no description
FileTypesByExtNode.createSheet.fileExt.name=File Extensions
FileTypesByExtNode.createSheet.fileExt.displayName=File Extensions
FileTypesByExtNode.createSheet.fileExt.desc=no description
FileTypesByExtNode.fname.text=By Extension
FileTypesByExtNode.createSheet.name.name=Name
FileTypesByExtNode.createSheet.name.displayName=Name

View File

@ -49,16 +49,16 @@ public interface DisplayableItemNodeVisitor<T> {
T visit(ImageNode in);
T visit(VolumeNode vn);
T visit(SlackFileNode sfn);
/*
* Views Area
*/
T visit(ViewsNode vn);
T visit(FileTypeByExtNode fsfn);
T visit(FileTypesByExtNode.ByExtNode fsfn);
T visit(DeletedContentNode dcn);
@ -154,8 +154,6 @@ public interface DisplayableItemNodeVisitor<T> {
T visit(EmptyNode.MessageNode emptyNode);
/**
* Visitor with an implementable default behavior for all types. Override
* specific visit types to not use the default behavior.
@ -214,30 +212,30 @@ public interface DisplayableItemNodeVisitor<T> {
}
@Override
public T visit(FileTypeByExtNode fsfn) {
public T visit(FileTypesByExtNode.ByExtNode fsfn) {
return defaultVisit(fsfn);
}
@Override
public T visit(FileTypesByMimeType.ByMimeTypeNode ftByMimeTypeNode) {
return defaultVisit(ftByMimeTypeNode);
}
@Override
public T visit(FileTypesByMimeType.MediaTypeNode ftByMimeTypeMediaTypeNode) {
return defaultVisit(ftByMimeTypeMediaTypeNode);
}
@Override
public T visit(FileTypesByMimeType.MediaSubTypeNode ftByMimeTypeMediaTypeNode) {
return defaultVisit(ftByMimeTypeMediaTypeNode);
}
@Override
public T visit(EmptyNode.MessageNode ftByMimeTypeEmptyNode) {
return defaultVisit(ftByMimeTypeEmptyNode);
}
@Override
public T visit(DeletedContentNode dcn) {
return defaultVisit(dcn);
@ -297,11 +295,12 @@ public interface DisplayableItemNodeVisitor<T> {
public T visit(ResultsNode rn) {
return defaultVisit(rn);
}
@Override
public T visit(FileTypesNode ft) {
return defaultVisit(ft);
}
@Override
public T visit(DataSourcesNode in) {
return defaultVisit(in);
@ -426,6 +425,7 @@ public interface DisplayableItemNodeVisitor<T> {
public T visit(Accounts.BINNode node) {
return defaultVisit(node);
}
@Override
public T visit(Accounts.DefaultAccountTypeNode node) {
return defaultVisit(node);

View File

@ -25,20 +25,6 @@ public final class EmptyNode extends AbstractNode {
}
/**
* Method to check if the node in question is a ByMimeTypeNode which is empty.
*
* @param originNode the Node which you wish to check.
* @return True if originNode is an instance of ByMimeTypeNode and is empty, false otherwise.
*/
public static boolean isEmptyMimeTypeNode(Node originNode) {
boolean isEmptyMimeNode = false;
if (originNode instanceof FileTypesByMimeType.ByMimeTypeNode && ((FileTypesByMimeType.ByMimeTypeNode) originNode).isEmpty()) {
isEmptyMimeNode = true;
}
return isEmptyMimeNode;
}
static class EmptyChildFactory extends ChildFactory<String> {
String fileIdMsg; //NON-NLS

View File

@ -1,277 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
import org.sleuthkit.autopsy.datamodel.accounts.FileTypeExtensionFilters;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Node for a specific file type / extension. Children of it will be the files
* of that type.
*/
class FileTypeByExtNode extends DisplayableItemNode {
FileTypeExtensionFilters.SearchFilterInterface filter;
SleuthkitCase skCase;
// deprecated in favor of the version that takes an observable to provide refresh updates
@Deprecated
FileTypeByExtNode(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase) {
super(Children.create(new FileTypeChildFactory(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
this.filter = filter;
this.skCase = skCase;
init();
}
/**
*
* @param filter Extensions that will be shown for this node
* @param skCase
* @param o Observable that sends updates when the child factories
* should refresh
*/
FileTypeByExtNode(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
super(Children.create(new FileTypeChildFactory(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName()));
this.filter = filter;
this.skCase = skCase;
init();
o.addObserver(new FileTypeNodeObserver());
}
private void init() {
super.setName(filter.getName());
updateDisplayName();
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png"); //NON-NLS
}
// update the display name when new events are fired
private class FileTypeNodeObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
updateDisplayName();
}
}
private void updateDisplayName() {
final long count = FileTypeChildFactory.calculateItems(skCase, filter);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.filterType.name"),
NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.filterType.displayName"),
NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.filterType.desc"),
filter.getDisplayName()));
String extensions = "";
for (String ext : filter.getFilter()) {
extensions += "'" + ext + "', ";
}
extensions = extensions.substring(0, extensions.lastIndexOf(','));
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.fileExt.name"),
NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.fileExt.displayName"),
NbBundle.getMessage(this.getClass(), "FileTypeByExtNode.createSheet.fileExt.desc"),
extensions));
return s;
}
@Override
public boolean isLeafTypeNode() {
return true;
}
/**
* Consider allowing different configurations for Images, Videos, etc
* (in which case we'd return getClass().getName() + filter.getName()
* for all filters).
*/
@Override
public String getItemType() {
return DisplayableItemNode.FILE_PARENT_NODE_KEY;
}
/**
* Child node factory for a specific file type - does the database query.
*/
private static class FileTypeChildFactory extends ChildFactory.Detachable<Content> {
private final SleuthkitCase skCase;
private final FileTypeExtensionFilters.SearchFilterInterface filter;
private final static Logger LOGGER = Logger.getLogger(FileTypeChildFactory.class.getName());
private final Observable notifier;
// use the constructor that gets an observable passed in for updates
@Deprecated
FileTypeChildFactory(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase) {
super();
this.filter = filter;
this.skCase = skCase;
notifier = null;
}
/**
*
* @param filter Extensions to display
* @param skCase
* @param o Observable that will notify when there could be new
* data to display
*/
private FileTypeChildFactory(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
super();
this.filter = filter;
this.skCase = skCase;
notifier = o;
}
@Override
protected void addNotify() {
if (notifier != null) {
notifier.addObserver(observer);
}
}
@Override
protected void removeNotify() {
if (notifier != null) {
notifier.deleteObserver(observer);
}
}
private final Observer observer = new FileTypeChildFactoryObserver();
// Cause refresh of children if there are changes
private class FileTypeChildFactoryObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
}
/**
* Get children count without actually loading all nodes
*
* @return
*/
private static long calculateItems(SleuthkitCase sleuthkitCase, FileTypeExtensionFilters.SearchFilterInterface filter) {
try {
return sleuthkitCase.countFilesWhere(createQuery(filter));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting file search view count", ex); //NON-NLS
return 0;
}
}
@Override
protected boolean createKeys(List<Content> list) {
try {
List<AbstractFile> files = skCase.findAllFilesWhere(createQuery(filter));
list.addAll(files);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Couldn't get search results", ex); //NON-NLS
}
return true;
}
private static String createQuery(FileTypeExtensionFilters.SearchFilterInterface filter) {
StringBuilder query = new StringBuilder();
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
if (UserPreferences.hideKnownFilesInViewsTree()) {
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
}
query.append(" AND (NULL"); //NON-NLS
for (String s : filter.getFilter()) {
query.append(" OR LOWER(name) LIKE LOWER('%").append(s).append("')"); //NON-NLS
}
query.append(')');
return query.toString();
}
@Override
protected Node createNodeForKey(Content key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {
@Override
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LayoutFileNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);
}
@Override
public LocalFileNode visit(DerivedFile df) {
return new LocalFileNode(df);
}
@Override
public LocalFileNode visit(LocalFile lf) {
return new LocalFileNode(lf);
}
@Override
protected AbstractNode defaultVisit(Content di) {
throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(), "FileTypeChildren.exception.notSupported.msg", di.toString()));
}
});
}
}
}

View File

@ -24,6 +24,9 @@ import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
@ -31,8 +34,20 @@ import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Node for root of file types view. Children are nodes for specific types.
@ -41,14 +56,15 @@ class FileTypesByExtNode extends DisplayableItemNode {
private static final String FNAME = NbBundle.getMessage(FileTypesByExtNode.class, "FileTypesByExtNode.fname.text");
private final FileTypeExtensionFilters.RootFilter filter;
/**
*
* @param skCase
* @param filter null to display root node of file type tree, pass in
* something to provide a sub-node.
* something to provide a sub-node.
*/
FileTypesByExtNode(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter) {
super(Children.create(new FileTypesByExtChildren(skCase, filter, null), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
super(Children.create(new ByExtChildren(skCase, filter, null), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
this.filter = filter;
init();
}
@ -57,11 +73,11 @@ class FileTypesByExtNode extends DisplayableItemNode {
*
* @param skCase
* @param filter
* @param o Observable that was created by a higher-level node that
* provides updates on events
* @param o Observable that was created by a higher-level node that provides
* updates on events
*/
private FileTypesByExtNode(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) {
super(Children.create(new FileTypesByExtChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
super(Children.create(new ByExtChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
this.filter = filter;
init();
}
@ -108,21 +124,23 @@ class FileTypesByExtNode extends DisplayableItemNode {
@Override
public String getItemType() {
/**
* Because Documents and Executable are further expandable, their
* column order settings should be stored separately.
* Because Documents and Executable are further expandable, their column
* order settings should be stored separately.
*/
if(filter == null)
if (filter == null) {
return getClass().getName();
if (filter.equals(FileTypeExtensionFilters.RootFilter.TSK_DOCUMENT_FILTER) ||
filter.equals(FileTypeExtensionFilters.RootFilter.TSK_EXECUTABLE_FILTER))
}
if (filter.equals(FileTypeExtensionFilters.RootFilter.TSK_DOCUMENT_FILTER)
|| filter.equals(FileTypeExtensionFilters.RootFilter.TSK_EXECUTABLE_FILTER)) {
return getClass().getName() + filter.getName();
}
return getClass().getName();
}
/**
*
*/
private static class FileTypesByExtChildren extends ChildFactory<FileTypeExtensionFilters.SearchFilterInterface> {
private static class ByExtChildren extends ChildFactory<FileTypeExtensionFilters.SearchFilterInterface> {
private final SleuthkitCase skCase;
private final FileTypeExtensionFilters.RootFilter filter;
@ -132,15 +150,15 @@ class FileTypesByExtNode extends DisplayableItemNode {
*
* @param skCase
* @param filter Is null for root node
* @param o Observable that provides updates based on events being
* fired (or null if one needs to be created)
* @param o Observable that provides updates based on events being fired
* (or null if one needs to be created)
*/
private FileTypesByExtChildren(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) {
private ByExtChildren(SleuthkitCase skCase, FileTypeExtensionFilters.RootFilter filter, Observable o) {
super();
this.skCase = skCase;
this.filter = filter;
if (o == null) {
this.notifier = new FileTypesByExtChildrenObservable();
this.notifier = new ByExtChildrenObservable();
} else {
this.notifier = o;
}
@ -150,9 +168,9 @@ 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 FileTypesByExtChildrenObservable extends Observable {
private final class ByExtChildrenObservable extends Observable {
private FileTypesByExtChildrenObservable() {
private ByExtChildrenObservable() {
IngestManager.getInstance().addIngestJobEventListener(pcl);
IngestManager.getInstance().addIngestModuleEventListener(pcl);
Case.addPropertyChangeListener(pcl);
@ -224,7 +242,231 @@ class FileTypesByExtNode extends DisplayableItemNode {
} else if (key.getName().equals(FileTypeExtensionFilters.RootFilter.TSK_EXECUTABLE_FILTER.getName())) {
return new FileTypesByExtNode(skCase, FileTypeExtensionFilters.RootFilter.TSK_EXECUTABLE_FILTER, notifier);
} else {
return new FileTypeByExtNode(key, skCase, notifier);
return new ByExtNode(key, skCase, notifier);
}
}
}
/**
* Node for a specific file type / extension. Children of it will be the
* files of that type.
*/
static class ByExtNode extends DisplayableItemNode {
FileTypeExtensionFilters.SearchFilterInterface filter;
SleuthkitCase skCase;
/**
*
* @param filter Extensions that will be shown for this node
* @param skCase
* @param o Observable that sends updates when the child factories
* should refresh
*/
ByExtNode(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
super(Children.create(new ByExtChildFactory(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName()));
this.filter = filter;
this.skCase = skCase;
init();
o.addObserver(new ByExtNodeObserver());
}
private void init() {
super.setName(filter.getName());
updateDisplayName();
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png"); //NON-NLS
}
// update the display name when new events are fired
private class ByExtNodeObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
updateDisplayName();
}
}
private void updateDisplayName() {
final long count = ByExtChildFactory.calculateItems(skCase, filter);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.name"),
NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.displayName"),
NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.desc"),
filter.getDisplayName()));
String extensions = "";
for (String ext : filter.getFilter()) {
extensions += "'" + ext + "', ";
}
extensions = extensions.substring(0, extensions.lastIndexOf(','));
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.name"),
NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.displayName"),
NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.desc"),
extensions));
return s;
}
@Override
public boolean isLeafTypeNode() {
return true;
}
/**
* Consider allowing different configurations for Images, Videos, etc
* (in which case we'd return getClass().getName() + filter.getName()
* for all filters).
*/
@Override
public String getItemType() {
return DisplayableItemNode.FILE_PARENT_NODE_KEY;
}
/**
* Child node factory for a specific file type - does the database
* query.
*/
private static class ByExtChildFactory extends ChildFactory.Detachable<Content> {
private final SleuthkitCase skCase;
private final FileTypeExtensionFilters.SearchFilterInterface filter;
private final static Logger LOGGER = Logger.getLogger(ByExtChildFactory.class.getName());
private final Observable notifier;
// use the constructor that gets an observable passed in for updates
@Deprecated
ByExtChildFactory(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase) {
super();
this.filter = filter;
this.skCase = skCase;
notifier = null;
}
/**
*
* @param filter Extensions to display
* @param skCase
* @param o Observable that will notify when there could be new data
* to display
*/
private ByExtChildFactory(FileTypeExtensionFilters.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
super();
this.filter = filter;
this.skCase = skCase;
notifier = o;
}
@Override
protected void addNotify() {
if (notifier != null) {
notifier.addObserver(observer);
}
}
@Override
protected void removeNotify() {
if (notifier != null) {
notifier.deleteObserver(observer);
}
}
private final Observer observer = new FileTypeChildFactoryObserver();
// Cause refresh of children if there are changes
private class FileTypeChildFactoryObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
}
/**
* Get children count without actually loading all nodes
*
* @return
*/
private static long calculateItems(SleuthkitCase sleuthkitCase, FileTypeExtensionFilters.SearchFilterInterface filter) {
try {
return sleuthkitCase.countFilesWhere(createQuery(filter));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting file search view count", ex); //NON-NLS
return 0;
}
}
@Override
protected boolean createKeys(List<Content> list) {
try {
List<AbstractFile> files = skCase.findAllFilesWhere(createQuery(filter));
list.addAll(files);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Couldn't get search results", ex); //NON-NLS
}
return true;
}
private static String createQuery(FileTypeExtensionFilters.SearchFilterInterface filter) {
StringBuilder query = new StringBuilder();
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
if (UserPreferences.hideKnownFilesInViewsTree()) {
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
}
query.append(" AND (NULL"); //NON-NLS
for (String s : filter.getFilter()) {
query.append(" OR LOWER(name) LIKE LOWER('%").append(s).append("')"); //NON-NLS
}
query.append(')');
return query.toString();
}
@Override
protected Node createNodeForKey(Content key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {
@Override
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LayoutFileNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);
}
@Override
public LocalFileNode visit(DerivedFile df) {
return new LocalFileNode(df);
}
@Override
public LocalFileNode visit(LocalFile lf) {
return new LocalFileNode(lf);
}
@Override
protected AbstractNode defaultVisit(Content di) {
throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(), "FileTypeChildren.exception.notSupported.msg", di.toString()));
}
});
}
}
}

View File

@ -57,7 +57,7 @@ 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 final class FileTypesByMimeType extends Observable implements AutopsyVisitableItem {
private final SleuthkitCase SKCASE;
/**
@ -167,315 +167,334 @@ class FileTypesByMimeType extends Observable implements AutopsyVisitableItem {
return v.visit(this);
}
/**
* Class which represents the root node of the "By MIME Type" tree, will have
* children of each media type present in the database or no children when the
* file detection module has not been run and MIME type is currently unknown.
*/
class ByMimeTypeNode extends DisplayableItemNode {
@NbBundle.Messages("FileTypesByMimeType.name.text=By MIME Type")
final String NAME = Bundle.FileTypesByMimeType_name_text();
ByMimeTypeNode() {
super(Children.create(new ByMimeTypeNodeChildren(), true));
super.setName(NAME);
super.setDisplayName(NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
}
@Override
public boolean isLeafTypeNode() {
return false;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
boolean isEmpty() {
return existingMimeTypes.isEmpty();
}
}
/**
* Creates the children for the "By MIME Type" node these children will each
* represent a distinct media type present in the DB
*/
private class ByMimeTypeNodeChildren extends ChildFactory<String> implements Observer {
private ByMimeTypeNodeChildren() {
super();
addObserver(this);
}
@Override
protected boolean createKeys(List<String> mediaTypeNodes) {
if (!existingMimeTypes.isEmpty()) {
mediaTypeNodes.addAll(getMediaTypeList());
/**
* Method to check if the node in question is a ByMimeTypeNode which is
* empty.
*
* @param originNode the Node which you wish to check.
* @return True if originNode is an instance of ByMimeTypeNode and is empty,
* false otherwise.
*/
public static boolean isEmptyMimeTypeNode(Node originNode) {
boolean isEmptyMimeNode = false;
if (originNode instanceof FileTypesByMimeType.ByMimeTypeNode && ((FileTypesByMimeType.ByMimeTypeNode) originNode).isEmpty()) {
isEmptyMimeNode = true;
}
return true;
}
@Override
protected Node createNodeForKey(String key) {
return new MediaTypeNode(key);
}
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
}
/**
* The Media type node created by the ByMimeTypeNodeChildren and
contains one of the unique media types present in the database for this case.
*/
class MediaTypeNode extends DisplayableItemNode {
MediaTypeNode(String name) {
super(Children.create(new MediaTypeNodeChildren(name), true));
setName(name);
setDisplayName(name);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
}
@Override
public boolean isLeafTypeNode() {
return false;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
}
/**
* Creates children for media type nodes, children will be MediaSubTypeNodes and
* represent one of the subtypes which are present in the database of their
* media type.
*/
private class MediaTypeNodeChildren extends ChildFactory<String> implements Observer {
String mediaType;
MediaTypeNodeChildren(String name) {
addObserver(this);
this.mediaType = name;
}
@Override
protected boolean createKeys(List<String> mediaTypeNodes) {
mediaTypeNodes.addAll(existingMimeTypes.get(mediaType));
return true;
}
@Override
protected Node createNodeForKey(String subtype) {
String mimeType = mediaType + "/" + subtype;
return new MediaSubTypeNode(mimeType);
}
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
}
/**
* Node which represents the media sub type in the By MIME type tree, the media
* subtype is the portion of the MIME type following the /.
*/
class MediaSubTypeNode extends DisplayableItemNode implements Observer {
private MediaSubTypeNode(String mimeType) {
super(Children.create(new MediaSubTypeNodeChildren(mimeType), true));
addObserver(this);
init(mimeType);
}
private void init(String mimeType) {
super.setName(mimeType);
updateDisplayName(mimeType);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png"); //NON-NLS
return isEmptyMimeNode;
}
/**
* Updates the display name of the mediaSubTypeNode to include the count of
* files which it represents.
*
* @param mimeType - the complete MimeType, needed for accurate query
* results
* Class which represents the root node of the "By MIME Type" tree, will
* have children of each media type present in the database or no children
* when the file detection module has not been run and MIME type is
* currently unknown.
*/
private void updateDisplayName(String mimeType) {
class ByMimeTypeNode extends DisplayableItemNode {
final long count = new MediaSubTypeNodeChildren(mimeType).calculateItems(SKCASE, mimeType);
@NbBundle.Messages("FileTypesByMimeType.name.text=By MIME Type")
final String NAME = Bundle.FileTypesByMimeType_name_text();
ByMimeTypeNode() {
super(Children.create(new ByMimeTypeNodeChildren(), true));
super.setName(NAME);
super.setDisplayName(NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
}
@Override
public boolean isLeafTypeNode() {
return false;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
boolean isEmpty() {
return existingMimeTypes.isEmpty();
}
super.setDisplayName(mimeType.split("/")[1] + " (" + count + ")");
}
/**
* This returns true because any MediaSubTypeNode that exists is going to be
* a bottom level node in the Tree view on the left of Autopsy.
*
* @return true
* Creates the children for the "By MIME Type" node these children will each
* represent a distinct media type present in the DB
*/
@Override
public boolean isLeafTypeNode() {
return true;
}
private class ByMimeTypeNodeChildren extends ChildFactory<String> implements Observer {
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
private ByMimeTypeNodeChildren() {
super();
addObserver(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
@Override
protected boolean createKeys(List<String> mediaTypeNodes) {
if (!existingMimeTypes.isEmpty()) {
mediaTypeNodes.addAll(getMediaTypeList());
}
return true;
}
@Override
public void update(Observable o, Object arg) {
updateDisplayName(getName());
}
}
@Override
protected Node createNodeForKey(String key) {
return new MediaTypeNode(key);
}
/**
* Factory for populating the contents of the Media Sub Type Node with the files
* that match MimeType which is represented by this position in the tree.
*/
private class MediaSubTypeNodeChildren extends ChildFactory.Detachable<Content> implements Observer {
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
private final String mimeType;
private MediaSubTypeNodeChildren(String mimeType) {
super();
addObserver(this);
this.mimeType = mimeType;
}
/**
* Get children count without actually loading all nodes
*
* @return count(*) - the number of items that will be shown in this items
* Directory Listing
* The Media type node created by the ByMimeTypeNodeChildren and contains
* one of the unique media types present in the database for this case.
*/
private long calculateItems(SleuthkitCase sleuthkitCase, String mime_type) {
try {
return sleuthkitCase.countFilesWhere(createQuery(mime_type));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting file search view count", ex); //NON-NLS
return 0;
class MediaTypeNode extends DisplayableItemNode {
MediaTypeNode(String name) {
super(Children.create(new MediaTypeNodeChildren(name), true));
setName(name);
setDisplayName(name);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
}
@Override
public boolean isLeafTypeNode() {
return false;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
}
/**
* Creates children for media type nodes, children will be MediaSubTypeNodes
* and represent one of the subtypes which are present in the database of
* their media type.
*/
private class MediaTypeNodeChildren extends ChildFactory<String> implements Observer {
String mediaType;
MediaTypeNodeChildren(String name) {
addObserver(this);
this.mediaType = name;
}
@Override
protected boolean createKeys(List<String> mediaTypeNodes) {
mediaTypeNodes.addAll(existingMimeTypes.get(mediaType));
return true;
}
@Override
protected Node createNodeForKey(String subtype) {
String mimeType = mediaType + "/" + subtype;
return new MediaSubTypeNode(mimeType);
}
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
}
/**
* Node which represents the media sub type in the By MIME type tree, the
* media subtype is the portion of the MIME type following the /.
*/
class MediaSubTypeNode extends DisplayableItemNode implements Observer {
private MediaSubTypeNode(String mimeType) {
super(Children.create(new MediaSubTypeNodeChildren(mimeType), true));
addObserver(this);
init(mimeType);
}
private void init(String mimeType) {
super.setName(mimeType);
updateDisplayName(mimeType);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png"); //NON-NLS
}
/**
* Updates the display name of the mediaSubTypeNode to include the count
* of files which it represents.
*
* @param mimeType - the complete MimeType, needed for accurate query
* results
*/
private void updateDisplayName(String mimeType) {
final long count = new MediaSubTypeNodeChildren(mimeType).calculateItems(SKCASE, mimeType);
super.setDisplayName(mimeType.split("/")[1] + " (" + count + ")");
}
/**
* This returns true because any MediaSubTypeNode that exists is going
* to be a bottom level node in the Tree view on the left of Autopsy.
*
* @return true
*/
@Override
public boolean isLeafTypeNode() {
return true;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
@Override
public void update(Observable o, Object arg) {
updateDisplayName(getName());
}
}
/**
* Uses the createQuery method to complete the query, Select * from
* tsk_files WHERE. The results from the database will contain the files
* which match this mime type and their information.
*
* @param list - will contain all files and their attributes from the
* tsk_files table where mime_type matches the one specified
* @return true
* Factory for populating the contents of the Media Sub Type Node with the
* files that match MimeType which is represented by this position in the
* tree.
*/
@Override
protected boolean createKeys(List<Content> list) {
try {
List<AbstractFile> files = SKCASE.findAllFilesWhere(createQuery(mimeType));
list.addAll(files);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Couldn't get search results", ex); //NON-NLS
private class MediaSubTypeNodeChildren extends ChildFactory.Detachable<Content> implements Observer {
private final String mimeType;
private MediaSubTypeNodeChildren(String mimeType) {
super();
addObserver(this);
this.mimeType = mimeType;
}
return true;
}
/**
* Create the portion of the query following WHERE for a query of the
* database for each file which matches the complete MIME type represented
* by this node. Matches against the mime_type column in tsk_files.
*
* @param mimeType - the complete mimetype of the file mediatype/subtype
* @return query.toString - portion of SQL query which will follow a WHERE
* clause.
*/
private String createQuery(String mime_type) {
StringBuilder query = new StringBuilder();
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
query.append(" AND (type IN (").append(TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal()).append(","); //NON-NLS
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal()).append(",");
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal()).append(",");
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()).append("))");
if (UserPreferences.hideKnownFilesInViewsTree()) {
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
/**
* Get children count without actually loading all nodes
*
* @return count(*) - the number of items that will be shown in this
* items Directory Listing
*/
private long calculateItems(SleuthkitCase sleuthkitCase, String mime_type) {
try {
return sleuthkitCase.countFilesWhere(createQuery(mime_type));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting file search view count", ex); //NON-NLS
return 0;
}
}
/**
* Uses the createQuery method to complete the query, Select * from
* tsk_files WHERE. The results from the database will contain the files
* which match this mime type and their information.
*
* @param list - will contain all files and their attributes from the
* tsk_files table where mime_type matches the one specified
* @return true
*/
@Override
protected boolean createKeys(List<Content> list) {
try {
List<AbstractFile> files = SKCASE.findAllFilesWhere(createQuery(mimeType));
list.addAll(files);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Couldn't get search results", ex); //NON-NLS
}
return true;
}
/**
* Create the portion of the query following WHERE for a query of the
* database for each file which matches the complete MIME type
* represented by this node. Matches against the mime_type column in
* tsk_files.
*
* @param mimeType - the complete mimetype of the file mediatype/subtype
* @return query.toString - portion of SQL query which will follow a
* WHERE clause.
*/
private String createQuery(String mime_type) {
StringBuilder query = new StringBuilder();
query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
query.append(" AND (type IN (").append(TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal()).append(","); //NON-NLS
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal()).append(",");
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal()).append(",");
query.append(TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()).append("))");
if (UserPreferences.hideKnownFilesInViewsTree()) {
query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
}
query.append(" AND mime_type = '").append(mime_type).append("'"); //NON-NLS
return query.toString();
}
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
/**
* Creates the content to populate the Directory Listing Table view for
* each file
*
* @param key
* @return
*/
@Override
protected Node createNodeForKey(Content key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {
@Override
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LayoutFileNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);
}
@Override
public LocalFileNode visit(DerivedFile df) {
return new LocalFileNode(df);
}
@Override
public LocalFileNode visit(LocalFile lf) {
return new LocalFileNode(lf);
}
@Override
protected AbstractNode defaultVisit(Content di) {
throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(), "FileTypeChildren.exception.notSupported.msg", di.toString()));
}
});
}
query.append(" AND mime_type = '").append(mime_type).append("'"); //NON-NLS
return query.toString();
}
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
/**
* Creates the content to populate the Directory Listing Table view for each
* file
*
* @param key
* @return
*/
@Override
protected Node createNodeForKey(Content key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {
@Override
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LayoutFileNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);
}
@Override
public LocalFileNode visit(DerivedFile df) {
return new LocalFileNode(df);
}
@Override
public LocalFileNode visit(LocalFile lf) {
return new LocalFileNode(lf);
}
@Override
protected AbstractNode defaultVisit(Content di) {
throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(), "FileTypeChildren.exception.notSupported.msg", di.toString()));
}
});
}
}
}

View File

@ -63,6 +63,7 @@ import org.sleuthkit.autopsy.datamodel.DataSources;
import org.sleuthkit.autopsy.datamodel.DataSourcesNode;
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
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;
@ -134,7 +135,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
refreshContentTreeSafe();
break;
case UserPreferences.HIDE_KNOWN_FILES_IN_VIEWS_TREE:
case UserPreferences.HIDE_SLACK_FILES_IN_VIEWS_TREE:
case UserPreferences.HIDE_SLACK_FILES_IN_VIEWS_TREE:
// TODO: Need a way to refresh the Views subtree
break;
}
@ -602,7 +603,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
}
}
}
@NbBundle.Messages("DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.")
/**
* Event handler to run when selection changed
@ -645,12 +646,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
Node kffn = new KnownFileFilterNode(drfn, KnownFileFilterNode.getSelectionContext(originNode));
Node sffn = new SlackFileFilterNode(kffn, SlackFileFilterNode.getSelectionContext(originNode));
// Create a TableFilterNode with knowledge of the node's type to allow for column order settings
//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 (EmptyNode.isEmptyMimeTypeNode(originNode)) {
if (FileTypesByMimeType.isEmptyMimeTypeNode(originNode)) {
EmptyNode emptyNode = new EmptyNode(Bundle.DirectoryTreeTopComponent_emptyMimeNode_text());
Node emptyDrfn = new DataResultFilterNode(emptyNode, DirectoryTreeTopComponent.this.em);
Node emptyKffn = new KnownFileFilterNode(emptyDrfn, KnownFileFilterNode.getSelectionContext(emptyNode));