Merge pull request #2896 from millmanorama/2781-file-tye-count-threshold

stop showing counts in file type tree once there are more than 200k files…
This commit is contained in:
Richard Cordovano 2017-06-28 12:42:45 -04:00 committed by GitHub
commit 8bcade9280
2 changed files with 120 additions and 64 deletions

View File

@ -53,6 +53,8 @@ import org.sleuthkit.datamodel.TskData;
*/ */
public final class FileTypesByExtension implements AutopsyVisitableItem { public final class FileTypesByExtension implements AutopsyVisitableItem {
private static final Logger LOGGER = Logger.getLogger(FileTypesByExtension.class.getName());
private final SleuthkitCase skCase; private final SleuthkitCase skCase;
public FileTypesByExtension(SleuthkitCase skCase) { public FileTypesByExtension(SleuthkitCase skCase) {
@ -72,33 +74,25 @@ import org.sleuthkit.datamodel.TskData;
* Listens for case and ingest invest. Updates observers when events are * Listens for case and ingest invest. Updates observers when events are
* fired. FileType and FileTypes nodes are all listening to this. * fired. FileType and FileTypes nodes are all listening to this.
*/ */
private static class FileTypesByExtObservable extends Observable { static private class FileTypesByExtObservable extends Observable {
private FileTypesByExtObservable() { private boolean showCounts = true;
private final PropertyChangeListener pcl;
private FileTypesByExtObservable(SleuthkitCase skCase) {
super(); super();
IngestManager.getInstance().addIngestJobEventListener(pcl); this.pcl = (PropertyChangeEvent evt) -> {
IngestManager.getInstance().addIngestModuleEventListener(pcl);
Case.addPropertyChangeListener(pcl);
}
private void removeListeners() {
deleteObservers();
IngestManager.getInstance().removeIngestJobEventListener(pcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
Case.removePropertyChangeListener(pcl);
}
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString()) || eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString()) || eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
/** /**
* Checking for a current case is a stop gap measure until a * Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked out. * different way of handling the closing of cases is worked
* Currently, remote events may be received for a case that is * out. Currently, remote events may be received for a case
* already closed. * that is already closed.
*/ */
try { try {
Case.getCurrentCase(); Case.getCurrentCase();
shouldShowCounts(skCase);
update(); update();
} catch (IllegalStateException notUsed) { } catch (IllegalStateException notUsed) {
/** /**
@ -113,6 +107,39 @@ import org.sleuthkit.datamodel.TskData;
} }
}; };
IngestManager.getInstance().addIngestJobEventListener(pcl);
IngestManager.getInstance().addIngestModuleEventListener(pcl);
Case.addPropertyChangeListener(pcl);
}
/**
* Should the nodes show counts?
*
*
* @return True, unless the DB has more than 200k rows.
*/
private boolean shouldShowCounts(SleuthkitCase skCase) {
if (showCounts) {
try {
if (skCase.countFilesWhere("1=1") > 200000) {
showCounts = false;
}
} catch (TskCoreException tskCoreException) {
showCounts = false;
LOGGER.log(Level.SEVERE, "Error counting files.", tskCoreException);
}
}
return showCounts;
}
private void removeListeners() {
deleteObservers();
IngestManager.getInstance().removeIngestJobEventListener(pcl);
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
Case.removePropertyChangeListener(pcl);
}
private void update() { private void update() {
setChanged(); setChanged();
notifyObservers(); notifyObservers();
@ -146,7 +173,7 @@ import org.sleuthkit.datamodel.TskData;
* @param o Observable that was created by a higher-level node that * @param o Observable that was created by a higher-level node that
* provides updates on events * provides updates on events
*/ */
private FileTypesByExtNode(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, Observable o) { private FileTypesByExtNode(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, FileTypesByExtObservable o) {
super(Children.create(new FileTypesByExtNodeChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName())); super(Children.create(new FileTypesByExtNodeChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
this.filter = filter; this.filter = filter;
init(); init();
@ -206,7 +233,7 @@ import org.sleuthkit.datamodel.TskData;
private final SleuthkitCase skCase; private final SleuthkitCase skCase;
private final FileTypesByExtension.RootFilter filter; private final FileTypesByExtension.RootFilter filter;
private final Observable notifier; private final FileTypesByExtObservable notifier;
/** /**
* *
@ -215,12 +242,12 @@ import org.sleuthkit.datamodel.TskData;
* @param o Observable that provides updates based on events * @param o Observable that provides updates based on events
* being fired (or null if one needs to be created) * being fired (or null if one needs to be created)
*/ */
private FileTypesByExtNodeChildren(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, Observable o) { private FileTypesByExtNodeChildren(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, FileTypesByExtObservable o) {
super(); super();
this.skCase = skCase; this.skCase = skCase;
this.filter = filter; this.filter = filter;
if (o == null) { if (o == null) {
this.notifier = new FileTypesByExtObservable(); this.notifier = new FileTypesByExtObservable(skCase);
} else { } else {
this.notifier = o; this.notifier = o;
} }
@ -263,6 +290,7 @@ import org.sleuthkit.datamodel.TskData;
FileTypesByExtension.SearchFilterInterface filter; FileTypesByExtension.SearchFilterInterface filter;
SleuthkitCase skCase; SleuthkitCase skCase;
private final FileTypesByExtObservable notifier;
/** /**
* *
@ -271,10 +299,11 @@ import org.sleuthkit.datamodel.TskData;
* @param o Observable that sends updates when the child factories * @param o Observable that sends updates when the child factories
* should refresh * should refresh
*/ */
FileExtensionNode(FileTypesByExtension.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) { FileExtensionNode(FileTypesByExtension.SearchFilterInterface filter, SleuthkitCase skCase, FileTypesByExtObservable o) {
super(Children.create(new FileExtensionNodeChildren(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName())); super(Children.create(new FileExtensionNodeChildren(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName()));
this.filter = filter; this.filter = filter;
this.skCase = skCase; this.skCase = skCase;
this.notifier = o;
init(); init();
o.addObserver(new ByExtNodeObserver()); o.addObserver(new ByExtNodeObserver());
} }
@ -295,8 +324,10 @@ import org.sleuthkit.datamodel.TskData;
} }
private void updateDisplayName() { private void updateDisplayName() {
final long count = FileExtensionNodeChildren.calculateItems(skCase, filter); final String count = notifier.shouldShowCounts(skCase)
super.setDisplayName(filter.getDisplayName() + " (" + count + ")"); ? " (" + Long.toString(FileExtensionNodeChildren.calculateItems(skCase, filter)) + ")"
: "";
super.setDisplayName(filter.getDisplayName() + count);
} }
@Override @Override

View File

@ -71,41 +71,18 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
private final HashMap<String, List<String>> existingMimeTypes = new HashMap<>(); private final HashMap<String, List<String>> existingMimeTypes = new HashMap<>();
private static final Logger LOGGER = Logger.getLogger(FileTypesByMimeType.class.getName()); private static final Logger LOGGER = Logger.getLogger(FileTypesByMimeType.class.getName());
private boolean showCounts = true;
private void removeListeners() { private void removeListeners() {
deleteObservers(); deleteObservers();
IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestJobEventListener(pcl);
Case.removePropertyChangeListener(pcl); Case.removePropertyChangeListener(pcl);
} }
/* /*
* The pcl is in the class because it has the easiest mechanisms to add and * The pcl is in the class because it has the easiest mechanisms to add and
* remove itself during its life cycles. * remove itself during its life cycles.
*/ */
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { private final PropertyChangeListener pcl;
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked out.
* Currently, remote events may be received for a case that is
* already closed.
*/
try {
Case.getCurrentCase();
populateHashMap();
} catch (IllegalStateException notUsed) {
/**
* Case is closed, do nothing.
*/
}
} else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
if (evt.getNewValue() == null) {
removeListeners();
}
}
};
/** /**
* Retrieve the media types by retrieving the keyset from the hashmap. * Retrieve the media types by retrieving the keyset from the hashmap.
@ -140,7 +117,6 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
existingMimeTypes.clear(); existingMimeTypes.clear();
if (skCase == null) { if (skCase == null) {
return; return;
} }
try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(allDistinctMimeTypesQuery.toString())) { try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(allDistinctMimeTypesQuery.toString())) {
@ -170,12 +146,59 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
} }
FileTypesByMimeType(SleuthkitCase skCase) { FileTypesByMimeType(SleuthkitCase skCase) {
this.pcl = (PropertyChangeEvent evt) -> {
String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
/**
* Checking for a current case is a stop gap measure until a
* different way of handling the closing of cases is worked out.
* Currently, remote events may be received for a case that is
* already closed.
*/
try {
Case.getCurrentCase();
shouldShowCounts(skCase);
populateHashMap();
} catch (IllegalStateException notUsed) {
/**
* Case is closed, do nothing.
*/
}
} else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
if (evt.getNewValue() == null) {
removeListeners();
}
}
};
IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestJobEventListener(pcl);
Case.addPropertyChangeListener(pcl); Case.addPropertyChangeListener(pcl);
this.skCase = skCase; this.skCase = skCase;
populateHashMap(); populateHashMap();
} }
/**
* Should the nodes show counts?
*
*
* @return True, unless the DB has more than 200k rows.
*/
private boolean shouldShowCounts(final SleuthkitCase skCase) {
if (showCounts) {
try {
if (skCase.countFilesWhere("1=1") > 200000) {
showCounts = false;
}
} catch (TskCoreException tskCoreException) {
showCounts = false;
LOGGER.log(Level.SEVERE, "Error counting files.", tskCoreException);
}
}
return showCounts;
}
@Override @Override
public <T> T accept(AutopsyItemVisitor<T> v) { public <T> T accept(AutopsyItemVisitor<T> v) {
return v.visit(this); return v.visit(this);
@ -358,10 +381,12 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
* results * results
*/ */
private void updateDisplayName(String mimeType) { private void updateDisplayName(String mimeType) {
final long count = new MediaSubTypeNodeChildren(mimeType).calculateItems(skCase, mimeType); final String count = shouldShowCounts(skCase)
? " (" + Long.toString(new MediaSubTypeNodeChildren(mimeType).calculateItems(skCase, mimeType)) + ")"
: "";
String[] mimeTypeParts = mimeType.split("/"); String[] mimeTypeParts = mimeType.split("/");
//joins up all remaining parts of the mimeType into one sub-type string //joins up all remaining parts of the mimeType into one sub-type string
super.setDisplayName(StringUtils.join(ArrayUtils.subarray(mimeTypeParts, 1, mimeTypeParts.length), "/") + " (" + count + ")"); super.setDisplayName(StringUtils.join(ArrayUtils.subarray(mimeTypeParts, 1, mimeTypeParts.length), "/") + count);
} }
/** /**