mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 17:57:43 +00:00
Merge remote-tracking branch 'upstream/release-4.4.1' into develop
This commit is contained in:
commit
a13c95e1b8
@ -74,12 +74,12 @@ public final class FileTypes implements AutopsyVisitableItem {
|
||||
boolean shouldShowCounts() {
|
||||
if (showCounts) {
|
||||
try {
|
||||
if (skCase.countFilesWhere("1=1") > 200000) {
|
||||
if (skCase.countFilesWhere("1=1") > 200000) { //NON-NLS
|
||||
showCounts = false;
|
||||
}
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
showCounts = false;
|
||||
logger.log(Level.SEVERE, "Error counting files.", tskCoreException);
|
||||
logger.log(Level.SEVERE, "Error counting files.", tskCoreException); //NON-NLS
|
||||
}
|
||||
}
|
||||
return showCounts;
|
||||
@ -96,10 +96,10 @@ public final class FileTypes implements AutopsyVisitableItem {
|
||||
super(new RootContentChildren(Arrays.asList(
|
||||
new FileTypesByExtension(FileTypes.this),
|
||||
new FileTypesByMimeType(FileTypes.this))),
|
||||
Lookups.singleton(NAME));
|
||||
Lookups.singleton(NAME));
|
||||
setName(NAME);
|
||||
setDisplayName(NAME);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png"); //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -184,18 +184,15 @@ public final class FileTypes implements AutopsyVisitableItem {
|
||||
static abstract class BGCountUpdatingNode extends DisplayableItemNode implements Observer {
|
||||
|
||||
private long childCount = -1;
|
||||
private final SleuthkitCase skCase;
|
||||
private FileTypes typesRoot;
|
||||
|
||||
BGCountUpdatingNode(FileTypes typesRoot, Children children) {
|
||||
this(typesRoot, children, null);
|
||||
|
||||
}
|
||||
|
||||
BGCountUpdatingNode(FileTypes typesRoot, Children children, Lookup lookup) {
|
||||
super(children, lookup);
|
||||
this.typesRoot = typesRoot;
|
||||
this.skCase = typesRoot.getSleuthkitCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -205,37 +202,44 @@ public final class FileTypes implements AutopsyVisitableItem {
|
||||
|
||||
abstract String getDisplayNameBase();
|
||||
|
||||
abstract String geQuery();
|
||||
/**
|
||||
* Calculate the number of children of this node, possibly by querying
|
||||
* the DB.
|
||||
*
|
||||
* @return @throws TskCoreException if there was an error querying the
|
||||
* DB to calculate the number of children.
|
||||
*/
|
||||
abstract long calculateChildCount() throws TskCoreException;
|
||||
|
||||
/**
|
||||
* Updates the display name of the mediaSubTypeNode to include the count
|
||||
* of files which it represents.
|
||||
*/
|
||||
@NbBundle.Messages("FileTypes.bgCounting.placeholder=(counting...)")
|
||||
void updateDisplayName() {
|
||||
if (typesRoot.shouldShowCounts()) {
|
||||
//only show "(counting...)" the first time, otherwise it is distracting.
|
||||
setDisplayName(getDisplayNameBase() + ((childCount < 0) ? "(counting...)"
|
||||
: ("(" + childCount + ")")));
|
||||
setDisplayName(getDisplayNameBase() + ((childCount < 0) ? Bundle.FileTypes_bgCounting_placeholder()
|
||||
: ("(" + childCount + ")"))); //NON-NLS
|
||||
new SwingWorker<Long, Void>() {
|
||||
@Override
|
||||
protected Long doInBackground() throws Exception {
|
||||
return skCase.countFilesWhere(geQuery());
|
||||
return calculateChildCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
childCount = get();
|
||||
setDisplayName(getDisplayNameBase() + " (" + childCount + ")");
|
||||
setDisplayName(getDisplayNameBase() + " (" + childCount + ")"); //NON-NLS
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
setDisplayName(getDisplayNameBase());
|
||||
logger.log(Level.WARNING, "Failed to get count of files for " + getDisplayNameBase(), ex);
|
||||
logger.log(Level.WARNING, "Failed to get count of files for " + getDisplayNameBase(), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
} else {
|
||||
setDisplayName(getDisplayNameBase() + ((childCount < 0) ? ""
|
||||
: ("(" + childCount + "+)")));
|
||||
setDisplayName(getDisplayNameBase() + ((childCount < 0) ? "" : ("(" + childCount + "+)"))); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,10 +325,9 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
String geQuery() {
|
||||
return createQuery(filter);
|
||||
long calculateChildCount() throws TskCoreException {
|
||||
return skCase.countFilesWhere(createQuery(filter));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String createQuery(FileTypesByExtension.SearchFilterInterface filter) {
|
||||
|
@ -26,10 +26,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
@ -50,7 +50,7 @@ import org.sleuthkit.datamodel.TskData;
|
||||
* File Types view, shows all files with a mime type. Will initially be empty
|
||||
* until file type identification has been performed. Contains a Property Change
|
||||
* Listener which is checking for changes in IngestJobEvent Completed or
|
||||
* Cancelled and IngestModuleEvent Content Changed.
|
||||
* Canceled and IngestModuleEvent Content Changed.
|
||||
*/
|
||||
public final class FileTypesByMimeType extends Observable implements AutopsyVisitableItem {
|
||||
|
||||
@ -59,9 +59,9 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
/**
|
||||
* 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
|
||||
* type as the key and a list of media subtypes as the value.
|
||||
* type as the key and a Map, from media subtype to count, as the value.
|
||||
*/
|
||||
private final HashMap<String, List<String>> existingMimeTypes = new HashMap<>();
|
||||
private final HashMap<String, Map<String, Long>> existingMimeTypeCounts = new HashMap<>();
|
||||
private static final Logger LOGGER = Logger.getLogger(FileTypesByMimeType.class.getName());
|
||||
private final FileTypes typesRoot;
|
||||
|
||||
@ -76,54 +76,40 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
*/
|
||||
private final PropertyChangeListener pcl;
|
||||
|
||||
/**
|
||||
* Retrieve the media types by retrieving the keyset from the hashmap.
|
||||
*
|
||||
* @return mediaTypes - a list of strings representing all distinct media
|
||||
* types of files for this case
|
||||
*/
|
||||
private List<String> getMediaTypeList() {
|
||||
synchronized (existingMimeTypes) {
|
||||
List<String> mediaTypes = new ArrayList<>(existingMimeTypes.keySet());
|
||||
Collections.sort(mediaTypes);
|
||||
return mediaTypes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the query on the database to get all distinct MIME types of
|
||||
* files in it, and populate the hashmap with those results.
|
||||
*/
|
||||
private void populateHashMap() {
|
||||
StringBuilder allDistinctMimeTypesQuery = new StringBuilder();
|
||||
allDistinctMimeTypesQuery.append("SELECT DISTINCT mime_type from tsk_files where mime_type IS NOT null"); //NON-NLS
|
||||
allDistinctMimeTypesQuery.append(" AND dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()); //NON-NLS
|
||||
allDistinctMimeTypesQuery.append(" AND (type IN (").append(TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal()).append(","); //NON-NLS
|
||||
allDistinctMimeTypesQuery.append(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal()).append(",");
|
||||
allDistinctMimeTypesQuery.append(TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal()).append(",");
|
||||
if (!UserPreferences.hideSlackFilesInViewsTree()) {
|
||||
allDistinctMimeTypesQuery.append(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()).append(",");
|
||||
}
|
||||
allDistinctMimeTypesQuery.append(TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()).append("))");
|
||||
synchronized (existingMimeTypes) {
|
||||
existingMimeTypes.clear();
|
||||
String query = "SELECT mime_type,count(*) as count from tsk_files "
|
||||
+ " where mime_type IS NOT null "
|
||||
+ " AND dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()
|
||||
+ " AND (type IN ("
|
||||
+ TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal() + ","
|
||||
+ TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal() + ","
|
||||
+ TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal() + ","
|
||||
+ TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()
|
||||
+ ((UserPreferences.hideSlackFilesInViewsTree()) ? ""
|
||||
: ("," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()))
|
||||
+ "))" + " GROUP BY mime_type";
|
||||
synchronized (existingMimeTypeCounts) {
|
||||
existingMimeTypeCounts.clear();
|
||||
|
||||
if (skCase == null) {
|
||||
return;
|
||||
}
|
||||
try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(allDistinctMimeTypesQuery.toString())) {
|
||||
try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(query)) {
|
||||
ResultSet resultSet = dbQuery.getResultSet();
|
||||
while (resultSet.next()) {
|
||||
final String mime_type = resultSet.getString("mime_type"); //NON-NLS
|
||||
if (!mime_type.isEmpty()) {
|
||||
String mimeType[] = mime_type.split("/");
|
||||
//if the mime_type contained multiple slashes then everything after the first slash will become the subtype
|
||||
final String mimeMediaSubType = StringUtils.join(ArrayUtils.subarray(mimeType, 1, mimeType.length), "/");
|
||||
if (mimeType.length > 1 && !mimeType[0].isEmpty() && !mimeMediaSubType.isEmpty()) {
|
||||
if (!existingMimeTypes.containsKey(mimeType[0])) {
|
||||
existingMimeTypes.put(mimeType[0], new ArrayList<>());
|
||||
}
|
||||
existingMimeTypes.get(mimeType[0]).add(mimeMediaSubType);
|
||||
final String mediaType = StringUtils.substringBefore(mime_type, "/");
|
||||
final String subType = StringUtils.removeStart(mime_type, mediaType + "/");
|
||||
if (!mediaType.isEmpty() && !subType.isEmpty()) {
|
||||
final long count = resultSet.getLong("count");
|
||||
existingMimeTypeCounts.computeIfAbsent(mediaType, t -> new HashMap<>())
|
||||
.put(subType, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,11 +119,10 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
}
|
||||
|
||||
setChanged();
|
||||
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
FileTypesByMimeType( FileTypes typesRoot) {
|
||||
FileTypesByMimeType(FileTypes typesRoot) {
|
||||
this.skCase = typesRoot.getSleuthkitCase();
|
||||
this.typesRoot = typesRoot;
|
||||
this.pcl = (PropertyChangeEvent evt) -> {
|
||||
@ -228,9 +213,10 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return existingMimeTypes.isEmpty();
|
||||
synchronized (existingMimeTypeCounts) {
|
||||
return existingMimeTypeCounts.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,9 +232,13 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<String> mediaTypeNodes) {
|
||||
if (!existingMimeTypes.isEmpty()) {
|
||||
mediaTypeNodes.addAll(getMediaTypeList());
|
||||
final List<String> keylist;
|
||||
synchronized (existingMimeTypeCounts) {
|
||||
keylist = new ArrayList<>(existingMimeTypeCounts.keySet());
|
||||
}
|
||||
Collections.sort(keylist);
|
||||
mediaTypeNodes.addAll(keylist);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -261,7 +251,6 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
public void update(Observable o, Object arg) {
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,7 +299,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<String> mediaTypeNodes) {
|
||||
mediaTypeNodes.addAll(existingMimeTypes.get(mediaType));
|
||||
mediaTypeNodes.addAll(existingMimeTypeCounts.get(mediaType).keySet());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -333,7 +322,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
private final String subType;
|
||||
|
||||
private MediaSubTypeNode(String mimeType) {
|
||||
super(typesRoot,Children.create(new MediaSubTypeNodeChildren(mimeType), true));
|
||||
super(typesRoot, Children.create(new MediaSubTypeNodeChildren(mimeType), true));
|
||||
this.mimeType = mimeType;
|
||||
this.subType = StringUtils.substringAfter(mimeType, "/");
|
||||
super.setName(mimeType);
|
||||
@ -375,24 +364,8 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
}
|
||||
|
||||
@Override
|
||||
String geQuery() {
|
||||
return createQuery(mimeType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children count without actually loading all nodes
|
||||
*
|
||||
* @return count(*) - the number of items that will be shown in this items
|
||||
* Directory Listing
|
||||
*/
|
||||
static 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;
|
||||
long calculateChildCount() {
|
||||
return existingMimeTypeCounts.get(StringUtils.substringBefore(mimeType, "/")).get(subType);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user