From 674191d391ea677c6b0e9fd1a68a7b79e42bc219 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 07:35:30 -0400 Subject: [PATCH 01/28] extracted interface --- .../uiutils/DataFetchLoadableComponent.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java new file mode 100644 index 0000000000..6bc8b778eb --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.datasourcesummary.uiutils; + +import java.util.List; + +/** + * + * @author gregd + */ +public interface DataFetchLoadableComponent { + void showMessage(String message); + void showDefaultLoadingMessage(); + void showResults(List data); + + + /** + * Shows the data in a DataFetchResult. If there was an error during the + * operation, the errorMessage will be displayed. If the operation completed + * successfully and no data is present, noResultsMessage will be shown. + * Otherwise, the data will be shown as rows in the table. + * + * @param result The DataFetchResult. + * @param errorMessage The error message to be shown in the event of an + * error. + * @param noResultsMessage The message to be shown if there are no results + * but the operation completed successfully. + */ + void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage); + + /** + * Shows the data in a DataFetchResult. If there was an error during the + * operation, the DEFAULT_ERROR_MESSAGE will be displayed. If the operation + * completed successfully and no data is present, DEFAULT_NO_RESULTS_MESSAGE + * will be shown. Otherwise, the data will be shown as rows in the table. + * + * @param result The DataFetchResult. + */ + public void showDataFetchResult(DataFetchResult> result); +} From 66ad2c6d3030c3398251f38826d51ff21fed00a7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 16:59:28 -0400 Subject: [PATCH 02/28] refactoring --- .../datasourcesummary/ui/Bundle.properties | 4 +- .../ui/DataSourceSummaryTabbedPane.java | 4 +- ...ummaryCountsPanel.form => TypesPanel.form} | 4 +- ...ummaryCountsPanel.java => TypesPanel.java} | 49 ++++- .../uiutils/AbstractLoadableComponent.java | 145 +++++++++++++++ .../uiutils/BaseMessageOverlay.java | 73 ++++++++ .../uiutils/Bundle.properties-MERGED | 6 +- .../uiutils/JTablePanel.java | 172 +----------------- .../uiutils/ListTableModel.java | 4 +- ...eComponent.java => LoadableComponent.java} | 22 ++- .../uiutils/PieChartPanel.java | 153 ++++++++++++++++ 11 files changed, 454 insertions(+), 182 deletions(-) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceSummaryCountsPanel.form => TypesPanel.form} (97%) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceSummaryCountsPanel.java => TypesPanel.java} (88%) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java rename Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/{DataFetchLoadableComponent.java => LoadableComponent.java} (74%) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index 708010e07a..e2560a53b8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -33,7 +33,7 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= -DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category -DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains +TypesPanel.resultsByTypeLabel.text=Results by Type +TypesPanel.byCategoryLabel.text=Files by Category diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index 7e0cd951c3..337034560b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -32,7 +32,7 @@ import org.sleuthkit.datamodel.DataSource; * IngestJobInfoPanel. */ @Messages({ - "DataSourceSummaryTabbedPane_countsTab_title=Counts", + "DataSourceSummaryTabbedPane_typesTab_title=Types", "DataSourceSummaryTabbedPane_detailsTab_title=Details", "DataSourceSummaryTabbedPane_userActivityTab_title=User Activity", "DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History" @@ -44,7 +44,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { // A pair of the tab name and the corresponding BaseDataSourceSummaryTabs to be displayed. private final List> tabs = Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), + Pair.of(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryUserActivityPanel()) ); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form similarity index 97% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.form rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index c9c1930787..9164cceaf4 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -127,7 +127,7 @@ - + @@ -138,7 +138,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java similarity index 88% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.java rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 306a036941..36de380194 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryCountsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -18,13 +18,18 @@ */ package org.sleuthkit.autopsy.datasourcesummary.ui; +import java.util.Arrays; import org.sleuthkit.autopsy.datasourcesummary.uiutils.NonEditableTableModel; import java.util.Map; import javax.swing.JLabel; import javax.swing.table.DefaultTableCellRenderer; +import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel; import org.sleuthkit.datamodel.DataSource; @@ -33,14 +38,44 @@ import org.sleuthkit.datamodel.DataSource; * specified DataSource */ @Messages({ - "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type", + "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Artifact Types", "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count" + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Types", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count", + + "TypesPanel_fileTypesPieChart_title=File Types", + "TypesPanel_fileTypesPieChart_title=Artifact Types", + "TypesPanel_filesByCategoryTable_title=Files by Category", + + "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", + "TypesPanel_filesByCategoryTable_countColumn_title=Count", + + "TypesPanel_filesByCategoryTable_title=Files by Category", }) -class DataSourceSummaryCountsPanel extends BaseDataSourceSummaryPanel { +class TypesPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; + + private final PieChartPanel fileTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); + private final PieChartPanel artifactTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); + + private final JTablePanel> filesByCategoryTable = + JTablePanel.getJTablePanel(Arrays.asList( + new ColumnModel<>( + Bundle.TypesPanel_filesByCategoryTable_labelColumn_title(), + (pair) -> pair.getFirst(), + 250 + ), + new ColumnModel<>( + Bundle.TypesPanel_filesByCategoryTable_countColumn_title(), + (pair) -> pair.getSecond(), + 150 + ) + )); + + + new PieChartPanel(Bundle.TypesPanel_filesByCategoryTable_title()); + // Result returned for a data model if no data found. private static final Object[][] EMPTY_PAIRS = new Object[][]{}; @@ -64,7 +99,7 @@ class DataSourceSummaryCountsPanel extends BaseDataSourceSummaryPanel { /** * Creates new form DataSourceSummaryCountsPanel */ - DataSourceSummaryCountsPanel() { + TypesPanel() { rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT); initComponents(); fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false); @@ -186,9 +221,9 @@ class DataSourceSummaryCountsPanel extends BaseDataSourceSummaryPanel { 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(TypesPanel.class, "TypesPanel.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(resultsByTypeLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.resultsByTypeLabel.text")); // NOI18N artifactCountsTable.setAutoCreateRowSorter(true); artifactCountsScrollPane.setViewportView(artifactCountsTable); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java new file mode 100644 index 0000000000..0b5657983c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java @@ -0,0 +1,145 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.datasourcesummary.uiutils; + +import java.util.List; +import java.util.logging.Level; +import javax.swing.JPanel; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * + * @author gregd + */ +@NbBundle.Messages({ + "AbstractLoadableComponent_loadingMessage_defaultText=Loading results...", + "AbstractLoadableComponent_errorMessage_defaultText=There was an error loading results.", + "AbstractLoadableComponent_noDataExists_defaultText=No data exists.", +}) +public abstract class AbstractLoadableComponent extends JPanel implements LoadableComponent { + + public static final String DEFAULT_LOADING_MESSAGE = Bundle.AbstractLoadableComponent_loadingMessage_defaultText(); + public static final String DEFAULT_ERROR_MESSAGE = Bundle.AbstractLoadableComponent_errorMessage_defaultText(); + public static final String DEFAULT_NO_RESULTS_MESSAGE = Bundle.AbstractLoadableComponent_noDataExists_defaultText(); + + private static final Logger logger = Logger.getLogger(AbstractLoadableComponent.class.getName()); + + /** + * @return The default error message. + */ + public static String getDefaultErrorMessage() { + return DEFAULT_ERROR_MESSAGE; + } + + /** + * @return The default message for no results. + */ + public static String getDefaultNoResultsMessage() { + return DEFAULT_NO_RESULTS_MESSAGE; + } + + /** + * Clears the results from the underlying JTable and shows the provided + * message. + * + * @param message The message to be shown. + */ + public synchronized void showMessage(String message) { + setResultList(null); + setOverlay(true, message); + repaint(); + } + + /** + * Shows a default loading message on the table. This will clear any results + * in the table. + */ + public void showDefaultLoadingMessage() { + showMessage(DEFAULT_LOADING_MESSAGE); + } + + /** + * Shows the list as rows of data in the table. If overlay message will be + * cleared if present. + * + * @param data The data to be shown where each item represents a row of + * data. + */ + public synchronized void showResults(List data) { + setOverlay(false, null); + setResultList(data); + repaint(); + } + + /** + * Shows the data in a DataFetchResult. If there was an error during the + * operation, the errorMessage will be displayed. If the operation completed + * successfully and no data is present, noResultsMessage will be shown. + * Otherwise, the data will be shown as rows in the table. + * + * @param result The DataFetchResult. + * @param errorMessage The error message to be shown in the event of an + * error. + * @param noResultsMessage The message to be shown if there are no results + * but the operation completed successfully. + */ + public void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage) { + if (result == null) { + logger.log(Level.SEVERE, "Null data fetch result received."); + return; + } + + switch (result.getResultType()) { + case SUCCESS: + if (result.getData() == null || result.getData().isEmpty()) { + showMessage(noResultsMessage); + } else { + showResults(result.getData()); + } + break; + case ERROR: + // if there is an error, log accordingly, set result list to + // empty and display error message + logger.log(Level.WARNING, "An exception was caused while results were loaded.", result.getException()); + showMessage(errorMessage); + break; + default: + // an unknown loading state was specified. log accordingly. + logger.log(Level.SEVERE, "No known loading state was found in result."); + break; + } + } + + /** + * Shows the data in a DataFetchResult. If there was an error during the + * operation, the DEFAULT_ERROR_MESSAGE will be displayed. If the operation + * completed successfully and no data is present, DEFAULT_NO_RESULTS_MESSAGE + * will be shown. Otherwise, the data will be shown as rows in the table. + * + * @param result The DataFetchResult. + */ + public void showDataFetchResult(DataFetchResult> result) { + showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, DEFAULT_NO_RESULTS_MESSAGE); + } + + /** + * Sets the message and visibility of the overlay. Repaint does not need to + * be handled in this method. + * + * @param visible The visibility of the overlay. + * @param message The message in the overlay. + */ + protected abstract void setOverlay(boolean visible, String message); + + /** + * Sets the data to be shown in the JTable. Repaint does not need to be + * handled in this method. + * + * @param data The list of data objects to be shown. + */ + protected abstract void setResultList(List data); +} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java new file mode 100644 index 0000000000..2f66a2e5eb --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.datasourcesummary.uiutils; + +import java.awt.Graphics; +import javax.swing.JLabel; + +/** + * + * @author gregd + */ +public class BaseMessageOverlay { + + private static final long serialVersionUID = 1L; + + private final JLabel label; + private boolean visible = false; + + /** + * Main constructor for the Overlay. + */ + public BaseMessageOverlay() { + label = new JLabel(); + label.setHorizontalAlignment(JLabel.CENTER); + label.setVerticalAlignment(JLabel.CENTER); + label.setOpaque(false); + + } + + /** + * @return Whether or not this message overlay should be visible. + */ + public boolean isVisible() { + return visible; + } + + /** + * Sets this layer visible when painted. In order to be shown in UI, this + * component needs to be repainted. + * + * @param visible Whether or not it is visible. + */ + public void setVisible(boolean visible) { + this.visible = visible; + } + + /** + * Sets the message to be displayed in the child jlabel. + * + * @param message The message to be displayed. + */ + public void setMessage(String message) { + label.setText(String.format("
%s
", + message == null ? "" : message)); + } + + //@Override + //public void paintOverlay(Graphics2D g2d, ChartPanel pnl) + public void paintOverlay(Graphics g, int width, int height) { + // Paint the underlying view. + + if (!visible) { + return; + } + + // paint the jlabel if visible. + label.setBounds(0, 0, width, height); + label.paint(g); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle.properties-MERGED index 332a884f05..491c3bfa56 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/Bundle.properties-MERGED @@ -1,3 +1,3 @@ -JTablePanel_errorMessage_defaultText=There was an error loading results. -JTablePanel_loadingMessage_defaultText=Loading results... -JTablePanel_noDataExists_defaultText=No data exists. +AbstractLoadableComponent_errorMessage_defaultText=There was an error loading results. +AbstractLoadableComponent_loadingMessage_defaultText=Loading results... +AbstractLoadableComponent_noDataExists_defaultText=No data exists. diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 1e4184d85b..3df60ec9d8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -23,19 +23,15 @@ import java.awt.Graphics; import java.util.Collections; import java.util.List; import java.util.function.Function; -import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JLayer; -import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.plaf.LayerUI; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; -import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.CellModel; @@ -43,11 +39,7 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRendere * A table that displays a list of items and also can display messages for * loading, load error, and not loaded. */ -@Messages({ - "JTablePanel_loadingMessage_defaultText=Loading results...", - "JTablePanel_errorMessage_defaultText=There was an error loading results.", - "JTablePanel_noDataExists_defaultText=No data exists.",}) -public class JTablePanel extends JPanel { +public class JTablePanel extends AbstractLoadableComponent { /** * JTables don't allow displaying messages. So this LayerUI is used to @@ -58,27 +50,7 @@ public class JTablePanel extends JPanel { private static class Overlay extends LayerUI { private static final long serialVersionUID = 1L; - - private final JLabel label; - private boolean visible; - - /** - * Main constructor for the Overlay. - */ - Overlay() { - label = new JLabel(); - label.setHorizontalAlignment(JLabel.CENTER); - label.setVerticalAlignment(JLabel.CENTER); - label.setOpaque(false); - - } - - /** - * @return Whether or not this message overlay should be visible. - */ - boolean isVisible() { - return visible; - } + private BaseMessageOverlay overlay = new BaseMessageOverlay(); /** * Sets this layer visible when painted. In order to be shown in UI, @@ -87,7 +59,7 @@ public class JTablePanel extends JPanel { * @param visible Whether or not it is visible. */ void setVisible(boolean visible) { - this.visible = visible; + overlay.setVisible(visible); } /** @@ -96,25 +68,13 @@ public class JTablePanel extends JPanel { * @param message The message to be displayed. */ void setMessage(String message) { - label.setText(String.format("
%s
", - message == null ? "" : message)); + overlay.setMessage(message); } @Override public void paint(Graphics g, JComponent c) { - // Paint the underlying view. super.paint(g, c); - - if (!visible) { - return; - } - - int w = c.getWidth(); - int h = c.getHeight(); - - // paint the jlabel if visible. - label.setBounds(0, 0, w, h); - label.paint(g); + overlay.paintOverlay(g, c.getWidth(), c.getHeight()); } } @@ -180,11 +140,6 @@ public class JTablePanel extends JPanel { private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(JTablePanel.class.getName()); - - private static final String DEFAULT_LOADING_MESSAGE = Bundle.JTablePanel_loadingMessage_defaultText(); - private static final String DEFAULT_ERROR_MESSAGE = Bundle.JTablePanel_errorMessage_defaultText(); - private static final String DEFAULT_NO_RESULTS_MESSAGE = Bundle.JTablePanel_noDataExists_defaultText(); - private static final CellModelTableCellRenderer DEFAULT_CELL_RENDERER = new CellModelTableCellRenderer(); /** @@ -248,20 +203,6 @@ public class JTablePanel extends JPanel { return resultTable.setColumnModel(getTableColumnModel(columns)); } - /** - * @return The default error message. - */ - public static String getDefaultErrorMessage() { - return DEFAULT_ERROR_MESSAGE; - } - - /** - * @return The default message for no results. - */ - public static String getDefaultNoResultsMessage() { - return DEFAULT_NO_RESULTS_MESSAGE; - } - private final JScrollPane tableScrollPane; private final Overlay overlayLayer; private final ListTableModel tableModel; @@ -303,13 +244,8 @@ public class JTablePanel extends JPanel { return this; } - /** - * Sets the data to be shown in the JTable. Repaint is not handled in this - * method and should be handled separately. - * - * @param data The list of data objects to be shown. - */ - private void setResultList(List data) { + @Override + protected void setResultList(List data) { // set the list of data to be shown as either the data or an empty list // on null. List dataToSet = (data == null) ? Collections.emptyList() : data; @@ -321,99 +257,9 @@ public class JTablePanel extends JPanel { this.tableModel.setDataRows(dataToSet); } - /** - * Sets the message and visibility of the overlay. Repaint is not handled in - * this method and should be handled separately. - * - * @param visible The visibility of the overlay. - * @param message The message in the overlay. - */ - private void setOverlay(boolean visible, String message) { + @Override + protected void setOverlay(boolean visible, String message) { this.overlayLayer.setVisible(visible); this.overlayLayer.setMessage(message); } - - /** - * Clears the results from the underlying JTable and shows the provided - * message. - * - * @param message The message to be shown. - */ - public synchronized void showMessage(String message) { - setResultList(null); - setOverlay(true, message); - repaint(); - } - - /** - * Shows a default loading message on the table. This will clear any results - * in the table. - */ - public void showDefaultLoadingMessage() { - showMessage(DEFAULT_LOADING_MESSAGE); - } - - /** - * Shows the list as rows of data in the table. If overlay message will be - * cleared if present. - * - * @param data The data to be shown where each item represents a row of - * data. - */ - public synchronized void showResults(List data) { - setOverlay(false, null); - setResultList(data); - repaint(); - } - - /** - * Shows the data in a DataFetchResult. If there was an error during the - * operation, the errorMessage will be displayed. If the operation completed - * successfully and no data is present, noResultsMessage will be shown. - * Otherwise, the data will be shown as rows in the table. - * - * @param result The DataFetchResult. - * @param errorMessage The error message to be shown in the event of an - * error. - * @param noResultsMessage The message to be shown if there are no results - * but the operation completed successfully. - */ - public void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage) { - if (result == null) { - logger.log(Level.SEVERE, "Null data processor result received."); - return; - } - - switch (result.getResultType()) { - case SUCCESS: - if (result.getData() == null || result.getData().isEmpty()) { - showMessage(noResultsMessage); - } else { - showResults(result.getData()); - } - break; - case ERROR: - // if there is an error, log accordingly, set result list to - // empty and display error message - logger.log(Level.WARNING, "An exception was caused while results were loaded.", result.getException()); - showMessage(errorMessage); - break; - default: - // an unknown loading state was specified. log accordingly. - logger.log(Level.SEVERE, "No known loading state was found in result."); - break; - } - } - - /** - * Shows the data in a DataFetchResult. If there was an error during the - * operation, the DEFAULT_ERROR_MESSAGE will be displayed. If the operation - * completed successfully and no data is present, DEFAULT_NO_RESULTS_MESSAGE - * will be shown. Otherwise, the data will be shown as rows in the table. - * - * @param result The DataFetchResult. - */ - public void showDataFetchResult(DataFetchResult> result) { - showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, DEFAULT_NO_RESULTS_MESSAGE); - } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java index bf5f1d1552..07241619ff 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java @@ -25,8 +25,8 @@ import javax.swing.table.TableModel; * An interface to be used with the JTablePanel that specifies a TableModel to * be used with the underlying JTable based on a list of object type T. */ -public interface ListTableModel extends TableModel { - +public interface ListTableModel extends TableModel { + /** * @return The list of objects supporting the rows to be displayed in the * table. diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java similarity index 74% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java index 6bc8b778eb..f8e6d03300 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/DataFetchLoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java @@ -11,9 +11,29 @@ import java.util.List; * * @author gregd */ -public interface DataFetchLoadableComponent { +public interface LoadableComponent { + + /** + * Clears the results from the underlying JTable and shows the provided + * message. + * + * @param message The message to be shown. + */ void showMessage(String message); + + /** + * Shows a default loading message on the table. This will clear any results + * in the table. + */ void showDefaultLoadingMessage(); + + /** + * Shows the list as rows of data in the table. If overlay message will be + * cleared if present. + * + * @param data The data to be shown where each item represents a row of + * data. + */ void showResults(List data); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java new file mode 100644 index 0000000000..f644d179ce --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java @@ -0,0 +1,153 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.datasourcesummary.uiutils; + +import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.Graphics2D; +import java.text.DecimalFormat; +import java.util.List; +import javax.swing.JLabel; +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.panel.AbstractOverlay; +import org.jfree.chart.panel.Overlay; +import org.jfree.chart.plot.PiePlot; +import org.jfree.data.general.DefaultPieDataset; + +/** + * + * @author gregd + */ +public class PieChartPanel extends AbstractLoadableComponent { + + /** + * + */ + public static class PieChartItem { + private final String label; + private final double value; + + public PieChartItem(String label, double value) { + this.label = label; + this.value = value; + } + + public String getLabel() { + return label; + } + + public double getValue() { + return value; + } + } + + private static class MessageOverlay extends AbstractOverlay implements Overlay { + + private static final long serialVersionUID = 1L; + private BaseMessageOverlay overlay = new BaseMessageOverlay(); + + /** + * Sets this layer visible when painted. In order to be shown in UI, + * this component needs to be repainted. + * + * @param visible Whether or not it is visible. + */ + void setVisible(boolean visible) { + overlay.setVisible(visible); + } + + /** + * Sets the message to be displayed in the child jlabel. + * + * @param message The message to be displayed. + */ + void setMessage(String message) { + overlay.setMessage(message); + } + + @Override + public void paintOverlay(Graphics2D gd, ChartPanel cp) { + overlay.paintOverlay(gd, cp.getWidth(), cp.getHeight()); + } + + } + + + 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 static final PieSectionLabelGenerator DEFAULT_LABEL_GENERATOR = + new StandardPieSectionLabelGenerator( + "{0}: {1} ({2})", new DecimalFormat("0"), new DecimalFormat("0.0%")); + + private final MessageOverlay overlay = new MessageOverlay(); + private final DefaultPieDataset dataset = new DefaultPieDataset(); + private final JFreeChart chart; + + public PieChartPanel() { + this(null); + } + + public PieChartPanel(String title) { + // Create chart + this.chart = ChartFactory.createPieChart( + title, + dataset, + true, + true, + false); + + chart.setBackgroundPaint(null); + chart.getLegend().setItemFont(DEFAULT_FONT); + chart.getTitle().setFont(DEFAULT_HEADER_FONT); + + PiePlot plot = ((PiePlot) chart.getPlot()); + + plot.setLabelGenerator(DEFAULT_LABEL_GENERATOR); + plot.setLabelFont(DEFAULT_FONT); + plot.setBackgroundPaint(null); + plot.setOutlinePaint(null); + + // Create Panel + ChartPanel panel = new ChartPanel(chart); + panel.addOverlay(overlay); + this.setLayout(new BorderLayout()); + this.add(panel, BorderLayout.CENTER); + } + + public String getTitle() { + return (this.chart == null || this.chart.getTitle() == null) ? + null : + this.chart.getTitle().getText(); + } + + + public PieChartPanel setTitle(String title) { + this.chart.getTitle().setText(title); + return this; + } + + @Override + protected void setOverlay(boolean visible, String message) { + this.overlay.setVisible(visible); + this.overlay.setMessage(message); + } + + @Override + protected void setResultList(List data) { + this.dataset.clear(); + if (data != null) { + for (PieChartPanel.PieChartItem slice : data) { + this.dataset.setValue(slice.getLabel(), slice.getValue()); + } + } + } +} From f6259aeed26c59ab3be9d52b37ec3a6edcf2433d Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 17:40:31 -0400 Subject: [PATCH 03/28] working through panel --- .../datasourcesummary/ui/TypesPanel.java | 119 ++++++++---------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 36de380194..910f3c0a8c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -19,16 +19,22 @@ package org.sleuthkit.autopsy.datasourcesummary.ui; import java.util.Arrays; +import java.util.List; import org.sleuthkit.autopsy.datasourcesummary.uiutils.NonEditableTableModel; import java.util.Map; -import javax.swing.JLabel; -import javax.swing.table.DefaultTableCellRenderer; +import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel; import org.sleuthkit.datamodel.DataSource; @@ -42,25 +48,21 @@ import org.sleuthkit.datamodel.DataSource; "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count", "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Types", "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count", - "TypesPanel_fileTypesPieChart_title=File Types", "TypesPanel_fileTypesPieChart_title=Artifact Types", "TypesPanel_filesByCategoryTable_title=Files by Category", - "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", "TypesPanel_filesByCategoryTable_countColumn_title=Count", - - "TypesPanel_filesByCategoryTable_title=Files by Category", -}) + "TypesPanel_filesByCategoryTable_title=Files by Category",}) class TypesPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; - + private final PieChartPanel fileTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); private final PieChartPanel artifactTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); - - private final JTablePanel> filesByCategoryTable = - JTablePanel.getJTablePanel(Arrays.asList( + + private final JTablePanel> filesByCategoryTable + = JTablePanel.getJTablePanel(Arrays.asList( new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_labelColumn_title(), (pair) -> pair.getFirst(), @@ -72,76 +74,57 @@ class TypesPanel extends BaseDataSourceSummaryPanel { 150 ) )); - - - new PieChartPanel(Bundle.TypesPanel_filesByCategoryTable_title()); + + private final List> loadables = Arrays.asList( + fileTypesPieChart, + artifactTypesPieChart, + filesByCategoryTable + ); + + private final List> dataFetchComponents; + + public TypesPanel() { - // Result returned for a data model if no data found. - private static final Object[][] EMPTY_PAIRS = new Object[][]{}; + // set up data acquisition methods + dataFetchComponents = Arrays.asList( + new DataFetchWorker.DataFetchComponents>( + (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), + (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + new DataFetchWorker.DataFetchComponents>( + (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), + (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) + ); - // column headers for file by category table - private static final Object[] FILE_BY_CATEGORY_COLUMN_HEADERS = new Object[]{ - Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_type_header(), - Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_count_header() - }; - - // column headers for artifact counts table - private static final Object[] ARTIFACT_COUNTS_COLUMN_HEADERS = new Object[]{ - Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_type_header(), - Bundle.DataSourceSummaryCountsPanel_ArtifactCountsTableModel_count_header() - }; - - private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer(); - - private final FileTypePieChart fileTypePieChart = new FileTypePieChart(); - - /** - * Creates new form DataSourceSummaryCountsPanel - */ - TypesPanel() { - rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT); initComponents(); - fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false); - artifactCountsTable.getTableHeader().setReorderingAllowed(false); - setDataSource(null); } @Override protected void onNewDataSource(DataSource dataSource) { + // if no data source is present or the case is not open, + // set results for tables to null. if (dataSource == null || !Case.isCaseOpen()) { - updateCountsTableData(EMPTY_PAIRS, EMPTY_PAIRS); + this.dataFetchComponents.forEach((item) -> item.getResultHandler() + .accept(DataFetchResult.getSuccessResult(null))); + } else { - updateCountsTableData(getFileCategoryModel(dataSource), getArtifactCountsModel(dataSource)); + // set tables to display loading screen + this.loadables.forEach((table) -> table.showDefaultLoadingMessage()); + + // create swing workers to run for each table + List> workers = dataFetchComponents + .stream() + .map((components) -> new DataFetchWorker<>(components, dataSource)) + .collect(Collectors.toList()); + + // submit swing workers to run + submit(workers); } - this.fileTypePieChart.setDataSource(dataSource); } - /** - * Specify the DataSource to display file information for. - * - * @param fileCategoryDataModel The file category data model. - * @param artifactDataModel The artifact type data model. - */ - private void updateCountsTableData(Object[][] fileCategoryDataModel, Object[][] artifactDataModel) { - fileCountsByCategoryTable.setModel(new NonEditableTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS)); - fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); - fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130); - - artifactCountsTable.setModel(new NonEditableTableModel(artifactDataModel, ARTIFACT_COUNTS_COLUMN_HEADERS)); - artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230); - artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); - - this.repaint(); - } - - /** - * Determines the JTable data model for datasource file categories. - * - * @param dataSource The DataSource. - * - * @return The model to be used with a JTable. - */ + @Messages({ "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All", "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated", From b6f0fd722eaedf917c3d2c74677db57c669b0068 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Sep 2020 07:43:49 -0400 Subject: [PATCH 04/28] working through refactoring types panel --- .../datasourcesummary/ui/TypesPanel.java | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 910f3c0a8c..449b96106c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.datasourcesummary.ui; import java.util.Arrays; import java.util.List; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.NonEditableTableModel; import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; @@ -29,6 +28,8 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; +import static org.sleuthkit.autopsy.datasourcesummary.uiutils.AbstractLoadableComponent.DEFAULT_ERROR_MESSAGE; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; @@ -49,28 +50,27 @@ import org.sleuthkit.datamodel.DataSource; "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Types", "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count", "TypesPanel_fileTypesPieChart_title=File Types", - "TypesPanel_fileTypesPieChart_title=Artifact Types", + "TypesPanel_artifactsTypesPieChart_title=Artifact Types", "TypesPanel_filesByCategoryTable_title=Files by Category", "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", - "TypesPanel_filesByCategoryTable_countColumn_title=Count", - "TypesPanel_filesByCategoryTable_title=Files by Category",}) + "TypesPanel_filesByCategoryTable_countColumn_title=Count",}) class TypesPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private final PieChartPanel fileTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); - private final PieChartPanel artifactTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); + private final PieChartPanel artifactTypesPieChart = new PieChartPanel(Bundle.TypesPanel_artifactsTypesPieChart_title()); private final JTablePanel> filesByCategoryTable = JTablePanel.getJTablePanel(Arrays.asList( new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_labelColumn_title(), - (pair) -> pair.getFirst(), + (pair) -> new DefaultCellModel(pair.getLeft()), 250 ), new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_countColumn_title(), - (pair) -> pair.getSecond(), + (pair) -> new DefaultCellModel(Long.toString(getZeroIfNull(pair.getRight()))), 150 ) )); @@ -88,10 +88,10 @@ class TypesPanel extends BaseDataSourceSummaryPanel { // set up data acquisition methods dataFetchComponents = Arrays.asList( + // files by category worker new DataFetchWorker.DataFetchComponents>( - (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), - (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + TypesPanel::getFileCategoryModel, + (result) -> filesByCategoryTable.showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, TOOL_TIP_TEXT_KEY)), new DataFetchWorker.DataFetchComponents>( (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), @@ -132,20 +132,20 @@ class TypesPanel extends BaseDataSourceSummaryPanel { "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack", "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory" }) - private static Object[][] getFileCategoryModel(DataSource selectedDataSource) { - Long fileCount = zeroIfNull(DataSourceCountsSummary.getCountOfFiles(selectedDataSource)); - Long unallocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfUnallocatedFiles(selectedDataSource)); - Long allocatedFiles = zeroIfNull(DataSourceCountsSummary.getCountOfAllocatedFiles(selectedDataSource)); - Long slackFiles = zeroIfNull(DataSourceCountsSummary.getCountOfSlackFiles(selectedDataSource)); - Long directories = zeroIfNull(DataSourceCountsSummary.getCountOfDirectories(selectedDataSource)); + private static List> getFileCategoryModel(DataSource selectedDataSource) { + Long fileCount = getZeroIfNull(DataSourceCountsSummary.getCountOfFiles(selectedDataSource)); + Long unallocatedFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfUnallocatedFiles(selectedDataSource)); + Long allocatedFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfAllocatedFiles(selectedDataSource)); + Long slackFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfSlackFiles(selectedDataSource)); + Long directories = getZeroIfNull(DataSourceCountsSummary.getCountOfDirectories(selectedDataSource)); - return new Object[][]{ - new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount}, - new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(), allocatedFiles}, - new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(), unallocatedFiles}, - new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(), slackFiles}, - new Object[]{Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(), directories} - }; + return Arrays.asList( + Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount), + Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(), allocatedFiles), + Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(), unallocatedFiles), + Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(), slackFiles), + Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(), directories) + ); } /** @@ -155,9 +155,11 @@ class TypesPanel extends BaseDataSourceSummaryPanel { * * @return The value or 0 if null. */ - private static Long zeroIfNull(Long origValue) { + private static Long getZeroIfNull(Long origValue) { return origValue == null ? 0 : origValue; } + + private static String get /** * The counts of different artifact types found in a DataSource. From 2615dd6e7a15b5822a808ded838dccfb60f1942b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Sep 2020 15:41:10 -0400 Subject: [PATCH 05/28] working through types panel layout --- .../datasourcesummary/ui/Bundle.properties | 2 - .../ui/Bundle.properties-MERGED | 45 +- .../ui/DataSourceSummaryDetailsPanel.java | 57 +-- .../datasourcesummary/ui/TypesPanel.form | 304 ++++++------ .../datasourcesummary/ui/TypesPanel.java | 450 ++++++++++++------ .../uiutils/AbstractLoadableComponent.java | 31 +- .../uiutils/BaseMessageOverlay.java | 7 - .../uiutils/JTablePanel.java | 9 +- .../uiutils/LoadableComponent.java | 19 +- .../uiutils/PieChartPanel.java | 6 +- 10 files changed, 528 insertions(+), 402 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index e2560a53b8..a11db6f147 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,5 +35,3 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains -TypesPanel.resultsByTypeLabel.text=Results by Type -TypesPanel.byCategoryLabel.text=Files by Category diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 98f650b3de..73a07a3e2a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -1,14 +1,5 @@ CTL_DataSourceSummaryAction=Data Source Summary -DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count -DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables @@ -18,12 +9,6 @@ DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_notAnalyzed_label=Not Ana DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_other_label=Other DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case. DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure -DataSourceSummaryDetailsPanel.units.bytes=\ bytes -DataSourceSummaryDetailsPanel.units.gigabytes=\ GB -DataSourceSummaryDetailsPanel.units.kilobytes=\ kB -DataSourceSummaryDetailsPanel.units.megabytes=\ MB -DataSourceSummaryDetailsPanel.units.petabytes=\ PB -DataSourceSummaryDetailsPanel.units.terabytes=\ TB DataSourceSummaryDialog.closeButton.text=Close DataSourceSummaryDetailsPanel.displayNameLabel.text=Display Name: DataSourceSummaryDetailsPanel.originalNameLabel.text=Name: @@ -59,8 +44,6 @@ DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= -DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category -DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type DataSourceSummaryDialog.window.title=Data Sources Summary DataSourceSummaryNode.column.dataSourceName.header=Data Source Name DataSourceSummaryNode.column.files.header=Files @@ -69,9 +52,9 @@ DataSourceSummaryNode.column.status.header=Ingest Status DataSourceSummaryNode.column.tags.header=Tags DataSourceSummaryNode.column.type.header=Type DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source -DataSourceSummaryTabbedPane_countsTab_title=Counts DataSourceSummaryTabbedPane_detailsTab_title=Details DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History +DataSourceSummaryTabbedPane_typesTab_title=Types DataSourceSummaryTabbedPane_userActivityTab_title=User Activity DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains @@ -84,4 +67,30 @@ DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program +SizeRepresentationUtil_units_bytes=\ bytes +SizeRepresentationUtil_units_gigabytes=\ GB +SizeRepresentationUtil_units_kilobytes=\ kB +SizeRepresentationUtil_units_megabytes=\ MB +SizeRepresentationUtil_units_petabytes=\ PB +SizeRepresentationUtil_units_terabytes=\ TB +TypesPanel_artifactsTypesPieChart_title=Artifact Types +TypesPanel_fileMimeTypesChart_audio_title=Audio +TypesPanel_fileMimeTypesChart_documents_title=Documents +TypesPanel_fileMimeTypesChart_executables_title=Executables +TypesPanel_fileMimeTypesChart_images_title=Images +TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed +TypesPanel_fileMimeTypesChart_other_title=Other +TypesPanel_fileMimeTypesChart_title=File Types +TypesPanel_fileMimeTypesChart_videos_title=Videos +TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated +TypesPanel_filesByCategoryTable_allRow_title=All +TypesPanel_filesByCategoryTable_countColumn_title=Count +TypesPanel_filesByCategoryTable_directoryRow_title=Directory +TypesPanel_filesByCategoryTable_labelColumn_title=File Type +TypesPanel_filesByCategoryTable_slackRow_title=Slack +TypesPanel_filesByCategoryTable_title=Files by Category +TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated +TypesPanel_osLabel_title=OS +TypesPanel_sizeLabel_title=Size +TypesPanel_usageLabel_title=Usage ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java index 3bc0eaf36d..d37d1e21a2 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java @@ -37,8 +37,6 @@ class DataSourceSummaryDetailsPanel extends BaseDataSourceSummaryPanel { //Because this panel was made using the gridbaglayout and netbean's Customize Layout tool it will be best to continue to modify it through that private static final long serialVersionUID = 1L; - private static final Integer SIZE_COVERSION_CONSTANT = 1000; - private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##"); private static final Logger logger = Logger.getLogger(DataSourceSummaryDetailsPanel.class.getName()); /** @@ -71,7 +69,7 @@ class DataSourceSummaryDetailsPanel extends BaseDataSourceSummaryPanel { private void updateDetailsPanelData(DataSource selectedDataSource, Long unallocatedFilesSize, String osDetails, String usage) { clearTableValues(); if (selectedDataSource != null) { - unallocatedSizeValue.setText(getSizeString(unallocatedFilesSize)); + unallocatedSizeValue.setText(SizeRepresentationUtil.getSizeString(unallocatedFilesSize)); operatingSystemValue.setText(StringUtils.isBlank(osDetails) ? "" : osDetails); dataSourceUsageValue.setText(StringUtils.isBlank(usage) ? "" : usage); @@ -103,8 +101,8 @@ class DataSourceSummaryDetailsPanel extends BaseDataSourceSummaryPanel { */ private void setFieldsForImage(Image selectedImage) { imageTypeValue.setText(selectedImage.getType().getName()); - sizeValue.setText(getSizeString(selectedImage.getSize())); - sectorSizeValue.setText(getSizeString(selectedImage.getSsize())); + sizeValue.setText(SizeRepresentationUtil.getSizeString(selectedImage.getSize())); + sectorSizeValue.setText(SizeRepresentationUtil.getSizeString(selectedImage.getSsize())); for (String path : selectedImage.getPaths()) { ((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path}); @@ -142,54 +140,7 @@ class DataSourceSummaryDetailsPanel extends BaseDataSourceSummaryPanel { } } - /** - * Get a long size in bytes as a string formated to be read by users. - * - * @param size Long value representing a size in bytes - * - * @return return a string formated with a user friendly version of the size - * as a string, returns empty String when provided empty size - */ - @Messages({ - "DataSourceSummaryDetailsPanel.units.bytes= bytes", - "DataSourceSummaryDetailsPanel.units.kilobytes= kB", - "DataSourceSummaryDetailsPanel.units.megabytes= MB", - "DataSourceSummaryDetailsPanel.units.gigabytes= GB", - "DataSourceSummaryDetailsPanel.units.terabytes= TB", - "DataSourceSummaryDetailsPanel.units.petabytes= PB" - }) - private static String getSizeString(Long size) { - if (size == null) { - return ""; - } - double approximateSize = size; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes(); - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_kilobytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_megabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_gigabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_terabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_petabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } + /** * Update the visibility of all fields and their labels based on whether diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index 9164cceaf4..7f55a50216 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -16,12 +16,12 @@ - + - + @@ -34,153 +34,57 @@ - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + - - + + + - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - + + + + + + + + + + + + - + + + + - + - - - - - - - - - - - + + + + + + @@ -195,21 +99,147 @@ - + + + + + + + + + - - + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 449b96106c..70642e95c4 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -18,17 +18,25 @@ */ package org.sleuthkit.autopsy.datasourcesummary.ui; +import java.awt.BorderLayout; +import java.text.DecimalFormat; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.swing.JLabel; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; -import static org.sleuthkit.autopsy.datasourcesummary.uiutils.AbstractLoadableComponent.DEFAULT_ERROR_MESSAGE; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceDetailsSummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceMimeTypeSummary; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.AbstractLoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; @@ -37,6 +45,8 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel.PieChartItem; +import org.sleuthkit.autopsy.guiutils.WrapLayout; import org.sleuthkit.datamodel.DataSource; @@ -45,21 +55,79 @@ import org.sleuthkit.datamodel.DataSource; * specified DataSource */ @Messages({ - "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Artifact Types", - "DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Types", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count", - "TypesPanel_fileTypesPieChart_title=File Types", "TypesPanel_artifactsTypesPieChart_title=Artifact Types", "TypesPanel_filesByCategoryTable_title=Files by Category", "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", - "TypesPanel_filesByCategoryTable_countColumn_title=Count",}) + "TypesPanel_filesByCategoryTable_countColumn_title=Count", + "TypesPanel_filesByCategoryTable_allRow_title=All", + "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated", + "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated", + "TypesPanel_filesByCategoryTable_slackRow_title=Slack", + "TypesPanel_filesByCategoryTable_directoryRow_title=Directory", + "TypesPanel_fileMimeTypesChart_title=File Types", + "TypesPanel_fileMimeTypesChart_audio_title=Audio", + "TypesPanel_fileMimeTypesChart_documents_title=Documents", + "TypesPanel_fileMimeTypesChart_executables_title=Executables", + "TypesPanel_fileMimeTypesChart_images_title=Images", + "TypesPanel_fileMimeTypesChart_videos_title=Videos", + "TypesPanel_fileMimeTypesChart_other_title=Other", + "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed", + "TypesPanel_usageLabel_title=Usage", + "TypesPanel_osLabel_title=OS", + "TypesPanel_sizeLabel_title=Size"}) class TypesPanel extends BaseDataSourceSummaryPanel { - private static final long serialVersionUID = 1L; + private static class LoadableLabel extends AbstractLoadableComponent { + private static final long serialVersionUID = 1L; + + private final JLabel label = new JLabel(); + private final String key; - private final PieChartPanel fileTypesPieChart = new PieChartPanel(Bundle.TypesPanel_fileTypesPieChart_title()); - private final PieChartPanel artifactTypesPieChart = new PieChartPanel(Bundle.TypesPanel_artifactsTypesPieChart_title()); + public LoadableLabel(String key) { + this.key = key; + setLayout(new BorderLayout()); + add(label, BorderLayout.CENTER); + } + + private void setValue(String value, boolean italicize) { + String formattedKey = StringUtils.isBlank(key) ? "" : key; + String formattedValue = StringUtils.isBlank(value) ? "" : value; + String htmlFormattedValue = (italicize) ? String.format("%s", formattedValue) : formattedValue; + label.setText(String.format("
%s: %s
", formattedKey, htmlFormattedValue)); + } + + @Override + protected void setMessage(boolean visible, String message) { + setValue(message, true); + } + + @Override + protected void setResults(String data) { + setValue(data, false); + } + } + + + private static final long serialVersionUID = 1L; + private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#"); + + private static final List> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE) + ); + + private static final Set CATEGORY_MIME_TYPES = FILE_MIME_TYPE_CATEGORIES + .stream() + .flatMap((cat) -> cat.getRight().getMediaTypes().stream()) + .collect(Collectors.toSet()); + + + private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title()); + + private final PieChartPanel artifactTypesChart = new PieChartPanel(Bundle.TypesPanel_artifactsTypesPieChart_title()); private final JTablePanel> filesByCategoryTable = JTablePanel.getJTablePanel(Arrays.asList( @@ -70,35 +138,61 @@ class TypesPanel extends BaseDataSourceSummaryPanel { ), new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_countColumn_title(), - (pair) -> new DefaultCellModel(Long.toString(getZeroIfNull(pair.getRight()))), + (pair) -> new DefaultCellModel(Long.toString(pair.getRight() == null ? 0 : pair.getRight())), 150 ) )); + + private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); + private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); + private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); private final List> loadables = Arrays.asList( - fileTypesPieChart, - artifactTypesPieChart, + usageLabel, + osLabel, + sizeLabel, + fileMimeTypesChart, + artifactTypesChart, filesByCategoryTable ); - private final List> dataFetchComponents; - - + private final List> dataFetchComponents = Arrays.asList( + // usage label worker + new DataFetchWorker.DataFetchComponents<>( + DataSourceDetailsSummary::getDataSourceType, + usageLabel::showDataFetchResult), + // os label worker + new DataFetchWorker.DataFetchComponents<>( + DataSourceDetailsSummary::getOperatingSystems, + osLabel::showDataFetchResult), + // size label worker + new DataFetchWorker.DataFetchComponents<>( + (dataSource) -> { + Long size = dataSource == null ? dataSource.getSize() : null; + return SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false); + }, + sizeLabel::showDataFetchResult), + // file types worker + new DataFetchWorker.DataFetchComponents<>( + this::getMimeTypeCategoriesModel, + fileMimeTypesChart::showDataFetchResult), + // artifact counts worker + new DataFetchWorker.DataFetchComponents<>( + this::getArtifactCountsModel, + artifactTypesChart::showDataFetchResult), + // files by category worker + new DataFetchWorker.DataFetchComponents<>( + this::getFileCategoryModel, + filesByCategoryTable::showDataFetchResult) + ); + public TypesPanel() { - - // set up data acquisition methods - dataFetchComponents = Arrays.asList( - // files by category worker - new DataFetchWorker.DataFetchComponents>( - TypesPanel::getFileCategoryModel, - (result) -> filesByCategoryTable.showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, TOOL_TIP_TEXT_KEY)), - new DataFetchWorker.DataFetchComponents>( - (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), - (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) - ); - initComponents(); + customizeComponents(); + } + + private void customizeComponents() { + this.pieChartRow.setLayout(new WrapLayout(0,5)); } @Override @@ -124,42 +218,51 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } } - - @Messages({ - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory" - }) - private static List> getFileCategoryModel(DataSource selectedDataSource) { - Long fileCount = getZeroIfNull(DataSourceCountsSummary.getCountOfFiles(selectedDataSource)); - Long unallocatedFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfUnallocatedFiles(selectedDataSource)); - Long allocatedFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfAllocatedFiles(selectedDataSource)); - Long slackFiles = getZeroIfNull(DataSourceCountsSummary.getCountOfSlackFiles(selectedDataSource)); - Long directories = getZeroIfNull(DataSourceCountsSummary.getCountOfDirectories(selectedDataSource)); + private List> getFileCategoryModel(DataSource selectedDataSource) { + if (selectedDataSource == null) { + return null; + } - return Arrays.asList( - Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(), fileCount), - Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(), allocatedFiles), - Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(), unallocatedFiles), - Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(), slackFiles), - Pair.of(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(), directories) + List>> itemsAndRetrievers = Arrays.asList( + Pair.of(Bundle.TypesPanel_filesByCategoryTable_allRow_title(), DataSourceCountsSummary::getCountOfFiles), + Pair.of(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title(), DataSourceCountsSummary::getCountOfAllocatedFiles), + Pair.of(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title(), DataSourceCountsSummary::getCountOfUnallocatedFiles), + Pair.of(Bundle.TypesPanel_filesByCategoryTable_slackRow_title(), DataSourceCountsSummary::getCountOfSlackFiles), + Pair.of(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title(), DataSourceCountsSummary::getCountOfDirectories) ); + + return itemsAndRetrievers + .stream() + .map(pair -> { + Long result = pair.getRight().apply(selectedDataSource); + return Pair.of(pair.getLeft(), result == null ? 0 : result); + }) + .collect(Collectors.toList()); } - /** - * Returns 0 if value is null. - * - * @param origValue The original value. - * - * @return The value or 0 if null. - */ - private static Long getZeroIfNull(Long origValue) { - return origValue == null ? 0 : origValue; + private List getMimeTypeCategoriesModel(DataSource dataSource) { + if (dataSource == null) { + return null; + } + + Stream> fileCategoryItems = FILE_MIME_TYPE_CATEGORIES + .stream() + .map((strCat) + -> Pair.of(strCat.getLeft(), + DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes(dataSource, strCat.getRight().getMediaTypes()))); + + Stream> otherItems = Stream.of( + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_other_title(), + DataSourceMimeTypeSummary.getCountOfFilesNotInMimeTypes(dataSource, CATEGORY_MIME_TYPES)), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(), + DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(dataSource)) + ); + + return Stream.concat(fileCategoryItems, otherItems) + .filter(keyCount -> keyCount.getRight() != null && keyCount.getRight() > 0) + .map(keyCount -> new PieChartItem(keyCount.getLeft(), keyCount.getRight())) + .collect(Collectors.toList()); } - - private static String get /** * The counts of different artifact types found in a DataSource. @@ -168,18 +271,21 @@ class TypesPanel extends BaseDataSourceSummaryPanel { * * @return The JTable data model of counts of artifact types. */ - private static Object[][] getArtifactCountsModel(DataSource selectedDataSource) { + private List getArtifactCountsModel(DataSource selectedDataSource) { Map artifactMapping = DataSourceCountsSummary.getCountsOfArtifactsByType(selectedDataSource); if (artifactMapping == null) { - return EMPTY_PAIRS; + return null; } return artifactMapping.entrySet().stream() - .filter((entrySet) -> entrySet != null && entrySet.getKey() != null) + .filter((entrySet) -> entrySet != null) .sorted((a, b) -> a.getKey().compareTo(b.getKey())) - .map((entrySet) -> new Object[]{entrySet.getKey(), entrySet.getValue()}) - .toArray(Object[][]::new); + .map((entrySet) -> new PieChartItem(entrySet.getKey(), entrySet.getValue())) + .collect(Collectors.toList()); } + + + /** * This method is called from within the constructor to initialize the form. @@ -189,121 +295,163 @@ class TypesPanel extends BaseDataSourceSummaryPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; javax.swing.JScrollPane scrollParent = new javax.swing.JScrollPane(); - javax.swing.JPanel parentPanel = new javax.swing.JPanel(); - javax.swing.JScrollPane fileCountsByCategoryScrollPane = new javax.swing.JScrollPane(); - fileCountsByCategoryTable = new javax.swing.JTable(); - javax.swing.JLabel byCategoryLabel = new javax.swing.JLabel(); - javax.swing.JLabel resultsByTypeLabel = new javax.swing.JLabel(); - javax.swing.JScrollPane artifactCountsScrollPane = new javax.swing.JScrollPane(); - 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(); + jPanel1 = new javax.swing.JPanel(); + javax.swing.JPanel usagePanel = usageLabel; + osPanel = osLabel; + sizePanel = sizeLabel; + pieChartRow = new javax.swing.JPanel(); + javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; + javax.swing.JPanel artifactTypesPanel = artifactTypesChart; + javax.swing.JPanel filesByCategoryPanel = filesByCategoryTable; - parentPanel.setMinimumSize(new java.awt.Dimension(840, 320)); + jPanel1.setLayout(new java.awt.GridBagLayout()); - fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable); + usagePanel.setMinimumSize(null); - org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.byCategoryLabel.text")); // NOI18N + javax.swing.GroupLayout usagePanelLayout = new javax.swing.GroupLayout(usagePanel); + usagePanel.setLayout(usagePanelLayout); + usagePanelLayout.setHorizontalGroup( + usagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 815, Short.MAX_VALUE) + ); + usagePanelLayout.setVerticalGroup( + usagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 17, Short.MAX_VALUE) + ); - org.openide.awt.Mnemonics.setLocalizedText(resultsByTypeLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.resultsByTypeLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(usagePanel, gridBagConstraints); - artifactCountsTable.setAutoCreateRowSorter(true); - artifactCountsScrollPane.setViewportView(artifactCountsTable); + osPanel.setMinimumSize(null); + osPanel.setPreferredSize(null); - 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) + javax.swing.GroupLayout osPanelLayout = new javax.swing.GroupLayout(osPanel); + osPanel.setLayout(osPanelLayout); + osPanelLayout.setHorizontalGroup( + osPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 0, Short.MAX_VALUE) ); - filesByCatParentLayout.setVerticalGroup( - filesByCatParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + osPanelLayout.setVerticalGroup( + osPanelLayout.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) + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(osPanel, gridBagConstraints); + + sizePanel.setMinimumSize(null); + sizePanel.setPreferredSize(null); + + javax.swing.GroupLayout sizePanelLayout = new javax.swing.GroupLayout(sizePanel); + sizePanel.setLayout(sizePanelLayout); + sizePanelLayout.setHorizontalGroup( + sizePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 815, Short.MAX_VALUE) ); - resultsByTypeParentLayout.setVerticalGroup( - resultsByTypeParentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) + sizePanelLayout.setVerticalGroup( + sizePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 17, 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)) + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(sizePanel, gridBagConstraints); + + pieChartRow.setMinimumSize(null); + pieChartRow.setPreferredSize(null); + + fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300)); + fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300)); + fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300)); + + javax.swing.GroupLayout fileMimeTypesPanelLayout = new javax.swing.GroupLayout(fileMimeTypesPanel); + fileMimeTypesPanel.setLayout(fileMimeTypesPanelLayout); + fileMimeTypesPanelLayout.setHorizontalGroup( + fileMimeTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, 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()))))) + fileMimeTypesPanelLayout.setVerticalGroup( + fileMimeTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) ); - scrollParent.setViewportView(parentPanel); + pieChartRow.add(fileMimeTypesPanel); + + artifactTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300)); + artifactTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300)); + artifactTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300)); + + javax.swing.GroupLayout artifactTypesPanelLayout = new javax.swing.GroupLayout(artifactTypesPanel); + artifactTypesPanel.setLayout(artifactTypesPanelLayout); + artifactTypesPanelLayout.setHorizontalGroup( + artifactTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + ); + artifactTypesPanelLayout.setVerticalGroup( + artifactTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) + ); + + pieChartRow.add(artifactTypesPanel); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(pieChartRow, gridBagConstraints); + + filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(400, 187)); + filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 187)); + + javax.swing.GroupLayout filesByCategoryPanelLayout = new javax.swing.GroupLayout(filesByCategoryPanel); + filesByCategoryPanel.setLayout(filesByCategoryPanelLayout); + filesByCategoryPanelLayout.setHorizontalGroup( + filesByCategoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + ); + filesByCategoryPanelLayout.setVerticalGroup( + filesByCategoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 187, Short.MAX_VALUE) + ); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(filesByCategoryPanel, gridBagConstraints); + + scrollParent.setViewportView(jPanel1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollParent) + .addComponent(scrollParent, javax.swing.GroupLayout.DEFAULT_SIZE, 840, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollParent) + .addComponent(scrollParent, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JTable artifactCountsTable; - private javax.swing.JTable fileCountsByCategoryTable; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel osPanel; + private javax.swing.JPanel pieChartRow; + private javax.swing.JPanel sizePanel; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java index 0b5657983c..902f27519e 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java @@ -5,7 +5,7 @@ */ package org.sleuthkit.autopsy.datasourcesummary.uiutils; -import java.util.List; +import java.util.Collection; import java.util.logging.Level; import javax.swing.JPanel; import org.openide.util.NbBundle; @@ -49,8 +49,8 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa * @param message The message to be shown. */ public synchronized void showMessage(String message) { - setResultList(null); - setOverlay(true, message); + setResults(null); + setMessage(true, message); repaint(); } @@ -69,9 +69,9 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa * @param data The data to be shown where each item represents a row of * data. */ - public synchronized void showResults(List data) { - setOverlay(false, null); - setResultList(data); + public synchronized void showResults(T data) { + setMessage(false, null); + setResults(data); repaint(); } @@ -87,7 +87,7 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa * @param noResultsMessage The message to be shown if there are no results * but the operation completed successfully. */ - public void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage) { + public void showDataFetchResult(DataFetchResult result, String errorMessage, String noResultsMessage) { if (result == null) { logger.log(Level.SEVERE, "Null data fetch result received."); return; @@ -95,10 +95,11 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa switch (result.getResultType()) { case SUCCESS: - if (result.getData() == null || result.getData().isEmpty()) { + T data = result.getData(); + if (data == null || (data instanceof Collection && ((Collection) data).isEmpty())) { showMessage(noResultsMessage); } else { - showResults(result.getData()); + showResults(data); } break; case ERROR: @@ -122,18 +123,18 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa * * @param result The DataFetchResult. */ - public void showDataFetchResult(DataFetchResult> result) { + public void showDataFetchResult(DataFetchResult result) { showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, DEFAULT_NO_RESULTS_MESSAGE); } /** - * Sets the message and visibility of the overlay. Repaint does not need to + * Sets the message and visibility of the message. Repaint does not need to * be handled in this method. * - * @param visible The visibility of the overlay. - * @param message The message in the overlay. + * @param visible The visibility of the message. + * @param message The message to be displayed if visible. */ - protected abstract void setOverlay(boolean visible, String message); + protected abstract void setMessage(boolean visible, String message); /** * Sets the data to be shown in the JTable. Repaint does not need to be @@ -141,5 +142,5 @@ public abstract class AbstractLoadableComponent extends JPanel implements Loa * * @param data The list of data objects to be shown. */ - protected abstract void setResultList(List data); + protected abstract void setResults(T data); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java index 2f66a2e5eb..650ac04ff8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java @@ -13,9 +13,6 @@ import javax.swing.JLabel; * @author gregd */ public class BaseMessageOverlay { - - private static final long serialVersionUID = 1L; - private final JLabel label; private boolean visible = false; @@ -57,11 +54,7 @@ public class BaseMessageOverlay { message == null ? "" : message)); } - //@Override - //public void paintOverlay(Graphics2D g2d, ChartPanel pnl) public void paintOverlay(Graphics g, int width, int height) { - // Paint the underlying view. - if (!visible) { return; } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 3df60ec9d8..7b54717338 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -32,14 +32,13 @@ import javax.swing.plaf.LayerUI; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.CellModel; /** * A table that displays a list of items and also can display messages for * loading, load error, and not loaded. */ -public class JTablePanel extends AbstractLoadableComponent { +public class JTablePanel extends AbstractLoadableComponent> { /** * JTables don't allow displaying messages. So this LayerUI is used to @@ -139,7 +138,6 @@ public class JTablePanel extends AbstractLoadableComponent { private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(JTablePanel.class.getName()); private static final CellModelTableCellRenderer DEFAULT_CELL_RENDERER = new CellModelTableCellRenderer(); /** @@ -244,8 +242,9 @@ public class JTablePanel extends AbstractLoadableComponent { return this; } + @Override - protected void setResultList(List data) { + protected void setResults(List data) { // set the list of data to be shown as either the data or an empty list // on null. List dataToSet = (data == null) ? Collections.emptyList() : data; @@ -258,7 +257,7 @@ public class JTablePanel extends AbstractLoadableComponent { } @Override - protected void setOverlay(boolean visible, String message) { + protected void setMessage(boolean visible, String message) { this.overlayLayer.setVisible(visible); this.overlayLayer.setMessage(message); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java index f8e6d03300..24a84b1c07 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java @@ -5,14 +5,12 @@ */ package org.sleuthkit.autopsy.datasourcesummary.uiutils; -import java.util.List; - /** * * @author gregd */ public interface LoadableComponent { - + /** * Clears the results from the underlying JTable and shows the provided * message. @@ -20,13 +18,13 @@ public interface LoadableComponent { * @param message The message to be shown. */ void showMessage(String message); - + /** * Shows a default loading message on the table. This will clear any results * in the table. */ void showDefaultLoadingMessage(); - + /** * Shows the list as rows of data in the table. If overlay message will be * cleared if present. @@ -34,10 +32,9 @@ public interface LoadableComponent { * @param data The data to be shown where each item represents a row of * data. */ - void showResults(List data); - - - /** + void showResults(T data); + + /** * Shows the data in a DataFetchResult. If there was an error during the * operation, the errorMessage will be displayed. If the operation completed * successfully and no data is present, noResultsMessage will be shown. @@ -49,7 +46,7 @@ public interface LoadableComponent { * @param noResultsMessage The message to be shown if there are no results * but the operation completed successfully. */ - void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage); + void showDataFetchResult(DataFetchResult result, String errorMessage, String noResultsMessage); /** * Shows the data in a DataFetchResult. If there was an error during the @@ -59,5 +56,5 @@ public interface LoadableComponent { * * @param result The DataFetchResult. */ - public void showDataFetchResult(DataFetchResult> result); + public void showDataFetchResult(DataFetchResult result); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java index f644d179ce..b27b26d293 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java @@ -25,7 +25,7 @@ import org.jfree.data.general.DefaultPieDataset; * * @author gregd */ -public class PieChartPanel extends AbstractLoadableComponent { +public class PieChartPanel extends AbstractLoadableComponent> { /** * @@ -136,13 +136,13 @@ public class PieChartPanel extends AbstractLoadableComponent data) { + protected void setResults(List data) { this.dataset.clear(); if (data != null) { for (PieChartPanel.PieChartItem slice : data) { From 6a0e4183870dcc75e178d4918043e44a88c5592a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Sep 2020 15:41:19 -0400 Subject: [PATCH 06/28] working through types panel layout --- .../ui/SizeRepresentationUtil.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java new file mode 100644 index 0000000000..92dc3f02f4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java @@ -0,0 +1,77 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.datasourcesummary.ui; + +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.List; +import org.openide.util.NbBundle; + +/** + * + * @author gregd + */ +public class SizeRepresentationUtil { + + private static final int SIZE_CONVERSION_CONSTANT = 1000; + private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##"); + + private static List UNITS = Arrays.asList( + Bundle.SizeRepresentationUtil_units_bytes(), + Bundle.SizeRepresentationUtil_units_kilobytes(), + Bundle.SizeRepresentationUtil_units_megabytes(), + Bundle.SizeRepresentationUtil_units_gigabytes(), + Bundle.SizeRepresentationUtil_units_terabytes(), + Bundle.SizeRepresentationUtil_units_petabytes() + ); + + /** + * Get a long size in bytes as a string formated to be read by users. + * + * @param size Long value representing a size in bytes + * + * @return return a string formated with a user friendly version of the size + * as a string, returns empty String when provided empty size + */ + public static String getSizeString(Long size) { + return getSizeString(size, APPROXIMATE_SIZE_FORMAT, true); + } + + + @NbBundle.Messages({ + "SizeRepresentationUtil_units_bytes= bytes", + "SizeRepresentationUtil_units_kilobytes= kB", + "SizeRepresentationUtil_units_megabytes= MB", + "SizeRepresentationUtil_units_gigabytes= GB", + "SizeRepresentationUtil_units_terabytes= TB", + "SizeRepresentationUtil_units_petabytes= PB" + }) + public static String getSizeString(Long size, DecimalFormat format, boolean showFullSize) { + if (size == null) { + return ""; + } + double approximateSize = size; + int unitsIndex = 0; + for (; unitsIndex < UNITS.size(); unitsIndex++) { + if (approximateSize < SIZE_CONVERSION_CONSTANT) { + break; + } else { + approximateSize /= SIZE_CONVERSION_CONSTANT; + } + } + + String fullSize = String.valueOf(size) + UNITS.get(0); + String closestUnitSize = format.format(approximateSize) + UNITS.get(unitsIndex); + + if (unitsIndex == 0) { + return fullSize; + } else if (showFullSize) { + return String.format("%s (%s)", closestUnitSize, fullSize); + } else { + return closestUnitSize; + } + } +} From 59e0d28fe63ede3e639b3deeb8e583b1710d5acd Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Sep 2020 14:28:01 -0400 Subject: [PATCH 07/28] working through layout --- .../ui/Bundle.properties-MERGED | 8 - .../ui/FileTypePieChart.java | 190 ---------------- .../datasourcesummary/ui/TypesPanel.form | 215 +++++++----------- .../datasourcesummary/ui/TypesPanel.java | 177 ++++---------- .../recentactivity/Bundle.properties-MERGED | 8 +- .../netbeans/core/startup/Bundle.properties | 2 +- .../core/windows/view/ui/Bundle.properties | 2 +- 7 files changed, 138 insertions(+), 464 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/FileTypePieChart.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 73a07a3e2a..90d6f5e9e6 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -1,12 +1,4 @@ CTL_DataSourceSummaryAction=Data Source Summary -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_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.title=Load Failure DataSourceSummaryDialog.closeButton.text=Close diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/FileTypePieChart.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/FileTypePieChart.java deleted file mode 100644 index 691234cd48..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/FileTypePieChart.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2020 Basis Technology Corp. - * Contact: carrier sleuthkit 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 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()); - } -} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index 7f55a50216..8c45912276 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -11,37 +11,62 @@ +
- - - - - - - - - - - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - + + + + + @@ -49,114 +74,73 @@ - - - - - - - - - - - - - - - - - + + + + + - + - + + + - - - - - - - - - - - - - - - - - + + + + + - + - + + + - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + + + + + - + - + - + @@ -165,29 +149,23 @@ - - - - - - - - - - - - + + + + + + - + - + - + @@ -196,28 +174,21 @@ - - - - - - - - - - - - + + + + + - + - + @@ -225,24 +196,8 @@ - - - - - - - - - - - - - - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 70642e95c4..cbb03beab6 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -87,6 +87,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { this.key = key; setLayout(new BorderLayout()); add(label, BorderLayout.CENTER); + this.showResults(null); } private void setValue(String value, boolean italicize) { @@ -168,7 +169,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { // size label worker new DataFetchWorker.DataFetchComponents<>( (dataSource) -> { - Long size = dataSource == null ? dataSource.getSize() : null; + Long size = dataSource == null ? null : dataSource.getSize(); return SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false); }, sizeLabel::showDataFetchResult), @@ -295,163 +296,73 @@ class TypesPanel extends BaseDataSourceSummaryPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; javax.swing.JScrollPane scrollParent = new javax.swing.JScrollPane(); - jPanel1 = new javax.swing.JPanel(); + javax.swing.JPanel contentParent = new javax.swing.JPanel(); javax.swing.JPanel usagePanel = usageLabel; - osPanel = osLabel; - sizePanel = sizeLabel; + javax.swing.JPanel osPanel = osLabel; + javax.swing.JPanel sizePanel = sizeLabel; pieChartRow = new javax.swing.JPanel(); javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; javax.swing.JPanel artifactTypesPanel = artifactTypesChart; javax.swing.JPanel filesByCategoryPanel = filesByCategoryTable; - jPanel1.setLayout(new java.awt.GridBagLayout()); + setLayout(new java.awt.BorderLayout()); - usagePanel.setMinimumSize(null); + contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787)); + contentParent.setMinimumSize(new java.awt.Dimension(650, 500)); + contentParent.setPreferredSize(null); + contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS)); - javax.swing.GroupLayout usagePanelLayout = new javax.swing.GroupLayout(usagePanel); - usagePanel.setLayout(usagePanelLayout); - usagePanelLayout.setHorizontalGroup( - usagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 815, Short.MAX_VALUE) - ); - usagePanelLayout.setVerticalGroup( - usagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 17, Short.MAX_VALUE) - ); + usagePanel.setAlignmentX(0.0F); + usagePanel.setMaximumSize(new java.awt.Dimension(32767, 20)); + usagePanel.setMinimumSize(new java.awt.Dimension(10, 20)); + usagePanel.setName(""); // NOI18N + usagePanel.setPreferredSize(new java.awt.Dimension(800, 20)); + contentParent.add(usagePanel); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - jPanel1.add(usagePanel, gridBagConstraints); + osPanel.setAlignmentX(0.0F); + osPanel.setMaximumSize(new java.awt.Dimension(32767, 20)); + osPanel.setMinimumSize(new java.awt.Dimension(10, 20)); + osPanel.setPreferredSize(new java.awt.Dimension(800, 20)); + contentParent.add(osPanel); - osPanel.setMinimumSize(null); - osPanel.setPreferredSize(null); + sizePanel.setAlignmentX(0.0F); + sizePanel.setMaximumSize(new java.awt.Dimension(32767, 20)); + sizePanel.setMinimumSize(new java.awt.Dimension(10, 20)); + sizePanel.setPreferredSize(new java.awt.Dimension(800, 20)); + contentParent.add(sizePanel); - javax.swing.GroupLayout osPanelLayout = new javax.swing.GroupLayout(osPanel); - osPanel.setLayout(osPanelLayout); - osPanelLayout.setHorizontalGroup( - osPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) - ); - osPanelLayout.setVerticalGroup( - osPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) - ); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - jPanel1.add(osPanel, gridBagConstraints); - - sizePanel.setMinimumSize(null); - sizePanel.setPreferredSize(null); - - javax.swing.GroupLayout sizePanelLayout = new javax.swing.GroupLayout(sizePanel); - sizePanel.setLayout(sizePanelLayout); - sizePanelLayout.setHorizontalGroup( - sizePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 815, Short.MAX_VALUE) - ); - sizePanelLayout.setVerticalGroup( - sizePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 17, Short.MAX_VALUE) - ); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - jPanel1.add(sizePanel, gridBagConstraints); - - pieChartRow.setMinimumSize(null); - pieChartRow.setPreferredSize(null); - - fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300)); - fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300)); - fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300)); - - javax.swing.GroupLayout fileMimeTypesPanelLayout = new javax.swing.GroupLayout(fileMimeTypesPanel); - fileMimeTypesPanel.setLayout(fileMimeTypesPanelLayout); - fileMimeTypesPanelLayout.setHorizontalGroup( - fileMimeTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) - ); - fileMimeTypesPanelLayout.setVerticalGroup( - fileMimeTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) - ); + pieChartRow.setAlignmentX(0.0F); + fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(500, 375)); + fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(500, 375)); + fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(500, 375)); pieChartRow.add(fileMimeTypesPanel); - artifactTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300)); - artifactTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300)); - artifactTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300)); - - javax.swing.GroupLayout artifactTypesPanelLayout = new javax.swing.GroupLayout(artifactTypesPanel); - artifactTypesPanel.setLayout(artifactTypesPanelLayout); - artifactTypesPanelLayout.setHorizontalGroup( - artifactTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) - ); - artifactTypesPanelLayout.setVerticalGroup( - artifactTypesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 300, Short.MAX_VALUE) - ); - + artifactTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + artifactTypesPanel.setMaximumSize(new java.awt.Dimension(650, 500)); + artifactTypesPanel.setMinimumSize(new java.awt.Dimension(650, 500)); + artifactTypesPanel.setPreferredSize(new java.awt.Dimension(650, 500)); pieChartRow.add(artifactTypesPanel); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 3; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - jPanel1.add(pieChartRow, gridBagConstraints); + contentParent.add(pieChartRow); - filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(400, 187)); - filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 187)); + filesByCategoryPanel.setAlignmentX(0.0F); + filesByCategoryPanel.setMaximumSize(new java.awt.Dimension(32767, 106)); + filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(10, 106)); + filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 106)); + contentParent.add(filesByCategoryPanel); - javax.swing.GroupLayout filesByCategoryPanelLayout = new javax.swing.GroupLayout(filesByCategoryPanel); - filesByCategoryPanel.setLayout(filesByCategoryPanelLayout); - filesByCategoryPanelLayout.setHorizontalGroup( - filesByCategoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) - ); - filesByCategoryPanelLayout.setVerticalGroup( - filesByCategoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 187, Short.MAX_VALUE) - ); + scrollParent.setViewportView(contentParent); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 4; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - jPanel1.add(filesByCategoryPanel, gridBagConstraints); - - scrollParent.setViewportView(jPanel1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollParent, javax.swing.GroupLayout.DEFAULT_SIZE, 840, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollParent, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE) - ); + add(scrollParent, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel jPanel1; - private javax.swing.JPanel osPanel; private javax.swing.JPanel pieChartRow; - private javax.swing.JPanel sizePanel; // End of variables declaration//GEN-END:variables } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index af0dbf306b..1d52c03e67 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -5,10 +5,15 @@ ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for an ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. ChromeCacheExtractor.moduleName=ChromeCacheExtractor +# {0} - module name +# {1} - row number +# {2} - table length +# {3} - cache path ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3} DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive +# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity Extract.indexError.message=Failed to index artifact for keyword search. @@ -72,7 +77,7 @@ ExtractZone_progress_Msg=Extracting :Zone.Identifer files ExtractZone_Restricted=Restricted Sites Zone ExtractZone_Trusted=Trusted Sites Zone OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\nThe module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. +OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Short-Description=Recent Activity finder ingest module Browser.name.Microsoft.Edge=Microsoft Edge @@ -211,6 +216,7 @@ Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM) RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. +# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index 35138509d8..dbdb74f41f 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Wed, 08 Jul 2020 15:15:46 -0400 +#Thu, 03 Sep 2020 13:12:57 -0400 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index cf36e85b33..cd9f34ad5b 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Wed, 08 Jul 2020 15:15:46 -0400 +#Thu, 03 Sep 2020 13:12:57 -0400 CTL_MainWindow_Title=Autopsy 4.16.0 CTL_MainWindow_Title_No_Project=Autopsy 4.16.0 From 17644fe664fe02aadd5f4858633bf4bcc014106b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Sep 2020 16:09:08 -0400 Subject: [PATCH 08/28] working through layout --- .../datasourcesummary/ui/Bundle.properties | 1 + .../ui/Bundle.properties-MERGED | 1 + .../datasourcesummary/ui/TypesPanel.form | 67 +++++++++++++++++-- .../datasourcesummary/ui/TypesPanel.java | 20 ++++-- 4 files changed, 77 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index a11db6f147..da286b2336 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,3 +35,4 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains +TypesPanel.filesByCategoryLabel.text=Files by Category diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 90d6f5e9e6..e7e698b71f 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -65,6 +65,7 @@ SizeRepresentationUtil_units_kilobytes=\ kB SizeRepresentationUtil_units_megabytes=\ MB SizeRepresentationUtil_units_petabytes=\ PB SizeRepresentationUtil_units_terabytes=\ TB +TypesPanel.filesByCategoryLabel.text=Files by Category TypesPanel_artifactsTypesPieChart_title=Artifact Types TypesPanel_fileMimeTypesChart_audio_title=Audio TypesPanel_fileMimeTypesChart_documents_title=Documents diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index 8c45912276..ca2ff887fd 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -40,10 +40,7 @@ - - - - + @@ -122,6 +119,15 @@ + + + + + + + + + @@ -178,17 +184,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index cbb03beab6..b2fef68f05 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -305,14 +305,16 @@ class TypesPanel extends BaseDataSourceSummaryPanel { pieChartRow = new javax.swing.JPanel(); javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; javax.swing.JPanel artifactTypesPanel = artifactTypesChart; + javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); + javax.swing.JLabel filesByCategoryLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2)); javax.swing.JPanel filesByCategoryPanel = filesByCategoryTable; setLayout(new java.awt.BorderLayout()); contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787)); - contentParent.setMinimumSize(new java.awt.Dimension(650, 500)); - contentParent.setPreferredSize(null); + contentParent.setMinimumSize(new java.awt.Dimension(650, 510)); contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS)); usagePanel.setAlignmentX(0.0F); @@ -335,6 +337,9 @@ class TypesPanel extends BaseDataSourceSummaryPanel { contentParent.add(sizePanel); pieChartRow.setAlignmentX(0.0F); + pieChartRow.setMaximumSize(new java.awt.Dimension(1170, 895)); + pieChartRow.setMinimumSize(null); + pieChartRow.setPreferredSize(null); fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(500, 375)); @@ -349,11 +354,16 @@ class TypesPanel extends BaseDataSourceSummaryPanel { pieChartRow.add(artifactTypesPanel); contentParent.add(pieChartRow); + contentParent.add(filler2); + + org.openide.awt.Mnemonics.setLocalizedText(filesByCategoryLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.filesByCategoryLabel.text")); // NOI18N + contentParent.add(filesByCategoryLabel); + contentParent.add(filler1); filesByCategoryPanel.setAlignmentX(0.0F); - filesByCategoryPanel.setMaximumSize(new java.awt.Dimension(32767, 106)); - filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(10, 106)); - filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 106)); + filesByCategoryPanel.setMaximumSize(new java.awt.Dimension(32767, 107)); + filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(10, 107)); + filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 107)); contentParent.add(filesByCategoryPanel); scrollParent.setViewportView(contentParent); From cd74274c44d36c27a2bd29effb1fe292b37dc69f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 4 Sep 2020 09:14:54 -0400 Subject: [PATCH 09/28] cleanup of layout and commenting --- .../ui/DataSourceSummaryDetailsPanel.java | 3 - .../ui/SizeRepresentationUtil.java | 47 +++++-- .../datasourcesummary/ui/TypesPanel.form | 85 ++++-------- .../datasourcesummary/ui/TypesPanel.java | 121 ++++++++---------- .../uiutils/AbstractLoadableComponent.java | 36 +++++- .../uiutils/BaseMessageOverlay.java | 31 ++++- .../uiutils/JTablePanel.java | 1 - .../uiutils/ListTableModel.java | 4 +- .../uiutils/LoadableComponent.java | 25 +++- .../uiutils/PieChartPanel.java | 90 ++++++++++--- 10 files changed, 261 insertions(+), 182 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java index d37d1e21a2..bfdf32407c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryDetailsPanel.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.datasourcesummary.ui; -import java.text.DecimalFormat; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.table.DefaultTableModel; @@ -140,8 +139,6 @@ class DataSourceSummaryDetailsPanel extends BaseDataSourceSummaryPanel { } } - - /** * Update the visibility of all fields and their labels based on whether * they have contents. Empty fields have them and their contents hidden. diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java index 92dc3f02f4..0e3c18b67b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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; @@ -11,8 +24,8 @@ import java.util.List; import org.openide.util.NbBundle; /** - * - * @author gregd + * This class provides utilities for representing storage size in most relevant + * units (i.e. bytes, megabytes, etc.). */ public class SizeRepresentationUtil { @@ -31,16 +44,26 @@ public class SizeRepresentationUtil { /** * Get a long size in bytes as a string formated to be read by users. * - * @param size Long value representing a size in bytes + * @param size Long value representing a size in bytes. * - * @return return a string formated with a user friendly version of the size - * as a string, returns empty String when provided empty size + * @return Return a string formated with a user friendly version of the size + * as a string, returns empty String when provided empty size. */ public static String getSizeString(Long size) { return getSizeString(size, APPROXIMATE_SIZE_FORMAT, true); } - - + + /** + * Get a long size in bytes as a string formated to be read by users. + * + * @param size Long value representing a size in byte.s + * @param format The means of formatting the number. + * @param showFullSize Optionally show the number of bytes in the + * datasource. + * + * @return Return a string formated with a user friendly version of the size + * as a string, returns empty String when provided empty size. + */ @NbBundle.Messages({ "SizeRepresentationUtil_units_bytes= bytes", "SizeRepresentationUtil_units_kilobytes= kB", @@ -62,10 +85,10 @@ public class SizeRepresentationUtil { approximateSize /= SIZE_CONVERSION_CONSTANT; } } - + String fullSize = String.valueOf(size) + UNITS.get(0); String closestUnitSize = format.format(approximateSize) + UNITS.get(unitsIndex); - + if (unitsIndex == 0) { return fullSize; } else if (showFullSize) { diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index ca2ff887fd..7d84fd7bd4 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -40,7 +40,10 @@ - + + + + @@ -116,73 +119,31 @@ - + + + + + + - + - + - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -252,6 +213,16 @@ + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index b2fef68f05..5f3c16298b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -22,7 +22,6 @@ import java.awt.BorderLayout; import java.text.DecimalFormat; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -46,13 +45,12 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel.PieChartItem; -import org.sleuthkit.autopsy.guiutils.WrapLayout; import org.sleuthkit.datamodel.DataSource; /** * Panel for displaying summary information on the known files present in the - * specified DataSource + * specified DataSource. */ @Messages({ "TypesPanel_artifactsTypesPieChart_title=Artifact Types", @@ -77,13 +75,23 @@ import org.sleuthkit.datamodel.DataSource; "TypesPanel_sizeLabel_title=Size"}) class TypesPanel extends BaseDataSourceSummaryPanel { + /** + * A label that allows for displaying loading messages and can be used with + * a DataFetchResult. Text displays as ":". + */ private static class LoadableLabel extends AbstractLoadableComponent { + private static final long serialVersionUID = 1L; - + private final JLabel label = new JLabel(); private final String key; - public LoadableLabel(String key) { + /** + * Main constructor for the label. + * + * @param key The key to be displayed. + */ + LoadableLabel(String key) { this.key = key; setLayout(new BorderLayout()); add(label, BorderLayout.CENTER); @@ -96,7 +104,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { String htmlFormattedValue = (italicize) ? String.format("%s", formattedValue) : formattedValue; label.setText(String.format("
%s: %s
", formattedKey, htmlFormattedValue)); } - + @Override protected void setMessage(boolean visible, String message) { setValue(message, true); @@ -107,11 +115,11 @@ class TypesPanel extends BaseDataSourceSummaryPanel { setValue(data, false); } } - - + private static final long serialVersionUID = 1L; private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#"); + // All file type categories. private static final List> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( Pair.of(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE), Pair.of(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO), @@ -120,43 +128,44 @@ class TypesPanel extends BaseDataSourceSummaryPanel { Pair.of(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE) ); + // The mime types in those categories. private static final Set CATEGORY_MIME_TYPES = FILE_MIME_TYPE_CATEGORIES .stream() .flatMap((cat) -> cat.getRight().getMediaTypes().stream()) .collect(Collectors.toSet()); - private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title()); - private final PieChartPanel artifactTypesChart = new PieChartPanel(Bundle.TypesPanel_artifactsTypesPieChart_title()); - private final JTablePanel> filesByCategoryTable = JTablePanel.getJTablePanel(Arrays.asList( + // title column new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_labelColumn_title(), (pair) -> new DefaultCellModel(pair.getLeft()), 250 ), + // count column new ColumnModel<>( Bundle.TypesPanel_filesByCategoryTable_countColumn_title(), (pair) -> new DefaultCellModel(Long.toString(pair.getRight() == null ? 0 : pair.getRight())), 150 ) )); - + private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); + // all loadable components private final List> loadables = Arrays.asList( usageLabel, osLabel, sizeLabel, fileMimeTypesChart, - artifactTypesChart, filesByCategoryTable ); + // all of the means for obtaining data for the gui components. private final List> dataFetchComponents = Arrays.asList( // usage label worker new DataFetchWorker.DataFetchComponents<>( @@ -177,23 +186,17 @@ class TypesPanel extends BaseDataSourceSummaryPanel { new DataFetchWorker.DataFetchComponents<>( this::getMimeTypeCategoriesModel, fileMimeTypesChart::showDataFetchResult), - // artifact counts worker - new DataFetchWorker.DataFetchComponents<>( - this::getArtifactCountsModel, - artifactTypesChart::showDataFetchResult), // files by category worker new DataFetchWorker.DataFetchComponents<>( this::getFileCategoryModel, filesByCategoryTable::showDataFetchResult) ); + /** + * Main constructor. + */ public TypesPanel() { initComponents(); - customizeComponents(); - } - - private void customizeComponents() { - this.pieChartRow.setLayout(new WrapLayout(0,5)); } @Override @@ -219,13 +222,19 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } } + /** + * Retrieves data for the file category table. + * + * @param selectedDataSource The datasource. + * + * @return The key value pairs to be displayed. + */ private List> getFileCategoryModel(DataSource selectedDataSource) { if (selectedDataSource == null) { return null; } - List>> itemsAndRetrievers = Arrays.asList( - Pair.of(Bundle.TypesPanel_filesByCategoryTable_allRow_title(), DataSourceCountsSummary::getCountOfFiles), + List>> itemsAndRetrievers = Arrays.asList(Pair.of(Bundle.TypesPanel_filesByCategoryTable_allRow_title(), DataSourceCountsSummary::getCountOfFiles), Pair.of(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title(), DataSourceCountsSummary::getCountOfAllocatedFiles), Pair.of(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title(), DataSourceCountsSummary::getCountOfUnallocatedFiles), Pair.of(Bundle.TypesPanel_filesByCategoryTable_slackRow_title(), DataSourceCountsSummary::getCountOfSlackFiles), @@ -241,17 +250,26 @@ class TypesPanel extends BaseDataSourceSummaryPanel { .collect(Collectors.toList()); } + /** + * Gets all the data for the file type pie chart. + * + * @param dataSource + * + * @return + */ private List getMimeTypeCategoriesModel(DataSource dataSource) { if (dataSource == null) { return null; } + // for each category of file types, get the counts of files Stream> fileCategoryItems = FILE_MIME_TYPE_CATEGORIES .stream() .map((strCat) -> Pair.of(strCat.getLeft(), DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes(dataSource, strCat.getRight().getMediaTypes()))); + // also get counts for other and not analayzed Stream> otherItems = Stream.of( Pair.of(Bundle.TypesPanel_fileMimeTypesChart_other_title(), DataSourceMimeTypeSummary.getCountOfFilesNotInMimeTypes(dataSource, CATEGORY_MIME_TYPES)), @@ -259,35 +277,13 @@ class TypesPanel extends BaseDataSourceSummaryPanel { DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(dataSource)) ); + // create pie chart items to provide to pie chart return Stream.concat(fileCategoryItems, otherItems) .filter(keyCount -> keyCount.getRight() != null && keyCount.getRight() > 0) .map(keyCount -> new PieChartItem(keyCount.getLeft(), keyCount.getRight())) .collect(Collectors.toList()); } - /** - * The counts of different artifact types found in a DataSource. - * - * @param selectedDataSource The DataSource. - * - * @return The JTable data model of counts of artifact types. - */ - private List getArtifactCountsModel(DataSource selectedDataSource) { - Map artifactMapping = DataSourceCountsSummary.getCountsOfArtifactsByType(selectedDataSource); - if (artifactMapping == null) { - return null; - } - - return artifactMapping.entrySet().stream() - .filter((entrySet) -> entrySet != null) - .sorted((a, b) -> a.getKey().compareTo(b.getKey())) - .map((entrySet) -> new PieChartItem(entrySet.getKey(), entrySet.getValue())) - .collect(Collectors.toList()); - } - - - - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -302,19 +298,19 @@ class TypesPanel extends BaseDataSourceSummaryPanel { javax.swing.JPanel usagePanel = usageLabel; javax.swing.JPanel osPanel = osLabel; javax.swing.JPanel sizePanel = sizeLabel; - pieChartRow = new javax.swing.JPanel(); javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; - javax.swing.JPanel artifactTypesPanel = artifactTypesChart; javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); javax.swing.JLabel filesByCategoryLabel = new javax.swing.JLabel(); javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2)); javax.swing.JPanel filesByCategoryPanel = filesByCategoryTable; + filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); setLayout(new java.awt.BorderLayout()); contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787)); - contentParent.setMinimumSize(new java.awt.Dimension(650, 510)); + contentParent.setMinimumSize(new java.awt.Dimension(400, 300)); + contentParent.setPreferredSize(new java.awt.Dimension(400, 300)); contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS)); usagePanel.setAlignmentX(0.0F); @@ -336,24 +332,12 @@ class TypesPanel extends BaseDataSourceSummaryPanel { sizePanel.setPreferredSize(new java.awt.Dimension(800, 20)); contentParent.add(sizePanel); - pieChartRow.setAlignmentX(0.0F); - pieChartRow.setMaximumSize(new java.awt.Dimension(1170, 895)); - pieChartRow.setMinimumSize(null); - pieChartRow.setPreferredSize(null); - fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); - fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(500, 375)); - fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(500, 375)); - fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(500, 375)); - pieChartRow.add(fileMimeTypesPanel); - - artifactTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); - artifactTypesPanel.setMaximumSize(new java.awt.Dimension(650, 500)); - artifactTypesPanel.setMinimumSize(new java.awt.Dimension(650, 500)); - artifactTypesPanel.setPreferredSize(new java.awt.Dimension(650, 500)); - pieChartRow.add(artifactTypesPanel); - - contentParent.add(pieChartRow); + fileMimeTypesPanel.setAlignmentX(0.0F); + fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300)); + fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300)); + fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300)); + contentParent.add(fileMimeTypesPanel); contentParent.add(filler2); org.openide.awt.Mnemonics.setLocalizedText(filesByCategoryLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.filesByCategoryLabel.text")); // NOI18N @@ -365,6 +349,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(10, 107)); filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 107)); contentParent.add(filesByCategoryPanel); + contentParent.add(filler3); scrollParent.setViewportView(contentParent); @@ -373,6 +358,6 @@ class TypesPanel extends BaseDataSourceSummaryPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel pieChartRow; + private javax.swing.Box.Filler filler3; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java index 902f27519e..b19f293ca7 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.uiutils; @@ -12,18 +25,27 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; /** - * - * @author gregd + * Abstract class for common methods of a loadable component. */ @NbBundle.Messages({ "AbstractLoadableComponent_loadingMessage_defaultText=Loading results...", "AbstractLoadableComponent_errorMessage_defaultText=There was an error loading results.", - "AbstractLoadableComponent_noDataExists_defaultText=No data exists.", -}) + "AbstractLoadableComponent_noDataExists_defaultText=No data exists.",}) public abstract class AbstractLoadableComponent extends JPanel implements LoadableComponent { + /** + * The default loading message. + */ public static final String DEFAULT_LOADING_MESSAGE = Bundle.AbstractLoadableComponent_loadingMessage_defaultText(); + + /** + * The default error message. + */ public static final String DEFAULT_ERROR_MESSAGE = Bundle.AbstractLoadableComponent_errorMessage_defaultText(); + + /** + * The default 'no results' message. + */ public static final String DEFAULT_NO_RESULTS_MESSAGE = Bundle.AbstractLoadableComponent_noDataExists_defaultText(); private static final Logger logger = Logger.getLogger(AbstractLoadableComponent.class.getName()); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java index 650ac04ff8..873fcb4d95 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/BaseMessageOverlay.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.uiutils; @@ -9,10 +22,11 @@ import java.awt.Graphics; import javax.swing.JLabel; /** - * - * @author gregd + * Base class for drawing a message overlay. Contains a paint method for + * painting a JLabel using a java.awt.Graphics object. */ public class BaseMessageOverlay { + private final JLabel label; private boolean visible = false; @@ -54,6 +68,13 @@ public class BaseMessageOverlay { message == null ? "" : message)); } + /** + * Paints the jlabel at full width and height with the graphics object. + * + * @param g The graphics object. + * @param width The width. + * @param height The height. + */ public void paintOverlay(Graphics g, int width, int height) { if (!visible) { return; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 7b54717338..a83adf2012 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -242,7 +242,6 @@ public class JTablePanel extends AbstractLoadableComponent> { return this; } - @Override protected void setResults(List data) { // set the list of data to be shown as either the data or an empty list diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java index 07241619ff..bf5f1d1552 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/ListTableModel.java @@ -25,8 +25,8 @@ import javax.swing.table.TableModel; * An interface to be used with the JTablePanel that specifies a TableModel to * be used with the underlying JTable based on a list of object type T. */ -public interface ListTableModel extends TableModel { - +public interface ListTableModel extends TableModel { + /** * @return The list of objects supporting the rows to be displayed in the * table. diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java index 24a84b1c07..652cf3bcd1 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/LoadableComponent.java @@ -1,13 +1,26 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.uiutils; /** - * - * @author gregd + * Interface for a loadable component that can show messages, results, or a + * DataFetchResult. */ public interface LoadableComponent { @@ -56,5 +69,5 @@ public interface LoadableComponent { * * @param result The DataFetchResult. */ - public void showDataFetchResult(DataFetchResult result); + void showDataFetchResult(DataFetchResult result); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java index b27b26d293..55873cb64a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit 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.uiutils; @@ -22,32 +35,48 @@ import org.jfree.chart.plot.PiePlot; import org.jfree.data.general.DefaultPieDataset; /** - * - * @author gregd + * A pie chart panel. */ public class PieChartPanel extends AbstractLoadableComponent> { /** - * + * An individual pie chart slice in the pie chart. */ public static class PieChartItem { + private final String label; private final double value; + /** + * Main constructor. + * + * @param label The label for this pie slice. + * @param value The value for this item. + */ public PieChartItem(String label, double value) { this.label = label; this.value = value; } + /** + * @return The label for this item. + */ public String getLabel() { return label; } + /** + * @return The value for this item. + */ public double getValue() { return value; } } - + + /** + * A JFreeChart message overlay that can show a message for the purposes of + * the LoadableComponent. + */ private static class MessageOverlay extends AbstractOverlay implements Overlay { private static final long serialVersionUID = 1L; @@ -71,31 +100,38 @@ public class PieChartPanel extends AbstractLoadableComponent Date: Fri, 4 Sep 2020 11:42:09 -0400 Subject: [PATCH 10/28] update to labels --- .../ui/Bundle.properties-MERGED | 1 - .../datasourcesummary/ui/TypesPanel.form | 95 +++++++++++--- .../datasourcesummary/ui/TypesPanel.java | 117 +++++++++++------- 3 files changed, 147 insertions(+), 66 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index e7e698b71f..7e07204b5f 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -76,7 +76,6 @@ TypesPanel_fileMimeTypesChart_other_title=Other TypesPanel_fileMimeTypesChart_title=File Types TypesPanel_fileMimeTypesChart_videos_title=Videos TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated -TypesPanel_filesByCategoryTable_allRow_title=All TypesPanel_filesByCategoryTable_countColumn_title=Count TypesPanel_filesByCategoryTable_directoryRow_title=Directory TypesPanel_filesByCategoryTable_labelColumn_title=File Type diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index 7d84fd7bd4..bba2629289 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -40,10 +40,10 @@ - + - + @@ -165,48 +165,105 @@
+ + + - - - - - - - - - + - + - + - - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 5f3c16298b..0be8a63a63 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -23,7 +23,6 @@ import java.text.DecimalFormat; import java.util.Arrays; import java.util.List; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.swing.JLabel; @@ -57,7 +56,6 @@ import org.sleuthkit.datamodel.DataSource; "TypesPanel_filesByCategoryTable_title=Files by Category", "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", "TypesPanel_filesByCategoryTable_countColumn_title=Count", - "TypesPanel_filesByCategoryTable_allRow_title=All", "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated", "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated", "TypesPanel_filesByCategoryTable_slackRow_title=Slack", @@ -156,13 +154,22 @@ class TypesPanel extends BaseDataSourceSummaryPanel { private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); + private final LoadableLabel allocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title()); + private final LoadableLabel unallocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title()); + private final LoadableLabel slackLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_slackRow_title()); + private final LoadableLabel directoriesLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title()); + // all loadable components private final List> loadables = Arrays.asList( usageLabel, osLabel, sizeLabel, fileMimeTypesChart, - filesByCategoryTable + filesByCategoryTable, + allocatedLabel, + unallocatedLabel, + slackLabel, + directoriesLabel ); // all of the means for obtaining data for the gui components. @@ -186,10 +193,22 @@ class TypesPanel extends BaseDataSourceSummaryPanel { new DataFetchWorker.DataFetchComponents<>( this::getMimeTypeCategoriesModel, fileMimeTypesChart::showDataFetchResult), - // files by category worker + // allocated files worker new DataFetchWorker.DataFetchComponents<>( - this::getFileCategoryModel, - filesByCategoryTable::showDataFetchResult) + (dataSource) -> getStringOrZero(DataSourceCountsSummary.getCountOfAllocatedFiles(dataSource)), + allocatedLabel::showDataFetchResult), + // unallocated files worker + new DataFetchWorker.DataFetchComponents<>( + (dataSource) -> getStringOrZero(DataSourceCountsSummary.getCountOfUnallocatedFiles(dataSource)), + unallocatedLabel::showDataFetchResult), + // slack files worker + new DataFetchWorker.DataFetchComponents<>( + (dataSource) -> getStringOrZero(DataSourceCountsSummary.getCountOfSlackFiles(dataSource)), + slackLabel::showDataFetchResult), + // directories worker + new DataFetchWorker.DataFetchComponents<>( + (dataSource) -> getStringOrZero(DataSourceCountsSummary.getCountOfDirectories(dataSource)), + directoriesLabel::showDataFetchResult) ); /** @@ -222,40 +241,12 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } } - /** - * Retrieves data for the file category table. - * - * @param selectedDataSource The datasource. - * - * @return The key value pairs to be displayed. - */ - private List> getFileCategoryModel(DataSource selectedDataSource) { - if (selectedDataSource == null) { - return null; - } - - List>> itemsAndRetrievers = Arrays.asList(Pair.of(Bundle.TypesPanel_filesByCategoryTable_allRow_title(), DataSourceCountsSummary::getCountOfFiles), - Pair.of(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title(), DataSourceCountsSummary::getCountOfAllocatedFiles), - Pair.of(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title(), DataSourceCountsSummary::getCountOfUnallocatedFiles), - Pair.of(Bundle.TypesPanel_filesByCategoryTable_slackRow_title(), DataSourceCountsSummary::getCountOfSlackFiles), - Pair.of(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title(), DataSourceCountsSummary::getCountOfDirectories) - ); - - return itemsAndRetrievers - .stream() - .map(pair -> { - Long result = pair.getRight().apply(selectedDataSource); - return Pair.of(pair.getLeft(), result == null ? 0 : result); - }) - .collect(Collectors.toList()); - } - /** * Gets all the data for the file type pie chart. * - * @param dataSource + * @param dataSource The datasource. * - * @return + * @return The pie chart items. */ private List getMimeTypeCategoriesModel(DataSource dataSource) { if (dataSource == null) { @@ -284,6 +275,17 @@ class TypesPanel extends BaseDataSourceSummaryPanel { .collect(Collectors.toList()); } + /** + * Returns string value of long. If null returns a string of '0'. + * + * @param longVal The long value. + * + * @return The string value of the long. + */ + private String getStringOrZero(Long longVal) { + return String.valueOf(longVal == null ? 0 : longVal); + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -301,16 +303,18 @@ class TypesPanel extends BaseDataSourceSummaryPanel { javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); javax.swing.JLabel filesByCategoryLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(32767, 2)); - javax.swing.JPanel filesByCategoryPanel = filesByCategoryTable; + javax.swing.JPanel allocatedPanel = allocatedLabel; + javax.swing.JPanel unallocatedPanel = unallocatedLabel; + javax.swing.JPanel slackPanel = slackLabel; + javax.swing.JPanel directoriesPanel = directoriesLabel; filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); setLayout(new java.awt.BorderLayout()); contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787)); - contentParent.setMinimumSize(new java.awt.Dimension(400, 300)); - contentParent.setPreferredSize(new java.awt.Dimension(400, 300)); + contentParent.setMinimumSize(new java.awt.Dimension(400, 490)); + contentParent.setPreferredSize(null); contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS)); usagePanel.setAlignmentX(0.0F); @@ -340,15 +344,36 @@ class TypesPanel extends BaseDataSourceSummaryPanel { contentParent.add(fileMimeTypesPanel); contentParent.add(filler2); + filesByCategoryLabel.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(filesByCategoryLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.filesByCategoryLabel.text")); // NOI18N + filesByCategoryLabel.setMaximumSize(new java.awt.Dimension(120, 20)); + filesByCategoryLabel.setMinimumSize(new java.awt.Dimension(120, 20)); + filesByCategoryLabel.setPreferredSize(new java.awt.Dimension(120, 20)); contentParent.add(filesByCategoryLabel); - contentParent.add(filler1); - filesByCategoryPanel.setAlignmentX(0.0F); - filesByCategoryPanel.setMaximumSize(new java.awt.Dimension(32767, 107)); - filesByCategoryPanel.setMinimumSize(new java.awt.Dimension(10, 107)); - filesByCategoryPanel.setPreferredSize(new java.awt.Dimension(400, 107)); - contentParent.add(filesByCategoryPanel); + allocatedPanel.setAlignmentX(0.0F); + allocatedPanel.setMaximumSize(new java.awt.Dimension(32767, 16)); + allocatedPanel.setMinimumSize(new java.awt.Dimension(10, 16)); + allocatedPanel.setPreferredSize(new java.awt.Dimension(800, 16)); + contentParent.add(allocatedPanel); + + unallocatedPanel.setAlignmentX(0.0F); + unallocatedPanel.setMaximumSize(new java.awt.Dimension(32767, 16)); + unallocatedPanel.setMinimumSize(new java.awt.Dimension(10, 16)); + unallocatedPanel.setPreferredSize(new java.awt.Dimension(800, 16)); + contentParent.add(unallocatedPanel); + + slackPanel.setAlignmentX(0.0F); + slackPanel.setMaximumSize(new java.awt.Dimension(32767, 16)); + slackPanel.setMinimumSize(new java.awt.Dimension(10, 16)); + slackPanel.setPreferredSize(new java.awt.Dimension(800, 16)); + contentParent.add(slackPanel); + + directoriesPanel.setAlignmentX(0.0F); + directoriesPanel.setMaximumSize(new java.awt.Dimension(32767, 16)); + directoriesPanel.setMinimumSize(new java.awt.Dimension(10, 16)); + directoriesPanel.setPreferredSize(new java.awt.Dimension(800, 16)); + contentParent.add(directoriesPanel); contentParent.add(filler3); scrollParent.setViewportView(contentParent); From c0f40f5d233cfccc85c1a0931c833719d6e9cb22 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 4 Sep 2020 12:35:05 -0400 Subject: [PATCH 11/28] updated labels --- .../datasourcesummary/ui/Bundle.properties | 1 - .../ui/Bundle.properties-MERGED | 12 ++--- .../datasourcesummary/ui/TypesPanel.form | 28 +---------- .../datasourcesummary/ui/TypesPanel.java | 47 +++---------------- 4 files changed, 13 insertions(+), 75 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index da286b2336..a11db6f147 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,4 +35,3 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains -TypesPanel.filesByCategoryLabel.text=Files by Category diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 7e07204b5f..ba06c4502e 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -65,7 +65,6 @@ SizeRepresentationUtil_units_kilobytes=\ kB SizeRepresentationUtil_units_megabytes=\ MB SizeRepresentationUtil_units_petabytes=\ PB SizeRepresentationUtil_units_terabytes=\ TB -TypesPanel.filesByCategoryLabel.text=Files by Category TypesPanel_artifactsTypesPieChart_title=Artifact Types TypesPanel_fileMimeTypesChart_audio_title=Audio TypesPanel_fileMimeTypesChart_documents_title=Documents @@ -75,13 +74,10 @@ TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed TypesPanel_fileMimeTypesChart_other_title=Other TypesPanel_fileMimeTypesChart_title=File Types TypesPanel_fileMimeTypesChart_videos_title=Videos -TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated -TypesPanel_filesByCategoryTable_countColumn_title=Count -TypesPanel_filesByCategoryTable_directoryRow_title=Directory -TypesPanel_filesByCategoryTable_labelColumn_title=File Type -TypesPanel_filesByCategoryTable_slackRow_title=Slack -TypesPanel_filesByCategoryTable_title=Files by Category -TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated +TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files +TypesPanel_filesByCategoryTable_directoryRow_title=Directories +TypesPanel_filesByCategoryTable_slackRow_title=Slack Files +TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files TypesPanel_osLabel_title=OS TypesPanel_sizeLabel_title=Size TypesPanel_usageLabel_title=Usage diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form index bba2629289..2efe151eb5 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.form @@ -42,9 +42,6 @@ - - - @@ -163,29 +160,6 @@
- - - - - - - - - - - - - - - - - - - - - - - @@ -277,6 +251,8 @@ + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 0be8a63a63..6721e8c12c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -35,12 +35,9 @@ import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceCountsSummary import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceDetailsSummary; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceMimeTypeSummary; import org.sleuthkit.autopsy.datasourcesummary.uiutils.AbstractLoadableComponent; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel.PieChartItem; @@ -53,13 +50,10 @@ import org.sleuthkit.datamodel.DataSource; */ @Messages({ "TypesPanel_artifactsTypesPieChart_title=Artifact Types", - "TypesPanel_filesByCategoryTable_title=Files by Category", - "TypesPanel_filesByCategoryTable_labelColumn_title=File Type", - "TypesPanel_filesByCategoryTable_countColumn_title=Count", - "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated", - "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated", - "TypesPanel_filesByCategoryTable_slackRow_title=Slack", - "TypesPanel_filesByCategoryTable_directoryRow_title=Directory", + "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files", + "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files", + "TypesPanel_filesByCategoryTable_slackRow_title=Slack Files", + "TypesPanel_filesByCategoryTable_directoryRow_title=Directories", "TypesPanel_fileMimeTypesChart_title=File Types", "TypesPanel_fileMimeTypesChart_audio_title=Audio", "TypesPanel_fileMimeTypesChart_documents_title=Documents", @@ -132,27 +126,11 @@ class TypesPanel extends BaseDataSourceSummaryPanel { .flatMap((cat) -> cat.getRight().getMediaTypes().stream()) .collect(Collectors.toSet()); - private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title()); - - private final JTablePanel> filesByCategoryTable - = JTablePanel.getJTablePanel(Arrays.asList( - // title column - new ColumnModel<>( - Bundle.TypesPanel_filesByCategoryTable_labelColumn_title(), - (pair) -> new DefaultCellModel(pair.getLeft()), - 250 - ), - // count column - new ColumnModel<>( - Bundle.TypesPanel_filesByCategoryTable_countColumn_title(), - (pair) -> new DefaultCellModel(Long.toString(pair.getRight() == null ? 0 : pair.getRight())), - 150 - ) - )); - private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); + + private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title()); private final LoadableLabel allocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title()); private final LoadableLabel unallocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title()); @@ -165,7 +143,6 @@ class TypesPanel extends BaseDataSourceSummaryPanel { osLabel, sizeLabel, fileMimeTypesChart, - filesByCategoryTable, allocatedLabel, unallocatedLabel, slackLabel, @@ -302,19 +279,17 @@ class TypesPanel extends BaseDataSourceSummaryPanel { javax.swing.JPanel sizePanel = sizeLabel; javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart; javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); - javax.swing.JLabel filesByCategoryLabel = new javax.swing.JLabel(); javax.swing.JPanel allocatedPanel = allocatedLabel; javax.swing.JPanel unallocatedPanel = unallocatedLabel; javax.swing.JPanel slackPanel = slackLabel; javax.swing.JPanel directoriesPanel = directoriesLabel; - filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); + javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); setLayout(new java.awt.BorderLayout()); contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787)); contentParent.setMinimumSize(new java.awt.Dimension(400, 490)); - contentParent.setPreferredSize(null); contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS)); usagePanel.setAlignmentX(0.0F); @@ -344,13 +319,6 @@ class TypesPanel extends BaseDataSourceSummaryPanel { contentParent.add(fileMimeTypesPanel); contentParent.add(filler2); - filesByCategoryLabel.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(filesByCategoryLabel, org.openide.util.NbBundle.getMessage(TypesPanel.class, "TypesPanel.filesByCategoryLabel.text")); // NOI18N - filesByCategoryLabel.setMaximumSize(new java.awt.Dimension(120, 20)); - filesByCategoryLabel.setMinimumSize(new java.awt.Dimension(120, 20)); - filesByCategoryLabel.setPreferredSize(new java.awt.Dimension(120, 20)); - contentParent.add(filesByCategoryLabel); - allocatedPanel.setAlignmentX(0.0F); allocatedPanel.setMaximumSize(new java.awt.Dimension(32767, 16)); allocatedPanel.setMinimumSize(new java.awt.Dimension(10, 16)); @@ -383,6 +351,5 @@ class TypesPanel extends BaseDataSourceSummaryPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.Box.Filler filler3; // End of variables declaration//GEN-END:variables } From 950b567d6fd24d00be059c0fe4a3d40ca11618c8 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 4 Sep 2020 13:41:21 -0400 Subject: [PATCH 12/28] working through types summary tab --- .../sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java | 5 +++-- .../autopsy/datasourcesummary/uiutils/PieChartPanel.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 6721e8c12c..40f6cb00dd 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -110,6 +110,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#"); + DecimalFormat COMMA_FORMATTER = new DecimalFormat("#,###"); // All file type categories. private static final List> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( @@ -253,14 +254,14 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } /** - * Returns string value of long. If null returns a string of '0'. + * Returns string value of long with comma separators. If null returns a string of '0'. * * @param longVal The long value. * * @return The string value of the long. */ private String getStringOrZero(Long longVal) { - return String.valueOf(longVal == null ? 0 : longVal); + return longVal == null ? "0" : COMMA_FORMATTER.format(longVal); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java index 55873cb64a..777cbf8902 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java @@ -114,7 +114,7 @@ public class PieChartPanel extends AbstractLoadableComponent Date: Tue, 8 Sep 2020 11:24:35 -0400 Subject: [PATCH 13/28] fixing merge conflict --- .../ui/Bundle.properties-MERGED | 33 ++--- .../ui/DataSourceSummaryTabbedPane.java | 16 +-- .../uiutils/JTablePanel.java | 128 +----------------- 3 files changed, 17 insertions(+), 160 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index e7a3a3db4f..fdcfd2ad9b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -39,16 +39,10 @@ DataSourceSummaryNode.column.status.header=Ingest Status DataSourceSummaryNode.column.tags.header=Tags DataSourceSummaryNode.column.type.header=Type DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source -<<<<<<< HEAD -DataSourceSummaryTabbedPane_detailsTab_title=Details -DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History -DataSourceSummaryTabbedPane_typesTab_title=Types -======= -DataSourceSummaryTabbedPane_countsTab_title=Counts DataSourceSummaryTabbedPane_detailsTab_title=Container DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History DataSourceSummaryTabbedPane_recentFileTab_title=Recent Files ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 +DataSourceSummaryTabbedPane_typesTab_title=Types DataSourceSummaryTabbedPane_userActivityTab_title=User Activity DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts @@ -69,7 +63,17 @@ DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program -<<<<<<< HEAD +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated +RecentFilePanel_col_header_domain=Domain +RecentFilePanel_col_header_path=Path +RecentFilePanel_col_header_sender=Sender +RecentFilePanel_no_open_documents=No recently open documents found. +RecentFilesPanel.openDocsLabel.text=Recently Opened Documents +RecentFilesPanel.downloadLabel.text=Recent Downloads +RecentFilesPanel.attachmentLabel.text=Recent Attachements +RecentFilesPanel_col_head_date=Date SizeRepresentationUtil_units_bytes=\ bytes SizeRepresentationUtil_units_gigabytes=\ GB SizeRepresentationUtil_units_kilobytes=\ kB @@ -92,17 +96,4 @@ TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files TypesPanel_osLabel_title=OS TypesPanel_sizeLabel_title=Size TypesPanel_usageLabel_title=Usage -======= -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated -RecentFilePanel_col_header_domain=Domain -RecentFilePanel_col_header_path=Path -RecentFilePanel_col_header_sender=Sender -RecentFilePanel_no_open_documents=No recently open documents found. -RecentFilesPanel.openDocsLabel.text=Recently Opened Documents -RecentFilesPanel.downloadLabel.text=Recent Downloads -RecentFilesPanel.attachmentLabel.text=Recent Attachements -RecentFilesPanel_col_head_date=Date ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index bb5e6f6386..2e8b28914a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -33,13 +33,8 @@ import org.sleuthkit.datamodel.DataSource; * IngestJobInfoPanel. */ @Messages({ -<<<<<<< HEAD "DataSourceSummaryTabbedPane_typesTab_title=Types", - "DataSourceSummaryTabbedPane_detailsTab_title=Details", -======= - "DataSourceSummaryTabbedPane_countsTab_title=Counts", "DataSourceSummaryTabbedPane_detailsTab_title=Container", ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 "DataSourceSummaryTabbedPane_userActivityTab_title=User Activity", "DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History", "DataSourceSummaryTabbedPane_recentFileTab_title=Recent Files" @@ -49,19 +44,12 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private static final long serialVersionUID = 1L; // A pair of the tab name and the corresponding BaseDataSourceSummaryTabs to be displayed. -<<<<<<< HEAD - private final List> tabs = Arrays.asList( - Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryUserActivityPanel()) - ); -======= + private final List> tabs = new ArrayList<>(Arrays.asList( - Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), + Pair.of(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_recentFileTab_title(), new RecentFilesPanel()) )); ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 9770c950cd..1d32a2a5db 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -184,7 +184,7 @@ public class JTablePanel extends AbstractLoadableComponent> { .map((colModel) -> colModel.getCellRenderer()) .collect(Collectors.toList()); - return new DefaultListTableModel<>(columnRenderers); + return new DefaultListTableModel(columnRenderers); } /** @@ -201,31 +201,10 @@ public class JTablePanel extends AbstractLoadableComponent> { return resultTable.setColumnModel(getTableColumnModel(columns)); } -<<<<<<< HEAD - private final JScrollPane tableScrollPane; - private final Overlay overlayLayer; - private final ListTableModel tableModel; - private final JTable table; -======= - /** - * @return The default error message. - */ - public static String getDefaultErrorMessage() { - return DEFAULT_ERROR_MESSAGE; - } - - /** - * @return The default message for no results. - */ - public static String getDefaultNoResultsMessage() { - return DEFAULT_NO_RESULTS_MESSAGE; - } - private JScrollPane tableScrollPane; private Overlay overlayLayer; private ListTableModel tableModel; private JTable table; ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 /** * Panel constructor. @@ -258,7 +237,8 @@ public class JTablePanel extends AbstractLoadableComponent> { this.tableModel = tableModel; table.setModel(tableModel); } - + + /** * @return The underlying JTable's column model. */ @@ -278,23 +258,8 @@ public class JTablePanel extends AbstractLoadableComponent> { return this; } -<<<<<<< HEAD @Override protected void setResults(List data) { -======= - /** - * Sets the data to be shown in the JTable. Repaint is not handled in this - * method and should be handled separately. - * - * @param data The list of data objects to be shown. - */ - private void setResultList(List data) { - - if(tableModel == null) { - throw new IllegalStateException("ListTableModel has not be initialized"); - } - ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 // set the list of data to be shown as either the data or an empty list // on null. List dataToSet = (data == null) ? Collections.emptyList() : data; @@ -311,92 +276,6 @@ public class JTablePanel extends AbstractLoadableComponent> { this.overlayLayer.setVisible(visible); this.overlayLayer.setMessage(message); } -<<<<<<< HEAD -======= - - /** - * Clears the results from the underlying JTable and shows the provided - * message. - * - * @param message The message to be shown. - */ - public synchronized void showMessage(String message) { - setResultList(null); - setOverlay(true, message); - repaint(); - } - - /** - * Shows a default loading message on the table. This will clear any results - * in the table. - */ - public void showDefaultLoadingMessage() { - showMessage(DEFAULT_LOADING_MESSAGE); - } - - /** - * Shows the list as rows of data in the table. If overlay message will be - * cleared if present. - * - * @param data The data to be shown where each item represents a row of - * data. - */ - public synchronized void showResults(List data) { - setOverlay(false, null); - setResultList(data); - repaint(); - } - - /** - * Shows the data in a DataFetchResult. If there was an error during the - * operation, the errorMessage will be displayed. If the operation completed - * successfully and no data is present, noResultsMessage will be shown. - * Otherwise, the data will be shown as rows in the table. - * - * @param result The DataFetchResult. - * @param errorMessage The error message to be shown in the event of an - * error. - * @param noResultsMessage The message to be shown if there are no results - * but the operation completed successfully. - */ - public void showDataFetchResult(DataFetchResult> result, String errorMessage, String noResultsMessage) { - if (result == null) { - logger.log(Level.SEVERE, "Null data processor result received."); - return; - } - - switch (result.getResultType()) { - case SUCCESS: - if (result.getData() == null || result.getData().isEmpty()) { - showMessage(noResultsMessage); - } else { - showResults(result.getData()); - } - break; - case ERROR: - // if there is an error, log accordingly, set result list to - // empty and display error message - logger.log(Level.WARNING, "An exception was caused while results were loaded.", result.getException()); - showMessage(errorMessage); - break; - default: - // an unknown loading state was specified. log accordingly. - logger.log(Level.SEVERE, "No known loading state was found in result."); - break; - } - } - - /** - * Shows the data in a DataFetchResult. If there was an error during the - * operation, the DEFAULT_ERROR_MESSAGE will be displayed. If the operation - * completed successfully and no data is present, DEFAULT_NO_RESULTS_MESSAGE - * will be shown. Otherwise, the data will be shown as rows in the table. - * - * @param result The DataFetchResult. - */ - public void showDataFetchResult(DataFetchResult> result) { - showDataFetchResult(result, DEFAULT_ERROR_MESSAGE, DEFAULT_NO_RESULTS_MESSAGE); - } /** * Initialize the gui components. @@ -411,5 +290,4 @@ public class JTablePanel extends AbstractLoadableComponent> { setLayout(new BorderLayout()); add(dualLayer, BorderLayout.CENTER); } ->>>>>>> fa0ae98de088d3573878927c94690af0154e5b00 } From 85b832e135a9392b46a8eb65e61d66aa72c9dfeb Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 11:45:17 -0400 Subject: [PATCH 14/28] refactor tabbed pane to handle tabs easily --- .../ui/DataSourceSummaryTabbedPane.java | 100 +++++++++++++----- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index 2e8b28914a..dffb0d9225 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -18,11 +18,11 @@ */ package org.sleuthkit.autopsy.datasourcesummary.ui; -import java.util.ArrayList; +import java.awt.Component; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; import javax.swing.JTabbedPane; -import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel; import org.sleuthkit.datamodel.DataSource; @@ -41,18 +41,77 @@ import org.sleuthkit.datamodel.DataSource; }) public class DataSourceSummaryTabbedPane extends JTabbedPane { + /** + * Records of tab information (i.e. title, component, function to call on + * new data source). + */ + private static class DataSourceTab { + + private final String tabTitle; + private final Component component; + private final Consumer onDataSource; + + /** + * Main constructor. + * + * @param tabTitle The title of the tab. + * @param component The component to be displayed. + * @param onDataSource The function to be called on a new data source. + */ + DataSourceTab(String tabTitle, Component component, Consumer onDataSource) { + this.tabTitle = tabTitle; + this.component = component; + this.onDataSource = onDataSource; + } + + /** + * Main constructor. + * + * @param tabTitle The title of the tab. + * @param component The component to be displayed. + * BaseDataSourceSummaryPanel.setDataSource method is + * used on new data source. + */ + DataSourceTab(String tabTitle, BaseDataSourceSummaryPanel panel) { + this.tabTitle = tabTitle; + this.component = panel; + this.onDataSource = panel::setDataSource; + } + + /** + * @return The title for the tab. + */ + String getTabTitle() { + return tabTitle; + } + + /** + * @return The component to display in the tab. + */ + Component getComponent() { + return component; + } + + /** + * @return The function to be called on new data source. + */ + Consumer getOnDataSource() { + return onDataSource; + } + } + private static final long serialVersionUID = 1L; - // A pair of the tab name and the corresponding BaseDataSourceSummaryTabs to be displayed. - - private final List> tabs = new ArrayList<>(Arrays.asList( - Pair.of(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_recentFileTab_title(), new RecentFilesPanel()) - )); - private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); + private final List tabs = Arrays.asList( + new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()), + new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()), + new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_recentFileTab_title(), new RecentFilesPanel()), + new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_ingestHistoryTab_title(), ingestHistoryPanel, ingestHistoryPanel::setDataSource), + new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()) + ); + private DataSource dataSource = null; /** @@ -63,18 +122,9 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { } private void initComponent() { - for (Pair tab : tabs) { - addTab(tab.getKey(), tab.getValue()); + for (DataSourceTab tab : tabs) { + addTab(tab.getTabTitle(), tab.getComponent()); } - - // IngestJobInfoPanel is not specifically a data source summary panel - // and is called separately for that reason. - addTab(Bundle.DataSourceSummaryTabbedPane_ingestHistoryTab_title(), ingestHistoryPanel); - - // The Container tab should be last. - Pair tab = Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()); - addTab(tab.getKey(), tab.getValue()); - tabs.add(tab); } /** @@ -94,12 +144,8 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; - for (Pair tab : tabs) { - tab.getValue().setDataSource(dataSource); + for (DataSourceTab tab : tabs) { + tab.getOnDataSource().accept(dataSource); } - - // IngestJobInfoPanel is not specifically a data source summary panel - // and is called separately for that reason. - ingestHistoryPanel.setDataSource(dataSource); } } From 7e03737af9a7de0024023ab8c951d1c57ebd6a0e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 11:50:44 -0400 Subject: [PATCH 15/28] revert accidental bundle update --- .../core/core.jar/org/netbeans/core/startup/Bundle.properties | 2 +- .../org/netbeans/core/windows/view/ui/Bundle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index dbdb74f41f..35138509d8 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Thu, 03 Sep 2020 13:12:57 -0400 +#Wed, 08 Jul 2020 15:15:46 -0400 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index cd9f34ad5b..cf36e85b33 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Thu, 03 Sep 2020 13:12:57 -0400 +#Wed, 08 Jul 2020 15:15:46 -0400 CTL_MainWindow_Title=Autopsy 4.16.0 CTL_MainWindow_Title_No_Project=Autopsy 4.16.0 From e330c2814b8aaadcd1ba2af43ef8b6f8e3a82a83 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 11:51:49 -0400 Subject: [PATCH 16/28] revert accidental bundle update --- .../autopsy/recentactivity/Bundle.properties-MERGED | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 1d52c03e67..af0dbf306b 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -5,15 +5,10 @@ ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for an ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. ChromeCacheExtractor.moduleName=ChromeCacheExtractor -# {0} - module name -# {1} - row number -# {2} - table length -# {3} - cache path ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3} DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive -# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity Extract.indexError.message=Failed to index artifact for keyword search. @@ -77,7 +72,7 @@ ExtractZone_progress_Msg=Extracting :Zone.Identifer files ExtractZone_Restricted=Restricted Sites Zone ExtractZone_Trusted=Trusted Sites Zone OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. +OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\nThe module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Short-Description=Recent Activity finder ingest module Browser.name.Microsoft.Edge=Microsoft Edge @@ -216,7 +211,6 @@ Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM) RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. -# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE From 66ad332521fc015badb0a01d03c9dd7e7cd0ab60 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 11:55:33 -0400 Subject: [PATCH 17/28] formatting --- .../sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java | 5 +++-- .../autopsy/datasourcesummary/uiutils/JTablePanel.java | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 40f6cb00dd..e0313dd5a8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -130,7 +130,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); - + private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title()); private final LoadableLabel allocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title()); @@ -254,7 +254,8 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } /** - * Returns string value of long with comma separators. If null returns a string of '0'. + * Returns string value of long with comma separators. If null returns a + * string of '0'. * * @param longVal The long value. * diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 1d32a2a5db..1480a5d582 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -224,7 +224,7 @@ public class JTablePanel extends AbstractLoadableComponent> { } /** - * Set the table model. This method must be called prior to calling + * Set the table model. This method must be called prior to calling * setResultList. * * @param tableModel @@ -237,8 +237,7 @@ public class JTablePanel extends AbstractLoadableComponent> { this.tableModel = tableModel; table.setModel(tableModel); } - - + /** * @return The underlying JTable's column model. */ @@ -276,7 +275,7 @@ public class JTablePanel extends AbstractLoadableComponent> { this.overlayLayer.setVisible(visible); this.overlayLayer.setMessage(message); } - + /** * Initialize the gui components. */ From 2dfa450b5c3db95ac7da131747d0748de1d5cb3e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 12:10:49 -0400 Subject: [PATCH 18/28] addressing codacy remarks --- .../datasourcesummary/ui/SizeRepresentationUtil.java | 5 ++++- .../uiutils/AbstractLoadableComponent.java | 2 ++ .../autopsy/datasourcesummary/uiutils/JTablePanel.java | 8 ++++---- .../autopsy/datasourcesummary/uiutils/PieChartPanel.java | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java index 0e3c18b67b..82832d58cf 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java @@ -86,7 +86,7 @@ public class SizeRepresentationUtil { } } - String fullSize = String.valueOf(size) + UNITS.get(0); + String fullSize = size + UNITS.get(0); String closestUnitSize = format.format(approximateSize) + UNITS.get(unitsIndex); if (unitsIndex == 0) { @@ -97,4 +97,7 @@ public class SizeRepresentationUtil { return closestUnitSize; } } + + private SizeRepresentationUtil() { + } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java index b19f293ca7..74df7fd4d5 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/AbstractLoadableComponent.java @@ -33,6 +33,8 @@ import org.sleuthkit.autopsy.coreutils.Logger; "AbstractLoadableComponent_noDataExists_defaultText=No data exists.",}) public abstract class AbstractLoadableComponent extends JPanel implements LoadableComponent { + private static final long serialVersionUID = 1L; + /** * The default loading message. */ diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java index 1480a5d582..f1c9ee92ff 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/JTablePanel.java @@ -49,7 +49,7 @@ public class JTablePanel extends AbstractLoadableComponent> { private static class Overlay extends LayerUI { private static final long serialVersionUID = 1L; - private BaseMessageOverlay overlay = new BaseMessageOverlay(); + private final BaseMessageOverlay overlayDelegate = new BaseMessageOverlay(); /** * Sets this layer visible when painted. In order to be shown in UI, @@ -58,7 +58,7 @@ public class JTablePanel extends AbstractLoadableComponent> { * @param visible Whether or not it is visible. */ void setVisible(boolean visible) { - overlay.setVisible(visible); + overlayDelegate.setVisible(visible); } /** @@ -67,13 +67,13 @@ public class JTablePanel extends AbstractLoadableComponent> { * @param message The message to be displayed. */ void setMessage(String message) { - overlay.setMessage(message); + overlayDelegate.setMessage(message); } @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); - overlay.paintOverlay(g, c.getWidth(), c.getHeight()); + overlayDelegate.paintOverlay(g, c.getWidth(), c.getHeight()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java index 777cbf8902..8d6eab4a9b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/PieChartPanel.java @@ -80,7 +80,7 @@ public class PieChartPanel extends AbstractLoadableComponent Date: Tue, 8 Sep 2020 12:16:25 -0400 Subject: [PATCH 19/28] addressing codacy remarks --- .../autopsy/datasourcesummary/ui/SizeRepresentationUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java index 82832d58cf..34c622563d 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/SizeRepresentationUtil.java @@ -27,7 +27,7 @@ import org.openide.util.NbBundle; * This class provides utilities for representing storage size in most relevant * units (i.e. bytes, megabytes, etc.). */ -public class SizeRepresentationUtil { +public final class SizeRepresentationUtil { private static final int SIZE_CONVERSION_CONSTANT = 1000; private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##"); From 825922acd9a0ac51d87d6090ae48f5d713910e37 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 15:23:58 -0400 Subject: [PATCH 20/28] comment fix --- .../datasourcesummary/ui/DataSourceSummaryTabbedPane.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index dffb0d9225..7b692dc367 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -67,10 +67,8 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { /** * Main constructor. * - * @param tabTitle The title of the tab. - * @param component The component to be displayed. - * BaseDataSourceSummaryPanel.setDataSource method is - * used on new data source. + * @param tabTitle The title of the tab. + * @param panel The component to be displayed in the tab. */ DataSourceTab(String tabTitle, BaseDataSourceSummaryPanel panel) { this.tabTitle = tabTitle; From 529cd7fff2994385fa52d1eacf4f998904e37843 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 15:48:04 -0400 Subject: [PATCH 21/28] revised sql queries --- .../datamodel/DataSourceCountsSummary.java | 6 ++---- .../datamodel/DataSourceInfoUtilities.java | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java index 0f2826636b..16b79f0823 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java @@ -69,8 +69,7 @@ public class DataSourceCountsSummary { */ 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(), + DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC), "Unable to get counts of unallocated files for datasource, providing empty results"); } @@ -97,8 +96,7 @@ public class DataSourceCountsSummary { */ 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(), + "type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(), "Unable to get count of slack files for datasources, providing empty results"); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java index 4480b207e1..8372748cde 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java @@ -37,7 +37,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardAttribute.Type; -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; @@ -66,8 +65,6 @@ final class DataSourceInfoUtilities { 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); @@ -88,8 +85,7 @@ final class DataSourceInfoUtilities { * @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(); + String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(); if (StringUtils.isNotBlank(additionalWhere)) { whereClause += " AND " + additionalWhere; From 6eda998a717928344ce404aabdf20d052aad0b4d Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 8 Sep 2020 18:33:19 -0400 Subject: [PATCH 22/28] updated queries --- .../datamodel/DataSourceMimeTypeSummary.java | 11 ++++ .../datasourcesummary/ui/TypesPanel.java | 60 ++++++++++++------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java index add28c0364..0617828b1f 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java @@ -66,6 +66,17 @@ public class DataSourceMimeTypeSummary { + " AND mime_type IS NOT NULL AND mime_type <> '' ", "Unable to get count of files without specified mime types"); } + + + /** + * Get a count of all regular files in a datasource. + * @param dataSource The datasource. + * @return The count of regular files. + */ + public static Long getCountOfAllRegularFiles(DataSource dataSource) { + return DataSourceInfoUtilities.getCountOfRegularFiles(dataSource, null, + "Unable to get count of all regular files"); + } /** * Gets the number of files in the data source with no assigned mime type. diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index e0313dd5a8..61555abca0 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -22,9 +22,7 @@ import java.awt.BorderLayout; import java.text.DecimalFormat; import java.util.Arrays; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; import javax.swing.JLabel; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -110,7 +108,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#"); - DecimalFormat COMMA_FORMATTER = new DecimalFormat("#,###"); + private static final DecimalFormat COMMA_FORMATTER = new DecimalFormat("#,###"); // All file type categories. private static final List> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( @@ -121,12 +119,6 @@ class TypesPanel extends BaseDataSourceSummaryPanel { Pair.of(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE) ); - // The mime types in those categories. - private static final Set CATEGORY_MIME_TYPES = FILE_MIME_TYPE_CATEGORIES - .stream() - .flatMap((cat) -> cat.getRight().getMediaTypes().stream()) - .collect(Collectors.toSet()); - private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title()); private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title()); @@ -232,27 +224,51 @@ class TypesPanel extends BaseDataSourceSummaryPanel { } // for each category of file types, get the counts of files - Stream> fileCategoryItems = FILE_MIME_TYPE_CATEGORIES + List> fileCategoryItems = FILE_MIME_TYPE_CATEGORIES .stream() - .map((strCat) - -> Pair.of(strCat.getLeft(), - DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes(dataSource, strCat.getRight().getMediaTypes()))); + .map((strCat) -> { + return Pair.of(strCat.getLeft(), + getLongOrZero(DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes( + dataSource, strCat.getRight().getMediaTypes()))); + }) + .collect(Collectors.toList()); - // also get counts for other and not analayzed - Stream> otherItems = Stream.of( - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_other_title(), - DataSourceMimeTypeSummary.getCountOfFilesNotInMimeTypes(dataSource, CATEGORY_MIME_TYPES)), - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(), - DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(dataSource)) - ); + // get a count of all files with no mime type + Long noMimeTypeCount = getLongOrZero(DataSourceMimeTypeSummary.getCountOfFilesWithNoMimeType(dataSource)); + + // get the sum of all counts for the known categories + Long categoryTotalCount = getLongOrZero(fileCategoryItems.stream() + .collect(Collectors.summingLong((pair) -> pair.getValue()))); + + // get a count of all regular files + Long allRegularFiles = getLongOrZero(DataSourceMimeTypeSummary.getCountOfAllRegularFiles(dataSource)); + + // create entry for mime types in other category + fileCategoryItems.add(Pair.of(Bundle.TypesPanel_fileMimeTypesChart_other_title(), + allRegularFiles - (categoryTotalCount + noMimeTypeCount))); + + // create entry for not analyzed mime types category + fileCategoryItems.add(Pair.of(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(), + noMimeTypeCount)); // create pie chart items to provide to pie chart - return Stream.concat(fileCategoryItems, otherItems) + return fileCategoryItems.stream() .filter(keyCount -> keyCount.getRight() != null && keyCount.getRight() > 0) .map(keyCount -> new PieChartItem(keyCount.getLeft(), keyCount.getRight())) .collect(Collectors.toList()); } + /** + * Returns the long value or zero if longVal is null. + * + * @param longVal The long value. + * + * @return The long value or 0 if provided value is null. + */ + private static long getLongOrZero(Long longVal) { + return longVal == null ? 0 : longVal; + } + /** * Returns string value of long with comma separators. If null returns a * string of '0'. @@ -261,7 +277,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { * * @return The string value of the long. */ - private String getStringOrZero(Long longVal) { + private static String getStringOrZero(Long longVal) { return longVal == null ? "0" : COMMA_FORMATTER.format(longVal); } From 919416c134795aadb61941cd4baa9c35c8b461b8 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Sep 2020 14:10:26 -0400 Subject: [PATCH 23/28] Skip .xry and .dar data sources in auto ingest --- .../autoingest/AutoIngestJobLogger.java | 14 ++++- .../autoingest/AutoIngestManager.java | 10 +++- .../autoingest/SupportedDataSources.java | 53 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobLogger.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobLogger.java index 708ce7ee14..378cc228fc 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobLogger.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobLogger.java @@ -70,7 +70,7 @@ final class AutoIngestJobLogger { */ INFO, /** - * Qualifies a log message about an unexpected event or condtion during + * Qualifies a log message about an unexpected event or condition during * automated ingest processing. */ WARNING, @@ -208,6 +208,18 @@ final class AutoIngestJobLogger { void logDataSourceProcessorSelected(String dsp) throws AutoIngestJobLoggerException, InterruptedException { log(MessageCategory.INFO, "Using data source processor: " + dsp); } + + /** + * Log that a data source is being skipped. + * + * @param dataSourceName The name of the data source + * + * @throws AutoIngestJobLogger.AutoIngestJobLoggerException + * @throws InterruptedException + */ + void logSkippingDataSource(String dataSourceName) throws AutoIngestJobLoggerException, InterruptedException { + log(MessageCategory.INFO, "File type can not currently be processed"); + } /** * Logs the failure of the selected data source processor. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 48b86025af..4a4ca0cc03 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -1038,7 +1038,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } } - + /** * A task that submits an input directory scan task to the input directory * scan task executor. @@ -2438,6 +2438,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now())); return; } + + if (SupportedDataSources.shouldSkipFile(dataSource.getPath().toString())) { + Manifest manifest = currentJob.getManifest(); + AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), currentJob.getCaseDirectoryPath()); + jobLogger.logSkippingDataSource(dataSource.getPath().toString()); + currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now())); + return; + } if (currentJob.isCanceled() || jobProcessingTaskFuture.isCancelled()) { return; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java new file mode 100644 index 0000000000..3d55632d10 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java @@ -0,0 +1,53 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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.experimental.autoingest; + +import java.util.Arrays; +import java.util.List; +import org.apache.commons.io.FilenameUtils; + +/** + * Utility class for checking whether a data source/file should be processed + * in an automated setting. The goal is to not spend time analyzing large + * files that Autopsy can not handle yet. + */ +public class SupportedDataSources { + + private static final List UNSUPPORTED_EXTENSIONS = Arrays.asList("xry", "dar"); + + /** + * Check whether a file should be added to a case, either as a data source or part of a + * logical file set. + * + * @param fileName The name of the file. + * + * @return true if the file is currently unsupported and should be skipped, false otherwise. + */ + public static boolean shouldSkipFile(String fileName) { + String ext = FilenameUtils.getExtension(fileName); + if (ext == null) { + return false; + } + return UNSUPPORTED_EXTENSIONS.contains(ext.toLowerCase()); + } + + private SupportedDataSources() { + // Static class + } +} From 6389756371bb472621cdeb08665fab04d3af2201 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 10 Sep 2020 14:20:49 -0400 Subject: [PATCH 24/28] revised queries --- .../datamodel/DataSourceCountsSummary.java | 7 ++--- .../datamodel/DataSourceInfoUtilities.java | 27 ++++++++++++++++--- .../datamodel/DataSourceMimeTypeSummary.java | 8 +++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java index 16b79f0823..54e61e4a87 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceCountsSummary.java @@ -43,7 +43,8 @@ public class DataSourceCountsSummary { * @return The count. */ public static Long getCountOfFiles(DataSource currentDataSource) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, null, + return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + null, "Unable to get count of files, providing empty results"); } @@ -55,7 +56,7 @@ public class DataSourceCountsSummary { * @return The count. */ public static Long getCountOfAllocatedFiles(DataSource currentDataSource) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.ALLOC), "Unable to get counts of unallocated files for datasource, providing empty results"); } @@ -68,7 +69,7 @@ public class DataSourceCountsSummary { * @return The count. */ public static Long getCountOfUnallocatedFiles(DataSource currentDataSource) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, DataSourceInfoUtilities.getMetaFlagsContainsStatement(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC), "Unable to get counts of unallocated files for datasource, providing empty results"); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java index 8372748cde..a5ec1be604 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java @@ -38,6 +38,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardAttribute.Type; import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM; import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM; import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM; @@ -50,8 +51,7 @@ 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. + * Gets a count of tsk_files for a particular datasource. * * @param currentDataSource The datasource. * @param additionalWhere Additional sql where clauses. @@ -75,8 +75,7 @@ final class DataSourceInfoUtilities { } /** - * 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. + * Gets a count of regular files for a particular datasource. * * @param currentDataSource The datasource. * @param additionalWhere Additional sql where clauses. @@ -94,6 +93,26 @@ final class DataSourceInfoUtilities { return getCountOfTskFiles(currentDataSource, whereClause, onError); } + /** + * Gets a count of regular non-slack files for a particular datasource. + * + * @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 getCountOfRegNonSlackFiles(DataSource currentDataSource, String additionalWhere, String onError) { + String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue() + + " AND type<>" + TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(); + + if (StringUtils.isNotBlank(additionalWhere)) { + whereClause += " AND " + additionalWhere; + } + + return getCountOfTskFiles(currentDataSource, whereClause, onError); + } + /** * An interface for handling a result set and returning a value. */ diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java index 0617828b1f..95dc360d2a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceMimeTypeSummary.java @@ -43,7 +43,7 @@ public class DataSourceMimeTypeSummary { * source, null if no count was retrieved */ public static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set setOfMimeTypes) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "mime_type IN " + getSqlSet(setOfMimeTypes), "Unable to get count of files for specified mime types"); } @@ -61,7 +61,7 @@ public class DataSourceMimeTypeSummary { * have the specific mime type, but do have a mime type. */ public static Long getCountOfFilesNotInMimeTypes(DataSource currentDataSource, Set setOfMimeTypes) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(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"); @@ -74,7 +74,7 @@ public class DataSourceMimeTypeSummary { * @return The count of regular files. */ public static Long getCountOfAllRegularFiles(DataSource dataSource) { - return DataSourceInfoUtilities.getCountOfRegularFiles(dataSource, null, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(dataSource, null, "Unable to get count of all regular files"); } @@ -88,7 +88,7 @@ public class DataSourceMimeTypeSummary { * */ public static Long getCountOfFilesWithNoMimeType(DataSource currentDataSource) { - return DataSourceInfoUtilities.getCountOfRegularFiles(currentDataSource, + return DataSourceInfoUtilities.getCountOfRegNonSlackFiles(currentDataSource, "(mime_type IS NULL OR mime_type = '') ", "Unable to get count of files without a mime type"); } From 41f3129174e4b580d3dbfc54b012c8badd5af683 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 10 Sep 2020 14:31:33 -0400 Subject: [PATCH 25/28] Codacy --- .../autopsy/experimental/autoingest/SupportedDataSources.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java index 3d55632d10..9df1587215 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SupportedDataSources.java @@ -27,7 +27,7 @@ import org.apache.commons.io.FilenameUtils; * in an automated setting. The goal is to not spend time analyzing large * files that Autopsy can not handle yet. */ -public class SupportedDataSources { +public final class SupportedDataSources { private static final List UNSUPPORTED_EXTENSIONS = Arrays.asList("xry", "dar"); From 8adf45e388dd72518d143b9e51ecfabdbbb92227 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 10 Sep 2020 19:55:13 -0400 Subject: [PATCH 26/28] update for octet stream --- .../ui/Bundle.properties-MERGED | 1 + .../datasourcesummary/ui/TypesPanel.java | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 8c6a5cdce4..0b14791df5 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -94,6 +94,7 @@ TypesPanel_fileMimeTypesChart_images_title=Images TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed TypesPanel_fileMimeTypesChart_other_title=Other TypesPanel_fileMimeTypesChart_title=File Types +TypesPanel_fileMimeTypesChart_unknown_title=Unknown TypesPanel_fileMimeTypesChart_videos_title=Videos TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files TypesPanel_filesByCategoryTable_directoryRow_title=Directories diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java index 61555abca0..46f475781c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/TypesPanel.java @@ -21,7 +21,9 @@ package org.sleuthkit.autopsy.datasourcesummary.ui; import java.awt.BorderLayout; import java.text.DecimalFormat; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import javax.swing.JLabel; import org.apache.commons.lang3.StringUtils; @@ -59,6 +61,7 @@ import org.sleuthkit.datamodel.DataSource; "TypesPanel_fileMimeTypesChart_images_title=Images", "TypesPanel_fileMimeTypesChart_videos_title=Videos", "TypesPanel_fileMimeTypesChart_other_title=Other", + "TypesPanel_fileMimeTypesChart_unknown_title=Unknown", "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed", "TypesPanel_usageLabel_title=Usage", "TypesPanel_osLabel_title=OS", @@ -111,12 +114,13 @@ class TypesPanel extends BaseDataSourceSummaryPanel { private static final DecimalFormat COMMA_FORMATTER = new DecimalFormat("#,###"); // All file type categories. - private static final List> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE), - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO), - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO), - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS), - Pair.of(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE) + private static final List>> FILE_MIME_TYPE_CATEGORIES = Arrays.asList( + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes()), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes()), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes()), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes()), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes()), + Pair.of(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(), new HashSet<>(Arrays.asList("application/octet-stream"))) ); private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title()); @@ -229,7 +233,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel { .map((strCat) -> { return Pair.of(strCat.getLeft(), getLongOrZero(DataSourceMimeTypeSummary.getCountOfFilesForMimeTypes( - dataSource, strCat.getRight().getMediaTypes()))); + dataSource, strCat.getRight()))); }) .collect(Collectors.toList()); From e92259d60ae965b558048e7118dbea7714bdac30 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 10 Sep 2020 21:32:22 -0400 Subject: [PATCH 27/28] Fix typo in message param doc CommunicationArtifactViewerHelper --- .../contentviewers/artifactviewers/Bundle.properties-MERGED | 2 +- .../artifactviewers/CommunicationArtifactViewerHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED index 24083965fb..d5c75e81a3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED @@ -26,7 +26,7 @@ CallLogArtifactViewer_label_from=From CallLogArtifactViewer_label_to=To CallLogArtifactViewer_suffix_local=(Local) CallLogArtifactViewer_value_unknown=Unknown -#{0} - contact name +# {0} - contact name CommunicationArtifactViewerHelper_contact_label=Contact: {0} CommunicationArtifactViewerHelper_contact_label_unknown=Unknown CommunicationArtifactViewerHelper_menuitem_copy=Copy diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java index 071fc7011b..e65550f88c 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CommunicationArtifactViewerHelper.java @@ -440,7 +440,7 @@ final class CommunicationArtifactViewerHelper { * @return A JLabel with the contact information. */ @NbBundle.Messages({ - "#{0} - contact name", + "# {0} - contact name", "CommunicationArtifactViewerHelper_contact_label=Contact: {0}", "CommunicationArtifactViewerHelper_contact_label_unknown=Unknown" }) From 98c92362aec4b3cf30a9a7d13db060d14c401e66 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 11 Sep 2020 08:59:04 -0400 Subject: [PATCH 28/28] Write to auto ingest log --- .../autopsy/experimental/autoingest/AutoIngestManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 4a4ca0cc03..74e50380ee 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -2443,6 +2443,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen Manifest manifest = currentJob.getManifest(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), currentJob.getCaseDirectoryPath()); jobLogger.logSkippingDataSource(dataSource.getPath().toString()); + sysLogger.log(Level.INFO, "Skipping data source that can not be processed ({0})", dataSource.getPath().toString()); currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now())); return; }