mirror of
https://github.com/elisspace/autopsy.git
synced 2026-09-15 15:32:59 +00:00
panel integration and refactoring
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
@@ -36,23 +37,48 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
|
||||
//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 Map<Long, String> osDetailMap = new HashMap<>();
|
||||
private static final Integer SIZE_COVERSION_CONSTANT = 1000;
|
||||
private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##");
|
||||
private final Map<Long, Long> unallocatedFilesSizeMap;
|
||||
private final Map<Long, String> usageMap;
|
||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryDetailsPanel.class.getName());
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryDetailsPanel
|
||||
*/
|
||||
@Messages({"DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.",
|
||||
"DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure"})
|
||||
DataSourceSummaryDetailsPanel(Map<Long, String> usageMap) {
|
||||
DataSourceSummaryDetailsPanel() {
|
||||
initComponents();
|
||||
this.usageMap = usageMap;
|
||||
this.unallocatedFilesSizeMap = DataSourceInfoUtilities.getSizeOfUnallocatedFiles();
|
||||
osDetailMap = DataSourceInfoUtilities.getOperatingSystems();
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* The datasource currently used as the model in this panel.
|
||||
*
|
||||
* @return The datasource currently being used as the model in this panel.
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets datasource to visualize in the panel.
|
||||
*
|
||||
* @param dataSource The datasource to use in this panel.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
if (dataSource == null) {
|
||||
updateDetailsPanelData(null, null, null, null);
|
||||
} else {
|
||||
long id = dataSource.getId();
|
||||
updateDetailsPanelData(dataSource,
|
||||
DataSourceInfoUtilities.getSizeOfUnallocatedFiles().get(id),
|
||||
DataSourceInfoUtilities.getOperatingSystems().get(id),
|
||||
DataSourceInfoUtilities.getDataSourceTypes().get(id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,77 +86,80 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
*
|
||||
* @param selectedDataSource the DataSource to display details about.
|
||||
*/
|
||||
void updateDetailsPanelData(DataSource selectedDataSource) {
|
||||
private void updateDetailsPanelData(DataSource selectedDataSource, Long unallocatedFilesSize, String osDetails, String usage) {
|
||||
clearTableValues();
|
||||
if (selectedDataSource != null) {
|
||||
String sizeString = "";
|
||||
String sectorSizeString = "";
|
||||
String md5String = "";
|
||||
String sha1String = "";
|
||||
String sha256String = "";
|
||||
String acquisitionDetailsString = "";
|
||||
String imageTypeString = "";
|
||||
String[] filePaths = new String[0];
|
||||
String osDetailString = osDetailMap.get(selectedDataSource.getId()) == null ? "" : osDetailMap.get(selectedDataSource.getId());
|
||||
String dataSourceTypeString = usageMap.get(selectedDataSource.getId()) == null ? "" : usageMap.get(selectedDataSource.getId());
|
||||
try {
|
||||
acquisitionDetailsString = selectedDataSource.getAcquisitionDetails();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex);
|
||||
}
|
||||
if (selectedDataSource instanceof Image) {
|
||||
imageTypeString = ((Image) selectedDataSource).getType().getName();
|
||||
filePaths = ((Image) selectedDataSource).getPaths();
|
||||
sizeString = getSizeString(selectedDataSource.getSize());
|
||||
sectorSizeString = getSizeString(((Image) selectedDataSource).getSsize());
|
||||
try {
|
||||
//older databases may have null as the hash values
|
||||
md5String = ((Image) selectedDataSource).getMd5();
|
||||
if (md5String == null) {
|
||||
md5String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex);
|
||||
}
|
||||
try {
|
||||
sha1String = ((Image) selectedDataSource).getSha1();
|
||||
if (sha1String == null) {
|
||||
sha1String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex);
|
||||
}
|
||||
try {
|
||||
sha256String = ((Image) selectedDataSource).getSha256();
|
||||
if (sha256String == null) {
|
||||
sha256String = "";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex);
|
||||
}
|
||||
}
|
||||
unallocatedSizeValue.setText(getSizeString(unallocatedFilesSize));
|
||||
operatingSystemValue.setText(StringUtils.isBlank(osDetails) ? "" : osDetails);
|
||||
dataSourceUsageValue.setText(StringUtils.isBlank(usage) ? "" : usage);
|
||||
|
||||
timeZoneValue.setText(selectedDataSource.getTimeZone());
|
||||
displayNameValue.setText(selectedDataSource.getName());
|
||||
originalNameValue.setText(selectedDataSource.getName());
|
||||
deviceIdValue.setText(selectedDataSource.getDeviceId());
|
||||
dataSourceUsageValue.setText(dataSourceTypeString);
|
||||
operatingSystemValue.setText(osDetailString);
|
||||
timeZoneValue.setText(selectedDataSource.getTimeZone());
|
||||
acquisitionDetailsTextArea.setText(acquisitionDetailsString);
|
||||
imageTypeValue.setText(imageTypeString);
|
||||
sizeValue.setText(sizeString);
|
||||
unallocatedSizeValue.setText(getSizeString(unallocatedFilesSizeMap.get(selectedDataSource.getId())));
|
||||
sectorSizeValue.setText(sectorSizeString);
|
||||
md5HashValue.setText(md5String);
|
||||
sha1HashValue.setText(sha1String);
|
||||
sha256HashValue.setText(sha256String);
|
||||
for (String path : filePaths) {
|
||||
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
||||
|
||||
try {
|
||||
acquisitionDetailsTextArea.setText(selectedDataSource.getAcquisitionDetails());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex);
|
||||
}
|
||||
|
||||
if (selectedDataSource instanceof Image) {
|
||||
setFieldsForImage((Image) selectedDataSource);
|
||||
}
|
||||
}
|
||||
updateFieldVisibility();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text fields for an image. This should be called after
|
||||
* clearTableValues and before updateFieldVisibility to ensure the proper
|
||||
* rendering.
|
||||
*
|
||||
* @param selectedImage The selected image.
|
||||
*/
|
||||
private void setFieldsForImage(Image selectedImage) {
|
||||
imageTypeValue.setText(selectedImage.getType().getName());
|
||||
sizeValue.setText(getSizeString(selectedImage.getSize()));
|
||||
sectorSizeValue.setText(getSizeString(selectedImage.getSsize()));
|
||||
|
||||
for (String path : selectedImage.getPaths()) {
|
||||
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
||||
}
|
||||
|
||||
try {
|
||||
//older databases may have null as the hash values
|
||||
String md5String = selectedImage.getMd5();
|
||||
if (md5String == null) {
|
||||
md5String = "";
|
||||
}
|
||||
md5HashValue.setText(md5String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
String sha1String = selectedImage.getSha1();
|
||||
if (sha1String == null) {
|
||||
sha1String = "";
|
||||
}
|
||||
sha1HashValue.setText(sha1String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
String sha256String = selectedImage.getSha256();
|
||||
if (sha256String == null) {
|
||||
sha256String = "";
|
||||
}
|
||||
sha256HashValue.setText(sha256String);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a long size in bytes as a string formated to be read by users.
|
||||
*
|
||||
@@ -147,7 +176,7 @@ class DataSourceSummaryDetailsPanel extends javax.swing.JPanel {
|
||||
"DataSourceSummaryDetailsPanel.units.terabytes= TB",
|
||||
"DataSourceSummaryDetailsPanel.units.petabytes= PB"
|
||||
})
|
||||
private String getSizeString(Long size) {
|
||||
private static String getSizeString(Long size) {
|
||||
if (size == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JTabbedPane" name="dataSourceTabbedPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="dataSourceSummaryTabbedPane"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="right"/>
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason;
|
||||
@@ -41,10 +40,8 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED);
|
||||
private final DataSourceSummaryCountsPanel countsPanel;
|
||||
private final DataSourceSummaryDetailsPanel detailsPanel;
|
||||
private final DataSourceBrowser dataSourcesPanel;
|
||||
private final IngestJobInfoPanel ingestHistoryPanel;
|
||||
private final DataSourceSummaryTabbedPane dataSourceSummaryTabbedPane;
|
||||
|
||||
/**
|
||||
* Creates new form DataSourceSummaryDialog for displaying a summary of the
|
||||
@@ -61,21 +58,14 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
super(owner, Bundle.DataSourceSummaryDialog_window_title(), true);
|
||||
Map<Long, String> usageMap = DataSourceInfoUtilities.getDataSourceTypes();
|
||||
Map<Long, Long> fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles();
|
||||
countsPanel = new DataSourceSummaryCountsPanel(fileCountsMap);
|
||||
detailsPanel = new DataSourceSummaryDetailsPanel(usageMap);
|
||||
dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap);
|
||||
ingestHistoryPanel = new IngestJobInfoPanel();
|
||||
dataSourceSummaryTabbedPane = new DataSourceSummaryTabbedPane();
|
||||
initComponents();
|
||||
dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_detailsTab_title(), detailsPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_countsTab_title(), countsPanel);
|
||||
dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_ingestHistoryTab_title(), ingestHistoryPanel);
|
||||
dataSourcesPanel.addListSelectionListener((ListSelectionEvent e) -> {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
DataSource selectedDataSource = dataSourcesPanel.getSelectedDataSource();
|
||||
countsPanel.updateCountsTableData(selectedDataSource);
|
||||
detailsPanel.updateDetailsPanelData(selectedDataSource);
|
||||
ingestHistoryPanel.setDataSource(selectedDataSource);
|
||||
dataSourceSummaryTabbedPane.setDataSource(selectedDataSource);
|
||||
this.repaint();
|
||||
}
|
||||
});
|
||||
@@ -116,7 +106,7 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
|
||||
closeButton = new javax.swing.JButton();
|
||||
dataSourceSummarySplitPane = new javax.swing.JSplitPane();
|
||||
dataSourceTabbedPane = new javax.swing.JTabbedPane();
|
||||
javax.swing.JTabbedPane dataSourceTabbedPane = dataSourceSummaryTabbedPane;
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryDialog.class, "DataSourceSummaryDialog.closeButton.text")); // NOI18N
|
||||
closeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@@ -173,6 +163,5 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JSplitPane dataSourceSummarySplitPane;
|
||||
private javax.swing.JTabbedPane dataSourceTabbedPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
||||
@@ -18,22 +18,31 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.resultviewers.summary;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryTabbedPane;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||
import org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
* A tabular result viewer that displays a summary of the selected Data Source.
|
||||
*/
|
||||
@ServiceProvider(service = DataResultViewer.class)
|
||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||
public class DataSourceSummaryResultViewer extends AbstractDataResultViewer {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOGGER = Logger.getLogger(DataSourceSummaryResultViewer.class.getName());
|
||||
|
||||
private final String title;
|
||||
|
||||
public DataSourceSummaryResultViewer() {
|
||||
@@ -50,6 +59,7 @@ public class DataSourceSummaryResultViewer extends AbstractDataResultViewer {
|
||||
public DataSourceSummaryResultViewer(ExplorerManager explorerManager, String title) {
|
||||
super(explorerManager);
|
||||
this.title = title;
|
||||
initComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,25 +69,47 @@ public class DataSourceSummaryResultViewer extends AbstractDataResultViewer {
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSource contentItem = node.getLookup().lookup(DataSource.class);
|
||||
if (contentItem == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getDataSource(datasourceObjId);
|
||||
return getDataSource(node) != null;
|
||||
}
|
||||
|
||||
private DataSource getDataSource(Node node) {
|
||||
return node == null ? null: node.getLookup().lookup(DataSource.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
public void setNode(Node node) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
LOGGER.log(Level.SEVERE, "Attempting to run setNode() from non-EDT thread.");
|
||||
return;
|
||||
}
|
||||
|
||||
DataSource dataSource = getDataSource(node);
|
||||
|
||||
if (dataSource == null) {
|
||||
LOGGER.log(Level.SEVERE, "No datasource for node found.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
try {
|
||||
summaryPanel.setDataSource(dataSource);
|
||||
}
|
||||
finally {
|
||||
this.setCursor(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
summaryPanel = new DataSourceSummaryTabbedPane();
|
||||
setLayout(new BorderLayout());
|
||||
add(summaryPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private DataSourceSummaryTabbedPane summaryPanel;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user