5199 fix deduping of items for other occurrences content viewer

This commit is contained in:
William Schaefer 2019-06-25 17:22:55 -04:00
parent f8151e1e59
commit bc7d5e74fa
3 changed files with 92 additions and 37 deletions

View File

@ -89,11 +89,10 @@ import org.sleuthkit.datamodel.TskData;
public class DataContentViewerOtherCases extends JPanel implements DataContentViewer { public class DataContentViewerOtherCases extends JPanel implements DataContentViewer {
private static final long serialVersionUID = -1L; private static final long serialVersionUID = -1L;
private static final String UUID_PLACEHOLDER_STRING = "NoCorrelationAttributeInstance";
private static final Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName()); private static final Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts()); private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts());
private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noResultsFound()); private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noResultsFound());
private final OtherOccurrencesFilesTableModel filesTableModel; private final OtherOccurrencesFilesTableModel filesTableModel;
private final OtherOccurrencesCasesTableModel casesTableModel; private final OtherOccurrencesCasesTableModel casesTableModel;
private final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel; private final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel;
@ -129,6 +128,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
reset(); reset();
} }
static String getPlaceholderUUID() {
return UUID_PLACEHOLDER_STRING;
}
private void customizeComponents() { private void customizeComponents() {
ActionListener actList = (ActionEvent e) -> { ActionListener actList = (ActionEvent e) -> {
JMenuItem jmi = (JMenuItem) e.getSource(); JMenuItem jmi = (JMenuItem) e.getSource();
@ -837,7 +840,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
* selection * selection
*/ */
private void updateOnDataSourceSelection() { private void updateOnDataSourceSelection() {
int[] selectedCaseIndexes = casesTable.getSelectedRows();
int[] selectedDataSources = dataSourcesTable.getSelectedRows(); int[] selectedDataSources = dataSourcesTable.getSelectedRows();
filesTableModel.clearTable(); filesTableModel.clearTable();
for (CorrelationAttributeInstance corAttr : correlationAttributes) { for (CorrelationAttributeInstance corAttr : correlationAttributes) {
@ -846,12 +848,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
// get correlation and reference set instances from DB // get correlation and reference set instances from DB
correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId)); correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) { for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
for (int selectedCaseRow : selectedCaseIndexes) {
for (int selectedDataSourceRow : selectedDataSources) { for (int selectedDataSourceRow : selectedDataSources) {
try { try {
if (nodeData.isCentralRepoNode()) { if (nodeData.isCentralRepoNode()) {
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)) != null if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) { && dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData); filesTableModel.addNodeData(nodeData);
} }
@ -866,7 +866,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
} }
} }
} }
}
if (filesTable.getRowCount() > 0) { if (filesTable.getRowCount() > 0) {
filesTable.setRowSelectionInterval(0, 0); filesTable.setRowSelectionInterval(0, 0);
} }
@ -928,7 +927,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
if (EamDb.isEnabled()) { if (EamDb.isEnabled()) {
CorrelationCase partialCase; CorrelationCase partialCase;
partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx)); partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
if (partialCase == null){ if (partialCase == null) {
return ""; return "";
} }
return EamDb.getInstance().getCaseByUUID(partialCase.getCaseUUID()).getCreationDate(); return EamDb.getInstance().getCaseByUUID(partialCase.getCaseUUID()).getCreationDate();
@ -1141,6 +1140,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
private final String dataSourceID; private final String dataSourceID;
private final String filePath; private final String filePath;
private final String type; private final String type;
private final String caseUUID;
UniquePathKey(OtherOccurrenceNodeInstanceData nodeData) { UniquePathKey(OtherOccurrenceNodeInstanceData nodeData) {
super(); super();
@ -1151,6 +1151,14 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
filePath = null; filePath = null;
} }
type = nodeData.getType(); type = nodeData.getType();
String tempCaseUUID;
try {
tempCaseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
tempCaseUUID = UUID_PLACEHOLDER_STRING;
//place holder value will be used since correlation attribute was unavailble
}
caseUUID = tempCaseUUID;
} }
@Override @Override
@ -1159,14 +1167,15 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
UniquePathKey otherKey = (UniquePathKey) (other); UniquePathKey otherKey = (UniquePathKey) (other);
return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID()) return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
&& Objects.equals(otherKey.getFilePath(), this.getFilePath()) && Objects.equals(otherKey.getFilePath(), this.getFilePath())
&& Objects.equals(otherKey.getType(), this.getType())); && Objects.equals(otherKey.getType(), this.getType())
&& Objects.equals(otherKey.getCaseUUID(), this.getCaseUUID()));
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getDataSourceID(), getFilePath(), getType()); return Objects.hash(getDataSourceID(), getFilePath(), getType(), getCaseUUID());
} }
/** /**
@ -1195,5 +1204,14 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
String getDataSourceID() { String getDataSourceID() {
return dataSourceID; return dataSourceID;
} }
/**
* Get the case uuid for the UniquePathKey
*
* @return the case UUID
*/
String getCaseUUID() {
return caseUUID;
}
} }
} }

View File

@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
/** /**
* Model for cells in the data sources section of the other occurrences data * Model for cells in the data sources section of the other occurrences data
@ -86,6 +87,25 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
return ((DataSourceColumnItem) dataSourceSet.toArray()[rowIdx]).getDeviceId(); return ((DataSourceColumnItem) dataSourceSet.toArray()[rowIdx]).getDeviceId();
} }
/**
* Get the case uuid of the case the data source shown at the specified row
* index exists in
*
* @param rowIdx the row index of the data source you want the case uuid for
*
* @return the case uuid of the case the specified data source exists in or
* an empty string if a device id could not be retrieved
*/
String getCaseUUIDForRow(int rowIdx) {
//if anything would prevent this from working we will return an empty string
if (dataSourceSet.isEmpty() || rowIdx < 0
|| rowIdx >= dataSourceSet.size()
|| !(dataSourceSet.toArray()[rowIdx] instanceof DataSourceColumnItem)) {
return "";
}
return ((DataSourceColumnItem) dataSourceSet.toArray()[rowIdx]).getCaseUUID();
}
/** /**
* Get the case name of the data source shown at the specified row index * Get the case name of the data source shown at the specified row index
* *
@ -115,7 +135,15 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
* @param newNodeData data to add to the table * @param newNodeData data to add to the table
*/ */
void addNodeData(OtherOccurrenceNodeData newNodeData) { void addNodeData(OtherOccurrenceNodeData newNodeData) {
dataSourceSet.add(new DataSourceColumnItem((OtherOccurrenceNodeInstanceData) newNodeData)); OtherOccurrenceNodeInstanceData nodeData = (OtherOccurrenceNodeInstanceData) newNodeData;
String caseUUID;
try {
caseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
caseUUID = DataContentViewerOtherCases.getPlaceholderUUID();
//place holder value will be used since correlation attribute was unavailble
}
dataSourceSet.add(new DataSourceColumnItem(nodeData.getCaseName(), nodeData.getDeviceID(), nodeData.getDataSourceName(), caseUUID));
fireTableDataChanged(); fireTableDataChanged();
} }
@ -136,17 +164,7 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
private final String caseName; private final String caseName;
private final String deviceId; private final String deviceId;
private final String dataSourceName; private final String dataSourceName;
private final String caseUUID;
/**
* Create a DataSourceColumnItem given an
* OtherOccurrenceNodeInstanceData object
*
* @param nodeData the OtherOccurrenceNodeInstanceData which contains
* the data source information
*/
private DataSourceColumnItem(OtherOccurrenceNodeInstanceData nodeData) {
this(nodeData.getCaseName(), nodeData.getDeviceID(), nodeData.getDataSourceName());
}
/** /**
* Create a DataSourceColumnItem given a case name, device id, and data * Create a DataSourceColumnItem given a case name, device id, and data
@ -156,10 +174,11 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
* @param deviceId the name of the device id for the data source * @param deviceId the name of the device id for the data source
* @param dataSourceName the name of the data source * @param dataSourceName the name of the data source
*/ */
private DataSourceColumnItem(String caseName, String deviceId, String dataSourceName) { private DataSourceColumnItem(String caseName, String deviceId, String dataSourceName, String caseUUID) {
this.caseName = caseName; this.caseName = caseName;
this.deviceId = deviceId; this.deviceId = deviceId;
this.dataSourceName = dataSourceName; this.dataSourceName = dataSourceName;
this.caseUUID = caseUUID;
} }
/** /**
@ -189,17 +208,27 @@ final class OtherOccurrencesDataSourcesTableModel extends AbstractTableModel {
return caseName; return caseName;
} }
/**
* Get the case uuid of the case the data source exists in
*
* @return the case UUID
*/
private String getCaseUUID() {
return caseUUID;
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
return other instanceof DataSourceColumnItem return other instanceof DataSourceColumnItem
&& caseName.equals(((DataSourceColumnItem) other).getCaseName()) && caseName.equals(((DataSourceColumnItem) other).getCaseName())
&& dataSourceName.equals(((DataSourceColumnItem) other).getDataSourceName()) && dataSourceName.equals(((DataSourceColumnItem) other).getDataSourceName())
&& deviceId.equals(((DataSourceColumnItem) other).getDeviceId()); && deviceId.equals(((DataSourceColumnItem) other).getDeviceId())
&& caseUUID.equals(((DataSourceColumnItem) other).getCaseUUID());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(caseName, deviceId, dataSourceName); return Objects.hash(caseName, deviceId, dataSourceName, caseUUID);
} }
} }

View File

@ -25,6 +25,7 @@ import java.util.Map;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
/** /**
* Model for cells in the files section of the other occurrences data content * Model for cells in the files section of the other occurrences data content
@ -114,7 +115,14 @@ public class OtherOccurrencesFilesTableModel extends AbstractTableModel {
} }
private String createNodeKey(OtherOccurrenceNodeInstanceData nodeData) { private String createNodeKey(OtherOccurrenceNodeInstanceData nodeData) {
return nodeData.getCaseName() + nodeData.getDataSourceName() + nodeData.getDeviceID() + nodeData.getFilePath(); String caseUUID;
try {
caseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
} catch (EamDbException ignored) {
caseUUID = DataContentViewerOtherCases.getPlaceholderUUID();
//place holder value will be used since correlation attribute was unavailble
}
return nodeData.getCaseName() + nodeData.getDataSourceName() + nodeData.getDeviceID() + nodeData.getFilePath() + caseUUID;
} }
/** /**