mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Moved file type export functionality
This commit is contained in:
parent
0aa708388c
commit
e948b14c86
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentutils;
|
|||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -45,10 +46,12 @@ import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
|
|||||||
*/
|
*/
|
||||||
public final class DataSourceInfoUtilities {
|
public final class DataSourceInfoUtilities {
|
||||||
|
|
||||||
|
public static final String COMMA_FORMAT_STR = "#,###";
|
||||||
|
public static final DecimalFormat COMMA_FORMATTER = new DecimalFormat(COMMA_FORMAT_STR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a count of tsk_files for a particular datasource.
|
* Gets a count of tsk_files for a particular datasource.
|
||||||
*
|
*
|
||||||
* @param skCase The current SleuthkitCase.
|
|
||||||
* @param currentDataSource The datasource.
|
* @param currentDataSource The datasource.
|
||||||
* @param additionalWhere Additional sql where clauses.
|
* @param additionalWhere Additional sql where clauses.
|
||||||
*
|
*
|
||||||
@ -56,11 +59,12 @@ public final class DataSourceInfoUtilities {
|
|||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
public static Long getCountOfTskFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere)
|
public static Long getCountOfTskFiles(DataSource currentDataSource, String additionalWhere)
|
||||||
throws TskCoreException, SQLException {
|
throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
if (currentDataSource != null) {
|
if (currentDataSource != null) {
|
||||||
return skCase.countFilesWhere(
|
return Case.getCurrentCaseThrows().getSleuthkitCase().countFilesWhere(
|
||||||
"data_source_obj_id=" + currentDataSource.getId()
|
"data_source_obj_id=" + currentDataSource.getId()
|
||||||
+ (StringUtils.isBlank(additionalWhere) ? "" : (" AND " + additionalWhere)));
|
+ (StringUtils.isBlank(additionalWhere) ? "" : (" AND " + additionalWhere)));
|
||||||
}
|
}
|
||||||
@ -70,7 +74,6 @@ public final class DataSourceInfoUtilities {
|
|||||||
/**
|
/**
|
||||||
* Gets a count of regular files for a particular datasource.
|
* Gets a count of regular files for a particular datasource.
|
||||||
*
|
*
|
||||||
* @param skCase The current SleuthkitCase.
|
|
||||||
* @param currentDataSource The datasource.
|
* @param currentDataSource The datasource.
|
||||||
* @param additionalWhere Additional sql where clauses.
|
* @param additionalWhere Additional sql where clauses.
|
||||||
*
|
*
|
||||||
@ -78,22 +81,22 @@ public final class DataSourceInfoUtilities {
|
|||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
public static Long getCountOfRegularFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere)
|
public static Long getCountOfRegularFiles(DataSource currentDataSource, String additionalWhere)
|
||||||
throws TskCoreException, SQLException {
|
throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue();
|
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue();
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(additionalWhere)) {
|
if (StringUtils.isNotBlank(additionalWhere)) {
|
||||||
whereClause += " AND " + additionalWhere;
|
whereClause += " AND " + additionalWhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getCountOfTskFiles(skCase, currentDataSource, whereClause);
|
return getCountOfTskFiles(currentDataSource, whereClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a count of regular non-slack files for a particular datasource.
|
* Gets a count of regular non-slack files for a particular datasource.
|
||||||
*
|
*
|
||||||
* @param skCase The current SleuthkitCase.
|
|
||||||
* @param currentDataSource The datasource.
|
* @param currentDataSource The datasource.
|
||||||
* @param additionalWhere Additional sql where clauses.
|
* @param additionalWhere Additional sql where clauses.
|
||||||
*
|
*
|
||||||
@ -101,9 +104,10 @@ public final class DataSourceInfoUtilities {
|
|||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
public static Long getCountOfRegNonSlackFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere)
|
public static Long getCountOfRegNonSlackFiles(DataSource currentDataSource, String additionalWhere)
|
||||||
throws TskCoreException, SQLException {
|
throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
||||||
+ " AND type<>" + TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType();
|
+ " AND type<>" + TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType();
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ public final class DataSourceInfoUtilities {
|
|||||||
whereClause += " AND " + additionalWhere;
|
whereClause += " AND " + additionalWhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getCountOfTskFiles(skCase, currentDataSource, whereClause);
|
return getCountOfTskFiles(currentDataSource, whereClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -429,4 +433,27 @@ public final class DataSourceInfoUtilities {
|
|||||||
Long longVal = getLongOrNull(artifact, attributeType);
|
Long longVal = getLongOrNull(artifact, attributeType);
|
||||||
return (longVal == null || longVal == 0) ? null : new Date(longVal * 1000);
|
return (longVal == null || longVal == 0) ? null : new Date(longVal * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the long value or zero if longVal is null.
|
||||||
|
*
|
||||||
|
* @param longVal The long value.
|
||||||
|
*
|
||||||
|
* @return The long value or 0 if provided value is null.
|
||||||
|
*/
|
||||||
|
public static long getLongOrZero(Long longVal) {
|
||||||
|
return longVal == null ? 0 : longVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns string value of long with comma separators. If null returns a
|
||||||
|
* string of '0'.
|
||||||
|
*
|
||||||
|
* @param longVal The long value.
|
||||||
|
*
|
||||||
|
* @return The string value of the long.
|
||||||
|
*/
|
||||||
|
public static String getStringOrZero(Long longVal) {
|
||||||
|
return longVal == null ? "0" : COMMA_FORMATTER.format(longVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,11 @@ import java.nio.file.Paths;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
182
Core/src/org/sleuthkit/autopsy/contentutils/TypesSummary.java
Executable file
182
Core/src/org/sleuthkit/autopsy/contentutils/TypesSummary.java
Executable file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 - 2021 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.contentutils;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for getting summary information on the known files present in the
|
||||||
|
* specified DataSource..
|
||||||
|
*/
|
||||||
|
public class TypesSummary {
|
||||||
|
|
||||||
|
private TypesSummary() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of regular files (not directories) in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
public static Long getCountOfFiles(DataSource currentDataSource)
|
||||||
|
throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of allocated files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
public static Long getCountOfAllocatedFiles(DataSource currentDataSource)
|
||||||
|
throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
|
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource,
|
||||||
|
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.ALLOC));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of unallocated files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
public static Long getCountOfUnallocatedFiles(DataSource currentDataSource)
|
||||||
|
throws NoCurrentCaseException, TskCoreException, SQLException {
|
||||||
|
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource,
|
||||||
|
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of directories in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
public static Long getCountOfDirectories(DataSource currentDataSource)
|
||||||
|
throws NoCurrentCaseException, TskCoreException, SQLException {
|
||||||
|
|
||||||
|
return DataSourceInfoUtilities.getCountOfTskFiles(currentDataSource,
|
||||||
|
"meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
|
||||||
|
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of slack files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
public static Long getCountOfSlackFiles(DataSource currentDataSource)
|
||||||
|
throws NoCurrentCaseException, TskCoreException, SQLException {
|
||||||
|
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
||||||
|
"type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information concerning a particular file type category.
|
||||||
|
*/
|
||||||
|
public static class FileTypeCategoryData {
|
||||||
|
|
||||||
|
private final String label;
|
||||||
|
private final Set<String> mimeTypes;
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param label The label for this slice.
|
||||||
|
* @param mimeTypes The mime types associated with this slice.
|
||||||
|
* @param color The color associated with this slice.
|
||||||
|
*/
|
||||||
|
public FileTypeCategoryData(String label, Set<String> mimeTypes, Color color) {
|
||||||
|
this.label = label;
|
||||||
|
this.mimeTypes = mimeTypes;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that accepts FileTypeCategory.
|
||||||
|
*
|
||||||
|
* @param label The label for this slice.
|
||||||
|
* @param mimeTypes The mime types associated with this slice.
|
||||||
|
* @param color The color associated with this slice.
|
||||||
|
*/
|
||||||
|
public FileTypeCategoryData(String label, FileTypeUtils.FileTypeCategory fileCategory, Color color) {
|
||||||
|
this(label, fileCategory.getMediaTypes(), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The label for this category.
|
||||||
|
*/
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The mime types associated with this category.
|
||||||
|
*/
|
||||||
|
public Set<String> getMimeTypes() {
|
||||||
|
return mimeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The color associated with this category.
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,10 +21,12 @@ package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
|||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities;
|
import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
@ -34,11 +36,10 @@ import org.sleuthkit.datamodel.DataSource;
|
|||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides methods to query for datasource files by mime type.
|
* Wrapper class for converting org.sleuthkit.autopsy.contentutils.TypesSummary
|
||||||
|
* functionality into a DefaultArtifactUpdateGovernor used by TypesPanel tab.
|
||||||
*/
|
*/
|
||||||
public class MimeTypeSummary implements DefaultUpdateGovernor {
|
public class MimeTypeSummaryGetter implements DefaultUpdateGovernor {
|
||||||
|
|
||||||
private final SleuthkitCaseProvider provider;
|
|
||||||
|
|
||||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
|
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
|
||||||
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
|
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
|
||||||
@ -46,17 +47,7 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
*/
|
*/
|
||||||
public MimeTypeSummary() {
|
public MimeTypeSummaryGetter() {
|
||||||
this(SleuthkitCaseProvider.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main constructor.
|
|
||||||
*
|
|
||||||
* @param provider The means of obtaining a sleuthkit case.
|
|
||||||
*/
|
|
||||||
public MimeTypeSummary(SleuthkitCaseProvider provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,7 +67,7 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
|
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
|
||||||
return INGEST_JOB_EVENTS;
|
return Collections.unmodifiableSet(INGEST_JOB_EVENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,12 +90,11 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes)
|
public Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "mime_type IN " + getSqlSet(setOfMimeTypes));
|
||||||
provider.get(),
|
} catch (NoCurrentCaseException ex) {
|
||||||
currentDataSource,
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
"mime_type IN " + getSqlSet(setOfMimeTypes)
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,13 +115,13 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfFilesNotInMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes)
|
public Long getCountOfFilesNotInMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource,
|
||||||
provider.get(),
|
"mime_type NOT IN " + getSqlSet(setOfMimeTypes)
|
||||||
currentDataSource,
|
+ " AND mime_type IS NOT NULL AND mime_type <> '' ");
|
||||||
"mime_type NOT IN " + getSqlSet(setOfMimeTypes)
|
} catch (NoCurrentCaseException ex) {
|
||||||
+ " AND mime_type IS NOT NULL AND mime_type <> '' "
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,8 +137,11 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfAllRegularFiles(DataSource dataSource)
|
public Long getCountOfAllRegularFiles(DataSource dataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(provider.get(), dataSource, null);
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(dataSource, null);
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,12 +158,11 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfFilesWithNoMimeType(DataSource currentDataSource)
|
public Long getCountOfFilesWithNoMimeType(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "(mime_type IS NULL OR mime_type = '') ");
|
||||||
provider.get(),
|
} catch (NoCurrentCaseException ex) {
|
||||||
currentDataSource,
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
"(mime_type IS NULL OR mime_type = '') "
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -21,41 +21,31 @@ package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
|||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.TypesSummary;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides information for the DataSourceSummaryCountsPanel.
|
* Wrapper class for converting org.sleuthkit.autopsy.contentutils.TypesSummary functionality into a
|
||||||
|
* DefaultArtifactUpdateGovernor used by DataSourceSummaryCountsPanel.
|
||||||
*/
|
*/
|
||||||
public class TypesSummary implements DefaultUpdateGovernor {
|
public class TypesSummaryGetter implements DefaultUpdateGovernor {
|
||||||
|
|
||||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
|
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
|
||||||
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
|
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
|
||||||
|
|
||||||
private final SleuthkitCaseProvider provider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
*/
|
*/
|
||||||
public TypesSummary() {
|
public TypesSummaryGetter() {
|
||||||
this(SleuthkitCaseProvider.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main constructor.
|
|
||||||
*
|
|
||||||
* @param provider The means of obtaining a sleuthkit case.
|
|
||||||
*/
|
|
||||||
public TypesSummary(SleuthkitCaseProvider provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,7 +65,7 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
|
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
|
||||||
return INGEST_JOB_EVENTS;
|
return Collections.unmodifiableSet(INGEST_JOB_EVENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,11 +81,11 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfFiles(DataSource currentDataSource)
|
public Long getCountOfFiles(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(
|
try {
|
||||||
provider.get(),
|
return TypesSummary.getCountOfFiles(currentDataSource);
|
||||||
currentDataSource,
|
} catch (NoCurrentCaseException ex) {
|
||||||
null
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,9 +101,11 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfAllocatedFiles(DataSource currentDataSource)
|
public Long getCountOfAllocatedFiles(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(provider.get(), currentDataSource,
|
return TypesSummary.getCountOfAllocatedFiles(currentDataSource);
|
||||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.ALLOC));
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,9 +121,11 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfUnallocatedFiles(DataSource currentDataSource)
|
public Long getCountOfUnallocatedFiles(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(provider.get(), currentDataSource,
|
return TypesSummary.getCountOfUnallocatedFiles(currentDataSource);
|
||||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC));
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,10 +141,11 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfDirectories(DataSource currentDataSource)
|
public Long getCountOfDirectories(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfTskFiles(provider.get(), currentDataSource,
|
return TypesSummary.getCountOfDirectories(currentDataSource);
|
||||||
"meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
|
} catch (NoCurrentCaseException ex) {
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType());
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,8 +161,10 @@ public class TypesSummary implements DefaultUpdateGovernor {
|
|||||||
*/
|
*/
|
||||||
public Long getCountOfSlackFiles(DataSource currentDataSource)
|
public Long getCountOfSlackFiles(DataSource currentDataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, SQLException {
|
||||||
|
try {
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(provider.get(), currentDataSource,
|
return TypesSummary.getCountOfSlackFiles(currentDataSource);
|
||||||
"type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType());
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
throw new SleuthkitCaseProviderException("No currently open case.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -23,17 +23,17 @@ import java.sql.SQLException;
|
|||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
import org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TypesSummary;
|
import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.TypesSummary.FileTypeCategoryData;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TypesSummaryGetter;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.ContainerSummaryGetter;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.ContainerSummaryGetter;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.MimeTypeSummary;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.MimeTypeSummaryGetter;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult.ResultType;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult.ResultType;
|
||||||
@ -90,7 +90,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
* @param usefulContent True if this is useful content; false if there
|
* @param usefulContent True if this is useful content; false if there
|
||||||
* is 0 mime type information.
|
* is 0 mime type information.
|
||||||
*/
|
*/
|
||||||
public TypesPieChartData(List<PieChartItem> pieSlices, boolean usefulContent) {
|
TypesPieChartData(List<PieChartItem> pieSlices, boolean usefulContent) {
|
||||||
this.pieSlices = pieSlices;
|
this.pieSlices = pieSlices;
|
||||||
this.usefulContent = usefulContent;
|
this.usefulContent = usefulContent;
|
||||||
}
|
}
|
||||||
@ -98,78 +98,20 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
/**
|
/**
|
||||||
* @return The pie chart data.
|
* @return The pie chart data.
|
||||||
*/
|
*/
|
||||||
public List<PieChartItem> getPieSlices() {
|
List<PieChartItem> getPieSlices() {
|
||||||
return pieSlices;
|
return pieSlices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether or not the data is usefulContent.
|
* @return Whether or not the data is usefulContent.
|
||||||
*/
|
*/
|
||||||
public boolean isUsefulContent() {
|
boolean isUsefulContent() {
|
||||||
return usefulContent;
|
return usefulContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Information concerning a particular category in the file types pie chart.
|
|
||||||
*/
|
|
||||||
private static class TypesPieCategory {
|
|
||||||
|
|
||||||
private final String label;
|
|
||||||
private final Set<String> mimeTypes;
|
|
||||||
private final Color color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main constructor.
|
|
||||||
*
|
|
||||||
* @param label The label for this slice.
|
|
||||||
* @param mimeTypes The mime types associated with this slice.
|
|
||||||
* @param color The color associated with this slice.
|
|
||||||
*/
|
|
||||||
TypesPieCategory(String label, Set<String> mimeTypes, Color color) {
|
|
||||||
this.label = label;
|
|
||||||
this.mimeTypes = mimeTypes;
|
|
||||||
this.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor that accepts FileTypeCategory.
|
|
||||||
*
|
|
||||||
* @param label The label for this slice.
|
|
||||||
* @param mimeTypes The mime types associated with this slice.
|
|
||||||
* @param color The color associated with this slice.
|
|
||||||
*/
|
|
||||||
TypesPieCategory(String label, FileTypeCategory fileCategory, Color color) {
|
|
||||||
this(label, fileCategory.getMediaTypes(), color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The label for this category.
|
|
||||||
*/
|
|
||||||
String getLabel() {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The mime types associated with this category.
|
|
||||||
*/
|
|
||||||
Set<String> getMimeTypes() {
|
|
||||||
return mimeTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The color associated with this category.
|
|
||||||
*/
|
|
||||||
Color getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#");
|
private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#");
|
||||||
private static final String COMMA_FORMAT_STR = "#,###";
|
|
||||||
|
|
||||||
private static final DecimalFormat COMMA_FORMATTER = new DecimalFormat(COMMA_FORMAT_STR);
|
|
||||||
|
|
||||||
private static final Color IMAGES_COLOR = new Color(156, 39, 176);
|
private static final Color IMAGES_COLOR = new Color(156, 39, 176);
|
||||||
private static final Color VIDEOS_COLOR = Color.YELLOW;
|
private static final Color VIDEOS_COLOR = Color.YELLOW;
|
||||||
@ -181,13 +123,13 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
|
private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
|
||||||
|
|
||||||
// All file type categories.
|
// All file type categories.
|
||||||
private static final List<TypesPieCategory> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
|
private static final List<FileTypeCategoryData> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
|
||||||
new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(), new HashSet<>(Arrays.asList("application/octet-stream")), UNKNOWN_COLOR)
|
new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(), new HashSet<>(Arrays.asList("application/octet-stream")), UNKNOWN_COLOR)
|
||||||
);
|
);
|
||||||
|
|
||||||
private final DataFetcher<DataSource, String> usageFetcher;
|
private final DataFetcher<DataSource, String> usageFetcher;
|
||||||
@ -233,7 +175,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
* Creates a new TypesPanel.
|
* Creates a new TypesPanel.
|
||||||
*/
|
*/
|
||||||
public TypesPanel() {
|
public TypesPanel() {
|
||||||
this(new MimeTypeSummary(), new TypesSummary(), new ContainerSummaryGetter());
|
this(new MimeTypeSummaryGetter(), new TypesSummaryGetter(), new ContainerSummaryGetter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -250,8 +192,8 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
* @param containerData The service for container information.
|
* @param containerData The service for container information.
|
||||||
*/
|
*/
|
||||||
public TypesPanel(
|
public TypesPanel(
|
||||||
MimeTypeSummary mimeTypeData,
|
MimeTypeSummaryGetter mimeTypeData,
|
||||||
TypesSummary typeData,
|
TypesSummaryGetter typeData,
|
||||||
ContainerSummaryGetter containerData) {
|
ContainerSummaryGetter containerData) {
|
||||||
|
|
||||||
super(mimeTypeData, typeData, containerData);
|
super(mimeTypeData, typeData, containerData);
|
||||||
@ -277,13 +219,13 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
size -> SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false)))),
|
size -> SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false)))),
|
||||||
new DataFetchWorker.DataFetchComponents<>(typesFetcher, this::showMimeTypeCategories),
|
new DataFetchWorker.DataFetchComponents<>(typesFetcher, this::showMimeTypeCategories),
|
||||||
new DataFetchWorker.DataFetchComponents<>(allocatedFetcher,
|
new DataFetchWorker.DataFetchComponents<>(allocatedFetcher,
|
||||||
countRes -> allocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
|
countRes -> allocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
|
||||||
new DataFetchWorker.DataFetchComponents<>(unallocatedFetcher,
|
new DataFetchWorker.DataFetchComponents<>(unallocatedFetcher,
|
||||||
countRes -> unallocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
|
countRes -> unallocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
|
||||||
new DataFetchWorker.DataFetchComponents<>(slackFetcher,
|
new DataFetchWorker.DataFetchComponents<>(slackFetcher,
|
||||||
countRes -> slackLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
|
countRes -> slackLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
|
||||||
new DataFetchWorker.DataFetchComponents<>(directoriesFetcher,
|
new DataFetchWorker.DataFetchComponents<>(directoriesFetcher,
|
||||||
countRes -> directoriesLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count))))
|
countRes -> directoriesLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count))))
|
||||||
);
|
);
|
||||||
|
|
||||||
initComponents();
|
initComponents();
|
||||||
@ -307,7 +249,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
*
|
*
|
||||||
* @return The pie chart items.
|
* @return The pie chart items.
|
||||||
*/
|
*/
|
||||||
private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummary mimeTypeData, DataSource dataSource)
|
private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummaryGetter mimeTypeData, DataSource dataSource)
|
||||||
throws SQLException, SleuthkitCaseProviderException, TskCoreException {
|
throws SQLException, SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
|
||||||
if (dataSource == null) {
|
if (dataSource == null) {
|
||||||
@ -318,8 +260,8 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
List<PieChartItem> fileCategoryItems = new ArrayList<>();
|
List<PieChartItem> fileCategoryItems = new ArrayList<>();
|
||||||
long categoryTotalCount = 0;
|
long categoryTotalCount = 0;
|
||||||
|
|
||||||
for (TypesPieCategory cat : FILE_MIME_TYPE_CATEGORIES) {
|
for (FileTypeCategoryData cat : FILE_MIME_TYPE_CATEGORIES) {
|
||||||
long thisValue = getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
|
long thisValue = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
|
||||||
categoryTotalCount += thisValue;
|
categoryTotalCount += thisValue;
|
||||||
|
|
||||||
fileCategoryItems.add(new PieChartItem(
|
fileCategoryItems.add(new PieChartItem(
|
||||||
@ -329,10 +271,10 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get a count of all files with no mime type
|
// get a count of all files with no mime type
|
||||||
long noMimeTypeCount = getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
|
long noMimeTypeCount = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
|
||||||
|
|
||||||
// get a count of all regular files
|
// get a count of all regular files
|
||||||
long allRegularFiles = getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
|
long allRegularFiles = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
|
||||||
|
|
||||||
// create entry for mime types in other category
|
// create entry for mime types in other category
|
||||||
long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
|
long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
|
||||||
@ -385,29 +327,6 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the long value or zero if longVal is null.
|
|
||||||
*
|
|
||||||
* @param longVal The long value.
|
|
||||||
*
|
|
||||||
* @return The long value or 0 if provided value is null.
|
|
||||||
*/
|
|
||||||
private static long getLongOrZero(Long longVal) {
|
|
||||||
return longVal == null ? 0 : longVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns string value of long with comma separators. If null returns a
|
|
||||||
* string of '0'.
|
|
||||||
*
|
|
||||||
* @param longVal The long value.
|
|
||||||
*
|
|
||||||
* @return The string value of the long.
|
|
||||||
*/
|
|
||||||
private static String getStringOrZero(Long longVal) {
|
|
||||||
return longVal == null ? "0" : COMMA_FORMATTER.format(longVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a key value pair to be exported in a sheet.
|
* Returns a key value pair to be exported in a sheet.
|
||||||
*
|
*
|
||||||
|
@ -5,6 +5,7 @@ DataSourceSummaryReport.endReport.srcModuleName.text=Excel Report
|
|||||||
ExcelExport_writeExcel_noSheetName=Sheet {0}
|
ExcelExport_writeExcel_noSheetName=Sheet {0}
|
||||||
ExcelExportAction_exportToXLSX_beginExport=Beginning Export...
|
ExcelExportAction_exportToXLSX_beginExport=Beginning Export...
|
||||||
ExcelExportAction_exportToXLSX_gatheringContainerData=Fetching Container & Image Data
|
ExcelExportAction_exportToXLSX_gatheringContainerData=Fetching Container & Image Data
|
||||||
|
ExcelExportAction_exportToXLSX_gatheringFileData=Fetching File and MIME Type Data
|
||||||
ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data
|
ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data
|
||||||
ExcelExportAction_exportToXLSX_gatheringTimelineData=Fetching Timeline Data
|
ExcelExportAction_exportToXLSX_gatheringTimelineData=Fetching Timeline Data
|
||||||
ExcelExportAction_exportToXLSX_writingToFile=Writing to File...
|
ExcelExportAction_exportToXLSX_writingToFile=Writing to File...
|
||||||
@ -32,6 +33,25 @@ ExportRecentFiles_col_header_path=Path
|
|||||||
ExportRecentFiles_col_header_sender=Sender
|
ExportRecentFiles_col_header_sender=Sender
|
||||||
ExportRecentFiles_docsTable_tabName=Recently Opened Documents
|
ExportRecentFiles_docsTable_tabName=Recently Opened Documents
|
||||||
ExportRecentFiles_downloadsTable_tabName=Recently Downloads
|
ExportRecentFiles_downloadsTable_tabName=Recently Downloads
|
||||||
|
ExportTypes_artifactsTypesPieChart_title=Artifact Types
|
||||||
|
ExportTypes_excelTabName=Types
|
||||||
|
ExportTypes_fileMimeTypesChart_audio_title=Audio
|
||||||
|
ExportTypes_fileMimeTypesChart_documents_title=Documents
|
||||||
|
ExportTypes_fileMimeTypesChart_executables_title=Executables
|
||||||
|
ExportTypes_fileMimeTypesChart_images_title=Images
|
||||||
|
ExportTypes_fileMimeTypesChart_notAnalyzed_title=Not Analyzed
|
||||||
|
ExportTypes_fileMimeTypesChart_other_title=Other
|
||||||
|
ExportTypes_fileMimeTypesChart_title=File Types
|
||||||
|
ExportTypes_fileMimeTypesChart_unknown_title=Unknown
|
||||||
|
ExportTypes_fileMimeTypesChart_valueLabel=Count
|
||||||
|
ExportTypes_fileMimeTypesChart_videos_title=Videos
|
||||||
|
ExportTypes_filesByCategoryTable_allocatedRow_title=Allocated Files
|
||||||
|
ExportTypes_filesByCategoryTable_directoryRow_title=Directories
|
||||||
|
ExportTypes_filesByCategoryTable_slackRow_title=Slack Files
|
||||||
|
ExportTypes_filesByCategoryTable_unallocatedRow_title=Unallocated Files
|
||||||
|
ExportTypes_osLabel_title=OS
|
||||||
|
ExportTypes_sizeLabel_title=Size
|
||||||
|
ExportTypes_usageLabel_title=Usage
|
||||||
SizeRepresentationUtil_units_bytes=bytes
|
SizeRepresentationUtil_units_bytes=bytes
|
||||||
SizeRepresentationUtil_units_gigabytes=GB
|
SizeRepresentationUtil_units_gigabytes=GB
|
||||||
SizeRepresentationUtil_units_kilobytes=KB
|
SizeRepresentationUtil_units_kilobytes=KB
|
||||||
|
@ -93,6 +93,7 @@ class ExcelExportAction {
|
|||||||
"ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data",
|
"ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data",
|
||||||
"ExcelExportAction_exportToXLSX_gatheringContainerData=Fetching Container & Image Data",
|
"ExcelExportAction_exportToXLSX_gatheringContainerData=Fetching Container & Image Data",
|
||||||
"ExcelExportAction_exportToXLSX_gatheringTimelineData=Fetching Timeline Data",
|
"ExcelExportAction_exportToXLSX_gatheringTimelineData=Fetching Timeline Data",
|
||||||
|
"ExcelExportAction_exportToXLSX_gatheringFileData=Fetching File and MIME Type Data",
|
||||||
"ExcelExportAction_exportToXLSX_writingToFile=Writing to File...",})
|
"ExcelExportAction_exportToXLSX_writingToFile=Writing to File...",})
|
||||||
|
|
||||||
void exportToXLSX(ReportProgressPanel progressPanel, DataSource dataSource, String baseReportDir)
|
void exportToXLSX(ReportProgressPanel progressPanel, DataSource dataSource, String baseReportDir)
|
||||||
@ -129,6 +130,14 @@ class ExcelExportAction {
|
|||||||
sheetExports.addAll(exports);
|
sheetExports.addAll(exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export file and MIME type data
|
||||||
|
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_gatheringFileData());
|
||||||
|
progressPanel.setProgress(4);
|
||||||
|
exports = ExportTypes.getExports(dataSource);
|
||||||
|
if (exports != null) {
|
||||||
|
sheetExports.addAll(exports);
|
||||||
|
}
|
||||||
|
|
||||||
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_writingToFile());
|
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_writingToFile());
|
||||||
progressPanel.setProgress(9);
|
progressPanel.setProgress(9);
|
||||||
ExcelExport.writeExcel(sheetExports, reportFile);
|
ExcelExport.writeExcel(sheetExports, reportFile);
|
||||||
|
@ -0,0 +1,312 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019-2021 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.report.modules.datasourcesummaryexport;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.ContainerSummary;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.TypesSummary;
|
||||||
|
import org.sleuthkit.autopsy.contentutils.TypesSummary.FileTypeCategoryData;
|
||||||
|
import org.sleuthkit.autopsy.report.modules.datasourcesummaryexport.ExcelSpecialFormatExport.KeyValueItemExportable;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel for displaying summary information on the known files present in the
|
||||||
|
* specified DataSource.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"ExportTypes_artifactsTypesPieChart_title=Artifact Types",
|
||||||
|
"ExportTypes_filesByCategoryTable_allocatedRow_title=Allocated Files",
|
||||||
|
"ExportTypes_filesByCategoryTable_unallocatedRow_title=Unallocated Files",
|
||||||
|
"ExportTypes_filesByCategoryTable_slackRow_title=Slack Files",
|
||||||
|
"ExportTypes_filesByCategoryTable_directoryRow_title=Directories",
|
||||||
|
"ExportTypes_fileMimeTypesChart_title=File Types",
|
||||||
|
"ExportTypes_fileMimeTypesChart_valueLabel=Count",
|
||||||
|
"ExportTypes_fileMimeTypesChart_audio_title=Audio",
|
||||||
|
"ExportTypes_fileMimeTypesChart_documents_title=Documents",
|
||||||
|
"ExportTypes_fileMimeTypesChart_executables_title=Executables",
|
||||||
|
"ExportTypes_fileMimeTypesChart_images_title=Images",
|
||||||
|
"ExportTypes_fileMimeTypesChart_videos_title=Videos",
|
||||||
|
"ExportTypes_fileMimeTypesChart_other_title=Other",
|
||||||
|
"ExportTypes_fileMimeTypesChart_unknown_title=Unknown",
|
||||||
|
"ExportTypes_fileMimeTypesChart_notAnalyzed_title=Not Analyzed",
|
||||||
|
"ExportTypes_usageLabel_title=Usage",
|
||||||
|
"ExportTypes_osLabel_title=OS",
|
||||||
|
"ExportTypes_sizeLabel_title=Size",
|
||||||
|
"ExportTypes_excelTabName=Types"})
|
||||||
|
class ExportTypes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data for types pie chart.
|
||||||
|
*/
|
||||||
|
private static class TypesPieChartData {
|
||||||
|
|
||||||
|
private final List<PieChartItem> pieSlices;
|
||||||
|
private final boolean usefulContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param pieSlices The pie slices.
|
||||||
|
* @param usefulContent True if this is useful content; false if there
|
||||||
|
* is 0 mime type information.
|
||||||
|
*/
|
||||||
|
TypesPieChartData(List<PieChartItem> pieSlices, boolean usefulContent) {
|
||||||
|
this.pieSlices = pieSlices;
|
||||||
|
this.usefulContent = usefulContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The pie chart data.
|
||||||
|
*/
|
||||||
|
List<PieChartItem> getPieSlices() {
|
||||||
|
return pieSlices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether or not the data is usefulContent.
|
||||||
|
*/
|
||||||
|
boolean isUsefulContent() {
|
||||||
|
return usefulContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Color IMAGES_COLOR = new Color(156, 39, 176);
|
||||||
|
private static final Color VIDEOS_COLOR = Color.YELLOW;
|
||||||
|
private static final Color AUDIO_COLOR = Color.BLUE;
|
||||||
|
private static final Color DOCUMENTS_COLOR = Color.GREEN;
|
||||||
|
private static final Color EXECUTABLES_COLOR = new Color(0, 188, 212);
|
||||||
|
private static final Color UNKNOWN_COLOR = Color.ORANGE;
|
||||||
|
private static final Color OTHER_COLOR = new Color(78, 52, 46);
|
||||||
|
private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
|
||||||
|
|
||||||
|
// All file type categories.
|
||||||
|
private static final List<FileTypeCategoryData> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
|
||||||
|
new FileTypeCategoryData(Bundle.ExportTypes_fileMimeTypesChart_unknown_title(), new HashSet<>(Arrays.asList("application/octet-stream")), UNKNOWN_COLOR)
|
||||||
|
);
|
||||||
|
|
||||||
|
private ExportTypes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derives a sql set string (i.e. "('val1', 'val2', 'val3')"). A naive
|
||||||
|
* attempt is made to sanitize the strings by removing single quotes from
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @param setValues The values that should be present in the set. Single
|
||||||
|
* quotes are removed.
|
||||||
|
*
|
||||||
|
* @return The sql set string.
|
||||||
|
*/
|
||||||
|
private static String getSqlSet(Set<String> setValues) {
|
||||||
|
List<String> quotedValues = setValues
|
||||||
|
.stream()
|
||||||
|
.map(str -> String.format("'%s'", str.replace("'", "")))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
String commaSeparatedQuoted = String.join(", ", quotedValues);
|
||||||
|
return String.format("(%s) ", commaSeparatedQuoted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of files in the case database for the current data source
|
||||||
|
* which have the specified mimetypes.
|
||||||
|
*
|
||||||
|
* @param currentDataSource the data source which we are finding a file
|
||||||
|
* count
|
||||||
|
*
|
||||||
|
* @param setOfMimeTypes the set of mime types which we are finding the
|
||||||
|
* number of occurences of
|
||||||
|
*
|
||||||
|
* @return a Long value which represents the number of occurrences of the
|
||||||
|
* specified mime types in the current case for the specified data
|
||||||
|
* source, null if no count was retrieved
|
||||||
|
*
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "mime_type IN " + getSqlSet(setOfMimeTypes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of files in the data source with no assigned mime type.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The number of files with no mime type or null if there is an
|
||||||
|
* issue searching the data source.
|
||||||
|
*
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private static Long getCountOfFilesWithNoMimeType(DataSource currentDataSource) throws TskCoreException, SQLException, NoCurrentCaseException {
|
||||||
|
return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "(mime_type IS NULL OR mime_type = '') ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the data for the file type pie chart.
|
||||||
|
*
|
||||||
|
* @param mimeTypeData The means of acquiring data.
|
||||||
|
* @param dataSource The datasource.
|
||||||
|
*
|
||||||
|
* @return The pie chart items.
|
||||||
|
*/
|
||||||
|
private static TypesPieChartData getMimeTypeCategoriesModel(DataSource dataSource)
|
||||||
|
throws SQLException, TskCoreException, NoCurrentCaseException {
|
||||||
|
|
||||||
|
if (dataSource == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for each category of file types, get the counts of files
|
||||||
|
List<PieChartItem> fileCategoryItems = new ArrayList<>();
|
||||||
|
long categoryTotalCount = 0;
|
||||||
|
|
||||||
|
for (FileTypeCategoryData cat : FILE_MIME_TYPE_CATEGORIES) {
|
||||||
|
long thisValue = DataSourceInfoUtilities.getLongOrZero(getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
|
||||||
|
categoryTotalCount += thisValue;
|
||||||
|
|
||||||
|
fileCategoryItems.add(new PieChartItem(
|
||||||
|
cat.getLabel(),
|
||||||
|
thisValue,
|
||||||
|
cat.getColor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a count of all files with no mime type
|
||||||
|
long noMimeTypeCount = DataSourceInfoUtilities.getLongOrZero(getCountOfFilesWithNoMimeType(dataSource));
|
||||||
|
|
||||||
|
// get a count of all regular files
|
||||||
|
long allRegularFiles = DataSourceInfoUtilities.getLongOrZero(DataSourceInfoUtilities.getCountOfRegNonSlackFiles(dataSource, null));
|
||||||
|
|
||||||
|
// create entry for mime types in other category
|
||||||
|
long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
|
||||||
|
PieChartItem otherPieItem = new PieChartItem(Bundle.ExportTypes_fileMimeTypesChart_other_title(),
|
||||||
|
otherCount, OTHER_COLOR);
|
||||||
|
|
||||||
|
// check at this point to see if these are all 0; if so, we don't have useful content.
|
||||||
|
boolean usefulContent = categoryTotalCount > 0 || otherCount > 0;
|
||||||
|
|
||||||
|
// create entry for not analyzed mime types category
|
||||||
|
PieChartItem notAnalyzedItem = new PieChartItem(Bundle.ExportTypes_fileMimeTypesChart_notAnalyzed_title(),
|
||||||
|
noMimeTypeCount, NOT_ANALYZED_COLOR);
|
||||||
|
|
||||||
|
// combine categories with 'other' and 'not analyzed'
|
||||||
|
List<PieChartItem> items = Stream.concat(
|
||||||
|
fileCategoryItems.stream(),
|
||||||
|
Stream.of(otherPieItem, notAnalyzedItem))
|
||||||
|
// remove items that have no value
|
||||||
|
.filter(slice -> slice.getValue() > 0)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return new TypesPieChartData(items, usefulContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a key value pair to be exported in a sheet.
|
||||||
|
*
|
||||||
|
* @param fetcher The means of fetching the data.
|
||||||
|
* @param key The key to use.
|
||||||
|
* @param dataSource The data source containing the data.
|
||||||
|
*
|
||||||
|
* @return The key value pair to be exported.
|
||||||
|
*/
|
||||||
|
private static KeyValueItemExportable getStrExportable(DataFetcher<DataSource, String> fetcher, String key, DataSource dataSource) {
|
||||||
|
String result = ExcelExportAction.getFetchResult(fetcher, "Types", dataSource);
|
||||||
|
return (result == null) ? null : new KeyValueItemExportable(key, new DefaultCellModel<>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a key value pair to be exported in a sheet formatting the long
|
||||||
|
* with commas separated by orders of 1000.
|
||||||
|
*
|
||||||
|
* @param fetcher The means of fetching the data.
|
||||||
|
* @param key The string key for this key value pair.
|
||||||
|
* @param dataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The key value pair.
|
||||||
|
*/
|
||||||
|
private static KeyValueItemExportable getCountExportable(DataFetcher<DataSource, Long> fetcher, String key, DataSource dataSource) {
|
||||||
|
Long count = ExcelExportAction.getFetchResult(fetcher, "Types", dataSource);
|
||||||
|
return (count == null) ? null : new KeyValueItemExportable(key,
|
||||||
|
new DefaultCellModel<Long>(count, DataSourceInfoUtilities.COMMA_FORMATTER::format, DataSourceInfoUtilities.COMMA_FORMAT_STR));
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<ExcelExport.ExcelSheetExport> getExports(DataSource dataSource) {
|
||||||
|
if (dataSource == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
DataFetcher<DataSource, String> usageFetcher = (ds) -> ContainerSummary.getDataSourceType(ds);
|
||||||
|
DataFetcher<DataSource, String> osFetcher = (ds) -> ContainerSummary.getOperatingSystems(ds);
|
||||||
|
DataFetcher<DataSource, Long> sizeFetcher = (ds) -> ds == null ? null : ds.getSize();
|
||||||
|
|
||||||
|
DataFetcher<DataSource, TypesPieChartData> typesFetcher = (ds) -> getMimeTypeCategoriesModel(ds);
|
||||||
|
|
||||||
|
DataFetcher<DataSource, Long> allocatedFetcher = (ds) -> TypesSummary.getCountOfAllocatedFiles(ds);
|
||||||
|
DataFetcher<DataSource, Long> unallocatedFetcher = (ds) -> TypesSummary.getCountOfUnallocatedFiles(ds);
|
||||||
|
DataFetcher<DataSource, Long> slackFetcher = (ds) -> TypesSummary.getCountOfSlackFiles(ds);
|
||||||
|
DataFetcher<DataSource, Long> directoriesFetcher = (ds) -> TypesSummary.getCountOfDirectories(ds);
|
||||||
|
|
||||||
|
// Retrieve data to create the types pie chart
|
||||||
|
TypesPieChartData typesData = ExcelExportAction.getFetchResult(typesFetcher, "Types", dataSource);
|
||||||
|
PieChartExport typesChart = (typesData == null || !typesData.isUsefulContent()) ? null
|
||||||
|
: new PieChartExport(
|
||||||
|
Bundle.ExportTypes_fileMimeTypesChart_title(),
|
||||||
|
Bundle.ExportTypes_fileMimeTypesChart_valueLabel(),
|
||||||
|
"#,###",
|
||||||
|
Bundle.ExportTypes_fileMimeTypesChart_title(),
|
||||||
|
typesData.getPieSlices());
|
||||||
|
|
||||||
|
return Arrays.asList(new ExcelSpecialFormatExport(Bundle.ExportTypes_excelTabName(),
|
||||||
|
Stream.of(
|
||||||
|
getStrExportable(usageFetcher, Bundle.ExportTypes_usageLabel_title(), dataSource),
|
||||||
|
getStrExportable(osFetcher, Bundle.ExportTypes_osLabel_title(), dataSource),
|
||||||
|
new KeyValueItemExportable(Bundle.ExportTypes_sizeLabel_title(),
|
||||||
|
SizeRepresentationUtil.getBytesCell(ExcelExportAction.getFetchResult(sizeFetcher, "Types", dataSource))),
|
||||||
|
typesChart,
|
||||||
|
getCountExportable(allocatedFetcher, Bundle.ExportTypes_filesByCategoryTable_allocatedRow_title(), dataSource),
|
||||||
|
getCountExportable(unallocatedFetcher, Bundle.ExportTypes_filesByCategoryTable_unallocatedRow_title(), dataSource),
|
||||||
|
getCountExportable(slackFetcher, Bundle.ExportTypes_filesByCategoryTable_slackRow_title(), dataSource),
|
||||||
|
getCountExportable(directoriesFetcher, Bundle.ExportTypes_filesByCategoryTable_directoryRow_title(), dataSource))
|
||||||
|
.filter(sheet -> sheet != null)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user