Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
OtherOccurrencesPanel.java
Go to the documentation of this file.
1/*
2 * Central Repository
3 *
4 * Copyright 2017-2021 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.centralrepository.contentviewer;
20
21import com.google.common.util.concurrent.ThreadFactoryBuilder;
22import org.sleuthkit.autopsy.centralrepository.application.NodeData;
23import org.sleuthkit.autopsy.centralrepository.application.UniquePathKey;
24import org.sleuthkit.autopsy.centralrepository.application.OtherOccurrences;
25import java.awt.Cursor;
26import java.awt.event.ActionEvent;
27import java.awt.event.ActionListener;
28import java.awt.event.ComponentAdapter;
29import java.awt.event.ComponentEvent;
30import java.io.File;
31import java.util.ArrayList;
32import java.util.Calendar;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.HashMap;
36import java.util.List;
37import java.util.Map;
38import java.util.concurrent.ExecutionException;
39import java.util.concurrent.ExecutorService;
40import java.util.concurrent.Executors;
41import java.util.concurrent.FutureTask;
42import java.util.logging.Level;
43import javax.swing.JFileChooser;
44import javax.swing.JMenuItem;
45import javax.swing.JOptionPane;
46import static javax.swing.JOptionPane.DEFAULT_OPTION;
47import static javax.swing.JOptionPane.ERROR_MESSAGE;
48import static javax.swing.JOptionPane.PLAIN_MESSAGE;
49import javax.swing.SwingWorker;
50import javax.swing.filechooser.FileNameExtensionFilter;
51import javax.swing.table.TableModel;
52import javax.swing.table.TableRowSorter;
53import org.openide.util.NbBundle;
54import org.sleuthkit.autopsy.casemodule.Case;
55import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
56import org.sleuthkit.autopsy.centralrepository.contentviewer.OtherOccurrencesNodeWorker.OtherOccurrencesData;
57import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
58import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
59import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
60import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
61import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
62import org.sleuthkit.autopsy.coreutils.Logger;
63import org.sleuthkit.datamodel.AbstractFile;
64
68@NbBundle.Messages({
69 "OtherOccurrencesPanel.table.noArtifacts=Item has no attributes with which to search.",
70 "OtherOccurrencesPanel.table.noResultsFound=No results found.",
71 "OtherOccurrencesPanel_table_loadingResults=Loading results"
72})
73public final class OtherOccurrencesPanel extends javax.swing.JPanel {
74
75 private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noArtifacts());
76 private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noResultsFound());
77 private static final Logger logger = Logger.getLogger(OtherOccurrencesPanel.class.getName());
78 private static final long serialVersionUID = 1L;
81 private final OtherOccurrencesDataSourcesTableModel dataSourcesTableModel;
82 private OccurrencePanel occurrencePanel;
83 private final Collection<CorrelationAttributeInstance> correlationAttributes;
84 private String dataSourceName = ""; //the data source of the file which the content viewer is being populated for
85 private String deviceId = ""; //the device id of the data source for the file which the content viewer is being populated for
86 private AbstractFile file = null;
87
88 private SwingWorker<?, ?> worker;
89
90 // Initializing the JFileChooser in a thread to prevent a block on the EDT
91 // see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
92 private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
93 private JFileChooser CSVFileChooser;
94
99 this.filesTableModel = new OtherOccurrencesFilesTableModel();
100 this.casesTableModel = new OtherOccurrencesCasesTableModel();
101 this.dataSourcesTableModel = new OtherOccurrencesDataSourcesTableModel();
102 this.correlationAttributes = new ArrayList<>();
105
106 ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("JFileChooser-background-thread-OtherOccurrencesPanel").build());
107 executor.execute(futureFileChooser);
108 }
109
110 private void customizeComponents() {
111 ActionListener actList = (ActionEvent e) -> {
112 JMenuItem jmi = (JMenuItem) e.getSource();
113 if (jmi.equals(showCaseDetailsMenuItem)) {
114 showCaseDetails(filesTable.getSelectedRow());
115 } else if (jmi.equals(exportToCSVMenuItem)) {
116 try {
117 saveToCSV();
118 } catch (NoCurrentCaseException ex) {
119 logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
120 }
121 } else if (jmi.equals(showCommonalityMenuItem)) {
123 }
124 };
125
126 exportToCSVMenuItem.addActionListener(actList);
127 showCaseDetailsMenuItem.addActionListener(actList);
128 showCommonalityMenuItem.addActionListener(actList);
129 filesTable.setComponentPopupMenu(rightClickPopupMenu);
130 // Configure column sorting.
131 TableRowSorter<TableModel> sorter = new TableRowSorter<>(filesTable.getModel());
132 filesTable.setRowSorter(sorter);
133
134 //sort tables alphabetically initially
135 casesTable.getRowSorter().toggleSortOrder(0);
136 dataSourcesTable.getRowSorter().toggleSortOrder(0);
137 filesTable.getRowSorter().toggleSortOrder(0);
138 reset();
139 casesTable.getSelectionModel().addListSelectionListener((e) -> {
140 if (Case.isCaseOpen()) {
142 }
143 });
144 dataSourcesTable.getSelectionModel().addListSelectionListener((e) -> {
145 if (Case.isCaseOpen()) {
147 }
148 });
149
150 //alows resizing of the 4th section
151 filesTable.getSelectionModel().addListSelectionListener((e) -> {
152 if (Case.isCaseOpen()) {
153 occurrencePanel = new OccurrencePanel();
155 }
156 });
157 detailsPanelScrollPane.addComponentListener(new ComponentAdapter() {
158 @Override
159 public void componentResized(ComponentEvent componentEvent) {
160 //when its resized make sure the width of the panel resizes to match the scroll pane width to avoid a horizontal scroll bar
161 occurrencePanel.setPreferredSize(new java.awt.Dimension(detailsPanelScrollPane.getPreferredSize().width, occurrencePanel.getPreferredSize().height));
163 }
164 });
165
166 }
167
168 @NbBundle.Messages({"OtherOccurrencesPanel.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
169 "# {0} - commonality percentage",
170 "# {1} - correlation type",
171 "# {2} - correlation value",
172 "OtherOccurrencesPanel.correlatedArtifacts.byType={0}% of data sources have {2} (type: {1})\n",
173 "OtherOccurrencesPanel.correlatedArtifacts.title=Attribute Frequency",
174 "OtherOccurrencesPanel.correlatedArtifacts.failed=Failed to get frequency details."})
179 private void showCommonalityDetails() {
180 if (correlationAttributes.isEmpty()) {
181 JOptionPane.showConfirmDialog(OtherOccurrencesPanel.this,
182 Bundle.OtherOccurrencesPanel_correlatedArtifacts_isEmpty(),
183 Bundle.OtherOccurrencesPanel_correlatedArtifacts_title(),
184 DEFAULT_OPTION, PLAIN_MESSAGE);
185 } else {
186 StringBuilder msg = new StringBuilder(correlationAttributes.size());
187 int percentage;
188 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
189 try {
190 // Leaving these calls on the EDT but adding wait cursor
193 try {
194 percentage = dbManager.getFrequencyPercentage(eamArtifact);
195 msg.append(Bundle.OtherOccurrencesPanel_correlatedArtifacts_byType(percentage,
196 eamArtifact.getCorrelationType().getDisplayName(),
197 eamArtifact.getCorrelationValue()));
199 logger.log(Level.WARNING, String.format("Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
200 }
201 }
202 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
203 JOptionPane.showConfirmDialog(OtherOccurrencesPanel.this,
204 msg.toString(),
205 Bundle.OtherOccurrencesPanel_correlatedArtifacts_title(),
206 DEFAULT_OPTION, PLAIN_MESSAGE);
207 } catch (CentralRepoException ex) {
208 this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
209 logger.log(Level.SEVERE, "Error getting commonality details.", ex);
210 JOptionPane.showConfirmDialog(OtherOccurrencesPanel.this,
211 Bundle.OtherOccurrencesPanel_correlatedArtifacts_failed(),
212 Bundle.OtherOccurrencesPanel_correlatedArtifacts_title(),
213 DEFAULT_OPTION, ERROR_MESSAGE);
214 }
215 }
216 }
217
218 @NbBundle.Messages({"OtherOccurrencesPanel.caseDetailsDialog.notSelected=No Row Selected",
219 "OtherOccurrencesPanel.caseDetailsDialog.noDetails=No details for this case.",
220 "OtherOccurrencesPanel.caseDetailsDialog.noDetailsReference=No case details for Global reference properties.",
221 "OtherOccurrencesPanel.caseDetailsDialog.noCaseNameError=Error",
222 "OtherOccurrencesPanel.noOpenCase.errMsg=No open case available."})
223 private void showCaseDetails(int selectedRowViewIdx) {
224 String caseDisplayName = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noCaseNameError();
225 String details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails();
226 try {
227 if (-1 != selectedRowViewIdx && filesTableModel.getRowCount() > 0) {
229 int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
230 List<NodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
231 if (!rowList.isEmpty()) {
232 CorrelationCase eamCasePartial = rowList.get(0).getCorrelationAttributeInstance().getCorrelationCase();
233 caseDisplayName = eamCasePartial.getDisplayName();
234 // query case details
235 CorrelationCase eamCase = dbManager.getCaseByUUID(eamCasePartial.getCaseUUID());
236 if (eamCase != null) {
237 details = eamCase.getCaseDetailsOptionsPaneDialog();
238 } else {
239 details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails();
240 }
241 } else {
242 details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetailsReference();
243 }
244 }
245 } catch (CentralRepoException ex) {
246 logger.log(Level.SEVERE, "Error loading case details", ex);
247 } finally {
248 JOptionPane.showConfirmDialog(OtherOccurrencesPanel.this,
249 details,
250 caseDisplayName,
251 DEFAULT_OPTION, PLAIN_MESSAGE);
252 }
253 }
254
255 private void saveToCSV() throws NoCurrentCaseException {
256 if (casesTableModel.getRowCount() > 0) {
257
258 if (CSVFileChooser == null) {
259 try {
261 } catch (InterruptedException | ExecutionException ex) {
262 // If something happened with the thread try and
263 // initalized the chooser now
264 logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread");
265 CSVFileChooser = new JFileChooser();
266 }
267 }
268
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);
271 CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory()));
272 CSVFileChooser.setSelectedFile(new File(fileName));
273 CSVFileChooser.setFileFilter(new FileNameExtensionFilter("csv file", "csv"));
274
275 int returnVal = CSVFileChooser.showSaveDialog(filesTable);
276 if (returnVal == JFileChooser.APPROVE_OPTION) {
277
278 File selectedFile = CSVFileChooser.getSelectedFile();
279 if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
280 selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
281 }
282 CSVWorker csvWorker = new CSVWorker(selectedFile, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes));
283 csvWorker.execute();
284 }
285 }
286 }
287
288 @NbBundle.Messages({"OtherOccurrencesPanel_earliestCaseNotAvailable=Not Available."})
292 public void reset() {
293 // start with empty table
294 casesTableModel.clearTable();
295 dataSourcesTableModel.clearTable();
296 filesTableModel.clearTable();
297 correlationAttributes.clear();
298 earliestCaseDate.setText(Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable());
299 foundInLabel.setText("");
300 //calling getPreferredSize has a side effect of ensuring it has a preferred size which reflects the contents which are visible
301 occurrencePanel = new OccurrencePanel();
302 occurrencePanel.getPreferredSize();
304 }
305
317 if (worker != null) {
318 worker.cancel(true);
319 worker = null;
320 }
321
322 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
323
324 worker = new OtherOccurrenceOneTypeWorker(aType, value, file, deviceId, dataSourceName) {
325 @Override
326 public void done() {
327 try {
328 if (isCancelled()) {
329 return;
330 }
331
332 casesTableModel.clearTable();
333
334 OtherOccurrenceOneTypeWorker.OneTypeData data = get();
335 correlationAttributes.addAll(data.getCorrelationAttributesToAdd());
336 for (CorrelationCase corCase : data.getCaseNames().values()) {
337 casesTableModel.addCorrelationCase(new CorrelationCaseWrapper(corCase));
338 }
339 int caseCount = casesTableModel.getRowCount();
340 if (correlationAttributes.isEmpty()) {
341 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
342 } else if (caseCount == 0) {
343 casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
344 } else {
345 String earliestDate = data.getEarliestCaseDate();
346 earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
347 foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
348 if (caseCount > 0) {
349 casesTable.setRowSelectionInterval(0, 0);
350 }
351 }
352
353 } catch (InterruptedException | ExecutionException ex) {
354 logger.log(Level.SEVERE, "Failed to update OtherOccurrence panel", ex);
355 }
356 }
357 };
358
359 worker.execute();
360 }
361
365 void showPanelLoadingMessage() {
366 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
367 }
368
375 @NbBundle.Messages({
376 "OtherOccurrencesPanel.foundIn.text=Found %d instances in %d cases and %d data sources."
377 })
378 void populateTable(OtherOccurrencesData data) {
379 this.file = data.getFile();
380 this.dataSourceName = data.getDataSourceName();
381 this.deviceId = data.getDeviceId();
382
383 casesTableModel.clearTable();
384
385 correlationAttributes.addAll(data.getCorrelationAttributes());
386
387 for (CorrelationCase corCase : data.getCaseMap().values()) {
388 casesTableModel.addCorrelationCase(new CorrelationCaseWrapper(corCase));
389 }
390 int caseCount = casesTableModel.getRowCount();
391 if (correlationAttributes.isEmpty()) {
392 casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
393 } else if (caseCount == 0) {
394 casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
395 } else {
396 String earliestDate = data.getEarliestCaseDate();
397 earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
398 foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
399 if (caseCount > 0) {
400 casesTable.setRowSelectionInterval(0, 0);
401 }
402 }
403 }
404
409 private void updateOnCaseSelection() {
410 if (worker != null) {
411 worker.cancel(true);
412 worker = null;
413 }
414
415 final int[] selectedCaseIndexes = casesTable.getSelectedRows();
416 dataSourcesTableModel.clearTable();
417 filesTableModel.clearTable();
418
419 if (selectedCaseIndexes.length == 0) {
420 //special case when no cases are selected
421 occurrencePanel = new OccurrencePanel();
422 occurrencePanel.getPreferredSize();
424
425 return;
426 }
427
428 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
429
431 @Override
432 public void done() {
433 if (isCancelled()) {
434 return;
435 }
436
437 try {
438 Map<UniquePathKey, NodeData> correlatedNodeDataMap = get();
439
440 String currentCaseName;
441 try {
442 currentCaseName = Case.getCurrentCaseThrows().getName();
443 } catch (NoCurrentCaseException ex) {
444 currentCaseName = null;
445 logger.log(Level.WARNING, "Unable to get current case for other occurrences content viewer", ex);
446 }
447 if (casesTableModel.getRowCount() > 0) {
448 for (NodeData nodeData : correlatedNodeDataMap.values()) {
449 for (int selectedRow : selectedCaseIndexes) {
450 try {
451 if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
452 && casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
453 dataSourcesTableModel.addNodeData(nodeData);
454 }
455 } catch (CentralRepoException ex) {
456 logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
457 }
458 }
459 }
460 }
461 if (dataSourcesTableModel.getRowCount() > 0) {
462 dataSourcesTable.setRowSelectionInterval(0, 0);
463 }
464
465 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
466
467 } catch (InterruptedException | ExecutionException ex) {
468 logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on data source selection", ex);
469 }
470 }
471 };
472
473 worker.execute();
474 }
475
481 if (worker != null) {
482 worker.cancel(true);
483 worker = null;
484 }
485
486 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
487
488 final int[] selectedDataSources = dataSourcesTable.getSelectedRows();
489 filesTableModel.clearTable();
490
492 @Override
493 public void done() {
494 if (isCancelled()) {
495 return;
496 }
497
498 try {
499 Map<UniquePathKey, NodeData> correlatedNodeDataMap = get();
500 if (dataSourcesTableModel.getRowCount() > 0) {
501 for (NodeData nodeData : correlatedNodeDataMap.values()) {
502 for (int selectedDataSourceRow : selectedDataSources) {
503 int rowModelIndex = dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow);
504 try {
505 if (dataSourcesTableModel.getCaseUUIDForRow(rowModelIndex).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
506 && dataSourcesTableModel.getDeviceIdForRow(rowModelIndex).equals(nodeData.getDeviceID())) {
507 filesTableModel.addNodeData(nodeData);
508 }
509 } catch (CentralRepoException ex) {
510 logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
511 }
512 }
513 }
514 }
515
516 if (filesTableModel.getRowCount() > 0) {
517 filesTable.setRowSelectionInterval(0, 0);
518 }
519 } catch (InterruptedException | ExecutionException ex) {
520 logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on case selection", ex);
521 } finally {
522 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
523 }
524 }
525 };
526
527 worker.execute();
528 }
529
534 private void updateOnFileSelection() {
535 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
536 try {
537 if (filesTableModel.getRowCount() > 0 && filesTable.getSelectedRowCount() == 1) {
538 //if there is one file selected update the deatils to show the data for that file
539 occurrencePanel = new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())));
540 } else if (dataSourcesTableModel.getRowCount() > 0 && dataSourcesTable.getSelectedRowCount() == 1) {
541 //if no files were selected and only one data source is selected update the information to reflect the data source
542 String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
543 String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
544 String caseCreatedDate = "";
545 if (casesTableModel.getRowCount() > 0) {
546 for (int row : casesTable.getSelectedRows()) {
547 if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
548 caseCreatedDate = getCaseCreatedDate(row);
549 break;
550 }
551 }
552 }
553 occurrencePanel = new OccurrencePanel(caseName, caseCreatedDate, dsName);
554 } else if (casesTable.getSelectedRowCount() == 1) {
555 //if no files were selected and a number of data source other than 1 are selected
556 //update the information to reflect the case
557 String createdDate;
558 String caseName = "";
559 if (casesTableModel.getRowCount() > 0) {
560 caseName = casesTableModel.getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
561 }
562 if (caseName.isEmpty()) {
563 occurrencePanel = new OccurrencePanel();
564 } else {
565 createdDate = getCaseCreatedDate(casesTable.getSelectedRow());
566 occurrencePanel = new OccurrencePanel(caseName, createdDate);
567 }
568 } else {
569 //else display an empty details area
570 occurrencePanel = new OccurrencePanel();
571 }
572 //calling getPreferredSize has a side effect of ensuring it has a preferred size which reflects the contents which are visible
573 occurrencePanel.getPreferredSize();
575 } finally {
576 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
577 }
578 }
579
588 private String getCaseCreatedDate(int caseTableRowIdx) {
589 try {
590 if (CentralRepository.isEnabled() && casesTableModel.getRowCount() > 0) {
591 CorrelationCase partialCase;
592 partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
593 if (partialCase == null) {
594 return "";
595 }
597 } else {
599 }
600 } catch (CentralRepoException ex) {
601 logger.log(Level.WARNING, "Error getting case created date for row: " + caseTableRowIdx, ex);
602 }
603 return "";
604 }
605
609 private class SelectionWorker extends SwingWorker<Map<UniquePathKey, NodeData>, Void> {
610
611 private final Collection<CorrelationAttributeInstance> coAtInstances;
612 private final String deviceIdStr;
613 private final String dataSourceNameStr;
614
623 SelectionWorker(Collection<CorrelationAttributeInstance> coAtInstances, String deviceIdStr, String dataSourceNameStr) {
624 this.coAtInstances = coAtInstances;
625 this.dataSourceNameStr = dataSourceNameStr;
626 this.deviceIdStr = deviceIdStr;
627 }
628
629 @Override
630 protected Map<UniquePathKey, NodeData> doInBackground() throws Exception {
631 Map<UniquePathKey, NodeData> correlatedNodeDataMap = new HashMap<>();
633 correlatedNodeDataMap.putAll(OtherOccurrences.getCorrelatedInstances(deviceIdStr, dataSourceNameStr, corAttr));
634
635 if (isCancelled()) {
636 return new HashMap<>();
637 }
638 }
639
640 return correlatedNodeDataMap;
641 }
642 }
643
647 private class CSVWorker extends SwingWorker<Void, Void> {
648
649 private final Collection<CorrelationAttributeInstance> correlationAttList;
650 private final String dataSourceName;
651 private final String deviceId;
652 private final File destFile;
653
663 CSVWorker(File destFile, String dataSourceName, String deviceId, Collection<CorrelationAttributeInstance> correlationAttList) {
664 this.destFile = destFile;
665 this.dataSourceName = dataSourceName;
666 this.deviceId = deviceId;
667 this.correlationAttList = correlationAttList;
668 }
669
670 @Override
671 protected Void doInBackground() throws Exception {
672 OtherOccurrences.writeOtherOccurrencesToFileAsCSV(this.destFile, this.correlationAttList, this.dataSourceName, this.deviceId);
673 return null;
674 }
675
676 @Override
677 public void done() {
678 try {
679 get();
680 } catch (InterruptedException | ExecutionException ex) {
681 JOptionPane.showMessageDialog(OtherOccurrencesPanel.this,
682 "Failed to create csv file for Other Occurrences at\n" + destFile.getAbsolutePath(),
683 "Error Creating CSV",
684 JOptionPane.ERROR_MESSAGE);
685
686 logger.log(Level.SEVERE, "Error writing selected rows to from OtherOccurrencePanel to " + destFile.getAbsolutePath(), ex);
687 }
688 }
689 }
690
696 @SuppressWarnings("unchecked")
697 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
698 private void initComponents() {
699 java.awt.GridBagConstraints gridBagConstraints;
700
701 rightClickPopupMenu = new javax.swing.JPopupMenu();
702 exportToCSVMenuItem = new javax.swing.JMenuItem();
703 showCaseDetailsMenuItem = new javax.swing.JMenuItem();
704 showCommonalityMenuItem = new javax.swing.JMenuItem();
705 tableContainerPanel = new javax.swing.JPanel();
706 tablesViewerSplitPane = new javax.swing.JSplitPane();
707 caseDatasourceFileSplitPane = new javax.swing.JSplitPane();
708 caseDatasourceSplitPane = new javax.swing.JSplitPane();
709 caseScrollPane = new javax.swing.JScrollPane();
710 casesTable = new javax.swing.JTable();
711 dataSourceScrollPane = new javax.swing.JScrollPane();
712 dataSourcesTable = new javax.swing.JTable();
713 filesTableScrollPane = new javax.swing.JScrollPane();
714 filesTable = new javax.swing.JTable();
715 detailsPanelScrollPane = new javax.swing.JScrollPane();
716 jPanel1 = new javax.swing.JPanel();
717 foundInLabel = new javax.swing.JLabel();
718 earliestCaseDate = new javax.swing.JLabel();
719 earliestCaseLabel = new javax.swing.JLabel();
720 filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
721
722 rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
723 public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
724 }
725 public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
726 }
727 public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
728 rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
729 }
730 });
731
732 org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.exportToCSVMenuItem.text")); // NOI18N
733 rightClickPopupMenu.add(exportToCSVMenuItem);
734
735 org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.showCaseDetailsMenuItem.text")); // NOI18N
736 rightClickPopupMenu.add(showCaseDetailsMenuItem);
737
738 org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.showCommonalityMenuItem.text")); // NOI18N
739 rightClickPopupMenu.add(showCommonalityMenuItem);
740
741 tableContainerPanel.setPreferredSize(new java.awt.Dimension(600, 63));
742 tableContainerPanel.setRequestFocusEnabled(false);
743
744 tablesViewerSplitPane.setDividerLocation(450);
745 tablesViewerSplitPane.setResizeWeight(0.75);
746
747 caseDatasourceFileSplitPane.setDividerLocation(300);
748 caseDatasourceFileSplitPane.setResizeWeight(0.66);
749 caseDatasourceFileSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.caseDatasourceFileSplitPane.toolTipText")); // NOI18N
750
751 caseDatasourceSplitPane.setDividerLocation(150);
752 caseDatasourceSplitPane.setResizeWeight(0.5);
753
754 caseScrollPane.setPreferredSize(new java.awt.Dimension(150, 30));
755
756 casesTable.setAutoCreateRowSorter(true);
757 casesTable.setModel(casesTableModel);
758 caseScrollPane.setViewportView(casesTable);
759
760 caseDatasourceSplitPane.setLeftComponent(caseScrollPane);
761
762 dataSourceScrollPane.setPreferredSize(new java.awt.Dimension(150, 30));
763
764 dataSourcesTable.setAutoCreateRowSorter(true);
765 dataSourcesTable.setModel(dataSourcesTableModel);
766 dataSourceScrollPane.setViewportView(dataSourcesTable);
767
768 caseDatasourceSplitPane.setRightComponent(dataSourceScrollPane);
769
770 caseDatasourceFileSplitPane.setLeftComponent(caseDatasourceSplitPane);
771
772 filesTableScrollPane.setPreferredSize(new java.awt.Dimension(150, 30));
773
774 filesTable.setAutoCreateRowSorter(true);
775 filesTable.setModel(filesTableModel);
776 filesTable.setToolTipText(org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.filesTable.toolTipText")); // NOI18N
777 filesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
778 filesTableScrollPane.setViewportView(filesTable);
779
780 caseDatasourceFileSplitPane.setRightComponent(filesTableScrollPane);
781
782 tablesViewerSplitPane.setLeftComponent(caseDatasourceFileSplitPane);
783
784 detailsPanelScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
785 detailsPanelScrollPane.setPreferredSize(new java.awt.Dimension(300, 100));
786 tablesViewerSplitPane.setRightComponent(detailsPanelScrollPane);
787
788 jPanel1.setPreferredSize(new java.awt.Dimension(576, 22));
789 jPanel1.setLayout(new java.awt.GridBagLayout());
790
791 foundInLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
792 org.openide.awt.Mnemonics.setLocalizedText(foundInLabel, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.foundInLabel.text")); // NOI18N
793 foundInLabel.setPreferredSize(new java.awt.Dimension(400, 16));
794 gridBagConstraints = new java.awt.GridBagConstraints();
795 gridBagConstraints.gridx = 3;
796 gridBagConstraints.gridy = 0;
797 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
798 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
799 gridBagConstraints.insets = new java.awt.Insets(2, 2, 0, 0);
800 jPanel1.add(foundInLabel, gridBagConstraints);
801
802 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.earliestCaseDate.text")); // NOI18N
803 earliestCaseDate.setMaximumSize(new java.awt.Dimension(200, 16));
804 gridBagConstraints = new java.awt.GridBagConstraints();
805 gridBagConstraints.gridx = 1;
806 gridBagConstraints.gridy = 0;
807 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
808 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
809 gridBagConstraints.insets = new java.awt.Insets(0, 7, 0, 0);
810 jPanel1.add(earliestCaseDate, gridBagConstraints);
811
812 org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel, org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.earliestCaseLabel.text")); // NOI18N
813 earliestCaseLabel.setToolTipText(org.openide.util.NbBundle.getMessage(OtherOccurrencesPanel.class, "OtherOccurrencesPanel.earliestCaseLabel.toolTipText")); // NOI18N
814 earliestCaseLabel.setMaximumSize(new java.awt.Dimension(260, 16));
815 gridBagConstraints = new java.awt.GridBagConstraints();
816 gridBagConstraints.gridx = 0;
817 gridBagConstraints.gridy = 0;
818 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
819 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
820 jPanel1.add(earliestCaseLabel, gridBagConstraints);
821 gridBagConstraints = new java.awt.GridBagConstraints();
822 gridBagConstraints.gridx = 2;
823 gridBagConstraints.gridy = 0;
824 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
825 gridBagConstraints.weightx = 0.1;
826 jPanel1.add(filler1, gridBagConstraints);
827
828 javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel);
829 tableContainerPanel.setLayout(tableContainerPanelLayout);
830 tableContainerPanelLayout.setHorizontalGroup(
831 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
832 .addGroup(tableContainerPanelLayout.createSequentialGroup()
833 .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
834 .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
835 .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 516, Short.MAX_VALUE))
836 .addContainerGap())
837 );
838 tableContainerPanelLayout.setVerticalGroup(
839 tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
840 .addGroup(tableContainerPanelLayout.createSequentialGroup()
841 .addGap(0, 0, 0)
842 .addComponent(tablesViewerSplitPane)
843 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
844 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
845 .addGap(12, 12, 12))
846 );
847
848 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
849 this.setLayout(layout);
850 layout.setHorizontalGroup(
851 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
852 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 528, Short.MAX_VALUE)
853 );
854 layout.setVerticalGroup(
855 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
856 .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE)
857 );
858 }// </editor-fold>//GEN-END:initComponents
859
860 private void rightClickPopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_rightClickPopupMenuPopupMenuWillBecomeVisible
861 boolean enableCentralRepoActions = false;
862 if (CentralRepository.isEnabled() && filesTable.getSelectedRowCount() == 1) {
863 int rowIndex = filesTable.getSelectedRow();
864 List<NodeData> selectedFile = filesTableModel.getListOfNodesForFile(rowIndex);
865 if (!selectedFile.isEmpty() && selectedFile.get(0) instanceof NodeData) {
866 enableCentralRepoActions = true;
867 }
868 }
869 showCaseDetailsMenuItem.setVisible(enableCentralRepoActions);
870 showCommonalityMenuItem.setVisible(enableCentralRepoActions);
871 }//GEN-LAST:event_rightClickPopupMenuPopupMenuWillBecomeVisible
872
873
874 // Variables declaration - do not modify//GEN-BEGIN:variables
875 private javax.swing.JSplitPane caseDatasourceFileSplitPane;
876 private javax.swing.JSplitPane caseDatasourceSplitPane;
877 private javax.swing.JScrollPane caseScrollPane;
878 private javax.swing.JTable casesTable;
879 private javax.swing.JScrollPane dataSourceScrollPane;
880 private javax.swing.JTable dataSourcesTable;
881 private javax.swing.JScrollPane detailsPanelScrollPane;
882 private javax.swing.JLabel earliestCaseDate;
883 private javax.swing.JLabel earliestCaseLabel;
884 private javax.swing.JMenuItem exportToCSVMenuItem;
885 private javax.swing.JTable filesTable;
886 private javax.swing.JScrollPane filesTableScrollPane;
887 private javax.swing.Box.Filler filler1;
888 private javax.swing.JLabel foundInLabel;
889 private javax.swing.JPanel jPanel1;
890 private javax.swing.JPopupMenu rightClickPopupMenu;
891 private javax.swing.JMenuItem showCaseDetailsMenuItem;
892 private javax.swing.JMenuItem showCommonalityMenuItem;
893 private javax.swing.JPanel tableContainerPanel;
894 private javax.swing.JSplitPane tablesViewerSplitPane;
895 // End of variables declaration//GEN-END:variables
896}
static Map< UniquePathKey, NodeData > getCorrelatedInstances(String deviceId, String dataSourceName, CorrelationAttributeInstance corAttr)
static void writeOtherOccurrencesToFileAsCSV(File destFile, Collection< CorrelationAttributeInstance > correlationAttList, String dataSourceName, String deviceId)
void populateTableForOneType(CorrelationAttributeInstance.Type aType, String value)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
int getFrequencyPercentage(CorrelationAttributeInstance corAttr)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.