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.io.BufferedWriter;
26 import java.io.IOException;
27 import java.nio.file.Files;
28 import java.text.DateFormat;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.ArrayList;
32 import java.util.Calendar;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Locale;
39 import java.util.Objects;
41 import java.util.logging.Level;
43 import javax.swing.JFileChooser;
44 import javax.swing.JMenuItem;
45 import javax.swing.JOptionPane;
46 import static javax.swing.JOptionPane.DEFAULT_OPTION;
47 import static javax.swing.JOptionPane.PLAIN_MESSAGE;
48 import static javax.swing.JOptionPane.ERROR_MESSAGE;
49 import javax.swing.JPanel;
50 import javax.swing.filechooser.FileNameExtensionFilter;
51 import javax.swing.table.DefaultTableModel;
52 import javax.swing.table.TableCellRenderer;
53 import javax.swing.table.TableColumn;
54 import javax.swing.table.TableModel;
55 import javax.swing.table.TableRowSorter;
56 import org.joda.time.DateTimeZone;
57 import org.joda.time.LocalDateTime;
58 import org.openide.nodes.Node;
59 import org.openide.util.NbBundle.Messages;
60 import org.openide.util.lookup.ServiceProvider;
84 @SuppressWarnings(
"PMD.SingularField")
85 @ServiceProvider(service = DataContentViewer.class, position = 9)
86 @Messages({
"DataContentViewerOtherCases.title=Other Occurrences",
87 "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",
88 "DataContentViewerOtherCases.table.noArtifacts=Item has no attributes with which to search.",
89 "DataContentViewerOtherCases.table.noResultsFound=No results found."})
92 private static final long serialVersionUID = -1L;
95 private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE =
new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts());
96 private static final CorrelationCaseWrapper NO_RESULTS_CASE =
new CorrelationCaseWrapper(Bundle.DataContentViewerOtherCases_table_noArtifacts());
97 private static final int DEFAULT_MIN_CELL_WIDTH = 15;
102 private String dataSourceName =
"";
103 private String deviceId =
"";
115 this.correlationAttributes =
new ArrayList<>();
118 customizeComponents();
123 ActionListener actList =
new ActionListener() {
125 public void actionPerformed(ActionEvent e) {
126 JMenuItem jmi = (JMenuItem) e.getSource();
127 if (jmi.equals(selectAllMenuItem)) {
128 filesTable.selectAll();
129 }
else if (jmi.equals(showCaseDetailsMenuItem)) {
130 showCaseDetails(filesTable.getSelectedRow());
131 }
else if (jmi.equals(exportToCSVMenuItem)) {
135 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
137 }
else if (jmi.equals(showCommonalityMenuItem)) {
138 showCommonalityDetails();
143 exportToCSVMenuItem.addActionListener(actList);
144 selectAllMenuItem.addActionListener(actList);
145 showCaseDetailsMenuItem.addActionListener(actList);
146 showCommonalityMenuItem.addActionListener(actList);
150 filesTable.setDefaultRenderer(Object.class, renderer);
153 TableRowSorter<TableModel> sorter =
new TableRowSorter<>(filesTable.getModel());
154 filesTable.setRowSorter(sorter);
155 casesTable.getSelectionModel().addListSelectionListener((e) -> {
157 updateOnCaseSelection();
160 dataSourcesTable.getSelectionModel().addListSelectionListener((e) -> {
162 updateOnDataSourceSelection();
165 casesTable.getRowSorter().toggleSortOrder(0);
166 dataSourcesTable.getRowSorter().toggleSortOrder(0);
169 @Messages({
"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
170 "# {0} - commonality percentage",
171 "# {1} - correlation type",
172 "# {2} - correlation value",
173 "DataContentViewerOtherCases.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
174 "DataContentViewerOtherCases.correlatedArtifacts.title=Attribute Frequency",
175 "DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get frequency details."})
181 if (correlationAttributes.isEmpty()) {
182 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
183 Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
184 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
185 DEFAULT_OPTION, PLAIN_MESSAGE);
187 StringBuilder msg =
new StringBuilder(correlationAttributes.size());
194 msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
195 eamArtifact.getCorrelationType().getDisplayName(),
196 eamArtifact.getCorrelationValue()));
198 LOGGER.log(Level.WARNING, String.format(
"Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
201 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
203 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
204 DEFAULT_OPTION, PLAIN_MESSAGE);
206 LOGGER.log(Level.SEVERE,
"Error getting commonality details.", ex);
207 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
208 Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
209 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
210 DEFAULT_OPTION, ERROR_MESSAGE);
215 @Messages({
"DataContentViewerOtherCases.caseDetailsDialog.notSelected=No Row Selected",
216 "DataContentViewerOtherCases.caseDetailsDialog.noDetails=No details for this case.",
217 "DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=No case details for Global reference properties.",
218 "DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=Error",
219 "DataContentViewerOtherCases.noOpenCase.errMsg=No open case available."})
222 String caseDisplayName = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noCaseNameError();
224 if (-1 != selectedRowViewIdx) {
226 int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
227 OtherOccurrenceNodeInstanceData nodeData = (OtherOccurrenceNodeInstanceData) tableModel.getRow(selectedRowModelIdx);
228 CorrelationCase eamCasePartial = nodeData.getCorrelationAttributeInstance().getCorrelationCase();
229 if (eamCasePartial == null) {
230 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
231 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference(),
233 DEFAULT_OPTION, PLAIN_MESSAGE);
239 if (eamCase == null) {
240 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
241 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
243 DEFAULT_OPTION, PLAIN_MESSAGE);
248 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
251 DEFAULT_OPTION, PLAIN_MESSAGE);
253 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
254 Bundle.DataContentViewerOtherCases_caseDetailsDialog_notSelected(),
256 DEFAULT_OPTION, PLAIN_MESSAGE);
259 LOGGER.log(Level.SEVERE,
"Error loading case details", ex);
260 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
261 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
263 DEFAULT_OPTION, PLAIN_MESSAGE);
268 if (0 != filesTable.getSelectedRowCount()) {
269 Calendar now = Calendar.getInstance();
270 String fileName = String.format(
"%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
272 CSVFileChooser.setSelectedFile(
new File(fileName));
273 CSVFileChooser.setFileFilter(
new FileNameExtensionFilter(
"csv file",
"csv"));
275 int returnVal = CSVFileChooser.showSaveDialog(filesTable);
276 if (returnVal == JFileChooser.APPROVE_OPTION) {
278 File selectedFile = CSVFileChooser.getSelectedFile();
279 if (!selectedFile.getName().endsWith(
".csv")) {
280 selectedFile =
new File(selectedFile.toString() +
".csv");
283 writeSelectedRowsToFileAsCSV(selectedFile);
289 StringBuilder content;
290 int[] selectedRowViewIndices = filesTable.getSelectedRows();
293 try (BufferedWriter writer = Files.newBufferedWriter(destFile.toPath())) {
296 content =
new StringBuilder(
"");
297 for (
int colIdx = 0; colIdx < colCount; colIdx++) {
298 content.append(
'"').append(tableModel.
getColumnName(colIdx)).append(
'"');
299 if (colIdx < (colCount - 1)) {
304 content.append(System.getProperty(
"line.separator"));
305 writer.write(content.toString());
308 for (
int rowViewIdx : selectedRowViewIndices) {
309 content =
new StringBuilder(
"");
310 for (
int colIdx = 0; colIdx < colCount; colIdx++) {
311 int rowModelIdx = filesTable.convertRowIndexToModel(rowViewIdx);
312 content.append(
'"').append(tableModel.
getValueAt(rowModelIdx, colIdx)).append(
'"');
313 if (colIdx < (colCount - 1)) {
317 content.append(System.getProperty(
"line.separator"));
318 writer.write(content.toString());
321 }
catch (IOException ex) {
322 LOGGER.log(Level.SEVERE,
"Error writing selected rows to CSV.", ex);
331 casesTableModel.clearTable();
332 ((DefaultTableModel) dataSourcesTable.getModel()).setRowCount(0);
333 tableModel.clearTable();
334 correlationAttributes.clear();
335 earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
336 foundInLabel.setText(
"");
341 return Bundle.DataContentViewerOtherCases_title();
346 return Bundle.DataContentViewerOtherCases_toolTip();
376 private BlackboardArtifact
378 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
380 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
383 if (nodeBbArtifactTag != null) {
384 return nodeBbArtifactTag.getArtifact();
385 }
else if (nodeBbArtifact != null) {
386 return nodeBbArtifact;
401 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class
403 ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class
405 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class
407 AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class
410 if (nodeBbArtifactTag != null) {
411 Content content = nodeBbArtifactTag.getContent();
412 if (content instanceof AbstractFile) {
413 return (AbstractFile) content;
415 }
else if (nodeContentTag != null) {
416 Content content = nodeContentTag.getContent();
417 if (content instanceof AbstractFile) {
418 return (AbstractFile) content;
420 }
else if (nodeBbArtifact != null) {
423 content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
424 }
catch (TskCoreException ex) {
425 LOGGER.log(Level.SEVERE,
"Error retrieving blackboard artifact", ex);
429 if (content instanceof AbstractFile) {
430 return (AbstractFile) content;
432 }
else if (nodeAbstractFile != null) {
433 return nodeAbstractFile;
448 Collection<CorrelationAttributeInstance> ret =
new ArrayList<>();
451 BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
457 if (this.file != null &&
EamDb.
isEnabled() && this.file.getSize() > 0) {
461 String md5 = this.file.getMd5Hash();
462 if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
472 file.getParentPath() + file.
getName(),
477 LOGGER.log(Level.INFO, String.format(
"Unable to check create CorrelationAttribtueInstance for value %s and type %s.", md5, aType.toString()), ex);
484 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
487 }
else if (this.file != null && this.file.getSize() > 0) {
488 String md5 = this.file.getMd5Hash();
489 if (md5 != null && !md5.isEmpty()) {
500 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
502 LOGGER.log(Level.INFO, String.format(
"Unable to create CorrelationAttributeInstance for value %s", md5), ex);
510 @Messages({
"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
516 String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable();
519 LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC);
520 DateFormat datetimeFormat =
new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss", Locale.US);
523 List<CorrelationCase> cases = dbManager.
getCases();
525 LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate()));
527 if (caseDate.isBefore(earliestDate)) {
528 earliestDate = caseDate;
529 dateStringDisplay = aCase.getCreationDate();
535 LOGGER.log(Level.SEVERE,
"Error getting list of cases from database.", ex);
536 }
catch (ParseException ex) {
537 LOGGER.log(Level.SEVERE,
"Error parsing date of cases from database.", ex);
541 earliestCaseDate.setText(dateStringDisplay);
560 String caseUUID = openCase.
getName();
562 HashMap<UniquePathKey, OtherOccurrenceNodeInstanceData> nodeDataMap =
new HashMap<>();
575 if (!artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID)
576 || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName)
577 || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId)
578 || !artifactInstance.getFilePath().equalsIgnoreCase(file.getParentPath() + file.getName())) {
582 nodeDataMap.put(uniquePathKey, newNode);
588 List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase);
590 for (AbstractFile caseDbFile : caseDbFiles) {
591 addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
597 LOGGER.log(Level.SEVERE,
"Error getting artifact instances from database.", ex);
599 LOGGER.log(Level.INFO,
"Error getting artifact instances from database.", ex);
601 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
602 }
catch (TskCoreException ex) {
605 LOGGER.log(Level.SEVERE,
"Exception while querying open case.", ex);
608 return new HashMap<>(0);
625 String md5 = corAttr.getCorrelationValue();
626 SleuthkitCase tsk = openCase.getSleuthkitCase();
627 List<AbstractFile> matches = tsk.findAllFilesWhere(String.format(
"md5 = '%s'",
new Object[]{md5}));
629 List<AbstractFile> caseDbArtifactInstances =
new ArrayList<>();
630 for (AbstractFile fileMatch : matches) {
631 if (this.file.equals(fileMatch)) {
634 caseDbArtifactInstances.add(fileMatch);
636 return caseDbArtifactInstances;
652 OtherOccurrenceNodeInstanceData newNode =
new OtherOccurrenceNodeInstanceData(newFile, autopsyCase);
656 if (newNode.getKnown() != TskData.FileKnown.BAD) {
657 List<ContentTag> fileMatchTags = autopsyCase.getServices().getTagsManager().getContentTagsByContent(newFile);
658 for (ContentTag tag : fileMatchTags) {
659 TskData.FileKnown tagKnownStatus = tag.getName().getKnownStatus();
660 if (tagKnownStatus.equals(TskData.FileKnown.BAD)) {
661 newNode.updateKnown(TskData.FileKnown.BAD);
673 if (nodeDataMap.containsKey(uniquePathKey)) {
674 if (newNode.getKnown() == TskData.FileKnown.BAD) {
675 OtherOccurrenceNodeInstanceData prevInstance = nodeDataMap.get(uniquePathKey);
676 prevInstance.updateKnown(newNode.getKnown());
679 nodeDataMap.put(uniquePathKey, newNode);
690 this.file = this.getAbstractFileFromNode(node);
692 return !getCorrelationAttributesFromNode(node).isEmpty();
694 return this.file != null
695 && this.file.getSize() > 0
696 && ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
708 this.file = this.getAbstractFileFromNode(node);
720 "DataContentViewerOtherCases.dataSources.header.text=Data Source Name",
721 "DataContentViewerOtherCases.foundIn.text=Found %d instances in %d cases and %d data sources."
725 if (this.file != null) {
726 Content dataSource = this.file.getDataSource();
727 dataSourceName = dataSource.getName();
730 }
catch (TskException | NoCurrentCaseException ex) {
736 correlationAttributes.addAll(getCorrelationAttributesFromNode(node));
737 Map<String, CorrelationCase> caseNames =
new HashMap<>();
739 Set<String> dataSources =
new HashSet<>();
741 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
744 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
745 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
746 if (nodeData.isCentralRepoNode()) {
748 dataSources.add(makeDataSourceString(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getDeviceID(), nodeData.getDataSourceName()));
749 caseNames.put(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID(), nodeData.getCorrelationAttributeInstance().getCorrelationCase());
751 LOGGER.log(Level.WARNING,
"Unable to get correlation case for displaying other occurrence for case: " + nodeData.getCaseName());
757 }
catch (NoCurrentCaseException ex) {
758 LOGGER.log(Level.WARNING,
"No current case open for other occurrences");
765 casesTableModel.addCorrelationCase(
new CorrelationCaseWrapper(corCase));
768 if (correlationAttributes.isEmpty()) {
769 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
770 }
else if (caseCount == 0) {
771 casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
774 setEarliestCaseDate();
775 foundInLabel.setText(String.format(Bundle.DataContentViewerOtherCases_foundIn_text(), totalCount, caseCount, dataSources.size()));
777 casesTable.setRowSelectionInterval(0, 0);
786 return caseUUID + deviceId + dataSourceName;
793 int[] selectedCaseIndexes = casesTable.getSelectedRows();
794 DefaultTableModel dataSourceModel = (DefaultTableModel) dataSourcesTable.getModel();
795 dataSourceModel.setRowCount(0);
796 tableModel.clearTable();
798 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
801 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
802 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
803 for (
int selectedRow : selectedCaseIndexes) {
805 if (nodeData.isCentralRepoNode()) {
806 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
807 && ((
CorrelationCase) casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow))).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
808 dataSourceModel.addRow(
new Object[]{nodeData.getDataSourceName(), nodeData.getDeviceID()});
811 dataSourceModel.addRow(
new Object[]{nodeData.getDataSourceName(), nodeData.getDeviceID()});
814 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName());
819 if (dataSourcesTable.getRowCount() > 0) {
820 dataSourcesTable.setRowSelectionInterval(0, 0);
829 int[] selectedCaseIndexes = casesTable.getSelectedRows();
830 DefaultTableModel dataSourceModel = (DefaultTableModel) dataSourcesTable.getModel();
831 int[] selectedDataSources = dataSourcesTable.getSelectedRows();
832 tableModel.clearTable();
834 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
837 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
838 for (OtherOccurrenceNodeInstanceData nodeData : correlatedNodeDataMap.values()) {
839 for (
int selectedCaseRow : selectedCaseIndexes) {
840 for (
int selectedDataSourceRow : selectedDataSources) {
842 if (nodeData.isCentralRepoNode()) {
843 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow)) != null
844 && ((
CorrelationCase) casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedCaseRow))).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
845 && dataSourceModel.getValueAt(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow), 1).toString().equals(nodeData.getDeviceID())) {
846 tableModel.addNodeData(nodeData);
849 if (dataSourceModel.getValueAt(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow), 1).toString().equals(nodeData.getDeviceID())) {
850 tableModel.addNodeData(nodeData);
854 LOGGER.log(Level.WARNING,
"Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName());
867 TableColumn column = filesTable.getColumnModel().getColumn(idx);
868 column.setMinWidth(DEFAULT_MIN_CELL_WIDTH);
870 if (columnWidth > 0) {
871 column.setPreferredWidth(columnWidth);
874 for (
int idx = 0; idx < dataSourcesTable.getColumnCount(); idx++) {
875 if (dataSourcesTable.getColumnModel().getColumn(idx).getHeaderValue().toString().equals(Bundle.DataContentViewerOtherCases_dataSources_header_text())) {
876 dataSourcesTable.getColumnModel().getColumn(idx).setPreferredWidth(100);
878 dataSourcesTable.getColumnModel().getColumn(idx).setPreferredWidth(210);
888 @SuppressWarnings(
"unchecked")
890 private
void initComponents() {
892 rightClickPopupMenu =
new javax.swing.JPopupMenu();
893 selectAllMenuItem =
new javax.swing.JMenuItem();
894 exportToCSVMenuItem =
new javax.swing.JMenuItem();
895 showCaseDetailsMenuItem =
new javax.swing.JMenuItem();
896 showCommonalityMenuItem =
new javax.swing.JMenuItem();
897 CSVFileChooser =
new javax.swing.JFileChooser();
898 otherCasesPanel =
new javax.swing.JPanel();
899 tableContainerPanel =
new javax.swing.JPanel();
900 earliestCaseLabel =
new javax.swing.JLabel();
901 earliestCaseDate =
new javax.swing.JLabel();
902 foundInLabel =
new javax.swing.JLabel();
903 jSplitPane2 =
new javax.swing.JSplitPane();
904 jSplitPane3 =
new javax.swing.JSplitPane();
905 caseScrollPane =
new javax.swing.JScrollPane();
906 casesTable =
new javax.swing.JTable();
907 dataSourceScrollPane =
new javax.swing.JScrollPane();
908 dataSourcesTable =
new javax.swing.JTable();
909 propertiesTableScrollPane =
new javax.swing.JScrollPane();
910 filesTable =
new javax.swing.JTable();
912 rightClickPopupMenu.addPopupMenuListener(
new javax.swing.event.PopupMenuListener() {
913 public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
915 public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
917 public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
918 rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
922 org.openide.awt.Mnemonics.setLocalizedText(selectAllMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.selectAllMenuItem.text"));
923 rightClickPopupMenu.add(selectAllMenuItem);
925 org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.exportToCSVMenuItem.text"));
926 rightClickPopupMenu.add(exportToCSVMenuItem);
928 org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCaseDetailsMenuItem.text"));
929 rightClickPopupMenu.add(showCaseDetailsMenuItem);
931 org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCommonalityMenuItem.text"));
932 rightClickPopupMenu.add(showCommonalityMenuItem);
934 setMinimumSize(
new java.awt.Dimension(1500, 10));
936 setPreferredSize(
new java.awt.Dimension(1500, 44));
938 otherCasesPanel.setPreferredSize(
new java.awt.Dimension(921, 62));
940 tableContainerPanel.setPreferredSize(
new java.awt.Dimension(1500, 63));
942 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.text"));
943 earliestCaseLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.toolTipText"));
945 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseDate.text"));
947 org.openide.awt.Mnemonics.setLocalizedText(foundInLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.foundInLabel.text"));
949 jSplitPane2.setDividerLocation(470);
951 jSplitPane3.setDividerLocation(150);
953 casesTable.setAutoCreateRowSorter(
true);
954 casesTable.setModel(casesTableModel);
955 caseScrollPane.setViewportView(casesTable);
957 jSplitPane3.setLeftComponent(caseScrollPane);
959 dataSourcesTable.setAutoCreateRowSorter(
true);
960 dataSourcesTable.setModel(
new javax.swing.table.DefaultTableModel(
965 "Data Source Name",
"Device ID"
968 boolean[] canEdit =
new boolean [] {
972 public boolean isCellEditable(
int rowIndex,
int columnIndex) {
973 return canEdit [columnIndex];
976 dataSourceScrollPane.setViewportView(dataSourcesTable);
978 jSplitPane3.setRightComponent(dataSourceScrollPane);
980 jSplitPane2.setLeftComponent(jSplitPane3);
982 propertiesTableScrollPane.setPreferredSize(
new java.awt.Dimension(1000, 30));
984 filesTable.setAutoCreateRowSorter(
true);
985 filesTable.setModel(tableModel);
986 filesTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.table.toolTip.text"));
987 filesTable.setComponentPopupMenu(rightClickPopupMenu);
988 filesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
989 propertiesTableScrollPane.setViewportView(filesTable);
991 jSplitPane2.setRightComponent(propertiesTableScrollPane);
993 javax.swing.GroupLayout tableContainerPanelLayout =
new javax.swing.GroupLayout(tableContainerPanel);
994 tableContainerPanel.setLayout(tableContainerPanelLayout);
995 tableContainerPanelLayout.setHorizontalGroup(
996 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
997 .addGroup(tableContainerPanelLayout.createSequentialGroup()
998 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
999 .addGroup(tableContainerPanelLayout.createSequentialGroup()
1000 .addComponent(earliestCaseLabel)
1001 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1002 .addComponent(earliestCaseDate)
1004 .addComponent(foundInLabel))
1005 .addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 911, Short.MAX_VALUE))
1008 tableContainerPanelLayout.setVerticalGroup(
1009 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1010 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
1011 .addComponent(jSplitPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 31, Short.MAX_VALUE)
1012 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
1013 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
1014 .addComponent(earliestCaseLabel)
1015 .addComponent(earliestCaseDate)
1016 .addComponent(foundInLabel))
1020 javax.swing.GroupLayout otherCasesPanelLayout =
new javax.swing.GroupLayout(otherCasesPanel);
1021 otherCasesPanel.setLayout(otherCasesPanelLayout);
1022 otherCasesPanelLayout.setHorizontalGroup(
1023 otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1024 .addGap(0, 921, Short.MAX_VALUE)
1025 .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1026 .addGroup(otherCasesPanelLayout.createSequentialGroup()
1027 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1030 otherCasesPanelLayout.setVerticalGroup(
1031 otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1032 .addGap(0, 62, Short.MAX_VALUE)
1033 .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1034 .addGroup(otherCasesPanelLayout.createSequentialGroup()
1035 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)
1039 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
1040 this.setLayout(layout);
1041 layout.setHorizontalGroup(
1042 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1043 .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1500, Short.MAX_VALUE)
1045 layout.setVerticalGroup(
1046 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
1047 .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
1052 boolean enableCentralRepoActions =
false;
1054 if (
EamDb.
isEnabled() && filesTable.getSelectedRowCount() == 1) {
1055 int rowIndex = filesTable.getSelectedRow();
1056 OtherOccurrenceNodeData selectedNode = (OtherOccurrenceNodeData) tableModel.getRow(rowIndex);
1057 if (selectedNode instanceof OtherOccurrenceNodeInstanceData) {
1058 OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) selectedNode;
1059 enableCentralRepoActions = instanceData.isCentralRepoNode();
1062 showCaseDetailsMenuItem.setVisible(enableCentralRepoActions);
1063 showCommonalityMenuItem.setVisible(enableCentralRepoActions);
1100 dataSourceID = nodeData.getDeviceID();
1101 if (nodeData.getFilePath() != null) {
1102 filePath = nodeData.getFilePath().toLowerCase();
1106 type = nodeData.getType();
1112 UniquePathKey otherKey = (UniquePathKey) (other);
1113 return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
1114 && Objects.equals(otherKey.getFilePath(), this.getFilePath())
1115 && Objects.equals(otherKey.getType(), this.getType()));
1125 return Objects.hash(getDataSourceID(), getFilePath(), getType());
1142 String getFilePath() {
1151 String getDataSourceID() {
1152 return dataSourceID;
void writeSelectedRowsToFileAsCSV(File destFile)
final Collection< CorrelationAttributeInstance > correlationAttributes
void rightClickPopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt)
static List< CorrelationAttributeInstance > makeInstancesFromBlackboardArtifact(BlackboardArtifact artifact, boolean checkEnabled)
CorrelationCase getCaseByUUID(String caseUUID)
int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
boolean equals(Object other)
String makeDataSourceString(String caseUUID, String deviceId, String dataSourceName)
int isPreferred(Node node)
javax.swing.JLabel earliestCaseLabel
javax.swing.JScrollPane propertiesTableScrollPane
javax.swing.JMenuItem selectAllMenuItem
javax.swing.JMenuItem showCommonalityMenuItem
void updateOnDataSourceSelection()
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
javax.swing.JPanel tableContainerPanel
void setEarliestCaseDate()
String getColumnName(int colIdx)
AbstractFile getAbstractFileFromNode(Node node)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
Object getValueAt(int rowIdx, int colIdx)
javax.swing.JTable dataSourcesTable
Collection< CorrelationAttributeInstance > getCorrelationAttributesFromNode(Node node)
String getCorrelationValue()
final String dataSourceID
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
List< CorrelationAttributeInstance.Type > getDefinedCorrelationTypes()
javax.swing.JPanel otherCasesPanel
final OtherOccurrencesFilesTableModel tableModel
Type getCorrelationType()
void populateTable(Node node)
javax.swing.JPopupMenu rightClickPopupMenu
int getColumnPreferredWidth(int colIdx)
javax.swing.JScrollPane dataSourceScrollPane
javax.swing.JScrollPane caseScrollPane
BlackboardArtifact getBlackboardArtifactFromNode(Node node)
void updateOnCaseSelection()
static EamDb getInstance()
javax.swing.JSplitPane jSplitPane2
boolean isSupported(Node node)
String getCaseDetailsOptionsPaneDialog()
javax.swing.JSplitPane jSplitPane3
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()
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)
static boolean isCaseOpen()
javax.swing.JTable casesTable
static final int FILES_TYPE_ID
javax.swing.JMenuItem showCaseDetailsMenuItem
List< CorrelationCase > getCases()