mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
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:
commit
8bcade9280
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user