19 package org.sleuthkit.autopsy.centralrepository.contentviewer;
21 import java.awt.Component;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.event.ComponentAdapter;
25 import java.awt.event.ComponentEvent;
26 import java.io.BufferedWriter;
28 import java.io.IOException;
29 import java.nio.file.Files;
30 import java.text.DateFormat;
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Collection;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Locale;
41 import java.util.Objects;
43 import java.util.logging.Level;
45 import javax.swing.JFileChooser;
46 import javax.swing.JMenuItem;
47 import javax.swing.JOptionPane;
48 import static javax.swing.JOptionPane.DEFAULT_OPTION;
49 import static javax.swing.JOptionPane.PLAIN_MESSAGE;
50 import static javax.swing.JOptionPane.ERROR_MESSAGE;
51 import javax.swing.JPanel;
52 import javax.swing.filechooser.FileNameExtensionFilter;
53 import javax.swing.table.TableModel;
54 import javax.swing.table.TableRowSorter;
55 import org.joda.time.DateTimeZone;
56 import org.joda.time.LocalDateTime;
57 import org.openide.nodes.Node;
58 import org.openide.util.NbBundle.Messages;
59 import org.openide.util.lookup.ServiceProvider;
83 @SuppressWarnings(
"PMD.SingularField")
84 @ServiceProvider(service = DataContentViewer.class, position = 9)
85 @Messages({
"DataContentViewerOtherCases.title=Other Occurrences",
86 "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",
87 "DataContentViewerOtherCases.table.noArtifacts=Item has no attributes with which to search.",
88 "DataContentViewerOtherCases.table.noResultsFound=No results found."})
91 private static final long serialVersionUID = -1L;
94 private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE =
new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts());
95 private static final CorrelationCaseWrapper NO_RESULTS_CASE =
new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noResultsFound());
102 private String dataSourceName =
"";
103 private String deviceId =
"";
115 this.dataSourcesTableModel =
new OtherOccurrencesDataSourcesTableModel();
116 this.correlationAttributes =
new ArrayList<>();
117 occurrencePanel =
new OccurrencePanel();
119 customizeComponents();
121 detailsPanelScrollPane.addComponentListener(
new ComponentAdapter() {
123 public void componentResized(ComponentEvent componentEvent) {
125 occurrencePanel.setPreferredSize(
new java.awt.Dimension(detailsPanelScrollPane.getPreferredSize().width, occurrencePanel.getPreferredSize().height));
126 detailsPanelScrollPane.setViewportView(occurrencePanel);
133 ActionListener actList = (ActionEvent e) -> {
134 JMenuItem jmi = (JMenuItem) e.getSource();
135 if (jmi.equals(selectAllMenuItem)) {
136 filesTable.selectAll();
137 }
else if (jmi.equals(showCaseDetailsMenuItem)) {
138 showCaseDetails(filesTable.getSelectedRow());
139 }
else if (jmi.equals(exportToCSVMenuItem)) {
143 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
145 }
else if (jmi.equals(showCommonalityMenuItem)) {
146 showCommonalityDetails();
150 exportToCSVMenuItem.addActionListener(actList);
151 selectAllMenuItem.addActionListener(actList);
152 showCaseDetailsMenuItem.addActionListener(actList);
153 showCommonalityMenuItem.addActionListener(actList);
156 TableRowSorter<TableModel> sorter =
new TableRowSorter<>(filesTable.getModel());
157 filesTable.setRowSorter(sorter);
158 casesTable.getSelectionModel().addListSelectionListener((e) -> {
160 updateOnCaseSelection();
163 dataSourcesTable.getSelectionModel().addListSelectionListener((e) -> {
165 updateOnDataSourceSelection();
170 filesTable.getSelectionModel().addListSelectionListener((e) -> {
172 occurrencePanel =
new OccurrencePanel();
173 updateOnFileSelection();
177 casesTable.getRowSorter().toggleSortOrder(0);
178 dataSourcesTable.getRowSorter().toggleSortOrder(0);
179 filesTable.getRowSorter().toggleSortOrder(0);
182 @Messages({
"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
183 "# {0} - commonality percentage",
184 "# {1} - correlation type",
185 "# {2} - correlation value",
186 "DataContentViewerOtherCases.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
187 "DataContentViewerOtherCases.correlatedArtifacts.title=Attribute Frequency",
188 "DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get frequency details."})
194 if (correlationAttributes.isEmpty()) {
195 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
196 Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
197 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
198 DEFAULT_OPTION, PLAIN_MESSAGE);
200 StringBuilder msg =
new StringBuilder(correlationAttributes.size());
207 msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
208 eamArtifact.getCorrelationType().getDisplayName(),
209 eamArtifact.getCorrelationValue()));
211 LOGGER.log(Level.WARNING, String.format(
"Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
214 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
216 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
217 DEFAULT_OPTION, PLAIN_MESSAGE);
219 LOGGER.log(Level.SEVERE,
"Error getting commonality details.", ex);
220 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
221 Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
222 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
223 DEFAULT_OPTION, ERROR_MESSAGE);
228 @Messages({
"DataContentViewerOtherCases.caseDetailsDialog.notSelected=No Row Selected",
229 "DataContentViewerOtherCases.caseDetailsDialog.noDetails=No details for this case.",
230 "DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=No case details for Global reference properties.",
231 "DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=Error",
232 "DataContentViewerOtherCases.noOpenCase.errMsg=No open case available."})
234 String caseDisplayName = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noCaseNameError();
235 String details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails();
237 if (-1 != selectedRowViewIdx) {
239 int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
240 List<OtherOccurrenceNodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
241 if (!rowList.isEmpty()) {
242 if (rowList.get(0) instanceof OtherOccurrenceNodeInstanceData) {
243 CorrelationCase eamCasePartial = ((OtherOccurrenceNodeInstanceData) rowList.get(0)).getCorrelationAttributeInstance().getCorrelationCase();
247 if (eamCase != null) {
250 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails();
253 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_notSelected();
256 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference();
260 LOGGER.log(Level.SEVERE,
"Error loading case details", ex);
262 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
265 DEFAULT_OPTION, PLAIN_MESSAGE);
271 Calendar now = Calendar.getInstance();
272 String fileName = String.format(
"%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
274 CSVFileChooser.setSelectedFile(
new File(fileName));
275 CSVFileChooser.setFileFilter(
new FileNameExtensionFilter(
"csv file",
"csv"));
277 int returnVal = CSVFileChooser.showSaveDialog(filesTable);
278 if (returnVal == JFileChooser.APPROVE_OPTION) {
280 File selectedFile = CSVFileChooser.getSelectedFile();
281 if (!selectedFile.getName().endsWith(
".csv")) {
282 selectedFile =
new File(selectedFile.toString() +
".csv");
284 writeOtherOccurrencesToFileAsCSV(selectedFile);
290 "DataContentViewerOtherCasesModel.csvHeader.case=Case",
291 "DataContentViewerOtherCasesModel.csvHeader.device=Device",
292 "DataContentViewerOtherCasesModel.csvHeader.dataSource=Data Source",
293 "DataContentViewerOtherCasesModel.csvHeader.attribute=Matched Attribute",
294 "DataContentViewerOtherCasesModel.csvHeader.value=Attribute Value",
295 "DataContentViewerOtherCasesModel.csvHeader.known=Known",
296 "DataContentViewerOtherCasesModel.csvHeader.path=Path",
297 "DataContentViewerOtherCasesModel.csvHeader.comment=Comment"
303 try (BufferedWriter writer = Files.newBufferedWriter(destFile.toPath())) {
305 StringBuilder headers =
new StringBuilder(
"\"");
306 headers.append(Bundle.DataContentViewerOtherCasesModel_csvHeader_case())
307 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_dataSource())
308 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_attribute())
309 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_value())
310 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_known())
311 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_path())
312 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_comment())
313 .append(
'"').append(System.getProperty(
"line.separator"));
314 writer.write(headers.toString());
317 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
319 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
320 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
321 writer.write(nodeData.toCsvString());
324 }
catch (IOException ex) {
325 LOGGER.log(Level.SEVERE,
"Error writing selected rows to CSV.", ex);
334 casesTableModel.clearTable();
335 dataSourcesTableModel.clearTable();
336 filesTableModel.clearTable();
337 correlationAttributes.clear();
338 earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
339 foundInLabel.setText(
"");
341 occurrencePanel =
new OccurrencePanel();
342 occurrencePanel.getPreferredSize();
343 detailsPanelScrollPane.setViewportView(occurrencePanel);
348 return Bundle.DataContentViewerOtherCases_title();
353 return Bundle.DataContentViewerOtherCases_toolTip();
384 private BlackboardArtifact
386 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
388 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
391 if (nodeBbArtifactTag != null) {
392 return nodeBbArtifactTag.getArtifact();
393 }
else if (nodeBbArtifact != null) {
394 return nodeBbArtifact;
409 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
411 ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class
413 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
415 AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class
418 if (nodeBbArtifactTag != null) {
419 Content content = nodeBbArtifactTag.getContent();
420 if (content instanceof AbstractFile) {
421 return (AbstractFile) content;
423 }
else if (nodeContentTag != null) {
424 Content content = nodeContentTag.getContent();
425 if (content instanceof AbstractFile) {
426 return (AbstractFile) content;
428 }
else if (nodeBbArtifact != null) {
431 content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
432 }
catch (TskCoreException ex) {
433 LOGGER.log(Level.SEVERE,
"Error retrieving blackboard artifact", ex);
437 if (content instanceof AbstractFile) {
438 return (AbstractFile) content;
440 }
else if (nodeAbstractFile != null) {
441 return nodeAbstractFile;
456 Collection<CorrelationAttributeInstance> ret =
new ArrayList<>();
459 BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
465 if (this.file != null &&
EamDb.
isEnabled() && this.file.getSize() > 0) {
469 String md5 = this.file.getMd5Hash();
470 if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
480 file.getParentPath() + file.
getName(),
485 LOGGER.log(Level.INFO, String.format(
"Unable to check create CorrelationAttribtueInstance for value %s and type %s.", md5, aType.toString()), ex);
492 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
495 }
else if (this.file != null && this.file.getSize() > 0) {
496 String md5 = this.file.getMd5Hash();
497 if (md5 != null && !md5.isEmpty()) {
508 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
510 LOGGER.log(Level.INFO, String.format(
"Unable to create CorrelationAttributeInstance for value %s", md5), ex);
518 @Messages({
"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
524 String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable();
527 LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC);
528 DateFormat datetimeFormat =
new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss", Locale.US);
531 List<CorrelationCase> cases = dbManager.
getCases();
533 LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate()));
535 if (caseDate.isBefore(earliestDate)) {
536 earliestDate = caseDate;
537 dateStringDisplay = aCase.getCreationDate();
543 LOGGER.log(Level.SEVERE,
"Error getting list of cases from database.", ex);
544 }
catch (ParseException ex) {
545 LOGGER.log(Level.SEVERE,
"Error parsing date of cases from database.", ex);
549 earliestCaseDate.setText(dateStringDisplay);
568 String caseUUID = openCase.
getName();
569 HashMap<UniquePathKey, OtherOccurrenceNodeInstanceData> nodeDataMap =
new HashMap<>();
582 if (!artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID)
583 || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName)
584 || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId)
585 || !artifactInstance.getFilePath().equalsIgnoreCase(file.getParentPath() + file.getName())) {
589 nodeDataMap.put(uniquePathKey, newNode);
594 List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase);
596 for (AbstractFile caseDbFile : caseDbFiles) {
597 addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
602 LOGGER.log(Level.SEVERE,
"Error getting artifact instances from database.", ex);
604 LOGGER.log(Level.INFO,
"Error getting artifact instances from database.", ex);
606 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
607 }
catch (TskCoreException ex) {
610 LOGGER.log(Level.SEVERE,
"Exception while querying open case.", ex);
613 return new HashMap<>(0);
630 String md5 = corAttr.getCorrelationValue();
631 SleuthkitCase tsk = openCase.getSleuthkitCase();
632 List<AbstractFile> matches = tsk.findAllFilesWhere(String.format(
"md5 = '%s'",
new Object[]{md5}));
634 List<AbstractFile> caseDbArtifactInstances =
new ArrayList<>();
635 for (AbstractFile fileMatch : matches) {
636 if (this.file.equals(fileMatch)) {
639 caseDbArtifactInstances.add(fileMatch);
641 return caseDbArtifactInstances;
657 OtherOccurrenceNodeInstanceData newNode =
new OtherOccurrenceNodeInstanceData(newFile, autopsyCase);
661 if (newNode.getKnown() != TskData.FileKnown.BAD) {
662 List<ContentTag> fileMatchTags = autopsyCase.getServices().getTagsManager().getContentTagsByContent(newFile);
663 for (ContentTag tag : fileMatchTags) {
664 TskData.FileKnown tagKnownStatus = tag.getName().getKnownStatus();
665 if (tagKnownStatus.equals(TskData.FileKnown.BAD)) {
666 newNode.updateKnown(TskData.FileKnown.BAD);
678 if (nodeDataMap.containsKey(uniquePathKey)) {
679 if (newNode.getKnown() == TskData.FileKnown.BAD) {
680 OtherOccurrenceNodeInstanceData prevInstance = nodeDataMap.get(uniquePathKey);
681 prevInstance.updateKnown(newNode.getKnown());
684 nodeDataMap.put(uniquePathKey, newNode);
695 this.file = this.getAbstractFileFromNode(node);
697 return !getCorrelationAttributesFromNode(node).isEmpty();
699 return this.file != null
700 && this.file.getSize() > 0
701 && ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
713 this.file = this.getAbstractFileFromNode(node);
725 "DataContentViewerOtherCases.dataSources.header.text=Data Source Name",
726 "DataContentViewerOtherCases.foundIn.text=Found %d instances in %d cases and %d data sources."
730 if (this.file != null) {
731 Content dataSource = this.file.getDataSource();
732 dataSourceName = dataSource.getName();
735 }
catch (TskException | NoCurrentCaseException ex) {
741 correlationAttributes.addAll(getCorrelationAttributesFromNode(node));
742 Map<String, CorrelationCase> caseNames =
new HashMap<>();
744 Set<String> dataSources =
new HashSet<>();
746 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
749 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
750 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
751 if (nodeData.isCentralRepoNode()) {
753 dataSources.add(makeDataSourceString(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getDeviceID(), nodeData.getDataSourceName()));
754 caseNames.put(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getCorrelationAttributeInstance().getCorrelationCase());
756 LOGGER.log(Level.WARNING,
"Unable to get correlation case for displaying other occurrence for case: " + nodeData.getCaseName(), ex);
762 }
catch (NoCurrentCaseException ex) {
763 LOGGER.log(Level.WARNING,
"No current case open for other occurrences", ex);
770 casesTableModel.addCorrelationCase(
new CorrelationCaseWrapper(corCase));
773 if (correlationAttributes.isEmpty()) {
774 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
775 }
else if (caseCount == 0) {
776 casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
778 setEarliestCaseDate();
779 foundInLabel.setText(String.format(Bundle.DataContentViewerOtherCases_foundIn_text(), totalCount, caseCount, dataSources.size()));
781 casesTable.setRowSelectionInterval(0, 0);
790 return caseUUID + deviceId + dataSourceName;
797 int[] selectedCaseIndexes = casesTable.getSelectedRows();
798 dataSourcesTableModel.clearTable();
799 filesTableModel.clearTable();
801 if (selectedCaseIndexes.length == 0) {
803 occurrencePanel =
new OccurrencePanel();
804 occurrencePanel.getPreferredSize();
805 detailsPanelScrollPane.setViewportView(occurrencePanel);
808 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
811 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
812 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
813 for (
int selectedRow : selectedCaseIndexes) {
815 if (nodeData.isCentralRepoNode()) {
816 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
817 && casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
818 dataSourcesTableModel.addNodeData(nodeData);
821 dataSourcesTableModel.addNodeData(nodeData);
824 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
829 if (dataSourcesTable.getRowCount() > 0) {
830 dataSourcesTable.setRowSelectionInterval(0, 0);
840 int[] selectedCaseIndexes = casesTable.getSelectedRows();
841 int[] selectedDataSources = dataSourcesTable.getSelectedRows();
842 filesTableModel.clearTable();
844 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
847 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
848 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
849 for (
int selectedCaseRow : selectedCaseIndexes) {
850 for (
int selectedDataSourceRow : selectedDataSources) {
852 if (nodeData.isCentralRepoNode()) {
853 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)) != null
854 && casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
855 && dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
856 filesTableModel.addNodeData(nodeData);
859 if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
860 filesTableModel.addNodeData(nodeData);
864 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
870 if (filesTable.getRowCount() > 0) {
871 filesTable.setRowSelectionInterval(0, 0);
880 if (filesTable.getSelectedRowCount() == 1) {
882 occurrencePanel =
new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())));
883 }
else if (dataSourcesTable.getSelectedRowCount() == 1) {
885 String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
886 String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
887 String caseCreatedDate =
"";
888 for (
int row : casesTable.getSelectedRows()) {
889 if (casesTableModel.
getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
890 caseCreatedDate = getCaseCreatedDate(row);
894 occurrencePanel =
new OccurrencePanel(caseName, caseCreatedDate, dsName);
895 }
else if (casesTable.getSelectedRowCount() == 1) {
898 String createdDate =
"";
899 String caseName =
"";
900 if (casesTable.getRowCount() > 0) {
901 caseName = casesTableModel.
getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
903 if (caseName.isEmpty()) {
904 occurrencePanel =
new OccurrencePanel();
906 createdDate = getCaseCreatedDate(casesTable.getSelectedRow());
907 occurrencePanel =
new OccurrencePanel(caseName, createdDate);
911 occurrencePanel =
new OccurrencePanel();
914 occurrencePanel.getPreferredSize();
915 detailsPanelScrollPane.setViewportView(occurrencePanel);
930 partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
931 if (partialCase == null){
939 LOGGER.log(Level.WARNING,
"Error getting case created date for row: " + caseTableRowIdx, ex);
949 @SuppressWarnings(
"unchecked")
951 private
void initComponents() {
953 rightClickPopupMenu =
new javax.swing.JPopupMenu();
954 selectAllMenuItem =
new javax.swing.JMenuItem();
955 exportToCSVMenuItem =
new javax.swing.JMenuItem();
956 showCaseDetailsMenuItem =
new javax.swing.JMenuItem();
957 showCommonalityMenuItem =
new javax.swing.JMenuItem();
958 CSVFileChooser =
new javax.swing.JFileChooser();
959 tableContainerPanel =
new javax.swing.JPanel();
960 earliestCaseLabel =
new javax.swing.JLabel();
961 earliestCaseDate =
new javax.swing.JLabel();
962 foundInLabel =
new javax.swing.JLabel();
963 tablesViewerSplitPane =
new javax.swing.JSplitPane();
964 caseDatasourceFileSplitPane =
new javax.swing.JSplitPane();
965 caseDatasourceSplitPane =
new javax.swing.JSplitPane();
966 caseScrollPane =
new javax.swing.JScrollPane();
967 casesTable =
new javax.swing.JTable();
968 dataSourceScrollPane =
new javax.swing.JScrollPane();
969 dataSourcesTable =
new javax.swing.JTable();
970 filesTableScrollPane =
new javax.swing.JScrollPane();
971 filesTable =
new javax.swing.JTable();
972 detailsPanelScrollPane =
new javax.swing.JScrollPane();
974 rightClickPopupMenu.addPopupMenuListener(
new javax.swing.event.PopupMenuListener() {
975 public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
977 public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
979 public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
980 rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
984 org.openide.awt.Mnemonics.setLocalizedText(selectAllMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.selectAllMenuItem.text"));
985 rightClickPopupMenu.add(selectAllMenuItem);
987 org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.exportToCSVMenuItem.text"));
988 rightClickPopupMenu.add(exportToCSVMenuItem);
990 org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCaseDetailsMenuItem.text"));
991 rightClickPopupMenu.add(showCaseDetailsMenuItem);
993 org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCommonalityMenuItem.text"));
994 rightClickPopupMenu.add(showCommonalityMenuItem);
996 setMinimumSize(
new java.awt.Dimension(600, 10));
998 setPreferredSize(
new java.awt.Dimension(600, 63));
1000 tableContainerPanel.setPreferredSize(
new java.awt.Dimension(600, 63));
1001 tableContainerPanel.setRequestFocusEnabled(
false);
1003 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.text"));
1004 earliestCaseLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.toolTipText"));
1006 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseDate.text"));
1008 org.openide.awt.Mnemonics.setLocalizedText(foundInLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.foundInLabel.text"));
1010 tablesViewerSplitPane.setDividerLocation(450);
1011 tablesViewerSplitPane.setResizeWeight(0.75);
1013 caseDatasourceFileSplitPane.setDividerLocation(300);
1014 caseDatasourceFileSplitPane.setResizeWeight(0.66);
1015 caseDatasourceFileSplitPane.setToolTipText(
"");
1017 caseDatasourceSplitPane.setDividerLocation(150);
1018 caseDatasourceSplitPane.setResizeWeight(0.5);
1020 caseScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1022 casesTable.setAutoCreateRowSorter(
true);
1023 casesTable.setModel(casesTableModel);
1024 caseScrollPane.setViewportView(casesTable);
1026 caseDatasourceSplitPane.setLeftComponent(caseScrollPane);
1028 dataSourceScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1030 dataSourcesTable.setAutoCreateRowSorter(
true);
1031 dataSourcesTable.setModel(dataSourcesTableModel);
1032 dataSourceScrollPane.setViewportView(dataSourcesTable);
1034 caseDatasourceSplitPane.setRightComponent(dataSourceScrollPane);
1036 caseDatasourceFileSplitPane.setLeftComponent(caseDatasourceSplitPane);
1038 filesTableScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1040 filesTable.setAutoCreateRowSorter(
true);
1041 filesTable.setModel(filesTableModel);
1042 filesTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.table.toolTip.text"));
1043 filesTable.setComponentPopupMenu(rightClickPopupMenu);
1044 filesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
1045 filesTableScrollPane.setViewportView(filesTable);
1047 caseDatasourceFileSplitPane.setRightComponent(filesTableScrollPane);
1049 tablesViewerSplitPane.setLeftComponent(caseDatasourceFileSplitPane);
1051 detailsPanelScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
1052 detailsPanelScrollPane.setPreferredSize(
new java.awt.Dimension(300, 100));
1053 tablesViewerSplitPane.setRightComponent(detailsPanelScrollPane);
1055 javax.swing.GroupLayout tableContainerPanelLayout =
new javax.swing.GroupLayout(tableContainerPanel);
1056 tableContainerPanel.setLayout(tableContainerPanelLayout);
1057 tableContainerPanelLayout.setHorizontalGroup(
1058 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1059 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1060 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1061 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1062 .addComponent(earliestCaseLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE)
1063 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1064 .addComponent(earliestCaseDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1065 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1066 .addComponent(foundInLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
1067 .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 765, Short.MAX_VALUE))
1070 tableContainerPanelLayout.setVerticalGroup(
1071 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1072 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1074 .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE)
1075 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1076 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
1077 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
1078 .addComponent(earliestCaseLabel)
1079 .addComponent(earliestCaseDate))
1080 .addComponent(foundInLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
1084 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1085 this.setLayout(layout);
1086 layout.setHorizontalGroup(
1087 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1088 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 775, Short.MAX_VALUE)
1090 layout.setVerticalGroup(
1091 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1092 .addGroup(layout.createSequentialGroup()
1093 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE)
1099 boolean enableCentralRepoActions =
false;
1100 if (
EamDb.
isEnabled() && filesTable.getSelectedRowCount() == 1) {
1101 int rowIndex = filesTable.getSelectedRow();
1102 List<OtherOccurrenceNodeData> selectedFile = filesTableModel.getListOfNodesForFile(rowIndex);
1103 if (!selectedFile.isEmpty() && selectedFile.get(0) instanceof OtherOccurrenceNodeInstanceData) {
1104 OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) selectedFile.get(0);
1105 enableCentralRepoActions = instanceData.isCentralRepoNode();
1108 showCaseDetailsMenuItem.setVisible(enableCentralRepoActions);
1109 showCommonalityMenuItem.setVisible(enableCentralRepoActions);
1147 dataSourceID = nodeData.getDeviceID();
1148 if (nodeData.getFilePath() != null) {
1149 filePath = nodeData.getFilePath().toLowerCase();
1153 type = nodeData.getType();
1159 UniquePathKey otherKey = (UniquePathKey) (other);
1160 return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
1161 && Objects.equals(otherKey.getFilePath(), this.getFilePath())
1162 && Objects.equals(otherKey.getType(), this.getType()));
1169 return Objects.hash(getDataSourceID(), getFilePath(), getType());
1186 String getFilePath() {
1195 String getDataSourceID() {
1196 return dataSourceID;
Object getValueAt(int rowIdx, int colIdx)
final Collection< CorrelationAttributeInstance > correlationAttributes
void updateOnFileSelection()
void rightClickPopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt)
static List< CorrelationAttributeInstance > makeInstancesFromBlackboardArtifact(BlackboardArtifact artifact, boolean checkEnabled)
CorrelationCase getCaseByUUID(String caseUUID)
int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
final OtherOccurrencesFilesTableModel filesTableModel
boolean equals(Object other)
String makeDataSourceString(String caseUUID, String deviceId, String dataSourceName)
int isPreferred(Node node)
javax.swing.JLabel earliestCaseLabel
javax.swing.JMenuItem selectAllMenuItem
javax.swing.JMenuItem showCommonalityMenuItem
void updateOnDataSourceSelection()
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
javax.swing.JPanel tableContainerPanel
void setEarliestCaseDate()
javax.swing.JSplitPane caseDatasourceFileSplitPane
AbstractFile getAbstractFileFromNode(Node node)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
javax.swing.JTable dataSourcesTable
Collection< CorrelationAttributeInstance > getCorrelationAttributesFromNode(Node node)
String getCorrelationValue()
final String dataSourceID
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
javax.swing.JScrollPane detailsPanelScrollPane
javax.swing.JSplitPane tablesViewerSplitPane
javax.swing.JScrollPane filesTableScrollPane
void writeOtherOccurrencesToFileAsCSV(File destFile)
List< CorrelationAttributeInstance.Type > getDefinedCorrelationTypes()
Type getCorrelationType()
void populateTable(Node node)
javax.swing.JPopupMenu rightClickPopupMenu
javax.swing.JSplitPane caseDatasourceSplitPane
javax.swing.JScrollPane dataSourceScrollPane
javax.swing.JScrollPane caseScrollPane
BlackboardArtifact getBlackboardArtifactFromNode(Node node)
void updateOnCaseSelection()
static EamDb getInstance()
boolean isSupported(Node node)
String getCaseDetailsOptionsPaneDialog()
void showCaseDetails(int selectedRowViewIdx)
javax.swing.JMenuItem exportToCSVMenuItem
static boolean isEnabled()
SleuthkitCase getSleuthkitCase()
void addOrUpdateNodeData(final Case autopsyCase, Map< UniquePathKey, OtherOccurrenceNodeInstanceData > nodeDataMap, AbstractFile newFile)
void showCommonalityDetails()
OccurrencePanel occurrencePanel
DataContentViewerOtherCases()
CorrelationCase getCase(Case autopsyCase)
javax.swing.JFileChooser CSVFileChooser
javax.swing.JLabel earliestCaseDate
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
final OtherOccurrencesCasesTableModel casesTableModel
static Case getCurrentCaseThrows()
javax.swing.JLabel foundInLabel
String getExportDirectory()
javax.swing.JTable filesTable
DataContentViewer createInstance()
void customizeComponents()
List< AbstractFile > getCaseDbMatches(CorrelationAttributeInstance corAttr, Case openCase)
Map< UniquePathKey, OtherOccurrenceNodeInstanceData > getCorrelatedInstances(CorrelationAttributeInstance corAttr, String dataSourceName, String deviceId)
String getCaseCreatedDate(int caseTableRowIdx)
static boolean isCaseOpen()
javax.swing.JTable casesTable
final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel
static final int FILES_TYPE_ID
javax.swing.JMenuItem showCaseDetailsMenuItem
List< CorrelationCase > getCases()