19 package org.sleuthkit.autopsy.centralrepository.contentviewer;
21 import java.awt.Component;
22 import java.awt.FontMetrics;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.io.BufferedWriter;
27 import java.io.IOException;
28 import java.nio.file.Files;
29 import java.text.DateFormat;
30 import java.text.ParseException;
31 import java.text.SimpleDateFormat;
32 import java.util.ArrayList;
33 import java.util.Calendar;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Locale;
39 import java.util.Objects;
40 import java.util.logging.Level;
42 import javax.swing.JFileChooser;
43 import javax.swing.JMenuItem;
44 import javax.swing.JOptionPane;
45 import static javax.swing.JOptionPane.DEFAULT_OPTION;
46 import static javax.swing.JOptionPane.PLAIN_MESSAGE;
47 import static javax.swing.JOptionPane.ERROR_MESSAGE;
48 import javax.swing.JPanel;
49 import javax.swing.filechooser.FileNameExtensionFilter;
50 import javax.swing.table.TableCellRenderer;
51 import javax.swing.table.TableColumn;
52 import org.joda.time.DateTimeZone;
53 import org.joda.time.LocalDateTime;
54 import org.openide.nodes.Node;
55 import org.openide.util.NbBundle.Messages;
56 import org.openide.util.lookup.ServiceProvider;
81 @SuppressWarnings(
"PMD.SingularField")
83 @Messages({
"DataContentViewerOtherCases.title=Other Occurrences",
84 "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",})
87 private static final long serialVersionUID = -1L;
91 private static final int DEFAULT_MIN_CELL_WIDTH = 15;
92 private static final int CELL_TEXT_WIDTH_PADDING = 5;
106 this.correlationAttributes =
new ArrayList<>();
109 customizeComponents();
114 ActionListener actList =
new ActionListener() {
116 public void actionPerformed(ActionEvent e) {
117 JMenuItem jmi = (JMenuItem) e.getSource();
118 if (jmi.equals(selectAllMenuItem)) {
119 otherCasesTable.selectAll();
120 }
else if (jmi.equals(showCaseDetailsMenuItem)) {
121 showCaseDetails(otherCasesTable.getSelectedRow());
122 }
else if (jmi.equals(exportToCSVMenuItem)) {
126 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
128 }
else if (jmi.equals(showCommonalityMenuItem)) {
129 showCommonalityDetails();
134 exportToCSVMenuItem.addActionListener(actList);
135 selectAllMenuItem.addActionListener(actList);
136 showCaseDetailsMenuItem.addActionListener(actList);
137 showCommonalityMenuItem.addActionListener(actList);
141 otherCasesTable.setDefaultRenderer(Object.class, renderer);
145 @Messages({
"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
146 "# {0} - commonality percentage",
147 "# {1} - correlation type",
148 "# {2} - correlation value",
149 "DataContentViewerOtherCases.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
150 "DataContentViewerOtherCases.correlatedArtifacts.title=Attribute Frequency",
151 "DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get frequency details."})
157 if (correlationAttributes.isEmpty()) {
158 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
159 Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
160 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
161 DEFAULT_OPTION, PLAIN_MESSAGE);
163 StringBuilder msg =
new StringBuilder(correlationAttributes.size());
170 msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
171 eamArtifact.getCorrelationType().getDisplayName(),
172 eamArtifact.getCorrelationValue()));
174 LOGGER.log(Level.WARNING, String.format(
"Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
177 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
179 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
180 DEFAULT_OPTION, PLAIN_MESSAGE);
182 LOGGER.log(Level.SEVERE,
"Error getting commonality details.", ex);
183 JOptionPane.showConfirmDialog(showCommonalityMenuItem,
184 Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
185 Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
186 DEFAULT_OPTION, ERROR_MESSAGE);
191 @Messages({
"DataContentViewerOtherCases.caseDetailsDialog.notSelected=No Row Selected",
192 "DataContentViewerOtherCases.caseDetailsDialog.noDetails=No details for this case.",
193 "DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=No case details for Global reference properties.",
194 "DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=Error",
195 "DataContentViewerOtherCases.noOpenCase.errMsg=No open case available."})
198 String caseDisplayName = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noCaseNameError();
200 if (-1 != selectedRowViewIdx) {
202 int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx);
203 OtherOccurrenceNodeInstanceData nodeData = (OtherOccurrenceNodeInstanceData) tableModel.getRow(selectedRowModelIdx);
204 CorrelationCase eamCasePartial = nodeData.getCorrelationAttributeInstance().getCorrelationCase();
205 if (eamCasePartial == null) {
206 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
207 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference(),
209 DEFAULT_OPTION, PLAIN_MESSAGE);
215 if (eamCase == null) {
216 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
217 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
219 DEFAULT_OPTION, PLAIN_MESSAGE);
224 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
227 DEFAULT_OPTION, PLAIN_MESSAGE);
229 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
230 Bundle.DataContentViewerOtherCases_caseDetailsDialog_notSelected(),
232 DEFAULT_OPTION, PLAIN_MESSAGE);
235 LOGGER.log(Level.SEVERE,
"Error loading case details", ex);
236 JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
237 Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
239 DEFAULT_OPTION, PLAIN_MESSAGE);
244 if (0 != otherCasesTable.getSelectedRowCount()) {
245 Calendar now = Calendar.getInstance();
246 String fileName = String.format(
"%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
248 CSVFileChooser.setSelectedFile(
new File(fileName));
249 CSVFileChooser.setFileFilter(
new FileNameExtensionFilter(
"csv file",
"csv"));
251 int returnVal = CSVFileChooser.showSaveDialog(otherCasesTable);
252 if (returnVal == JFileChooser.APPROVE_OPTION) {
254 File selectedFile = CSVFileChooser.getSelectedFile();
255 if (!selectedFile.getName().endsWith(
".csv")) {
256 selectedFile =
new File(selectedFile.toString() +
".csv");
259 writeSelectedRowsToFileAsCSV(selectedFile);
265 StringBuilder content;
266 int[] selectedRowViewIndices = otherCasesTable.getSelectedRows();
269 try (BufferedWriter writer = Files.newBufferedWriter(destFile.toPath())) {
272 content =
new StringBuilder(
"");
273 for (
int colIdx = 0; colIdx < colCount; colIdx++) {
274 content.append(
'"').append(tableModel.
getColumnName(colIdx)).append(
'"');
275 if (colIdx < (colCount - 1)) {
280 content.append(System.getProperty(
"line.separator"));
281 writer.write(content.toString());
284 for (
int rowViewIdx : selectedRowViewIndices) {
285 content =
new StringBuilder(
"");
286 for (
int colIdx = 0; colIdx < colCount; colIdx++) {
287 int rowModelIdx = otherCasesTable.convertRowIndexToModel(rowViewIdx);
288 content.append(
'"').append(tableModel.
getValueAt(rowModelIdx, colIdx)).append(
'"');
289 if (colIdx < (colCount - 1)) {
293 content.append(System.getProperty(
"line.separator"));
294 writer.write(content.toString());
297 }
catch (IOException ex) {
298 LOGGER.log(Level.SEVERE,
"Error writing selected rows to CSV.", ex);
307 tableModel.clearTable();
308 correlationAttributes.clear();
309 earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
314 return Bundle.DataContentViewerOtherCases_title();
319 return Bundle.DataContentViewerOtherCases_toolTip();
350 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class);
351 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class);
353 if (nodeBbArtifactTag != null) {
354 return nodeBbArtifactTag.getArtifact();
355 }
else if (nodeBbArtifact != null) {
356 return nodeBbArtifact;
370 BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class);
371 ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class);
372 BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class);
373 AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class);
375 if (nodeBbArtifactTag != null) {
376 Content content = nodeBbArtifactTag.getContent();
377 if (content instanceof AbstractFile) {
378 return (AbstractFile) content;
380 }
else if (nodeContentTag != null) {
381 Content content = nodeContentTag.getContent();
382 if (content instanceof AbstractFile) {
383 return (AbstractFile) content;
385 }
else if (nodeBbArtifact != null) {
388 content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
389 }
catch (TskCoreException ex) {
390 LOGGER.log(Level.SEVERE,
"Error retrieving blackboard artifact", ex);
394 if (content instanceof AbstractFile) {
395 return (AbstractFile) content;
397 }
else if (nodeAbstractFile != null) {
398 return nodeAbstractFile;
413 Collection<CorrelationAttributeInstance> ret =
new ArrayList<>();
416 BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
426 String md5 = this.file.getMd5Hash();
427 if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
437 file.getParentPath() + file.
getName(),
441 LOGGER.log(Level.INFO, String.format(
"Unable to check create CorrelationAttribtueInstance for value %s and type %s.", md5, aType.toString()), ex);
448 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
454 if (this.file != null) {
455 String md5 = this.file.getMd5Hash();
456 if (md5 != null && !md5.isEmpty()) {
467 LOGGER.log(Level.SEVERE,
"Error connecting to DB", ex);
469 LOGGER.log(Level.INFO, String.format(
"Unable to create CorrelationAttributeInstance for value %s", md5), ex);
478 @Messages({
"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
484 String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable();
487 LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC);
488 DateFormat datetimeFormat =
new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss", Locale.US);
491 List<CorrelationCase> cases = dbManager.
getCases();
493 LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate()));
495 if (caseDate.isBefore(earliestDate)) {
496 earliestDate = caseDate;
497 dateStringDisplay = aCase.getCreationDate();
503 LOGGER.log(Level.SEVERE,
"Error getting list of cases from database.", ex);
504 }
catch (ParseException ex) {
505 LOGGER.log(Level.SEVERE,
"Error parsing date of cases from database.", ex);
509 earliestCaseDate.setText(dateStringDisplay);
528 String caseUUID = openCase.
getName();
530 HashMap<UniquePathKey, OtherOccurrenceNodeInstanceData> nodeDataMap =
new HashMap<>();
543 if (!artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID)
544 || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName)
545 || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId)
546 || !artifactInstance.getFilePath().equalsIgnoreCase(file.getParentPath() + file.getName())) {
550 nodeDataMap.put(uniquePathKey, newNode);
556 List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase);
558 for (AbstractFile caseDbFile : caseDbFiles) {
559 addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
565 LOGGER.log(Level.SEVERE,
"Error getting artifact instances from database.", ex);
567 LOGGER.log(Level.INFO,
"Error getting artifact instances from database.", ex);
569 LOGGER.log(Level.SEVERE,
"Exception while getting open case.", ex);
570 }
catch (TskCoreException ex) {
573 LOGGER.log(Level.SEVERE,
"Exception while querying open case.", ex);
576 return new HashMap<>(0);
593 String md5 = corAttr.getCorrelationValue();
594 SleuthkitCase tsk = openCase.getSleuthkitCase();
595 List<AbstractFile> matches = tsk.findAllFilesWhere(String.format(
"md5 = '%s'",
new Object[]{md5}));
597 List<AbstractFile> caseDbArtifactInstances =
new ArrayList<>();
598 for (AbstractFile fileMatch : matches) {
599 if (this.file.equals(fileMatch)) {
602 caseDbArtifactInstances.add(fileMatch);
604 return caseDbArtifactInstances;
620 OtherOccurrenceNodeInstanceData newNode =
new OtherOccurrenceNodeInstanceData(newFile, autopsyCase);
624 if (newNode.getKnown() != TskData.FileKnown.BAD) {
625 List<ContentTag> fileMatchTags = autopsyCase.getServices().getTagsManager().getContentTagsByContent(newFile);
626 for (ContentTag tag : fileMatchTags) {
627 TskData.FileKnown tagKnownStatus = tag.getName().getKnownStatus();
628 if (tagKnownStatus.equals(TskData.FileKnown.BAD)) {
629 newNode.updateKnown(TskData.FileKnown.BAD);
641 if (nodeDataMap.containsKey(uniquePathKey)) {
642 if (newNode.getKnown() == TskData.FileKnown.BAD) {
643 OtherOccurrenceNodeInstanceData prevInstance = nodeDataMap.get(uniquePathKey);
644 prevInstance.updateKnown(newNode.getKnown());
647 nodeDataMap.put(uniquePathKey, newNode);
658 this.file = this.getAbstractFileFromNode(node);
660 return this.file != null
661 && this.file.getSize() > 0
662 && !getCorrelationAttributesFromNode(node).isEmpty();
664 return this.file != null
665 && this.file.getSize() > 0
666 && ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
671 @Messages({
"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to central repository database."})
679 this.file = this.getAbstractFileFromNode(node);
690 "DataContentViewerOtherCases.table.noArtifacts=Item has no attributes with which to search.",
691 "DataContentViewerOtherCases.table.noResultsFound=No results found."
694 String dataSourceName =
"";
695 String deviceId =
"";
697 if (this.file != null) {
698 Content dataSource = this.file.getDataSource();
699 dataSourceName = dataSource.getName();
702 }
catch (TskException | NoCurrentCaseException ex) {
708 correlationAttributes.addAll(getCorrelationAttributesFromNode(node));
710 Map<UniquePathKey, OtherOccurrenceNodeInstanceData> correlatedNodeDataMap =
new HashMap<>(0);
713 correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
715 correlatedNodeDataMap.values().forEach((nodeData) -> {
716 tableModel.addNodeData(nodeData);
720 if (correlationAttributes.isEmpty()) {
721 tableModel.addNodeData(
new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noArtifacts()));
722 setColumnWidthToText(0, Bundle.DataContentViewerOtherCases_table_noArtifacts());
724 tableModel.addNodeData(
new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noResultsFound()));
725 setColumnWidthToText(0, Bundle.DataContentViewerOtherCases_table_noResultsFound());
729 setEarliestCaseDate();
740 TableColumn column = otherCasesTable.getColumnModel().getColumn(columnIndex);
741 FontMetrics fontMetrics = otherCasesTable.getFontMetrics(otherCasesTable.getFont());
742 int stringWidth = fontMetrics.stringWidth(text);
743 column.setMinWidth(stringWidth + CELL_TEXT_WIDTH_PADDING);
751 TableColumn column = otherCasesTable.getColumnModel().getColumn(idx);
752 column.setMinWidth(DEFAULT_MIN_CELL_WIDTH);
754 if (columnWidth > 0) {
755 column.setPreferredWidth(columnWidth);
765 @SuppressWarnings(
"unchecked")
767 private
void initComponents() {
769 rightClickPopupMenu =
new javax.swing.JPopupMenu();
770 selectAllMenuItem =
new javax.swing.JMenuItem();
771 exportToCSVMenuItem =
new javax.swing.JMenuItem();
772 showCaseDetailsMenuItem =
new javax.swing.JMenuItem();
773 showCommonalityMenuItem =
new javax.swing.JMenuItem();
774 CSVFileChooser =
new javax.swing.JFileChooser();
775 otherCasesPanel =
new javax.swing.JPanel();
776 tableContainerPanel =
new javax.swing.JPanel();
777 tableScrollPane =
new javax.swing.JScrollPane();
778 otherCasesTable =
new javax.swing.JTable();
779 earliestCaseLabel =
new javax.swing.JLabel();
780 earliestCaseDate =
new javax.swing.JLabel();
781 tableStatusPanel =
new javax.swing.JPanel();
783 rightClickPopupMenu.addPopupMenuListener(
new javax.swing.event.PopupMenuListener() {
784 public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
786 public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
788 public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
789 rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
793 org.openide.awt.Mnemonics.setLocalizedText(selectAllMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.selectAllMenuItem.text"));
794 rightClickPopupMenu.add(selectAllMenuItem);
796 org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.exportToCSVMenuItem.text"));
797 rightClickPopupMenu.add(exportToCSVMenuItem);
799 org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCaseDetailsMenuItem.text"));
800 rightClickPopupMenu.add(showCaseDetailsMenuItem);
802 org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.showCommonalityMenuItem.text"));
803 rightClickPopupMenu.add(showCommonalityMenuItem);
805 setMinimumSize(
new java.awt.Dimension(1500, 10));
807 setPreferredSize(
new java.awt.Dimension(1500, 44));
809 otherCasesPanel.setPreferredSize(
new java.awt.Dimension(1500, 144));
811 tableContainerPanel.setPreferredSize(
new java.awt.Dimension(1500, 63));
813 tableScrollPane.setPreferredSize(
new java.awt.Dimension(1500, 30));
815 otherCasesTable.setAutoCreateRowSorter(
true);
816 otherCasesTable.setModel(tableModel);
817 otherCasesTable.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.table.toolTip.text"));
818 otherCasesTable.setComponentPopupMenu(rightClickPopupMenu);
819 otherCasesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
820 tableScrollPane.setViewportView(otherCasesTable);
822 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.text"));
823 earliestCaseLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseLabel.toolTipText"));
825 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate,
org.openide.util.NbBundle.getMessage(
DataContentViewerOtherCases.class,
"DataContentViewerOtherCases.earliestCaseDate.text"));
827 tableStatusPanel.setPreferredSize(
new java.awt.Dimension(1500, 16));
829 javax.swing.GroupLayout tableStatusPanelLayout =
new javax.swing.GroupLayout(tableStatusPanel);
830 tableStatusPanel.setLayout(tableStatusPanelLayout);
831 tableStatusPanelLayout.setHorizontalGroup(
832 tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
833 .addGap(0, 0, Short.MAX_VALUE)
835 tableStatusPanelLayout.setVerticalGroup(
836 tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
837 .addGap(0, 16, Short.MAX_VALUE)
840 javax.swing.GroupLayout tableContainerPanelLayout =
new javax.swing.GroupLayout(tableContainerPanel);
841 tableContainerPanel.setLayout(tableContainerPanelLayout);
842 tableContainerPanelLayout.setHorizontalGroup(
843 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
844 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
845 .addComponent(tableStatusPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1282, Short.MAX_VALUE)
846 .addGap(218, 218, 218))
847 .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
848 .addGroup(tableContainerPanelLayout.createSequentialGroup()
849 .addComponent(earliestCaseLabel)
850 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
851 .addComponent(earliestCaseDate)
852 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
854 tableContainerPanelLayout.setVerticalGroup(
855 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
856 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
857 .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
859 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
860 .addComponent(earliestCaseLabel)
861 .addComponent(earliestCaseDate))
863 .addComponent(tableStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
867 javax.swing.GroupLayout otherCasesPanelLayout =
new javax.swing.GroupLayout(otherCasesPanel);
868 otherCasesPanel.setLayout(otherCasesPanelLayout);
869 otherCasesPanelLayout.setHorizontalGroup(
870 otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
871 .addGap(0, 1500, Short.MAX_VALUE)
872 .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
873 .addComponent(tableContainerPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
875 otherCasesPanelLayout.setVerticalGroup(
876 otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
877 .addGap(0, 483, Short.MAX_VALUE)
878 .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
879 .addGroup(otherCasesPanelLayout.createSequentialGroup()
880 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE)
884 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
885 this.setLayout(layout);
886 layout.setHorizontalGroup(
887 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
888 .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
890 layout.setVerticalGroup(
891 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
892 .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE)
897 boolean enableCentralRepoActions =
false;
900 int rowIndex = otherCasesTable.getSelectedRow();
901 OtherOccurrenceNodeData selectedNode = (OtherOccurrenceNodeData) tableModel.getRow(rowIndex);
902 if (selectedNode instanceof OtherOccurrenceNodeInstanceData) {
903 OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) selectedNode;
904 enableCentralRepoActions = instanceData.isCentralRepoNode();
907 showCaseDetailsMenuItem.setVisible(enableCentralRepoActions);
908 showCommonalityMenuItem.setVisible(enableCentralRepoActions);
939 dataSourceID = nodeData.getDeviceID();
940 if (nodeData.getFilePath() != null) {
941 filePath = nodeData.getFilePath().toLowerCase();
945 type = nodeData.getType();
951 UniquePathKey otherKey = (UniquePathKey) (other);
952 return (Objects.equals(otherKey.getDataSourceID(), this.getDataSourceID())
953 && Objects.equals(otherKey.getFilePath(), this.getFilePath())
954 && Objects.equals(otherKey.getType(), this.getType()));
964 return Objects.hash(getDataSourceID(), getFilePath(), getType());
981 String getFilePath() {
990 String getDataSourceID() {
void writeSelectedRowsToFileAsCSV(File destFile)
final Collection< CorrelationAttributeInstance > correlationAttributes
void rightClickPopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt)
final DataContentViewerOtherCasesTableModel tableModel
CorrelationCase getCaseByUUID(String caseUUID)
javax.swing.JScrollPane tableScrollPane
int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
boolean equals(Object other)
int isPreferred(Node node)
javax.swing.JLabel earliestCaseLabel
javax.swing.JMenuItem selectAllMenuItem
javax.swing.JMenuItem showCommonalityMenuItem
void setColumnWidthToText(int columnIndex, String text)
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
static boolean useCentralRepo()
javax.swing.JPanel tableContainerPanel
void setEarliestCaseDate()
AbstractFile getAbstractFileFromNode(Node node)
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
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
static List< CorrelationAttributeInstance > makeInstancesFromBlackboardArtifact(BlackboardArtifact bbArtifact, boolean checkEnabled)
Type getCorrelationType()
void populateTable(Node node)
javax.swing.JPopupMenu rightClickPopupMenu
BlackboardArtifact getBlackboardArtifactFromNode(Node node)
static EamDb getInstance()
boolean isSupported(Node node)
int getColumnPreferredWidth(int colIdx)
String getCaseDetailsOptionsPaneDialog()
javax.swing.JTable otherCasesTable
void showCaseDetails(int selectedRowViewIdx)
String getColumnName(int colIdx)
javax.swing.JMenuItem exportToCSVMenuItem
static boolean isEnabled()
SleuthkitCase getSleuthkitCase()
void addOrUpdateNodeData(final Case autopsyCase, Map< UniquePathKey, OtherOccurrenceNodeInstanceData > nodeDataMap, AbstractFile newFile)
void showCommonalityDetails()
Object getValueAt(int rowIdx, int colIdx)
DataContentViewerOtherCases()
javax.swing.JPanel tableStatusPanel
CorrelationCase getCase(Case autopsyCase)
javax.swing.JFileChooser CSVFileChooser
javax.swing.JLabel earliestCaseDate
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
String getExportDirectory()
DataContentViewer createInstance()
void customizeComponents()
List< AbstractFile > getCaseDbMatches(CorrelationAttributeInstance corAttr, Case openCase)
Map< UniquePathKey, OtherOccurrenceNodeInstanceData > getCorrelatedInstances(CorrelationAttributeInstance corAttr, String dataSourceName, String deviceId)
static final int FILES_TYPE_ID
javax.swing.JMenuItem showCaseDetailsMenuItem
List< CorrelationCase > getCases()