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;
92 private static final String UUID_PLACEHOLDER_STRING =
"NoCorrelationAttributeInstance";
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());
101 private String dataSourceName =
"";
102 private String deviceId =
"";
114 this.dataSourcesTableModel =
new OtherOccurrencesDataSourcesTableModel();
115 this.correlationAttributes =
new ArrayList<>();
116 occurrencePanel =
new OccurrencePanel();
118 customizeComponents();
120 detailsPanelScrollPane.addComponentListener(
new ComponentAdapter() {
122 public void componentResized(ComponentEvent componentEvent) {
124 occurrencePanel.setPreferredSize(
new java.awt.Dimension(detailsPanelScrollPane.getPreferredSize().width, occurrencePanel.getPreferredSize().height));
125 detailsPanelScrollPane.setViewportView(occurrencePanel);
137 static String getPlaceholderUUID() {
138 return UUID_PLACEHOLDER_STRING;
142 ActionListener actList = (ActionEvent e) -> {
143 JMenuItem jmi = (JMenuItem) e.getSource();
144 if (jmi.equals(showCaseDetailsMenuItem)) {
145 showCaseDetails(filesTable.getSelectedRow());
146 }
else if (jmi.equals(exportToCSVMenuItem)) {
150 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
152 }
else if (jmi.equals(showCommonalityMenuItem)) {
153 showCommonalityDetails();
157 exportToCSVMenuItem.addActionListener(actList);
158 showCaseDetailsMenuItem.addActionListener(actList);
159 showCommonalityMenuItem.addActionListener(actList);
162 TableRowSorter<TableModel> sorter =
new TableRowSorter<>(filesTable.getModel());
163 filesTable.setRowSorter(sorter);
164 casesTable.getSelectionModel().addListSelectionListener((e) -> {
166 updateOnCaseSelection();
169 dataSourcesTable.getSelectionModel().addListSelectionListener((e) -> {
171 updateOnDataSourceSelection();
176 filesTable.getSelectionModel().addListSelectionListener((e) -> {
178 occurrencePanel =
new OccurrencePanel();
179 updateOnFileSelection();
183 casesTable.getRowSorter().toggleSortOrder(0);
184 dataSourcesTable.getRowSorter().toggleSortOrder(0);
185 filesTable.getRowSorter().toggleSortOrder(0);
188 @Messages({
"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
189 "# {0} - commonality percentage",
190 "# {1} - correlation type",
191 "# {2} - correlation value",
192 "DataContentViewerOtherCases.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
193 "DataContentViewerOtherCases.correlatedArtifacts.title=Attribute Frequency",
194 "DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get frequency details."})
200 if (correlationAttributes.isEmpty()) {
201 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
202 Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
203 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
204 DEFAULT_OPTION, PLAIN_MESSAGE);
206 StringBuilder msg =
new StringBuilder(correlationAttributes.size());
213 msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
214 eamArtifact.getCorrelationType().getDisplayName(),
215 eamArtifact.getCorrelationValue()));
217 LOGGER.log(Level.WARNING, String.format(
"Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
220 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
222 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
223 DEFAULT_OPTION, PLAIN_MESSAGE);
225 LOGGER.log(Level.SEVERE,
"Error getting commonality details.", ex);
226 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
227 Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
228 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
229 DEFAULT_OPTION, ERROR_MESSAGE);
234 @Messages({
"DataContentViewerOtherCases.caseDetailsDialog.notSelected=No Row Selected",
235 "DataContentViewerOtherCases.caseDetailsDialog.noDetails=No details for this case.",
236 "DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=No case details for Global reference properties.",
237 "DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=Error",
238 "DataContentViewerOtherCases.noOpenCase.errMsg=No open case available."})
240 String caseDisplayName = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noCaseNameError();
241 String details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails();
243 if (-1 != selectedRowViewIdx) {
245 int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
246 List<OtherOccurrenceNodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
247 if (!rowList.isEmpty()) {
248 if (rowList.get(0) instanceof OtherOccurrenceNodeInstanceData) {
249 CorrelationCase eamCasePartial = ((OtherOccurrenceNodeInstanceData) rowList.get(0)).getCorrelationAttributeInstance().getCorrelationCase();
253 if (eamCase != null) {
256 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails();
259 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_notSelected();
262 details = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference();
266 LOGGER.log(Level.SEVERE,
"Error loading case details", ex);
268 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
271 DEFAULT_OPTION, PLAIN_MESSAGE);
277 Calendar now = Calendar.getInstance();
278 String fileName = String.format(
"%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
280 CSVFileChooser.setSelectedFile(
new File(fileName));
281 CSVFileChooser.setFileFilter(
new FileNameExtensionFilter(
"csv file",
"csv"));
283 int returnVal = CSVFileChooser.showSaveDialog(filesTable);
284 if (returnVal == JFileChooser.APPROVE_OPTION) {
286 File selectedFile = CSVFileChooser.getSelectedFile();
287 if (!selectedFile.getName().endsWith(
".csv")) {
288 selectedFile =
new File(selectedFile.toString() +
".csv");
290 writeOtherOccurrencesToFileAsCSV(selectedFile);
296 "DataContentViewerOtherCasesModel.csvHeader.case=Case",
297 "DataContentViewerOtherCasesModel.csvHeader.device=Device",
298 "DataContentViewerOtherCasesModel.csvHeader.dataSource=Data Source",
299 "DataContentViewerOtherCasesModel.csvHeader.attribute=Matched Attribute",
300 "DataContentViewerOtherCasesModel.csvHeader.value=Attribute Value",
301 "DataContentViewerOtherCasesModel.csvHeader.known=Known",
302 "DataContentViewerOtherCasesModel.csvHeader.path=Path",
303 "DataContentViewerOtherCasesModel.csvHeader.comment=Comment"
309 try (BufferedWriter writer = Files.newBufferedWriter(destFile.toPath())) {
311 StringBuilder headers =
new StringBuilder(
"\"");
312 headers.append(Bundle.DataContentViewerOtherCasesModel_csvHeader_case())
313 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_dataSource())
314 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_attribute())
315 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_value())
316 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_known())
317 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_path())
318 .append(OtherOccurrenceNodeInstanceData.getCsvItemSeparator()).append(Bundle.DataContentViewerOtherCasesModel_csvHeader_comment())
319 .append(
'"').append(System.getProperty(
"line.separator"));
320 writer.write(headers.toString());
323 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
325 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
326 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
327 writer.write(nodeData.toCsvString());
330 }
catch (IOException ex) {
331 LOGGER.log(Level.SEVERE,
"Error writing selected rows to CSV.", ex);
340 casesTableModel.clearTable();
341 dataSourcesTableModel.clearTable();
342 filesTableModel.clearTable();
343 correlationAttributes.clear();
344 earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
345 foundInLabel.setText(
"");
347 occurrencePanel =
new OccurrencePanel();
348 occurrencePanel.getPreferredSize();
349 detailsPanelScrollPane.setViewportView(occurrencePanel);
354 return Bundle.DataContentViewerOtherCases_title();
359 return Bundle.DataContentViewerOtherCases_toolTip();
390 private BlackboardArtifact
392 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
394 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
397 if (nodeBbArtifactTag != null) {
398 return nodeBbArtifactTag.getArtifact();
399 }
else if (nodeBbArtifact != null) {
400 return nodeBbArtifact;
415 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
417 ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class
419 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
421 AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class
424 if (nodeBbArtifactTag != null) {
425 Content content = nodeBbArtifactTag.getContent();
426 if (content instanceof AbstractFile) {
427 return (AbstractFile) content;
429 }
else if (nodeContentTag != null) {
430 Content content = nodeContentTag.getContent();
431 if (content instanceof AbstractFile) {
432 return (AbstractFile) content;
434 }
else if (nodeBbArtifact != null) {
437 content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
438 }
catch (TskCoreException ex) {
439 LOGGER.log(Level.SEVERE,
"Error retrieving blackboard artifact", ex);
443 if (content instanceof AbstractFile) {
444 return (AbstractFile) content;
446 }
else if (nodeAbstractFile != null) {
447 return nodeAbstractFile;
462 Collection<CorrelationAttributeInstance> ret =
new ArrayList<>();
465 BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
475 String md5 = this.file.getMd5Hash();
476 if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
486 file.getParentPath() + file.
getName(),
491 LOGGER.log(Level.INFO, String.format(
"Unable to check create CorrelationAttribtueInstance for value %s and type %s.", md5, aType.toString()), ex);
498 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
501 }
else if (this.file != null && this.file.getSize() > 0) {
502 String md5 = this.file.getMd5Hash();
503 if (md5 != null && !md5.isEmpty()) {
514 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
516 LOGGER.log(Level.INFO, String.format(
"Unable to create CorrelationAttributeInstance for value %s", md5), ex);
524 @Messages({
"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
530 String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable();
533 LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC);
534 DateFormat datetimeFormat =
new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss", Locale.US);
537 List<CorrelationCase> cases = dbManager.
getCases();
539 LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate()));
541 if (caseDate.isBefore(earliestDate)) {
542 earliestDate = caseDate;
543 dateStringDisplay = aCase.getCreationDate();
549 LOGGER.log(Level.SEVERE,
"Error getting list of cases from database.", ex);
550 }
catch (ParseException ex) {
551 LOGGER.log(Level.SEVERE,
"Error parsing date of cases from database.", ex);
555 earliestCaseDate.setText(dateStringDisplay);
574 String caseUUID = openCase.
getName();
575 HashMap<UniquePathKey, OtherOccurrenceNodeInstanceData> nodeDataMap =
new HashMap<>();
588 if (!artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID)
589 || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName)
590 || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId)
591 || !artifactInstance.getFilePath().equalsIgnoreCase(file.getParentPath() + file.getName())) {
595 nodeDataMap.put(uniquePathKey, newNode);
600 List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase);
602 for (AbstractFile caseDbFile : caseDbFiles) {
603 addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
608 LOGGER.log(Level.SEVERE,
"Error getting artifact instances from database.", ex);
610 LOGGER.log(Level.INFO,
"Error getting artifact instances from database.", ex);
612 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
613 }
catch (TskCoreException ex) {
616 LOGGER.log(Level.SEVERE,
"Exception while querying open case.", ex);
619 return new HashMap<>(0);
636 String md5 = corAttr.getCorrelationValue();
637 SleuthkitCase tsk = openCase.getSleuthkitCase();
638 List<AbstractFile> matches = tsk.findAllFilesWhere(String.format(
"md5 = '%s'",
new Object[]{md5}));
640 List<AbstractFile> caseDbArtifactInstances =
new ArrayList<>();
641 for (AbstractFile fileMatch : matches) {
642 if (this.file.equals(fileMatch)) {
645 caseDbArtifactInstances.add(fileMatch);
647 return caseDbArtifactInstances;
663 OtherOccurrenceNodeInstanceData newNode =
new OtherOccurrenceNodeInstanceData(newFile, autopsyCase);
667 if (newNode.getKnown() != TskData.FileKnown.BAD) {
668 List<ContentTag> fileMatchTags = autopsyCase.getServices().getTagsManager().getContentTagsByContent(newFile);
669 for (ContentTag tag : fileMatchTags) {
670 TskData.FileKnown tagKnownStatus = tag.getName().getKnownStatus();
671 if (tagKnownStatus.equals(TskData.FileKnown.BAD)) {
672 newNode.updateKnown(TskData.FileKnown.BAD);
684 if (nodeDataMap.containsKey(uniquePathKey)) {
685 if (newNode.getKnown() == TskData.FileKnown.BAD) {
686 OtherOccurrenceNodeInstanceData prevInstance = nodeDataMap.get(uniquePathKey);
687 prevInstance.updateKnown(newNode.getKnown());
690 nodeDataMap.put(uniquePathKey, newNode);
701 this.file = this.getAbstractFileFromNode(node);
703 return !getCorrelationAttributesFromNode(node).isEmpty();
705 return this.file != null
706 && this.file.getSize() > 0
707 && ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
719 this.file = this.getAbstractFileFromNode(node);
731 "DataContentViewerOtherCases.dataSources.header.text=Data Source Name",
732 "DataContentViewerOtherCases.foundIn.text=Found %d instances in %d cases and %d data sources."
736 if (this.file != null) {
737 Content dataSource = this.file.getDataSource();
738 dataSourceName = dataSource.getName();
741 }
catch (TskException | NoCurrentCaseException ex) {
747 correlationAttributes.addAll(getCorrelationAttributesFromNode(node));
748 Map<String, CorrelationCase> caseNames =
new HashMap<>();
750 Set<String> dataSources =
new HashSet<>();
752 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
755 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
756 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
757 if (nodeData.isCentralRepoNode()) {
759 dataSources.add(makeDataSourceString(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getDeviceID(), nodeData.getDataSourceName()));
760 caseNames.put(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getCorrelationAttributeInstance().getCorrelationCase());
762 LOGGER.log(Level.WARNING,
"Unable to get correlation case for displaying other occurrence for case: " + nodeData.getCaseName(), ex);
768 }
catch (NoCurrentCaseException ex) {
769 LOGGER.log(Level.WARNING,
"No current case open for other occurrences", ex);
776 casesTableModel.addCorrelationCase(
new CorrelationCaseWrapper(corCase));
779 if (correlationAttributes.isEmpty()) {
780 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
781 }
else if (caseCount == 0) {
782 casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
784 setEarliestCaseDate();
785 foundInLabel.setText(String.format(Bundle.DataContentViewerOtherCases_foundIn_text(), totalCount, caseCount, dataSources.size()));
787 casesTable.setRowSelectionInterval(0, 0);
796 return caseUUID + deviceId + dataSourceName;
803 int[] selectedCaseIndexes = casesTable.getSelectedRows();
804 dataSourcesTableModel.clearTable();
805 filesTableModel.clearTable();
807 if (selectedCaseIndexes.length == 0) {
809 occurrencePanel =
new OccurrencePanel();
810 occurrencePanel.getPreferredSize();
811 detailsPanelScrollPane.setViewportView(occurrencePanel);
813 String currentCaseName;
816 }
catch (NoCurrentCaseException ex) {
817 currentCaseName = null;
818 LOGGER.log(Level.WARNING,
"Unable to get current case for other occurrences content viewer", ex);
821 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
824 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
825 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
826 for (
int selectedRow : selectedCaseIndexes) {
828 if (nodeData.isCentralRepoNode()) {
829 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
830 && casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
831 dataSourcesTableModel.addNodeData(nodeData);
833 }
else if (currentCaseName != null && (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(currentCaseName))) {
834 dataSourcesTableModel.addNodeData(nodeData);
837 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
842 if (dataSourcesTable.getRowCount() > 0) {
843 dataSourcesTable.setRowSelectionInterval(0, 0);
853 int[] selectedDataSources = dataSourcesTable.getSelectedRows();
854 filesTableModel.clearTable();
856 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
859 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
860 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
861 for (
int selectedDataSourceRow : selectedDataSources) {
863 if (nodeData.isCentralRepoNode()) {
864 if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
865 && dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
866 filesTableModel.addNodeData(nodeData);
869 if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
870 filesTableModel.addNodeData(nodeData);
874 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
879 if (filesTable.getRowCount() > 0) {
880 filesTable.setRowSelectionInterval(0, 0);
889 if (filesTable.getSelectedRowCount() == 1) {
891 occurrencePanel =
new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())));
892 }
else if (dataSourcesTable.getSelectedRowCount() == 1) {
894 String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
895 String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
896 String caseCreatedDate =
"";
897 for (
int row : casesTable.getSelectedRows()) {
898 if (casesTableModel.
getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
899 caseCreatedDate = getCaseCreatedDate(row);
903 occurrencePanel =
new OccurrencePanel(caseName, caseCreatedDate, dsName);
904 }
else if (casesTable.getSelectedRowCount() == 1) {
907 String createdDate =
"";
908 String caseName =
"";
909 if (casesTable.getRowCount() > 0) {
910 caseName = casesTableModel.
getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
912 if (caseName.isEmpty()) {
913 occurrencePanel =
new OccurrencePanel();
915 createdDate = getCaseCreatedDate(casesTable.getSelectedRow());
916 occurrencePanel =
new OccurrencePanel(caseName, createdDate);
920 occurrencePanel =
new OccurrencePanel();
923 occurrencePanel.getPreferredSize();
924 detailsPanelScrollPane.setViewportView(occurrencePanel);
939 partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
940 if (partialCase == null) {
948 LOGGER.log(Level.WARNING,
"Error getting case created date for row: " + caseTableRowIdx, ex);
958 @SuppressWarnings(
"unchecked")
960 private
void initComponents() {
961 java.awt.GridBagConstraints gridBagConstraints;
963 rightClickPopupMenu =
new javax.swing.JPopupMenu();
964 exportToCSVMenuItem =
new javax.swing.JMenuItem();
965 showCaseDetailsMenuItem =
new javax.swing.JMenuItem();
966 showCommonalityMenuItem =
new javax.swing.JMenuItem();
967 CSVFileChooser =
new javax.swing.JFileChooser();
968 tableContainerPanel =
new javax.swing.JPanel();
969 tablesViewerSplitPane =
new javax.swing.JSplitPane();
970 caseDatasourceFileSplitPane =
new javax.swing.JSplitPane();
971 caseDatasourceSplitPane =
new javax.swing.JSplitPane();
972 caseScrollPane =
new javax.swing.JScrollPane();
973 casesTable =
new javax.swing.JTable();
974 dataSourceScrollPane =
new javax.swing.JScrollPane();
975 dataSourcesTable =
new javax.swing.JTable();
976 filesTableScrollPane =
new javax.swing.JScrollPane();
977 filesTable =
new javax.swing.JTable();
978 detailsPanelScrollPane =
new javax.swing.JScrollPane();
979 jPanel1 =
new javax.swing.JPanel();
980 foundInLabel =
new javax.swing.JLabel();
981 earliestCaseDate =
new javax.swing.JLabel();
982 earliestCaseLabel =
new javax.swing.JLabel();
983 filler1 =
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 0),
new java.awt.Dimension(32767, 0));
985 rightClickPopupMenu.addPopupMenuListener(
new javax.swing.event.PopupMenuListener() {
986 public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
988 public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
990 public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
991 rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
995 org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.exportToCSVMenuItem.text"));
996 rightClickPopupMenu.add(exportToCSVMenuItem);
998 org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCaseDetailsMenuItem.text"));
999 rightClickPopupMenu.add(showCaseDetailsMenuItem);
1001 org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCommonalityMenuItem.text"));
1002 rightClickPopupMenu.add(showCommonalityMenuItem);
1004 setMinimumSize(
new java.awt.Dimension(1000, 10));
1006 setPreferredSize(
new java.awt.Dimension(1000, 63));
1008 tableContainerPanel.setPreferredSize(
new java.awt.Dimension(600, 63));
1009 tableContainerPanel.setRequestFocusEnabled(
false);
1011 tablesViewerSplitPane.setDividerLocation(450);
1012 tablesViewerSplitPane.setResizeWeight(0.75);
1014 caseDatasourceFileSplitPane.setDividerLocation(300);
1015 caseDatasourceFileSplitPane.setResizeWeight(0.66);
1016 caseDatasourceFileSplitPane.setToolTipText(
"");
1018 caseDatasourceSplitPane.setDividerLocation(150);
1019 caseDatasourceSplitPane.setResizeWeight(0.5);
1021 caseScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1023 casesTable.setAutoCreateRowSorter(
true);
1024 casesTable.setModel(casesTableModel);
1025 caseScrollPane.setViewportView(casesTable);
1027 caseDatasourceSplitPane.setLeftComponent(caseScrollPane);
1029 dataSourceScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1031 dataSourcesTable.setAutoCreateRowSorter(
true);
1032 dataSourcesTable.setModel(dataSourcesTableModel);
1033 dataSourceScrollPane.setViewportView(dataSourcesTable);
1035 caseDatasourceSplitPane.setRightComponent(dataSourceScrollPane);
1037 caseDatasourceFileSplitPane.setLeftComponent(caseDatasourceSplitPane);
1039 filesTableScrollPane.setPreferredSize(
new java.awt.Dimension(150, 30));
1041 filesTable.setAutoCreateRowSorter(
true);
1042 filesTable.setModel(filesTableModel);
1043 filesTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.table.toolTip.text"));
1044 filesTable.setComponentPopupMenu(rightClickPopupMenu);
1045 filesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
1046 filesTableScrollPane.setViewportView(filesTable);
1048 caseDatasourceFileSplitPane.setRightComponent(filesTableScrollPane);
1050 tablesViewerSplitPane.setLeftComponent(caseDatasourceFileSplitPane);
1052 detailsPanelScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
1053 detailsPanelScrollPane.setPreferredSize(
new java.awt.Dimension(300, 100));
1054 tablesViewerSplitPane.setRightComponent(detailsPanelScrollPane);
1056 jPanel1.setPreferredSize(
new java.awt.Dimension(576, 22));
1057 jPanel1.setLayout(
new java.awt.GridBagLayout());
1059 foundInLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
1060 org.openide.awt.Mnemonics.setLocalizedText(foundInLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.foundInLabel.text"));
1061 foundInLabel.setPreferredSize(
new java.awt.Dimension(400, 16));
1062 gridBagConstraints =
new java.awt.GridBagConstraints();
1063 gridBagConstraints.gridx = 3;
1064 gridBagConstraints.gridy = 0;
1065 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
1066 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
1067 gridBagConstraints.insets =
new java.awt.Insets(2, 2, 0, 0);
1068 jPanel1.add(foundInLabel, gridBagConstraints);
1070 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseDate.text"));
1071 earliestCaseDate.setMaximumSize(
new java.awt.Dimension(200, 16));
1072 gridBagConstraints =
new java.awt.GridBagConstraints();
1073 gridBagConstraints.gridx = 1;
1074 gridBagConstraints.gridy = 0;
1075 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
1076 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
1077 gridBagConstraints.insets =
new java.awt.Insets(0, 7, 0, 0);
1078 jPanel1.add(earliestCaseDate, gridBagConstraints);
1080 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.text"));
1081 earliestCaseLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.toolTipText"));
1082 earliestCaseLabel.setMaximumSize(
new java.awt.Dimension(260, 16));
1083 gridBagConstraints =
new java.awt.GridBagConstraints();
1084 gridBagConstraints.gridx = 0;
1085 gridBagConstraints.gridy = 0;
1086 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
1087 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
1088 jPanel1.add(earliestCaseLabel, gridBagConstraints);
1089 gridBagConstraints =
new java.awt.GridBagConstraints();
1090 gridBagConstraints.gridx = 2;
1091 gridBagConstraints.gridy = 0;
1092 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
1093 gridBagConstraints.weightx = 0.1;
1094 jPanel1.add(filler1, gridBagConstraints);
1096 javax.swing.GroupLayout tableContainerPanelLayout =
new javax.swing.GroupLayout(tableContainerPanel);
1097 tableContainerPanel.setLayout(tableContainerPanelLayout);
1098 tableContainerPanelLayout.setHorizontalGroup(
1099 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1100 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1101 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1102 .addComponent(tablesViewerSplitPane)
1103 .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
1106 tableContainerPanelLayout.setVerticalGroup(
1107 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1108 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1110 .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)
1111 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1112 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
1113 .addGap(12, 12, 12))
1116 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1117 this.setLayout(layout);
1118 layout.setHorizontalGroup(
1119 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1120 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1000, Short.MAX_VALUE)
1122 layout.setVerticalGroup(
1123 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1124 .addGroup(layout.createSequentialGroup()
1125 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE)
1131 boolean enableCentralRepoActions =
false;
1133 int rowIndex = filesTable.getSelectedRow();
1134 List<OtherOccurrenceNodeData> selectedFile = filesTableModel.getListOfNodesForFile(rowIndex);
1135 if (!selectedFile.isEmpty() && selectedFile.get(0) instanceof OtherOccurrenceNodeInstanceData) {
1136 OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) selectedFile.get(0);
1137 enableCentralRepoActions = instanceData.isCentralRepoNode();
1140 showCaseDetailsMenuItem.setVisible(enableCentralRepoActions);
1141 showCommonalityMenuItem.setVisible(enableCentralRepoActions);
1181 dataSourceID = nodeData.getDeviceID();
1182 if (nodeData.getFilePath() != null) {
1183 filePath = nodeData.getFilePath().toLowerCase();
1187 type = nodeData.getType();
1188 String tempCaseUUID;
1190 tempCaseUUID = nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID();
1196 }
catch (NoCurrentCaseException ex) {
1197 LOGGER.log(Level.WARNING,
"Unable to get current case", ex);
1198 tempCaseUUID = UUID_PLACEHOLDER_STRING;
1201 caseUUID = tempCaseUUID;
1207 UniquePathKey otherKey = (UniquePathKey) (other);
1208 return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
1209 && Objects.equals(otherKey.getFilePath(), this.getFilePath())
1210 && Objects.equals(otherKey.getType(), this.getType())
1211 && Objects.equals(otherKey.getCaseUUID(), this.getCaseUUID()));
1218 return Objects.hash(getDataSourceID(), getFilePath(), getType(), getCaseUUID());
1235 String getFilePath() {
1244 String getDataSourceID() {
1245 return dataSourceID;
1253 String getCaseUUID() {
Object getValueAt(int rowIdx, int colIdx)
final Collection< CorrelationAttributeInstance > correlationAttributes
void updateOnFileSelection()
void rightClickPopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt)
final OtherOccurrencesFilesTableModel filesTableModel
boolean equals(Object other)
List< CorrelationCase > getCases()
String makeDataSourceString(String caseUUID, String deviceId, String dataSourceName)
int isPreferred(Node node)
javax.swing.JLabel earliestCaseLabel
javax.swing.JMenuItem showCommonalityMenuItem
void updateOnDataSourceSelection()
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
javax.swing.JPanel tableContainerPanel
void setEarliestCaseDate()
javax.swing.JSplitPane caseDatasourceFileSplitPane
AbstractFile getAbstractFileFromNode(Node node)
CorrelationCase getCase(Case autopsyCase)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
CorrelationCase getCaseByUUID(String caseUUID)
javax.swing.JTable dataSourcesTable
Collection< CorrelationAttributeInstance > getCorrelationAttributesFromNode(Node node)
String getCorrelationValue()
final String dataSourceID
javax.swing.JScrollPane detailsPanelScrollPane
javax.swing.JSplitPane tablesViewerSplitPane
javax.swing.JScrollPane filesTableScrollPane
void writeOtherOccurrencesToFileAsCSV(File destFile)
List< CorrelationAttributeInstance.Type > getDefinedCorrelationTypes()
javax.swing.Box.Filler filler1
static List< CorrelationAttributeInstance > makeCorrAttrsForCorrelation(BlackboardArtifact artifact)
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()
boolean isSupported(Node node)
javax.swing.JPanel jPanel1
String getCaseDetailsOptionsPaneDialog()
void showCaseDetails(int selectedRowViewIdx)
javax.swing.JMenuItem exportToCSVMenuItem
SleuthkitCase getSleuthkitCase()
void addOrUpdateNodeData(final Case autopsyCase, Map< UniquePathKey, OtherOccurrenceNodeInstanceData > nodeDataMap, AbstractFile newFile)
void showCommonalityDetails()
OccurrencePanel occurrencePanel
DataContentViewerOtherCases()
int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
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 CentralRepository getInstance()
static boolean isCaseOpen()
javax.swing.JTable casesTable
final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel
static final int FILES_TYPE_ID
javax.swing.JMenuItem showCaseDetailsMenuItem
static boolean isEnabled()