mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merge pull request #6196 from sleuthkit/revert-6195-merge-develop-into-data-src-summaries
Revert "Merge develop into data src summaries"
This commit is contained in:
commit
30edc43c20
@ -50,9 +50,6 @@
|
|||||||
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
||||||
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
|
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
|
||||||
<dependency org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
|
<dependency org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/jfree/jfreechart -->
|
|
||||||
<dependency org="org.jfree" name="jfreechart" rev="1.0.19"/>
|
|
||||||
|
|
||||||
<!-- map support for geolocation -->
|
<!-- map support for geolocation -->
|
||||||
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
|
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
|
||||||
|
@ -479,14 +479,6 @@
|
|||||||
<runtime-relative-path>ext/jxmapviewer2-2.4.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jxmapviewer2-2.4.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/jxmapviewer2-2.4.jar</binary-origin>
|
<binary-origin>release/modules/ext/jxmapviewer2-2.4.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
|
||||||
<runtime-relative-path>ext/jfreechart-1.0.19.jar</runtime-relative-path>
|
|
||||||
<binary-origin>release/modules/ext/jfreechart-1.0.19.jar</binary-origin>
|
|
||||||
</class-path-extension>
|
|
||||||
<class-path-extension>
|
|
||||||
<runtime-relative-path>ext/jcommon-1.0.23.jar</runtime-relative-path>
|
|
||||||
<binary-origin>release/modules/ext/jcommon-1.0.23.jar</binary-origin>
|
|
||||||
</class-path-extension>
|
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jdom-2.0.5-contrib.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jdom-2.0.5-contrib.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/jdom-2.0.5-contrib.jar</binary-origin>
|
<binary-origin>release/modules/ext/jdom-2.0.5-contrib.jar</binary-origin>
|
||||||
|
@ -70,7 +70,7 @@ import org.sleuthkit.autopsy.actions.OpenOutputFolderAction;
|
|||||||
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
import org.sleuthkit.autopsy.appservices.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
|
import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
|
import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryAction;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
||||||
|
@ -33,6 +33,7 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text=
|
|||||||
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
||||||
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
||||||
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
||||||
|
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
||||||
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
||||||
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
DataSourceSummaryCountsPanel.jLabel1.text=Results by Type
|
||||||
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Top Programs Run
|
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Top Programs Run
|
@ -1,7 +1,6 @@
|
|||||||
CTL_DataSourceSummaryAction=Data Source Summary
|
CTL_DataSourceSummaryAction=Data Source Summary
|
||||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count
|
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count
|
||||||
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type
|
DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type
|
||||||
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
|
||||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All
|
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All
|
||||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated
|
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated
|
||||||
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count
|
DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count
|
||||||
@ -16,8 +15,6 @@ DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executabl
|
|||||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images
|
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images
|
||||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type
|
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type
|
||||||
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos
|
DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos
|
||||||
DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label=Not Analyzed
|
|
||||||
DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label=Other
|
|
||||||
DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.
|
DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.
|
||||||
DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure
|
DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure
|
||||||
DataSourceSummaryDetailsPanel.units.bytes=\ bytes
|
DataSourceSummaryDetailsPanel.units.bytes=\ bytes
|
||||||
@ -61,8 +58,9 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text=
|
|||||||
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details:
|
||||||
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space:
|
||||||
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
||||||
|
DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type
|
||||||
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
||||||
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
DataSourceSummaryCountsPanel.jLabel1.text=Results by Type
|
||||||
DataSourceSummaryDialog.window.title=Data Sources Summary
|
DataSourceSummaryDialog.window.title=Data Sources Summary
|
||||||
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
|
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
|
||||||
DataSourceSummaryNode.column.files.header=Files
|
DataSourceSummaryNode.column.files.header=Files
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.beans.PropertyVetoException;
|
import java.beans.PropertyVetoException;
|
||||||
@ -35,11 +35,10 @@ import javax.swing.event.ListSelectionListener;
|
|||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
||||||
import static javax.swing.SwingConstants.RIGHT;
|
import static javax.swing.SwingConstants.RIGHT;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.CaseDataSourcesSummary;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
@ -153,8 +152,8 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
|||||||
private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) {
|
private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) {
|
||||||
List<DataSourceSummary> summaryList = new ArrayList<>();
|
List<DataSourceSummary> summaryList = new ArrayList<>();
|
||||||
|
|
||||||
final Map<Long, Long> artifactCountsMap = CaseDataSourcesSummary.getCountsOfArtifacts();
|
final Map<Long, Long> artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts();
|
||||||
final Map<Long, Long> tagCountsMap = CaseDataSourcesSummary.getCountsOfTags();
|
final Map<Long, Long> tagCountsMap = DataSourceInfoUtilities.getCountsOfTags();
|
||||||
try {
|
try {
|
||||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
for (DataSource dataSource : skCase.getDataSources()) {
|
for (DataSource dataSource : skCase.getDataSources()) {
|
@ -0,0 +1,819 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 - 2020 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.casemodule.datasourcesummary;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for getting information about a data source or all data sources
|
||||||
|
* from the case database.
|
||||||
|
*/
|
||||||
|
final class DataSourceInfoUtilities {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a count of files for a particular datasource where it is not a
|
||||||
|
* virtual directory and has a name.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The datasource.
|
||||||
|
* @param additionalWhere Additional sql where clauses.
|
||||||
|
* @param onError The message to log on error.
|
||||||
|
*
|
||||||
|
* @return The count of files or null on error.
|
||||||
|
*/
|
||||||
|
private static Long getCountOfFiles(DataSource currentDataSource, String additionalWhere, String onError) {
|
||||||
|
if (currentDataSource != null) {
|
||||||
|
try {
|
||||||
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
return skCase.countFilesWhere(
|
||||||
|
"dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||||
|
+ " AND name<>''"
|
||||||
|
+ " AND data_source_obj_id=" + currentDataSource.getId()
|
||||||
|
+ " AND " + additionalWhere);
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, onError, ex);
|
||||||
|
//unable to get count of files for the specified types cell will be displayed as empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*/
|
||||||
|
static Long getCountOfFiles(DataSource currentDataSource) {
|
||||||
|
return getCountOfFiles(currentDataSource,
|
||||||
|
"type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType(),
|
||||||
|
"Unable to get count of files, providing empty results");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of unallocated files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*/
|
||||||
|
static Long getCountOfUnallocatedFiles(DataSource currentDataSource) {
|
||||||
|
return getCountOfFiles(currentDataSource,
|
||||||
|
"type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||||
|
+ " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
|
||||||
|
"Unable to get counts of unallocated files for datasource, providing empty results");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of directories in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*/
|
||||||
|
static Long getCountOfDirectories(DataSource currentDataSource) {
|
||||||
|
return getCountOfFiles(currentDataSource,
|
||||||
|
"type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||||
|
+ " AND meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue(),
|
||||||
|
"Unable to get count of directories for datasource, providing empty results");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get count of slack files in a data source.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*/
|
||||||
|
static Long getCountOfSlackFiles(DataSource currentDataSource) {
|
||||||
|
return getCountOfFiles(currentDataSource,
|
||||||
|
"type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(),
|
||||||
|
"Unable to get count of slack files for datasources, providing empty results");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for handling a result set and returning a value.
|
||||||
|
*/
|
||||||
|
private interface ResultSetHandler<T> {
|
||||||
|
|
||||||
|
T process(ResultSet resultset) throws SQLException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a result based on the provided query.
|
||||||
|
*
|
||||||
|
* @param query The query.
|
||||||
|
* @param processor The result set handler.
|
||||||
|
* @param errorMessage The error message to display if there is an error
|
||||||
|
* retrieving the resultset.
|
||||||
|
*
|
||||||
|
* @return The ResultSetHandler value or null if no ResultSet could be
|
||||||
|
* obtained.
|
||||||
|
*/
|
||||||
|
private static <T> T getBaseQueryResult(String query, ResultSetHandler<T> processor, String errorMessage) {
|
||||||
|
try (SleuthkitCase.CaseDbQuery dbQuery = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(query)) {
|
||||||
|
ResultSet resultSet = dbQuery.getResultSet();
|
||||||
|
try {
|
||||||
|
return processor.process(resultSet);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, errorMessage, ex);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, errorMessage, ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of unallocated files in a particular datasource.
|
||||||
|
*
|
||||||
|
* @param currentDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The size or null if the query could not be executed.
|
||||||
|
*/
|
||||||
|
static Long getSizeOfUnallocatedFiles(DataSource currentDataSource) {
|
||||||
|
if (currentDataSource == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String valueParam = "value";
|
||||||
|
final String countParam = "count";
|
||||||
|
String query = "SELECT SUM(size) AS " + valueParam + ", COUNT(*) AS " + countParam
|
||||||
|
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||||
|
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||||
|
+ " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||||
|
+ " AND name<>''"
|
||||||
|
+ " AND data_source_obj_id=" + currentDataSource.getId();
|
||||||
|
|
||||||
|
ResultSetHandler<Long> handler = (resultSet) -> {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
// ensure that there is an unallocated count result that is attached to this data source
|
||||||
|
long resultCount = resultSet.getLong(valueParam);
|
||||||
|
return (resultCount > 0) ? resultSet.getLong(valueParam) : null;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
String errorMessage = "Unable to get size of unallocated files; returning null.";
|
||||||
|
|
||||||
|
return getBaseQueryResult(query, handler, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a result set handler that will return a map of string to long.
|
||||||
|
*
|
||||||
|
* @param keyParam The named parameter in the result set representing the
|
||||||
|
* key.
|
||||||
|
* @param valueParam The named parameter in the result set representing the
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @return The result set handler to generate the map of string to long.
|
||||||
|
*/
|
||||||
|
private static ResultSetHandler<LinkedHashMap<String, Long>> getStringLongResultSetHandler(String keyParam, String valueParam) {
|
||||||
|
return (resultSet) -> {
|
||||||
|
LinkedHashMap<String, Long> toRet = new LinkedHashMap<>();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
try {
|
||||||
|
toRet.put(resultSet.getString(keyParam), resultSet.getLong(valueParam));
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to get a result pair from the result set.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return toRet;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves counts for each artifact type in a data source.
|
||||||
|
*
|
||||||
|
* @param selectedDataSource The data source.
|
||||||
|
*
|
||||||
|
* @return A mapping of artifact type name to the counts or null if there
|
||||||
|
* was an error executing the query.
|
||||||
|
*/
|
||||||
|
static Map<String, Long> getCountsOfArtifactsByType(DataSource selectedDataSource) {
|
||||||
|
if (selectedDataSource == null) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
final String nameParam = "name";
|
||||||
|
final String valueParam = "value";
|
||||||
|
String query
|
||||||
|
= "SELECT bbt.display_name AS " + nameParam + ", COUNT(*) AS " + valueParam
|
||||||
|
+ " FROM blackboard_artifacts bba "
|
||||||
|
+ " INNER JOIN blackboard_artifact_types bbt ON bba.artifact_type_id = bbt.artifact_type_id"
|
||||||
|
+ " WHERE bba.data_source_obj_id =" + selectedDataSource.getId()
|
||||||
|
+ " GROUP BY bbt.display_name";
|
||||||
|
|
||||||
|
String errorMessage = "Unable to get artifact type counts; returning null.";
|
||||||
|
return getBaseQueryResult(query, getStringLongResultSetHandler(nameParam, valueParam), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a result of a program run on a datasource.
|
||||||
|
*/
|
||||||
|
static class TopProgramsResult {
|
||||||
|
|
||||||
|
private final String programName;
|
||||||
|
private final String programPath;
|
||||||
|
private final Long runTimes;
|
||||||
|
private final Date lastRun;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param programName The name of the program.
|
||||||
|
* @param programPath The path of the program.
|
||||||
|
* @param runTimes The number of runs.
|
||||||
|
*/
|
||||||
|
TopProgramsResult(String programName, String programPath, Long runTimes, Date lastRun) {
|
||||||
|
this.programName = programName;
|
||||||
|
this.programPath = programPath;
|
||||||
|
this.runTimes = runTimes;
|
||||||
|
this.lastRun = lastRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the program
|
||||||
|
*/
|
||||||
|
String getProgramName() {
|
||||||
|
return programName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path of the program.
|
||||||
|
*/
|
||||||
|
String getProgramPath() {
|
||||||
|
return programPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of run times or null if not present.
|
||||||
|
*/
|
||||||
|
Long getRunTimes() {
|
||||||
|
return runTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The last time the program was run or null if not present.
|
||||||
|
*/
|
||||||
|
public Date getLastRun() {
|
||||||
|
return lastRun;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL join type.
|
||||||
|
*/
|
||||||
|
private enum JoinType {
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
INNER,
|
||||||
|
OUTER
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A blackboard attribute value column.
|
||||||
|
*/
|
||||||
|
private enum AttributeColumn {
|
||||||
|
value_text,
|
||||||
|
value_int32,
|
||||||
|
value_int64
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The suffix joined to a key name for use as an identifier of a query.
|
||||||
|
*/
|
||||||
|
private static final String QUERY_SUFFIX = "_query";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a sql statement querying the blackboard attributes table for a
|
||||||
|
* particular attribute type and returning a specified value. That query
|
||||||
|
* also joins with the blackboard artifact table.
|
||||||
|
*
|
||||||
|
* @param joinType The type of join statement to create.
|
||||||
|
* @param attributeColumn The blackboard attribute column that should be
|
||||||
|
* returned.
|
||||||
|
* @param attrType The attribute type to query for.
|
||||||
|
* @param keyName The aliased name of the attribute to return. This
|
||||||
|
* is also used to calculate the alias of the query
|
||||||
|
* same as getFullKey.
|
||||||
|
* @param bbaName The blackboard artifact table alias.
|
||||||
|
*
|
||||||
|
* @return The generated sql statement.
|
||||||
|
*/
|
||||||
|
private static String getAttributeJoin(JoinType joinType, AttributeColumn attributeColumn, ATTRIBUTE_TYPE attrType, String keyName, String bbaName) {
|
||||||
|
String queryName = keyName + QUERY_SUFFIX;
|
||||||
|
String innerQueryName = "inner_attribute_" + queryName;
|
||||||
|
|
||||||
|
return "\n" + joinType + " JOIN (\n"
|
||||||
|
+ " SELECT \n"
|
||||||
|
+ " " + innerQueryName + ".artifact_id,\n"
|
||||||
|
+ " " + innerQueryName + "." + attributeColumn + " AS " + keyName + "\n"
|
||||||
|
+ " FROM blackboard_attributes " + innerQueryName + "\n"
|
||||||
|
+ " WHERE " + innerQueryName + ".attribute_type_id = " + attrType.getTypeID() + " -- " + attrType.name() + "\n"
|
||||||
|
+ ") " + queryName + " ON " + queryName + ".artifact_id = " + bbaName + ".artifact_id\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a column key, creates the full name for the column key.
|
||||||
|
*
|
||||||
|
* @param key The column key.
|
||||||
|
*
|
||||||
|
* @return The full identifier for the column key.
|
||||||
|
*/
|
||||||
|
private static String getFullKey(String key) {
|
||||||
|
return key + QUERY_SUFFIX + "." + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a SQL 'where' statement from a list of clauses and puts
|
||||||
|
* parenthesis around each clause.
|
||||||
|
*
|
||||||
|
* @param clauses The clauses
|
||||||
|
*
|
||||||
|
* @return The generated 'where' statement.
|
||||||
|
*/
|
||||||
|
private static String getWhereString(List<String> clauses) {
|
||||||
|
if (clauses.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> parenthesized = clauses.stream()
|
||||||
|
.map(c -> "(" + c + ")")
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return "\nWHERE " + String.join("\n AND ", parenthesized) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a [column] LIKE sql clause.
|
||||||
|
*
|
||||||
|
* @param column The column identifier.
|
||||||
|
* @param likeString The string that will be used as column comparison.
|
||||||
|
* @param isLike if false, the statement becomes NOT LIKE.
|
||||||
|
*
|
||||||
|
* @return The generated statement.
|
||||||
|
*/
|
||||||
|
private static String getLikeClause(String column, String likeString, boolean isLike) {
|
||||||
|
return column + (isLike ? "" : " NOT") + " LIKE '" + likeString + "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of the top programs used on the data source. Currently
|
||||||
|
* determines this based off of which prefetch results return the highest
|
||||||
|
* count.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
* @param count The number of programs to return.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static List<TopProgramsResult> getTopPrograms(DataSource dataSource, int count) {
|
||||||
|
if (dataSource == null || count <= 0) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ntosboot should be ignored
|
||||||
|
final String ntosBootIdentifier = "NTOSBOOT";
|
||||||
|
// programs in windows directory to be ignored
|
||||||
|
final String windowsDir = "/WINDOWS%";
|
||||||
|
|
||||||
|
final String nameParam = "name";
|
||||||
|
final String pathParam = "path";
|
||||||
|
final String runCountParam = "run_count";
|
||||||
|
final String lastRunParam = "last_run";
|
||||||
|
|
||||||
|
String bbaQuery = "bba";
|
||||||
|
|
||||||
|
final String query = "SELECT\n"
|
||||||
|
+ " " + getFullKey(nameParam) + " AS " + nameParam + ",\n"
|
||||||
|
+ " " + getFullKey(pathParam) + " AS " + pathParam + ",\n"
|
||||||
|
+ " MAX(" + getFullKey(runCountParam) + ") AS " + runCountParam + ",\n"
|
||||||
|
+ " MAX(" + getFullKey(lastRunParam) + ") AS " + lastRunParam + "\n"
|
||||||
|
+ "FROM blackboard_artifacts " + bbaQuery + "\n"
|
||||||
|
+ getAttributeJoin(JoinType.INNER, AttributeColumn.value_text, ATTRIBUTE_TYPE.TSK_PROG_NAME, nameParam, bbaQuery)
|
||||||
|
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_text, ATTRIBUTE_TYPE.TSK_PATH, pathParam, bbaQuery)
|
||||||
|
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int32, ATTRIBUTE_TYPE.TSK_COUNT, runCountParam, bbaQuery)
|
||||||
|
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int64, ATTRIBUTE_TYPE.TSK_DATETIME, lastRunParam, bbaQuery)
|
||||||
|
+ getWhereString(Arrays.asList(
|
||||||
|
bbaQuery + ".artifact_type_id = " + ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID(),
|
||||||
|
bbaQuery + ".data_source_obj_id = " + dataSource.getId(),
|
||||||
|
// exclude ntosBootIdentifier from results
|
||||||
|
getLikeClause(getFullKey(nameParam), ntosBootIdentifier, false),
|
||||||
|
// exclude windows directory items from results
|
||||||
|
getFullKey(pathParam) + " IS NULL OR " + getLikeClause(getFullKey(pathParam), windowsDir, false)
|
||||||
|
))
|
||||||
|
+ "GROUP BY " + getFullKey(nameParam) + ", " + getFullKey(pathParam) + "\n"
|
||||||
|
+ "ORDER BY \n"
|
||||||
|
+ " MAX(" + getFullKey(runCountParam) + ") DESC,\n"
|
||||||
|
+ " MAX(" + getFullKey(lastRunParam) + ") DESC,\n"
|
||||||
|
+ " " + getFullKey(nameParam) + " ASC";
|
||||||
|
|
||||||
|
final String errorMessage = "Unable to get top program results; returning null.";
|
||||||
|
|
||||||
|
ResultSetHandler<List<TopProgramsResult>> handler = (resultSet) -> {
|
||||||
|
List<TopProgramsResult> progResults = new ArrayList<>();
|
||||||
|
|
||||||
|
boolean quitAtCount = false;
|
||||||
|
|
||||||
|
while (resultSet.next() && (!quitAtCount || progResults.size() < count)) {
|
||||||
|
try {
|
||||||
|
long lastRunEpoch = resultSet.getLong(lastRunParam);
|
||||||
|
Date lastRun = (resultSet.wasNull()) ? null : new Date(lastRunEpoch * 1000);
|
||||||
|
|
||||||
|
Long runCount = resultSet.getLong(runCountParam);
|
||||||
|
if (resultSet.wasNull()) {
|
||||||
|
runCount = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastRun != null || runCount != null) {
|
||||||
|
quitAtCount = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
progResults.add(new TopProgramsResult(
|
||||||
|
resultSet.getString(nameParam),
|
||||||
|
resultSet.getString(pathParam),
|
||||||
|
runCount,
|
||||||
|
lastRun));
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to get a top program result from the result set.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return progResults;
|
||||||
|
};
|
||||||
|
|
||||||
|
return getBaseQueryResult(query, handler, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions that determine the folder name of a list of path elements. If
|
||||||
|
* not matched, function returns null.
|
||||||
|
*/
|
||||||
|
private static final List<Function<List<String>, String>> SHORT_FOLDER_MATCHERS = Arrays.asList(
|
||||||
|
// handle Program Files and Program Files (x86) - if true, return the next folder
|
||||||
|
(pathList) -> {
|
||||||
|
if (pathList.size() < 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String rootParent = pathList.get(0).toUpperCase();
|
||||||
|
if ("PROGRAM FILES".equals(rootParent) || "PROGRAM FILES (X86)".equals(rootParent)) {
|
||||||
|
return pathList.get(1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// if there is a folder named "APPLICATION DATA" or "APPDATA"
|
||||||
|
(pathList) -> {
|
||||||
|
for (String pathEl : pathList) {
|
||||||
|
String uppered = pathEl.toUpperCase();
|
||||||
|
if ("APPLICATION DATA".equals(uppered) || "APPDATA".equals(uppered)) {
|
||||||
|
return "AppData";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines a short folder name if any. Otherwise, returns empty string.
|
||||||
|
*
|
||||||
|
* @param strPath The string path.
|
||||||
|
*
|
||||||
|
* @return The short folder name or empty string if not found.
|
||||||
|
*/
|
||||||
|
static String getShortFolderName(String strPath, String applicationName) {
|
||||||
|
if (strPath == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> pathEls = new ArrayList<>(Arrays.asList(applicationName));
|
||||||
|
|
||||||
|
File file = new File(strPath);
|
||||||
|
while (file != null && StringUtils.isNotBlank(file.getName())) {
|
||||||
|
pathEls.add(file.getName());
|
||||||
|
file = file.getParentFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.reverse(pathEls);
|
||||||
|
|
||||||
|
for (Function<List<String>, String> matchEntry : SHORT_FOLDER_MATCHERS) {
|
||||||
|
String result = matchEntry.apply(pathEls);
|
||||||
|
if (StringUtils.isNotBlank(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a string which is a concatenation of the value received from
|
||||||
|
* the result set.
|
||||||
|
*
|
||||||
|
* @param query The query.
|
||||||
|
* @param valueParam The parameter for the value in the result set.
|
||||||
|
* @param separator The string separator used in concatenation.
|
||||||
|
* @param errorMessage The error message if the result set could not
|
||||||
|
* be received.
|
||||||
|
* @param singleErrorMessage The error message if a single result could not
|
||||||
|
* be obtained.
|
||||||
|
*
|
||||||
|
* @return The concatenated string or null if the query could not be
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
private static String getConcattedStringsResult(String query, String valueParam, String separator, String errorMessage, String singleErrorMessage) {
|
||||||
|
ResultSetHandler<String> handler = (resultSet) -> {
|
||||||
|
String toRet = "";
|
||||||
|
boolean first = true;
|
||||||
|
while (resultSet.next()) {
|
||||||
|
try {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
toRet += separator;
|
||||||
|
}
|
||||||
|
toRet += resultSet.getString(valueParam);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, singleErrorMessage, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return toRet;
|
||||||
|
};
|
||||||
|
|
||||||
|
return getBaseQueryResult(query, handler, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a concatenated string value based on the text value of a
|
||||||
|
* particular attribute in a particular artifact for a specific data source.
|
||||||
|
*
|
||||||
|
* @param dataSourceId The data source id.
|
||||||
|
* @param artifactTypeId The artifact type id.
|
||||||
|
* @param attributeTypeId The attribute type id.
|
||||||
|
*
|
||||||
|
* @return The concatenated value or null if the query could not be
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
private static String getConcattedAttrValue(long dataSourceId, int artifactTypeId, int attributeTypeId) {
|
||||||
|
final String valueParam = "concatted_attribute_value";
|
||||||
|
String query = "SELECT attr.value_text AS " + valueParam
|
||||||
|
+ " FROM blackboard_artifacts bba "
|
||||||
|
+ " INNER JOIN blackboard_attributes attr ON bba.artifact_id = attr.artifact_id "
|
||||||
|
+ " WHERE bba.data_source_obj_id = " + dataSourceId
|
||||||
|
+ " AND bba.artifact_type_id = " + artifactTypeId
|
||||||
|
+ " AND attr.attribute_type_id = " + attributeTypeId;
|
||||||
|
|
||||||
|
String errorMessage = "Unable to execute query to retrieve concatted attribute values.";
|
||||||
|
String singleErrorMessage = "There was an error retrieving one of the results. That result will be omitted from concatted value.";
|
||||||
|
String separator = ", ";
|
||||||
|
return getConcattedStringsResult(query, valueParam, separator, errorMessage, singleErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the concatenation of operating system attributes for a
|
||||||
|
* particular data source.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The concatenated value or null if the query could not be
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
static String getOperatingSystems(DataSource dataSource) {
|
||||||
|
if (dataSource == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getConcattedAttrValue(dataSource.getId(),
|
||||||
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the concatenation of data source usage for a particular data
|
||||||
|
* source.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
*
|
||||||
|
* @return The concatenated value or null if the query could not be
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
static String getDataSourceType(DataSource dataSource) {
|
||||||
|
if (dataSource == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getConcattedAttrValue(dataSource.getId(),
|
||||||
|
BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map containing the TSK_DATA_SOURCE_USAGE description attributes
|
||||||
|
* associated with each data source in the current case.
|
||||||
|
*
|
||||||
|
* @return Collection which maps datasource id to a String which displays a
|
||||||
|
* comma seperated list of values of data source usage types
|
||||||
|
* expected to be in the datasource
|
||||||
|
*/
|
||||||
|
static Map<Long, String> getDataSourceTypes() {
|
||||||
|
try {
|
||||||
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
|
||||||
|
Map<Long, String> typeMap = new HashMap<>();
|
||||||
|
for (BlackboardArtifact typeArtifact : listOfArtifacts) {
|
||||||
|
BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION));
|
||||||
|
if (typeArtifact.getDataSource() != null && descriptionAttr != null) {
|
||||||
|
long dsId = typeArtifact.getDataSource().getId();
|
||||||
|
String type = typeMap.get(typeArtifact.getDataSource().getId());
|
||||||
|
if (type == null) {
|
||||||
|
type = descriptionAttr.getValueString();
|
||||||
|
} else {
|
||||||
|
type = type + ", " + descriptionAttr.getValueString();
|
||||||
|
}
|
||||||
|
typeMap.put(dsId, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeMap;
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex);
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map containing the number of files in each data source in the
|
||||||
|
* current case.
|
||||||
|
*
|
||||||
|
* @return Collection which maps datasource id to a count for the number of
|
||||||
|
* files in the datasource, will only contain entries for
|
||||||
|
* datasources which have at least 1 file
|
||||||
|
*/
|
||||||
|
static Map<Long, Long> getCountsOfFiles() {
|
||||||
|
try {
|
||||||
|
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||||
|
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||||
|
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||||
|
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
|
||||||
|
return getValuesMap(countFilesQuery);
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map containing the number of artifacts in each data source in the
|
||||||
|
* current case.
|
||||||
|
*
|
||||||
|
* @return Collection which maps datasource id to a count for the number of
|
||||||
|
* artifacts in the datasource, will only contain entries for
|
||||||
|
* datasources which have at least 1 artifact
|
||||||
|
*/
|
||||||
|
static Map<Long, Long> getCountsOfArtifacts() {
|
||||||
|
try {
|
||||||
|
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||||
|
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
|
||||||
|
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||||
|
return getValuesMap(countArtifactsQuery);
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map containing the number of tags which have been applied in each
|
||||||
|
* data source in the current case. Not necessarily the same as the number
|
||||||
|
* of items tagged, as an item can have any number of tags.
|
||||||
|
*
|
||||||
|
* @return Collection which maps datasource id to a count for the number of
|
||||||
|
* tags which have been applied in the datasource, will only contain
|
||||||
|
* entries for datasources which have at least 1 item tagged.
|
||||||
|
*/
|
||||||
|
static Map<Long, Long> getCountsOfTags() {
|
||||||
|
try {
|
||||||
|
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||||
|
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
|
||||||
|
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
|
||||||
|
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||||
|
//new hashmap so it can be modifiable
|
||||||
|
Map<Long, Long> tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery));
|
||||||
|
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
||||||
|
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
|
||||||
|
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
|
||||||
|
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
||||||
|
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
|
||||||
|
getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
|
||||||
|
return tagCountMap;
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
||||||
|
if (currentDataSource != null) {
|
||||||
|
try {
|
||||||
|
String inClause = String.join("', '", setOfMimeTypes);
|
||||||
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
return skCase.countFilesWhere("data_source_obj_id=" + currentDataSource.getId()
|
||||||
|
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
||||||
|
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
||||||
|
+ " AND mime_type IN ('" + inClause + "')"
|
||||||
|
+ " AND name<>''");
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get count of files for specified mime types", ex);
|
||||||
|
//unable to get count of files for the specified mimetypes cell will be displayed as empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to execute a select query with a
|
||||||
|
* DataSourceSingleValueCallback.
|
||||||
|
*
|
||||||
|
* @param query the portion of the query which should follow the SELECT
|
||||||
|
*
|
||||||
|
* @return a map of datasource object ID to a value of type Long
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
|
*/
|
||||||
|
private static Map<Long, Long> getValuesMap(String query) throws TskCoreException, NoCurrentCaseException {
|
||||||
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback();
|
||||||
|
skCase.getCaseDbAccessManager().select(query, callback);
|
||||||
|
return callback.getMapOfValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty private constructor
|
||||||
|
*/
|
||||||
|
private DataSourceInfoUtilities() {
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.datamodel;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@ -28,7 +28,6 @@ import org.openide.util.HelpCtx;
|
|||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
|
||||||
|
|
||||||
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction")
|
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction")
|
||||||
@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false)
|
@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false)
|
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
|
<Component id="fileCountsByMimeTypeScrollPane" linkSize="1" pref="140" max="32767" attributes="0"/>
|
||||||
|
<Component id="byMimeTypeLabel" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="byCategoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="fileCountsByCategoryScrollPane" linkSize="1" alignment="0" min="-2" pref="82" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jLabel1" min="-2" pref="79" max="-2" attributes="0"/>
|
||||||
|
<Component id="artifactCountsScrollPane" min="-2" pref="244" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="byMimeTypeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="byCategoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="artifactCountsScrollPane" alignment="1" pref="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="fileCountsByMimeTypeScrollPane" linkSize="2" min="-2" pref="107" max="-2" attributes="0"/>
|
||||||
|
<Component id="fileCountsByCategoryScrollPane" linkSize="2" min="-2" pref="86" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="fileCountsByMimeTypeScrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTable" name="fileCountsByMimeTypeTable">
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JLabel" name="byMimeTypeLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryCountsPanel.byMimeTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="fileCountsByCategoryScrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTable" name="fileCountsByCategoryTable">
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JLabel" name="byCategoryLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryCountsPanel.byCategoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryCountsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="artifactCountsScrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTable" name="artifactCountsTable">
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -24,8 +24,7 @@ import javax.swing.JLabel;
|
|||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary;
|
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
||||||
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,8 +40,6 @@ import org.sleuthkit.datamodel.DataSource;
|
|||||||
})
|
})
|
||||||
class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
// Result returned for a data model if no data found.
|
// Result returned for a data model if no data found.
|
||||||
private static final Object[][] EMPTY_PAIRS = new Object[][]{};
|
private static final Object[][] EMPTY_PAIRS = new Object[][]{};
|
||||||
|
|
||||||
@ -64,11 +61,10 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_count_header()
|
Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_count_header()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryCountsPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(DataSourceSummaryCountsPanel.class.getName());
|
||||||
private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer();
|
private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer();
|
||||||
|
|
||||||
private final FileTypePieChart fileTypePieChart = new FileTypePieChart();
|
|
||||||
|
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,6 +73,7 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
DataSourceSummaryCountsPanel() {
|
DataSourceSummaryCountsPanel() {
|
||||||
rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT);
|
rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT);
|
||||||
initComponents();
|
initComponents();
|
||||||
|
fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false);
|
||||||
fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false);
|
fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false);
|
||||||
artifactCountsTable.getTableHeader().setReorderingAllowed(false);
|
artifactCountsTable.getTableHeader().setReorderingAllowed(false);
|
||||||
setDataSource(null);
|
setDataSource(null);
|
||||||
@ -99,20 +96,29 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
if (dataSource == null || !Case.isCaseOpen()) {
|
if (dataSource == null || !Case.isCaseOpen()) {
|
||||||
updateCountsTableData(EMPTY_PAIRS, EMPTY_PAIRS);
|
updateCountsTableData(EMPTY_PAIRS,
|
||||||
|
EMPTY_PAIRS,
|
||||||
|
EMPTY_PAIRS);
|
||||||
} else {
|
} else {
|
||||||
updateCountsTableData(getFileCategoryModel(dataSource), getArtifactCountsModel(dataSource));
|
updateCountsTableData(getMimeTypeModel(dataSource),
|
||||||
|
getFileCategoryModel(dataSource),
|
||||||
|
getArtifactCountsModel(dataSource));
|
||||||
}
|
}
|
||||||
this.fileTypePieChart.setDataSource(dataSource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the DataSource to display file information for.
|
* Specify the DataSource to display file information for.
|
||||||
*
|
*
|
||||||
|
* @param mimeTypeDataModel The mime type data model.
|
||||||
* @param fileCategoryDataModel The file category data model.
|
* @param fileCategoryDataModel The file category data model.
|
||||||
* @param artifactDataModel The artifact type data model.
|
* @param artifactDataModel The artifact type data model.
|
||||||
*/
|
*/
|
||||||
private void updateCountsTableData(Object[][] fileCategoryDataModel, Object[][] artifactDataModel) {
|
private void updateCountsTableData(Object[][] mimeTypeDataModel, Object[][] fileCategoryDataModel, Object[][] artifactDataModel) {
|
||||||
|
fileCountsByMimeTypeTable.setModel(new NonEditableTableModel(mimeTypeDataModel, MIME_TYPE_COLUMN_HEADERS));
|
||||||
|
fileCountsByMimeTypeTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||||
|
fileCountsByMimeTypeTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
||||||
|
|
||||||
fileCountsByCategoryTable.setModel(new NonEditableTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS));
|
fileCountsByCategoryTable.setModel(new NonEditableTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS));
|
||||||
fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
|
||||||
fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130);
|
||||||
@ -124,6 +130,48 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the JTable data model for datasource mime types.
|
||||||
|
*
|
||||||
|
* @param dataSource The DataSource.
|
||||||
|
*
|
||||||
|
* @return The model to be used with a JTable.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images",
|
||||||
|
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos",
|
||||||
|
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio",
|
||||||
|
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents",
|
||||||
|
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables"
|
||||||
|
})
|
||||||
|
private static Object[][] getMimeTypeModel(DataSource dataSource) {
|
||||||
|
return new Object[][]{
|
||||||
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row(),
|
||||||
|
getCount(dataSource, FileTypeUtils.FileTypeCategory.IMAGE)},
|
||||||
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row(),
|
||||||
|
getCount(dataSource, FileTypeUtils.FileTypeCategory.VIDEO)},
|
||||||
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row(),
|
||||||
|
getCount(dataSource, FileTypeUtils.FileTypeCategory.AUDIO)},
|
||||||
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row(),
|
||||||
|
getCount(dataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS)},
|
||||||
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row(),
|
||||||
|
getCount(dataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE)}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the counts of files of a particular mime type for a particular
|
||||||
|
* DataSource.
|
||||||
|
*
|
||||||
|
* @param dataSource The DataSource.
|
||||||
|
* @param category The mime type category.
|
||||||
|
*
|
||||||
|
* @return The count.
|
||||||
|
*/
|
||||||
|
private static Long getCount(DataSource dataSource, FileTypeUtils.FileTypeCategory category) {
|
||||||
|
return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(dataSource, category.getMediaTypes());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the JTable data model for datasource file categories.
|
* Determines the JTable data model for datasource file categories.
|
||||||
*
|
*
|
||||||
@ -139,11 +187,11 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory"
|
"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory"
|
||||||
})
|
})
|
||||||
private static Object[][] getFileCategoryModel(DataSource selectedDataSource) {
|
private static Object[][] getFileCategoryModel(DataSource selectedDataSource) {
|
||||||
Long fileCount = zeroIfNull(DataSourceCountsSummary.getCountOfFiles(selectedDataSource));
|
Long fileCount = zeroIfNull(DataSourceInfoUtilities.getCountOfFiles(selectedDataSource));
|
||||||
Long unallocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfUnallocatedFiles(selectedDataSource));
|
Long unallocatedFiles = zeroIfNull(DataSourceInfoUtilities.getCountOfUnallocatedFiles(selectedDataSource));
|
||||||
Long allocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfAllocatedFiles(selectedDataSource));
|
Long allocatedFiles = zeroIfNull(getAllocatedCount(fileCount, unallocatedFiles));
|
||||||
Long slackFiles = zeroIfNull(DataSourceCountsSummary.getCountOfSlackFiles(selectedDataSource));
|
Long slackFiles = zeroIfNull(DataSourceInfoUtilities.getCountOfSlackFiles(selectedDataSource));
|
||||||
Long directories = zeroIfNull(DataSourceCountsSummary.getCountOfDirectories(selectedDataSource));
|
Long directories = zeroIfNull(DataSourceInfoUtilities.getCountOfDirectories(selectedDataSource));
|
||||||
|
|
||||||
return new Object[][]{
|
return new Object[][]{
|
||||||
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount},
|
new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount},
|
||||||
@ -165,6 +213,24 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
return origValue == null ? 0 : origValue;
|
return origValue == null ? 0 : origValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely gets the allocated files count.
|
||||||
|
*
|
||||||
|
* @param allFilesCount The count of all files.
|
||||||
|
* @param unallocatedFilesCount The count of unallocated files.
|
||||||
|
*
|
||||||
|
* @return The count of allocated files.
|
||||||
|
*/
|
||||||
|
private static long getAllocatedCount(Long allFilesCount, Long unallocatedFilesCount) {
|
||||||
|
if (allFilesCount == null) {
|
||||||
|
return 0;
|
||||||
|
} else if (unallocatedFilesCount == null) {
|
||||||
|
return allFilesCount;
|
||||||
|
} else {
|
||||||
|
return allFilesCount - unallocatedFilesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The counts of different artifact types found in a DataSource.
|
* The counts of different artifact types found in a DataSource.
|
||||||
*
|
*
|
||||||
@ -173,7 +239,7 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
* @return The JTable data model of counts of artifact types.
|
* @return The JTable data model of counts of artifact types.
|
||||||
*/
|
*/
|
||||||
private static Object[][] getArtifactCountsModel(DataSource selectedDataSource) {
|
private static Object[][] getArtifactCountsModel(DataSource selectedDataSource) {
|
||||||
Map<String, Long> artifactMapping = DataSourceCountsSummary.getCountsOfArtifactsByType(selectedDataSource);
|
Map<String, Long> artifactMapping = DataSourceInfoUtilities.getCountsOfArtifactsByType(selectedDataSource);
|
||||||
if (artifactMapping == null) {
|
if (artifactMapping == null) {
|
||||||
return EMPTY_PAIRS;
|
return EMPTY_PAIRS;
|
||||||
}
|
}
|
||||||
@ -194,120 +260,83 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
|
|||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
javax.swing.JScrollPane scrollParent = new javax.swing.JScrollPane();
|
fileCountsByMimeTypeScrollPane = new javax.swing.JScrollPane();
|
||||||
javax.swing.JPanel parentPanel = new javax.swing.JPanel();
|
fileCountsByMimeTypeTable = new javax.swing.JTable();
|
||||||
javax.swing.JScrollPane fileCountsByCategoryScrollPane = new javax.swing.JScrollPane();
|
byMimeTypeLabel = new javax.swing.JLabel();
|
||||||
|
fileCountsByCategoryScrollPane = new javax.swing.JScrollPane();
|
||||||
fileCountsByCategoryTable = new javax.swing.JTable();
|
fileCountsByCategoryTable = new javax.swing.JTable();
|
||||||
javax.swing.JLabel byCategoryLabel = new javax.swing.JLabel();
|
byCategoryLabel = new javax.swing.JLabel();
|
||||||
javax.swing.JLabel resultsByTypeLabel = new javax.swing.JLabel();
|
jLabel1 = new javax.swing.JLabel();
|
||||||
javax.swing.JScrollPane artifactCountsScrollPane = new javax.swing.JScrollPane();
|
artifactCountsScrollPane = new javax.swing.JScrollPane();
|
||||||
artifactCountsTable = new javax.swing.JTable();
|
artifactCountsTable = new javax.swing.JTable();
|
||||||
javax.swing.JPanel fileTypePiePanel = fileTypePieChart;
|
|
||||||
javax.swing.JPanel filesByCatParent = new javax.swing.JPanel();
|
|
||||||
javax.swing.JPanel resultsByTypeParent = new javax.swing.JPanel();
|
|
||||||
|
|
||||||
parentPanel.setMinimumSize(new java.awt.Dimension(840, 320));
|
fileCountsByMimeTypeScrollPane.setViewportView(fileCountsByMimeTypeTable);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(byMimeTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byMimeTypeLabel.text")); // NOI18N
|
||||||
|
|
||||||
fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable);
|
fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(resultsByTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.resultsByTypeLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.jLabel1.text")); // NOI18N
|
||||||
|
|
||||||
artifactCountsTable.setAutoCreateRowSorter(true);
|
|
||||||
artifactCountsScrollPane.setViewportView(artifactCountsTable);
|
artifactCountsScrollPane.setViewportView(artifactCountsTable);
|
||||||
|
|
||||||
fileTypePiePanel.setPreferredSize(new java.awt.Dimension(400, 300));
|
|
||||||
|
|
||||||
javax.swing.GroupLayout filesByCatParentLayout = new javax.swing.GroupLayout(filesByCatParent);
|
|
||||||
filesByCatParent.setLayout(filesByCatParentLayout);
|
|
||||||
filesByCatParentLayout.setHorizontalGroup(
|
|
||||||
filesByCatParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
filesByCatParentLayout.setVerticalGroup(
|
|
||||||
filesByCatParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout resultsByTypeParentLayout = new javax.swing.GroupLayout(resultsByTypeParent);
|
|
||||||
resultsByTypeParent.setLayout(resultsByTypeParentLayout);
|
|
||||||
resultsByTypeParentLayout.setHorizontalGroup(
|
|
||||||
resultsByTypeParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
resultsByTypeParentLayout.setVerticalGroup(
|
|
||||||
resultsByTypeParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout parentPanelLayout = new javax.swing.GroupLayout(parentPanel);
|
|
||||||
parentPanel.setLayout(parentPanelLayout);
|
|
||||||
parentPanelLayout.setHorizontalGroup(
|
|
||||||
parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addComponent(fileTypePiePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(18, 18, 18)
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addComponent(byCategoryLabel)
|
|
||||||
.addComponent(filesByCatParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
||||||
.addGap(18, 18, 18)
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(resultsByTypeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(resultsByTypeParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
);
|
|
||||||
parentPanelLayout.setVerticalGroup(
|
|
||||||
parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addComponent(fileTypePiePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
||||||
.addComponent(byCategoryLabel)
|
|
||||||
.addComponent(resultsByTypeLabel))
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, parentPanelLayout.createSequentialGroup()
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addComponent(resultsByTypeParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(148, 148, 148))
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addGroup(parentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
|
||||||
.addGroup(parentPanelLayout.createSequentialGroup()
|
|
||||||
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(31, 31, 31)
|
|
||||||
.addComponent(filesByCatParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)))
|
|
||||||
.addContainerGap())))))
|
|
||||||
);
|
|
||||||
|
|
||||||
scrollParent.setViewportView(parentPanel);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(scrollParent)
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
|
.addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
|
||||||
|
.addComponent(byMimeTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(byCategoryLabel)
|
||||||
|
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane});
|
||||||
|
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(scrollParent)
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(byMimeTypeLabel)
|
||||||
|
.addComponent(byCategoryLabel)
|
||||||
|
.addComponent(jLabel1))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE)))
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane});
|
||||||
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JScrollPane artifactCountsScrollPane;
|
||||||
private javax.swing.JTable artifactCountsTable;
|
private javax.swing.JTable artifactCountsTable;
|
||||||
|
private javax.swing.JLabel byCategoryLabel;
|
||||||
|
private javax.swing.JLabel byMimeTypeLabel;
|
||||||
|
private javax.swing.JScrollPane fileCountsByCategoryScrollPane;
|
||||||
private javax.swing.JTable fileCountsByCategoryTable;
|
private javax.swing.JTable fileCountsByCategoryTable;
|
||||||
|
private javax.swing.JScrollPane fileCountsByMimeTypeScrollPane;
|
||||||
|
private javax.swing.JTable fileCountsByMimeTypeTable;
|
||||||
|
private javax.swing.JLabel jLabel1;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
}
|
}
|
@ -40,7 +40,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="operatingSystemLabel">
|
<Component class="javax.swing.JLabel" name="operatingSystemLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="displayNameLabel">
|
<Component class="javax.swing.JLabel" name="displayNameLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -64,7 +64,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="originalNameLabel">
|
<Component class="javax.swing.JLabel" name="originalNameLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -76,7 +76,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sha1HashValue">
|
<Component class="javax.swing.JLabel" name="sha1HashValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -88,10 +88,10 @@
|
|||||||
<Component class="javax.swing.JLabel" name="operatingSystemValue">
|
<Component class="javax.swing.JLabel" name="operatingSystemValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -103,7 +103,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="displayNameValue">
|
<Component class="javax.swing.JLabel" name="displayNameValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.displayNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -115,7 +115,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sha256HashValue">
|
<Component class="javax.swing.JLabel" name="sha256HashValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="originalNameValue">
|
<Component class="javax.swing.JLabel" name="originalNameValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.originalNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -139,10 +139,10 @@
|
|||||||
<Component class="javax.swing.JLabel" name="deviceIdValue">
|
<Component class="javax.swing.JLabel" name="deviceIdValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -179,7 +179,7 @@
|
|||||||
<TableColumnModel selectionModel="0">
|
<TableColumnModel selectionModel="0">
|
||||||
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
|
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
|
||||||
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Title>
|
</Title>
|
||||||
<Editor/>
|
<Editor/>
|
||||||
<Renderer/>
|
<Renderer/>
|
||||||
@ -196,7 +196,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="dataSourceUsageValue">
|
<Component class="javax.swing.JLabel" name="dataSourceUsageValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -208,7 +208,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="timeZoneValue">
|
<Component class="javax.swing.JLabel" name="timeZoneValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -220,10 +220,10 @@
|
|||||||
<Component class="javax.swing.JLabel" name="imageTypeValue">
|
<Component class="javax.swing.JLabel" name="imageTypeValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -235,10 +235,10 @@
|
|||||||
<Component class="javax.swing.JLabel" name="md5HashValue">
|
<Component class="javax.swing.JLabel" name="md5HashValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashValue.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -250,7 +250,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sectorSizeValue">
|
<Component class="javax.swing.JLabel" name="sectorSizeValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -262,7 +262,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sizeValue">
|
<Component class="javax.swing.JLabel" name="sizeValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -274,7 +274,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="filePathsLabel">
|
<Component class="javax.swing.JLabel" name="filePathsLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -286,7 +286,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sha256HashLabel">
|
<Component class="javax.swing.JLabel" name="sha256HashLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha256HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -298,7 +298,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sha1HashLabel">
|
<Component class="javax.swing.JLabel" name="sha1HashLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sha1HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -310,7 +310,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="md5HashLabel">
|
<Component class="javax.swing.JLabel" name="md5HashLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.md5HashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -322,7 +322,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sectorSizeLabel">
|
<Component class="javax.swing.JLabel" name="sectorSizeLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sectorSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -334,7 +334,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="sizeLabel">
|
<Component class="javax.swing.JLabel" name="sizeLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -346,7 +346,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="imageTypeLabel">
|
<Component class="javax.swing.JLabel" name="imageTypeLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.imageTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -358,7 +358,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="acquisitionDetailsLabel">
|
<Component class="javax.swing.JLabel" name="acquisitionDetailsLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -370,7 +370,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="timeZoneLabel">
|
<Component class="javax.swing.JLabel" name="timeZoneLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.timeZoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -382,7 +382,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="dataSourceUsageLabel">
|
<Component class="javax.swing.JLabel" name="dataSourceUsageLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -394,7 +394,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="deviceIdLabel">
|
<Component class="javax.swing.JLabel" name="deviceIdLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -424,7 +424,7 @@
|
|||||||
<Property name="columns" type="int" value="20"/>
|
<Property name="columns" type="int" value="20"/>
|
||||||
<Property name="rows" type="int" value="4"/>
|
<Property name="rows" type="int" value="4"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="null"/>
|
<Border info="null"/>
|
||||||
@ -466,7 +466,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="unallocatedSizeLabel">
|
<Component class="javax.swing.JLabel" name="unallocatedSizeLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
||||||
@ -478,7 +478,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="unallocatedSizeValue">
|
<Component class="javax.swing.JLabel" name="unallocatedSizeValue">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.unallocatedSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Constraints>
|
<Constraints>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -25,7 +25,6 @@ import javax.swing.table.DefaultTableModel;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceDetailsSummary;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
@ -74,9 +73,9 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
|||||||
updateDetailsPanelData(null, null, null, null);
|
updateDetailsPanelData(null, null, null, null);
|
||||||
} else {
|
} else {
|
||||||
updateDetailsPanelData(dataSource,
|
updateDetailsPanelData(dataSource,
|
||||||
DataSourceDetailsSummary.getSizeOfUnallocatedFiles(dataSource),
|
DataSourceInfoUtilities.getSizeOfUnallocatedFiles(dataSource),
|
||||||
DataSourceDetailsSummary.getOperatingSystems(dataSource),
|
DataSourceInfoUtilities.getOperatingSystems(dataSource),
|
||||||
DataSourceDetailsSummary.getDataSourceType(dataSource));
|
DataSourceInfoUtilities.getDataSourceType(dataSource));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,7 @@
|
|||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
<Component id="dataSourceSummarySplitPane" pref="860" max="32767" attributes="0"/>
|
<Component id="dataSourceSummarySplitPane" pref="668" max="32767" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="dataSourceSummarySplitPane" pref="540" max="32767" attributes="0"/>
|
<Component id="dataSourceSummarySplitPane" pref="362" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="closeButton">
|
<Component class="javax.swing.JButton" name="closeButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryDialog.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDialog.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@ -27,7 +27,6 @@ import java.util.Observer;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.CaseDataSourcesSummary;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
||||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason;
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason;
|
||||||
@ -54,8 +53,8 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
|||||||
})
|
})
|
||||||
DataSourceSummaryDialog(Frame owner) {
|
DataSourceSummaryDialog(Frame owner) {
|
||||||
super(owner, Bundle.DataSourceSummaryDialog_window_title(), true);
|
super(owner, Bundle.DataSourceSummaryDialog_window_title(), true);
|
||||||
Map<Long, String> usageMap = CaseDataSourcesSummary.getDataSourceTypes();
|
Map<Long, String> usageMap = DataSourceInfoUtilities.getDataSourceTypes();
|
||||||
Map<Long, Long> fileCountsMap = CaseDataSourcesSummary.getCountsOfFiles();
|
Map<Long, Long> fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles();
|
||||||
dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap);
|
dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap);
|
||||||
dataSourceSummaryTabbedPane = new DataSourceSummaryTabbedPane();
|
dataSourceSummaryTabbedPane = new DataSourceSummaryTabbedPane();
|
||||||
initComponents();
|
initComponents();
|
||||||
@ -126,7 +125,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
|||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)
|
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 668, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
.addComponent(closeButton)))
|
.addComponent(closeButton)))
|
||||||
@ -136,7 +135,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
|||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 540, Short.MAX_VALUE)
|
.addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(closeButton)
|
.addComponent(closeButton)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -30,7 +30,6 @@ import org.openide.nodes.Children;
|
|||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
@ -16,12 +16,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
/**
|
/**
|
@ -42,7 +42,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="programsRunLabel">
|
<Component class="javax.swing.JLabel" name="programsRunLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryUserActivityPanel.programsRunLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryUserActivityPanel.programsRunLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
@ -32,8 +32,6 @@ import javax.swing.table.DefaultTableCellRenderer;
|
|||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary;
|
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,8 +114,8 @@ public class DataSourceSummaryUserActivityPanel extends javax.swing.JPanel {
|
|||||||
* @return The JTable data model of counts of program runs.
|
* @return The JTable data model of counts of program runs.
|
||||||
*/
|
*/
|
||||||
private static TopProgramsModel getTopProgramsModel(DataSource selectedDataSource) {
|
private static TopProgramsModel getTopProgramsModel(DataSource selectedDataSource) {
|
||||||
List<TopProgramsResult> topProgramList
|
List<DataSourceInfoUtilities.TopProgramsResult> topProgramList
|
||||||
= DataSourceTopProgramsSummary.getTopPrograms(selectedDataSource, TOP_PROGS_COUNT);
|
= DataSourceInfoUtilities.getTopPrograms(selectedDataSource, TOP_PROGS_COUNT);
|
||||||
|
|
||||||
if (topProgramList == null) {
|
if (topProgramList == null) {
|
||||||
return new TopProgramsModel(null);
|
return new TopProgramsModel(null);
|
||||||
@ -196,14 +194,14 @@ public class DataSourceSummaryUserActivityPanel extends javax.swing.JPanel {
|
|||||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header()
|
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header()
|
||||||
};
|
};
|
||||||
|
|
||||||
private final List<TopProgramsResult> programResults;
|
private final List<DataSourceInfoUtilities.TopProgramsResult> programResults;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
*
|
*
|
||||||
* @param programResults The results to display.
|
* @param programResults The results to display.
|
||||||
*/
|
*/
|
||||||
TopProgramsModel(List<TopProgramsResult> programResults) {
|
TopProgramsModel(List<DataSourceInfoUtilities.TopProgramsResult> programResults) {
|
||||||
this.programResults = programResults == null ? new ArrayList<>() : Collections.unmodifiableList(programResults);
|
this.programResults = programResults == null ? new ArrayList<>() : Collections.unmodifiableList(programResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,12 +226,12 @@ public class DataSourceSummaryUserActivityPanel extends javax.swing.JPanel {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TopProgramsResult result = programResults.get(rowIndex);
|
DataSourceInfoUtilities.TopProgramsResult result = programResults.get(rowIndex);
|
||||||
switch (columnIndex) {
|
switch (columnIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
return new ProgramNameCellValue(result.getProgramName(), result.getProgramPath());
|
return new ProgramNameCellValue(result.getProgramName(), result.getProgramPath());
|
||||||
case 1:
|
case 1:
|
||||||
return DataSourceTopProgramsSummary.getShortFolderName(result.getProgramPath(), result.getProgramName());
|
return DataSourceInfoUtilities.getShortFolderName(result.getProgramPath(), result.getProgramName());
|
||||||
case 2:
|
case 2:
|
||||||
return result.getRunTimes();
|
return result.getRunTimes();
|
||||||
case 3:
|
case 3:
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -24,7 +24,6 @@ import javax.swing.AbstractAction;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.Bundle;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ViewSummaryInformationAction action for opening a Data Sources Summary Dialog
|
* ViewSummaryInformationAction action for opening a Data Sources Summary Dialog
|
@ -36,7 +36,7 @@ import org.openide.util.NbBundle.Messages;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.ViewSummaryInformationAction;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
@ -24,7 +24,7 @@ import java.util.List;
|
|||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.ViewSummaryInformationAction;
|
||||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||||
import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
|
import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
|
||||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
|
||||||
import org.sleuthkit.datamodel.TskData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides methods to query for information for all datasources in a case.
|
|
||||||
*/
|
|
||||||
public class CaseDataSourcesSummary {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(CaseDataSourcesSummary.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a map containing the TSK_DATA_SOURCE_USAGE description attributes
|
|
||||||
* associated with each data source in the current case.
|
|
||||||
*
|
|
||||||
* @return Collection which maps datasource id to a String which displays a
|
|
||||||
* comma seperated list of values of data source usage types
|
|
||||||
* expected to be in the datasource
|
|
||||||
*/
|
|
||||||
public static Map<Long, String> getDataSourceTypes() {
|
|
||||||
try {
|
|
||||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
|
||||||
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
|
|
||||||
Map<Long, String> typeMap = new HashMap<>();
|
|
||||||
for (BlackboardArtifact typeArtifact : listOfArtifacts) {
|
|
||||||
BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION));
|
|
||||||
if (typeArtifact.getDataSource() != null && descriptionAttr != null) {
|
|
||||||
long dsId = typeArtifact.getDataSource().getId();
|
|
||||||
String type = typeMap.get(typeArtifact.getDataSource().getId());
|
|
||||||
if (type == null) {
|
|
||||||
type = descriptionAttr.getValueString();
|
|
||||||
} else {
|
|
||||||
type = type + ", " + descriptionAttr.getValueString();
|
|
||||||
}
|
|
||||||
typeMap.put(dsId, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typeMap;
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a map containing the number of files in each data source in the
|
|
||||||
* current case.
|
|
||||||
*
|
|
||||||
* @return Collection which maps datasource id to a count for the number of
|
|
||||||
* files in the datasource, will only contain entries for
|
|
||||||
* datasources which have at least 1 file
|
|
||||||
*/
|
|
||||||
public static Map<Long, Long> getCountsOfFiles() {
|
|
||||||
try {
|
|
||||||
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value FROM tsk_files"
|
|
||||||
+ " WHERE meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
|
||||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
|
||||||
+ " AND name<>''"
|
|
||||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
|
||||||
return getValuesMap(countFilesQuery);
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a map containing the number of artifacts in each data source in the
|
|
||||||
* current case.
|
|
||||||
*
|
|
||||||
* @return Collection which maps datasource id to a count for the number of
|
|
||||||
* artifacts in the datasource, will only contain entries for
|
|
||||||
* datasources which have at least 1 artifact
|
|
||||||
*/
|
|
||||||
public static Map<Long, Long> getCountsOfArtifacts() {
|
|
||||||
try {
|
|
||||||
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value"
|
|
||||||
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
|
|
||||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
|
||||||
return getValuesMap(countArtifactsQuery);
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a map containing the number of tags which have been applied in each
|
|
||||||
* data source in the current case. Not necessarily the same as the number
|
|
||||||
* of items tagged, as an item can have any number of tags.
|
|
||||||
*
|
|
||||||
* @return Collection which maps datasource id to a count for the number of
|
|
||||||
* tags which have been applied in the datasource, will only contain
|
|
||||||
* entries for datasources which have at least 1 item tagged.
|
|
||||||
*/
|
|
||||||
public static Map<Long, Long> getCountsOfTags() {
|
|
||||||
try {
|
|
||||||
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
|
||||||
+ " FROM content_tags as content_tags, tsk_files as tsk_files"
|
|
||||||
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
|
|
||||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
|
||||||
//new hashmap so it can be modifiable
|
|
||||||
Map<Long, Long> tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery));
|
|
||||||
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value"
|
|
||||||
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
|
|
||||||
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
|
|
||||||
+ " GROUP BY data_source_obj_id"; //NON-NLS
|
|
||||||
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
|
|
||||||
getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
|
|
||||||
return tagCountMap;
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to execute a select query with a
|
|
||||||
* DataSourceSingleValueCallback.
|
|
||||||
*
|
|
||||||
* @param query the portion of the query which should follow the SELECT
|
|
||||||
*
|
|
||||||
* @return a map of datasource object ID to a value of type Long
|
|
||||||
*
|
|
||||||
* @throws TskCoreException
|
|
||||||
* @throws NoCurrentCaseException
|
|
||||||
*/
|
|
||||||
private static Map<Long, Long> getValuesMap(String query) throws TskCoreException, NoCurrentCaseException {
|
|
||||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
|
||||||
DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback();
|
|
||||||
skCase.getCaseDbAccessManager().select(query, callback);
|
|
||||||
return callback.getMapOfValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CaseDataSourcesSummary() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2019 - 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.ResultSetHandler;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
import org.sleuthkit.datamodel.TskData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides information for the DataSourceSummaryCountsPanel.
|
|
||||||
*/
|
|
||||||
public class DataSourceCountsSummary {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceCountsSummary.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get count of regular files (not directories) in a data source.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfFiles(DataSource currentDataSource) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, null,
|
|
||||||
"Unable to get count of files, providing empty results");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get count of allocated files in a data source.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfAllocatedFiles(DataSource currentDataSource) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.ALLOC),
|
|
||||||
"Unable to get counts of unallocated files for datasource, providing empty results");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get count of unallocated files in a data source.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfUnallocatedFiles(DataSource currentDataSource) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(),
|
|
||||||
"Unable to get counts of unallocated files for datasource, providing empty results");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get count of directories in a data source.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfDirectories(DataSource currentDataSource) {
|
|
||||||
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(),
|
|
||||||
"Unable to get count of directories for datasource, providing empty results");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get count of slack files in a data source.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfSlackFiles(DataSource currentDataSource) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
|
||||||
+ " AND type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(),
|
|
||||||
"Unable to get count of slack files for datasources, providing empty results");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves counts for each artifact type in a data source.
|
|
||||||
*
|
|
||||||
* @param selectedDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return A mapping of artifact type name to the counts or null if there
|
|
||||||
* was an error executing the query.
|
|
||||||
*/
|
|
||||||
public static Map<String, Long> getCountsOfArtifactsByType(DataSource selectedDataSource) {
|
|
||||||
if (selectedDataSource == null) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
final String nameParam = "name";
|
|
||||||
final String valueParam = "value";
|
|
||||||
String query
|
|
||||||
= "SELECT bbt.display_name AS " + nameParam + ", COUNT(*) AS " + valueParam
|
|
||||||
+ " FROM blackboard_artifacts bba "
|
|
||||||
+ " INNER JOIN blackboard_artifact_types bbt ON bba.artifact_type_id = bbt.artifact_type_id"
|
|
||||||
+ " WHERE bba.data_source_obj_id =" + selectedDataSource.getId()
|
|
||||||
+ " GROUP BY bbt.display_name";
|
|
||||||
|
|
||||||
String errorMessage = "Unable to get artifact type counts; returning null.";
|
|
||||||
return DataSourceInfoUtilities.getBaseQueryResult(query,
|
|
||||||
getStringLongResultSetHandler(nameParam, valueParam),
|
|
||||||
errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a result set handler that will return a map of string to long.
|
|
||||||
*
|
|
||||||
* @param keyParam The named parameter in the result set representing the
|
|
||||||
* key.
|
|
||||||
* @param valueParam The named parameter in the result set representing the
|
|
||||||
* value.
|
|
||||||
*
|
|
||||||
* @return The result set handler to generate the map of string to long.
|
|
||||||
*/
|
|
||||||
private static ResultSetHandler<LinkedHashMap<String, Long>> getStringLongResultSetHandler(String keyParam, String valueParam) {
|
|
||||||
return (resultSet) -> {
|
|
||||||
LinkedHashMap<String, Long> toRet = new LinkedHashMap<>();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
try {
|
|
||||||
toRet.put(resultSet.getString(keyParam), resultSet.getLong(valueParam));
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logger.log(Level.WARNING, "Failed to get a result pair from the result set.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return toRet;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSourceCountsSummary() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.getBaseQueryResult;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
import org.sleuthkit.datamodel.TskData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides methods to query for data source overview details.
|
|
||||||
*/
|
|
||||||
public class DataSourceDetailsSummary {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceDetailsSummary.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the size of unallocated files in a particular datasource.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The size or null if the query could not be executed.
|
|
||||||
*/
|
|
||||||
public static Long getSizeOfUnallocatedFiles(DataSource currentDataSource) {
|
|
||||||
if (currentDataSource == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String valueParam = "value";
|
|
||||||
final String countParam = "count";
|
|
||||||
String query = "SELECT SUM(size) AS " + valueParam + ", COUNT(*) AS " + countParam
|
|
||||||
+ " FROM tsk_files"
|
|
||||||
+ " WHERE " + DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)
|
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()
|
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
|
|
||||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
|
||||||
+ " AND name<>''"
|
|
||||||
+ " AND data_source_obj_id=" + currentDataSource.getId();
|
|
||||||
|
|
||||||
DataSourceInfoUtilities.ResultSetHandler<Long> handler = (resultSet) -> {
|
|
||||||
if (resultSet.next()) {
|
|
||||||
// ensure that there is an unallocated count result that is attached to this data source
|
|
||||||
long resultCount = resultSet.getLong(valueParam);
|
|
||||||
return (resultCount > 0) ? resultSet.getLong(valueParam) : null;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String errorMessage = "Unable to get size of unallocated files; returning null.";
|
|
||||||
|
|
||||||
return DataSourceInfoUtilities.getBaseQueryResult(query, handler, errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the concatenation of operating system attributes for a
|
|
||||||
* particular data source.
|
|
||||||
*
|
|
||||||
* @param dataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The concatenated value or null if the query could not be
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
public static String getOperatingSystems(DataSource dataSource) {
|
|
||||||
if (dataSource == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getConcattedAttrValue(dataSource.getId(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID(),
|
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the concatenation of data source usage for a particular data
|
|
||||||
* source.
|
|
||||||
*
|
|
||||||
* @param dataSource The data source.
|
|
||||||
*
|
|
||||||
* @return The concatenated value or null if the query could not be
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
public static String getDataSourceType(DataSource dataSource) {
|
|
||||||
if (dataSource == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getConcattedAttrValue(dataSource.getId(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE.getTypeID(),
|
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a string which is a concatenation of the value received from
|
|
||||||
* the result set.
|
|
||||||
*
|
|
||||||
* @param query The query.
|
|
||||||
* @param valueParam The parameter for the value in the result set.
|
|
||||||
* @param separator The string separator used in concatenation.
|
|
||||||
* @param errorMessage The error message if the result set could not
|
|
||||||
* be received.
|
|
||||||
* @param singleErrorMessage The error message if a single result could not
|
|
||||||
* be obtained.
|
|
||||||
*
|
|
||||||
* @return The concatenated string or null if the query could not be
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
private static String getConcattedStringsResult(String query, String valueParam, String separator, String errorMessage, String singleErrorMessage) {
|
|
||||||
DataSourceInfoUtilities.ResultSetHandler<String> handler = (resultSet) -> {
|
|
||||||
String toRet = "";
|
|
||||||
boolean first = true;
|
|
||||||
while (resultSet.next()) {
|
|
||||||
try {
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
toRet += separator;
|
|
||||||
}
|
|
||||||
toRet += resultSet.getString(valueParam);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logger.log(Level.WARNING, singleErrorMessage, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return toRet;
|
|
||||||
};
|
|
||||||
|
|
||||||
return getBaseQueryResult(query, handler, errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a concatenated string value based on the text value of a
|
|
||||||
* particular attribute in a particular artifact for a specific data source.
|
|
||||||
*
|
|
||||||
* @param dataSourceId The data source id.
|
|
||||||
* @param artifactTypeId The artifact type id.
|
|
||||||
* @param attributeTypeId The attribute type id.
|
|
||||||
*
|
|
||||||
* @return The concatenated value or null if the query could not be
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
private static String getConcattedAttrValue(long dataSourceId, int artifactTypeId, int attributeTypeId) {
|
|
||||||
final String valueParam = "concatted_attribute_value";
|
|
||||||
String query = "SELECT attr.value_text AS " + valueParam
|
|
||||||
+ " FROM blackboard_artifacts bba "
|
|
||||||
+ " INNER JOIN blackboard_attributes attr ON bba.artifact_id = attr.artifact_id "
|
|
||||||
+ " WHERE bba.data_source_obj_id = " + dataSourceId
|
|
||||||
+ " AND bba.artifact_type_id = " + artifactTypeId
|
|
||||||
+ " AND attr.attribute_type_id = " + attributeTypeId;
|
|
||||||
|
|
||||||
String errorMessage = "Unable to execute query to retrieve concatted attribute values.";
|
|
||||||
String singleErrorMessage = "There was an error retrieving one of the results. That result will be omitted from concatted value.";
|
|
||||||
String separator = ", ";
|
|
||||||
return getConcattedStringsResult(query, valueParam, separator, errorMessage, singleErrorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSourceDetailsSummary() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2019 - 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|
||||||
import org.sleuthkit.datamodel.TskData;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM;
|
|
||||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utilities for getting information about a data source or all data sources
|
|
||||||
* from the case database.
|
|
||||||
*/
|
|
||||||
final class DataSourceInfoUtilities {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a count of tsk_files for a particular datasource where dir_type is
|
|
||||||
* not a virtual directory and has a name.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The datasource.
|
|
||||||
* @param additionalWhere Additional sql where clauses.
|
|
||||||
* @param onError The message to log on error.
|
|
||||||
*
|
|
||||||
* @return The count of files or null on error.
|
|
||||||
*/
|
|
||||||
static Long getCountOfTskFiles(DataSource currentDataSource, String additionalWhere, String onError) {
|
|
||||||
if (currentDataSource != null) {
|
|
||||||
try {
|
|
||||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
|
||||||
return skCase.countFilesWhere(
|
|
||||||
"data_source_obj_id=" + currentDataSource.getId()
|
|
||||||
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
|
|
||||||
+ " AND name<>''"
|
|
||||||
+ (StringUtils.isBlank(additionalWhere) ? "" : (" AND " + additionalWhere)));
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, onError, ex);
|
|
||||||
//unable to get count of files for the specified types cell will be displayed as empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a count of regular files for a particular datasource where the
|
|
||||||
* dir_type and type are not a virtual directory and has a name.
|
|
||||||
*
|
|
||||||
* @param currentDataSource The datasource.
|
|
||||||
* @param additionalWhere Additional sql where clauses.
|
|
||||||
* @param onError The message to log on error.
|
|
||||||
*
|
|
||||||
* @return The count of files or null on error.
|
|
||||||
*/
|
|
||||||
static Long getCountOfRegularFiles(DataSource currentDataSource, String additionalWhere, String onError) {
|
|
||||||
String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
|
|
||||||
+ " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(additionalWhere)) {
|
|
||||||
whereClause += " AND " + additionalWhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getCountOfTskFiles(currentDataSource, whereClause, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for handling a result set and returning a value.
|
|
||||||
*/
|
|
||||||
interface ResultSetHandler<T> {
|
|
||||||
|
|
||||||
T process(ResultSet resultset) throws SQLException;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a result based on the provided query.
|
|
||||||
*
|
|
||||||
* @param query The query.
|
|
||||||
* @param processor The result set handler.
|
|
||||||
* @param errorMessage The error message to display if there is an error
|
|
||||||
* retrieving the resultset.
|
|
||||||
*
|
|
||||||
* @return The ResultSetHandler value or null if no ResultSet could be
|
|
||||||
* obtained.
|
|
||||||
*/
|
|
||||||
static <T> T getBaseQueryResult(String query, ResultSetHandler<T> processor, String errorMessage) {
|
|
||||||
try (SleuthkitCase.CaseDbQuery dbQuery = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(query)) {
|
|
||||||
ResultSet resultSet = dbQuery.getResultSet();
|
|
||||||
try {
|
|
||||||
return processor.process(resultSet);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logger.log(Level.WARNING, errorMessage, ex);
|
|
||||||
}
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.WARNING, errorMessage, ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates sql where clause that does a bitwise check to see if flag is
|
|
||||||
* present.
|
|
||||||
*
|
|
||||||
* @param flag The flag for which to check.
|
|
||||||
*
|
|
||||||
* @return The clause.
|
|
||||||
*/
|
|
||||||
static String getMetaFlagsContainsStatement(TSK_FS_META_FLAG_ENUM flag) {
|
|
||||||
return "meta_flags & " + flag.getValue() + " > 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Empty private constructor
|
|
||||||
*/
|
|
||||||
private DataSourceInfoUtilities() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides methods to query for datasource files by mime type.
|
|
||||||
*/
|
|
||||||
public class DataSourceMimeTypeSummary {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
"mime_type IN " + getSqlSet(setOfMimeTypes),
|
|
||||||
"Unable to get count of files for specified mime types");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of files in the case database for the current data source
|
|
||||||
* which do not have the specified mimetypes.
|
|
||||||
*
|
|
||||||
* @param currentDataSource the data source which we are finding a file
|
|
||||||
* count
|
|
||||||
*
|
|
||||||
* @param setOfMimeTypes the set of mime types that should be excluded.
|
|
||||||
*
|
|
||||||
* @return a Long value which represents the number of files that do not
|
|
||||||
* have the specific mime type, but do have a mime type.
|
|
||||||
*/
|
|
||||||
public static Long getCountOfFilesNotInMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
"mime_type NOT IN " + getSqlSet(setOfMimeTypes)
|
|
||||||
+ " AND mime_type IS NOT NULL AND mime_type <> '' ",
|
|
||||||
"Unable to get count of files without specified mime types");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static Long getCountOfFilesWithNoMimeType(DataSource currentDataSource) {
|
|
||||||
return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource,
|
|
||||||
"(mime_type IS NULL OR mime_type = '') ",
|
|
||||||
"Unable to get count of files without a mime type");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSourceMimeTypeSummary() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,295 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.getBaseQueryResult;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides information to populate Top Programs Summary queries.
|
|
||||||
*/
|
|
||||||
public class DataSourceTopProgramsSummary {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceTopProgramsSummary.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A SQL join type.
|
|
||||||
*/
|
|
||||||
private enum JoinType {
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
INNER,
|
|
||||||
OUTER
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A blackboard attribute value column.
|
|
||||||
*/
|
|
||||||
private enum AttributeColumn {
|
|
||||||
value_text,
|
|
||||||
value_int32,
|
|
||||||
value_int64
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The suffix joined to a key name for use as an identifier of a query.
|
|
||||||
*/
|
|
||||||
private static final String QUERY_SUFFIX = "_query";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a sql statement querying the blackboard attributes table for a
|
|
||||||
* particular attribute type and returning a specified value. That query
|
|
||||||
* also joins with the blackboard artifact table.
|
|
||||||
*
|
|
||||||
* @param joinType The type of join statement to create.
|
|
||||||
* @param attributeColumn The blackboard attribute column that should be
|
|
||||||
* returned.
|
|
||||||
* @param attrType The attribute type to query for.
|
|
||||||
* @param keyName The aliased name of the attribute to return. This
|
|
||||||
* is also used to calculate the alias of the query
|
|
||||||
* same as getFullKey.
|
|
||||||
* @param bbaName The blackboard artifact table alias.
|
|
||||||
*
|
|
||||||
* @return The generated sql statement.
|
|
||||||
*/
|
|
||||||
private static String getAttributeJoin(JoinType joinType, AttributeColumn attributeColumn, BlackboardAttribute.ATTRIBUTE_TYPE attrType, String keyName, String bbaName) {
|
|
||||||
String queryName = keyName + QUERY_SUFFIX;
|
|
||||||
String innerQueryName = "inner_attribute_" + queryName;
|
|
||||||
|
|
||||||
return "\n" + joinType + " JOIN (\n"
|
|
||||||
+ " SELECT \n"
|
|
||||||
+ " " + innerQueryName + ".artifact_id,\n"
|
|
||||||
+ " " + innerQueryName + "." + attributeColumn + " AS " + keyName + "\n"
|
|
||||||
+ " FROM blackboard_attributes " + innerQueryName + "\n"
|
|
||||||
+ " WHERE " + innerQueryName + ".attribute_type_id = " + attrType.getTypeID() + " -- " + attrType.name() + "\n"
|
|
||||||
+ ") " + queryName + " ON " + queryName + ".artifact_id = " + bbaName + ".artifact_id\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a column key, creates the full name for the column key.
|
|
||||||
*
|
|
||||||
* @param key The column key.
|
|
||||||
*
|
|
||||||
* @return The full identifier for the column key.
|
|
||||||
*/
|
|
||||||
private static String getFullKey(String key) {
|
|
||||||
return key + QUERY_SUFFIX + "." + key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a SQL 'where' statement from a list of clauses and puts
|
|
||||||
* parenthesis around each clause.
|
|
||||||
*
|
|
||||||
* @param clauses The clauses
|
|
||||||
*
|
|
||||||
* @return The generated 'where' statement.
|
|
||||||
*/
|
|
||||||
private static String getWhereString(List<String> clauses) {
|
|
||||||
if (clauses.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> parenthesized = clauses.stream()
|
|
||||||
.map(c -> "(" + c + ")")
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return "\nWHERE " + String.join("\n AND ", parenthesized) + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a [column] LIKE sql clause.
|
|
||||||
*
|
|
||||||
* @param column The column identifier.
|
|
||||||
* @param likeString The string that will be used as column comparison.
|
|
||||||
* @param isLike if false, the statement becomes NOT LIKE.
|
|
||||||
*
|
|
||||||
* @return The generated statement.
|
|
||||||
*/
|
|
||||||
private static String getLikeClause(String column, String likeString, boolean isLike) {
|
|
||||||
return column + (isLike ? "" : " NOT") + " LIKE '" + likeString + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a list of the top programs used on the data source. Currently
|
|
||||||
* determines this based off of which prefetch results return the highest
|
|
||||||
* count.
|
|
||||||
*
|
|
||||||
* @param dataSource The data source.
|
|
||||||
* @param count The number of programs to return.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<TopProgramsResult> getTopPrograms(DataSource dataSource, int count) {
|
|
||||||
if (dataSource == null || count <= 0) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ntosboot should be ignored
|
|
||||||
final String ntosBootIdentifier = "NTOSBOOT";
|
|
||||||
// programs in windows directory to be ignored
|
|
||||||
final String windowsDir = "/WINDOWS%";
|
|
||||||
|
|
||||||
final String nameParam = "name";
|
|
||||||
final String pathParam = "path";
|
|
||||||
final String runCountParam = "run_count";
|
|
||||||
final String lastRunParam = "last_run";
|
|
||||||
|
|
||||||
String bbaQuery = "bba";
|
|
||||||
|
|
||||||
final String query = "SELECT\n"
|
|
||||||
+ " " + getFullKey(nameParam) + " AS " + nameParam + ",\n"
|
|
||||||
+ " " + getFullKey(pathParam) + " AS " + pathParam + ",\n"
|
|
||||||
+ " MAX(" + getFullKey(runCountParam) + ") AS " + runCountParam + ",\n"
|
|
||||||
+ " MAX(" + getFullKey(lastRunParam) + ") AS " + lastRunParam + "\n"
|
|
||||||
+ "FROM blackboard_artifacts " + bbaQuery + "\n"
|
|
||||||
+ getAttributeJoin(JoinType.INNER, AttributeColumn.value_text, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, nameParam, bbaQuery)
|
|
||||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_text, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, pathParam, bbaQuery)
|
|
||||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int32, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT, runCountParam, bbaQuery)
|
|
||||||
+ getAttributeJoin(JoinType.LEFT, AttributeColumn.value_int64, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, lastRunParam, bbaQuery)
|
|
||||||
+ getWhereString(Arrays.asList(
|
|
||||||
bbaQuery + ".artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID(),
|
|
||||||
bbaQuery + ".data_source_obj_id = " + dataSource.getId(),
|
|
||||||
// exclude ntosBootIdentifier from results
|
|
||||||
getLikeClause(getFullKey(nameParam), ntosBootIdentifier, false),
|
|
||||||
// exclude windows directory items from results
|
|
||||||
getFullKey(pathParam) + " IS NULL OR " + getLikeClause(getFullKey(pathParam), windowsDir, false)
|
|
||||||
))
|
|
||||||
+ "GROUP BY " + getFullKey(nameParam) + ", " + getFullKey(pathParam) + "\n"
|
|
||||||
+ "ORDER BY \n"
|
|
||||||
+ " MAX(" + getFullKey(runCountParam) + ") DESC,\n"
|
|
||||||
+ " MAX(" + getFullKey(lastRunParam) + ") DESC,\n"
|
|
||||||
+ " " + getFullKey(nameParam) + " ASC";
|
|
||||||
|
|
||||||
final String errorMessage = "Unable to get top program results; returning null.";
|
|
||||||
|
|
||||||
DataSourceInfoUtilities.ResultSetHandler<List<TopProgramsResult>> handler = (resultSet) -> {
|
|
||||||
List<TopProgramsResult> progResults = new ArrayList<>();
|
|
||||||
|
|
||||||
boolean quitAtCount = false;
|
|
||||||
|
|
||||||
while (resultSet.next() && (!quitAtCount || progResults.size() < count)) {
|
|
||||||
try {
|
|
||||||
long lastRunEpoch = resultSet.getLong(lastRunParam);
|
|
||||||
Date lastRun = (resultSet.wasNull()) ? null : new Date(lastRunEpoch * 1000);
|
|
||||||
|
|
||||||
Long runCount = resultSet.getLong(runCountParam);
|
|
||||||
if (resultSet.wasNull()) {
|
|
||||||
runCount = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastRun != null || runCount != null) {
|
|
||||||
quitAtCount = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
progResults.add(new TopProgramsResult(
|
|
||||||
resultSet.getString(nameParam),
|
|
||||||
resultSet.getString(pathParam),
|
|
||||||
runCount,
|
|
||||||
lastRun));
|
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logger.log(Level.WARNING, "Failed to get a top program result from the result set.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return progResults;
|
|
||||||
};
|
|
||||||
|
|
||||||
return getBaseQueryResult(query, handler, errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions that determine the folder name of a list of path elements. If
|
|
||||||
* not matched, function returns null.
|
|
||||||
*/
|
|
||||||
private static final List<Function<List<String>, String>> SHORT_FOLDER_MATCHERS = Arrays.asList(
|
|
||||||
// handle Program Files and Program Files (x86) - if true, return the next folder
|
|
||||||
(pathList) -> {
|
|
||||||
if (pathList.size() < 2) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String rootParent = pathList.get(0).toUpperCase();
|
|
||||||
if ("PROGRAM FILES".equals(rootParent) || "PROGRAM FILES (X86)".equals(rootParent)) {
|
|
||||||
return pathList.get(1);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// if there is a folder named "APPLICATION DATA" or "APPDATA"
|
|
||||||
(pathList) -> {
|
|
||||||
for (String pathEl : pathList) {
|
|
||||||
String uppered = pathEl.toUpperCase();
|
|
||||||
if ("APPLICATION DATA".equals(uppered) || "APPDATA".equals(uppered)) {
|
|
||||||
return "AppData";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines a short folder name if any. Otherwise, returns empty string.
|
|
||||||
*
|
|
||||||
* @param strPath The string path.
|
|
||||||
*
|
|
||||||
* @return The short folder name or empty string if not found.
|
|
||||||
*/
|
|
||||||
public static String getShortFolderName(String strPath, String applicationName) {
|
|
||||||
if (strPath == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> pathEls = new ArrayList<>(Arrays.asList(applicationName));
|
|
||||||
|
|
||||||
File file = new File(strPath);
|
|
||||||
while (file != null && StringUtils.isNotBlank(file.getName())) {
|
|
||||||
pathEls.add(file.getName());
|
|
||||||
file = file.getParentFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.reverse(pathEls);
|
|
||||||
|
|
||||||
for (Function<List<String>, String> matchEntry : SHORT_FOLDER_MATCHERS) {
|
|
||||||
String result = matchEntry.apply(pathEls);
|
|
||||||
if (StringUtils.isNotBlank(result)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSourceTopProgramsSummary() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes a result of a program run on a datasource.
|
|
||||||
*/
|
|
||||||
public class TopProgramsResult {
|
|
||||||
|
|
||||||
private final String programName;
|
|
||||||
private final String programPath;
|
|
||||||
private final Long runTimes;
|
|
||||||
private final Date lastRun;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main constructor.
|
|
||||||
*
|
|
||||||
* @param programName The name of the program.
|
|
||||||
* @param programPath The path of the program.
|
|
||||||
* @param runTimes The number of runs.
|
|
||||||
*/
|
|
||||||
TopProgramsResult(String programName, String programPath, Long runTimes, Date lastRun) {
|
|
||||||
this.programName = programName;
|
|
||||||
this.programPath = programPath;
|
|
||||||
this.runTimes = runTimes;
|
|
||||||
this.lastRun = lastRun;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The name of the program
|
|
||||||
*/
|
|
||||||
public String getProgramName() {
|
|
||||||
return programName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The path of the program.
|
|
||||||
*/
|
|
||||||
public String getProgramPath() {
|
|
||||||
return programPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of run times or null if not present.
|
|
||||||
*/
|
|
||||||
public Long getRunTimes() {
|
|
||||||
return runTimes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The last time the program was run or null if not present.
|
|
||||||
*/
|
|
||||||
public Date getLastRun() {
|
|
||||||
return lastRun;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,222 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
|
|
||||||
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
|
||||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
|
||||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
|
||||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
|
||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="scrollParent" alignment="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="scrollParent" alignment="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
<SubComponents>
|
|
||||||
<Container class="javax.swing.JScrollPane" name="scrollParent">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Container class="javax.swing.JPanel" name="parentPanel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[840, 320]"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="fileTypePiePanel" min="-2" pref="400" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="fileCountsByCategoryScrollPane" alignment="0" min="-2" pref="140" max="-2" attributes="0"/>
|
|
||||||
<Component id="byCategoryLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="filesByCatParent" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="resultsByTypeLabel" min="-2" pref="79" max="-2" attributes="0"/>
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Component id="artifactCountsScrollPane" min="-2" pref="244" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="resultsByTypeParent" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Component id="fileTypePiePanel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
|
||||||
<Component id="byCategoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="resultsByTypeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="1" attributes="0">
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
<Component id="resultsByTypeParent" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="148" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="artifactCountsScrollPane" pref="0" max="32767" attributes="0"/>
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Component id="fileCountsByCategoryScrollPane" min="-2" pref="107" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
|
|
||||||
<Component id="filesByCatParent" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
<SubComponents>
|
|
||||||
<Container class="javax.swing.JScrollPane" name="fileCountsByCategoryScrollPane">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JTable" name="fileCountsByCategoryTable">
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
<Component class="javax.swing.JLabel" name="byCategoryLabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryCountsPanel.byCategoryLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JLabel" name="resultsByTypeLabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryCountsPanel.resultsByTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
</Component>
|
|
||||||
<Container class="javax.swing.JScrollPane" name="artifactCountsScrollPane">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JTable" name="artifactCountsTable">
|
|
||||||
<Properties>
|
|
||||||
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
<Container class="javax.swing.JPanel" name="fileTypePiePanel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[400, 300]"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="fileTypePieChart"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
|
||||||
</Container>
|
|
||||||
<Container class="javax.swing.JPanel" name="filesByCatParent">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
<Container class="javax.swing.JPanel" name="resultsByTypeParent">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
|
||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
|
||||||
</Form>
|
|
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.ui;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Font;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
|
|
||||||
import org.jfree.chart.ChartFactory;
|
|
||||||
import org.jfree.chart.ChartPanel;
|
|
||||||
import org.jfree.chart.JFreeChart;
|
|
||||||
import org.jfree.chart.labels.PieSectionLabelGenerator;
|
|
||||||
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
|
|
||||||
import org.jfree.chart.plot.PiePlot;
|
|
||||||
import org.jfree.data.general.DefaultPieDataset;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import org.openide.util.NbBundle.Messages;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceMimeTypeSummary;
|
|
||||||
import static org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Pie Chart that shows file mime types in a data source.
|
|
||||||
*/
|
|
||||||
class FileTypePieChart extends JPanel {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private static final Font DEFAULT_FONT = new JLabel().getFont();
|
|
||||||
private static final Font DEFAULT_HEADER_FONT = new Font(DEFAULT_FONT.getName(), DEFAULT_FONT.getStyle(), (int) (DEFAULT_FONT.getSize() * 1.5));
|
|
||||||
|
|
||||||
private final DefaultPieDataset dataset = new DefaultPieDataset();
|
|
||||||
private DataSource dataSource;
|
|
||||||
|
|
||||||
// used for determining mime types that fall in the 'other' category
|
|
||||||
private static final Set<String> ALL_CATEGORY_MIME_TYPES = Arrays.asList(
|
|
||||||
FileTypeCategory.IMAGE,
|
|
||||||
FileTypeCategory.VIDEO,
|
|
||||||
FileTypeCategory.AUDIO,
|
|
||||||
FileTypeCategory.DOCUMENTS,
|
|
||||||
FileTypeCategory.EXECUTABLE)
|
|
||||||
.stream()
|
|
||||||
.flatMap((cat) -> cat.getMediaTypes().stream())
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor for the pie chart.
|
|
||||||
*/
|
|
||||||
@Messages({
|
|
||||||
"DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type",
|
|
||||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio",
|
|
||||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents",
|
|
||||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables",
|
|
||||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images",
|
|
||||||
"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos",
|
|
||||||
"DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label=Other",
|
|
||||||
"DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label=Not Analyzed"
|
|
||||||
})
|
|
||||||
FileTypePieChart() {
|
|
||||||
// Create chart
|
|
||||||
JFreeChart chart = ChartFactory.createPieChart(
|
|
||||||
Bundle.DataSourceSummaryCountsPanel_byMimeTypeLabel_text(),
|
|
||||||
dataset,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false);
|
|
||||||
|
|
||||||
chart.setBackgroundPaint(null);
|
|
||||||
chart.getLegend().setItemFont(DEFAULT_FONT);
|
|
||||||
chart.getTitle().setFont(DEFAULT_HEADER_FONT);
|
|
||||||
|
|
||||||
PiePlot plot = ((PiePlot) chart.getPlot());
|
|
||||||
|
|
||||||
//Format Label
|
|
||||||
PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator(
|
|
||||||
"{0}: {1} ({2})", new DecimalFormat("0"), new DecimalFormat("0.0%"));
|
|
||||||
|
|
||||||
plot.setLabelGenerator(labelGenerator);
|
|
||||||
plot.setLabelFont(DEFAULT_FONT);
|
|
||||||
|
|
||||||
plot.setBackgroundPaint(null);
|
|
||||||
plot.setOutlinePaint(null);
|
|
||||||
|
|
||||||
// Create Panel
|
|
||||||
ChartPanel panel = new ChartPanel(chart);
|
|
||||||
this.setLayout(new BorderLayout());
|
|
||||||
this.add(panel, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The datasource currently used as the model with this pie chart.
|
|
||||||
*
|
|
||||||
* @return The datasource currently being used as the model in this pie
|
|
||||||
* chart.
|
|
||||||
*/
|
|
||||||
DataSource getDataSource() {
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets datasource to visualize in the pie chart.
|
|
||||||
*
|
|
||||||
* @param dataSource The datasource to use in this pie chart.
|
|
||||||
*/
|
|
||||||
void setDataSource(DataSource dataSource) {
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.dataset.clear();
|
|
||||||
|
|
||||||
if (dataSource != null) {
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row(),
|
|
||||||
this.dataSource, FileTypeCategory.IMAGE);
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row(),
|
|
||||||
this.dataSource, FileTypeCategory.VIDEO);
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row(),
|
|
||||||
this.dataSource, FileTypeCategory.AUDIO);
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row(),
|
|
||||||
this.dataSource, FileTypeCategory.DOCUMENTS);
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row(),
|
|
||||||
this.dataSource, FileTypeCategory.EXECUTABLE);
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label(),
|
|
||||||
DataSourceMimeTypeSummary.getCountOfFilesNotInMimeTypes(this.dataSource, ALL_CATEGORY_MIME_TYPES));
|
|
||||||
addIfPresent(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label(),
|
|
||||||
DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(this.dataSource));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds count for file type category if there is a value. Uses fields
|
|
||||||
* 'dataSource' and 'dataset'.
|
|
||||||
*
|
|
||||||
* @param label The label for this pie slice.
|
|
||||||
* @param dataSource The data source.
|
|
||||||
* @param category The category for the pie slice.
|
|
||||||
*/
|
|
||||||
private void addIfPresent(String label, DataSource dataSource, FileTypeUtils.FileTypeCategory category) {
|
|
||||||
if (dataSource == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Long count = getCount(dataSource, category);
|
|
||||||
addIfPresent(label, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds count for a a label if the count is non-null and greater than 0.
|
|
||||||
*
|
|
||||||
* @param label The label.
|
|
||||||
* @param count The count.
|
|
||||||
*/
|
|
||||||
private void addIfPresent(String label, Long count) {
|
|
||||||
if (count != null && count > 0) {
|
|
||||||
this.dataset.setValue(label, count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the counts of files of a particular mime type for a particular
|
|
||||||
* DataSource.
|
|
||||||
*
|
|
||||||
* @param dataSource The DataSource.
|
|
||||||
* @param category The mime type category.
|
|
||||||
*
|
|
||||||
* @return The count.
|
|
||||||
*/
|
|
||||||
private static Long getCount(DataSource dataSource, FileTypeUtils.FileTypeCategory category) {
|
|
||||||
return DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes(dataSource, category.getMediaTypes());
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,7 +26,7 @@ import org.openide.explorer.ExplorerManager;
|
|||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryTabbedPane;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryTabbedPane;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
import org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer;
|
import org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user