Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CommonAttributePanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2018-2020 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  */
19 package org.sleuthkit.autopsy.commonpropertiessearch;
20 
23 import java.awt.Dimension;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.Observable;
32 import java.util.Observer;
33 import java.util.concurrent.ExecutionException;
34 import java.util.logging.Level;
35 import javax.swing.JPanel;
36 import javax.swing.SwingWorker;
37 import javax.swing.event.DocumentEvent;
38 import javax.swing.event.DocumentListener;
39 import org.netbeans.api.progress.ProgressHandle;
40 import org.openide.DialogDisplayer;
41 import org.openide.NotifyDescriptor;
42 import org.openide.explorer.ExplorerManager;
43 import org.openide.nodes.Node;
44 import org.openide.util.NbBundle;
45 import org.openide.util.NbBundle.Messages;
46 import org.openide.windows.WindowManager;
62 import org.sleuthkit.datamodel.DataSource;
63 import org.sleuthkit.datamodel.IngestJobInfo;
64 import org.sleuthkit.datamodel.IngestModuleInfo;
65 import org.sleuthkit.datamodel.SleuthkitCase;
66 import org.sleuthkit.datamodel.TskCoreException;
68 
73 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
74 final class CommonAttributePanel extends javax.swing.JDialog implements Observer {
75 
76  private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName());
77  private static final long serialVersionUID = 1L;
78 
79  private static final Long NO_DATA_SOURCE_SELECTED = -1L;
80 
81  private final UserInputErrorManager errorManager;
82 
83  private int percentageThresholdValue = 20;
84 
85  private final IntraCasePanel intraCasePanel;
86  private final InterCasePanel interCasePanel;
87 
91  @NbBundle.Messages({
92  "CommonAttributePanel.title=Common Property Panel",
93  "CommonAttributePanel.exception=Unexpected Exception loading DataSources.",
94  "CommonAttributePanel.frame.title=Find Common Properties",
95  "CommonAttributePanel.intraCasePanel.title=Curren Case Options"})
96  CommonAttributePanel() {
97  super(WindowManager.getDefault().getMainWindow(), Bundle.CommonAttributePanel_frame_title(), true);
98  initComponents();
99  this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
100 
101  interCasePanel = new InterCasePanel();
102  interCasePanel.setVisible(true);
103  interCasePanel.setSize((int) containerPanel.getPreferredSize().getWidth(), (int) containerPanel.getPreferredSize().getHeight());
104 
105  intraCasePanel = new IntraCasePanel();
106  intraCasePanel.setVisible(true);
107  intraCasePanel.setSize((int) containerPanel.getPreferredSize().getWidth(), (int) containerPanel.getPreferredSize().getHeight());
108 
109  this.setupDataSources();
110 
111  if (CommonAttributePanel.isEamDbAvailableForIntercaseSearch()) {
112  this.setupCases();
113  this.interCasePanel.setupCorrelationTypeFilter();
114  this.interCaseRadio.setSelected(true);
115  switchInnerPanel(interCasePanel);
116  } else {
117  this.disableIntercaseSearch();
118  this.intraCaseRadio.setSelected(true);
119  switchInnerPanel(intraCasePanel);
120  }
121  this.revalidate();
122  this.repaint();
123 
124  this.updatePercentageOptions(CommonAttributePanel.getNumberOfDataSourcesAvailable());
125 
126  this.errorManager = new UserInputErrorManager();
127 
128  this.percentageThresholdInputBox.getDocument().addDocumentListener(new DocumentListener() {
129 
130  private final Dimension preferredSize = CommonAttributePanel.this.percentageThresholdInputBox.getPreferredSize();
131 
132  private void maintainSize() {
133  CommonAttributePanel.this.percentageThresholdInputBox.setSize(preferredSize);
134  }
135 
136  @Override
137  public void insertUpdate(DocumentEvent event) {
138  this.maintainSize();
139  CommonAttributePanel.this.percentageThresholdChanged();
140  }
141 
142  @Override
143  public void removeUpdate(DocumentEvent event) {
144  this.maintainSize();
145  CommonAttributePanel.this.percentageThresholdChanged();
146  }
147 
148  @Override
149  public void changedUpdate(DocumentEvent event) {
150  this.maintainSize();
151  CommonAttributePanel.this.percentageThresholdChanged();
152  }
153  });
154  }
155 
163  static boolean isEamDbAvailableForIntercaseSearch() {
164  try {
165  return CentralRepository.isEnabled()
166  && CentralRepository.getInstance() != null
167  && CentralRepository.getInstance().getCases().size() > 1
168  && Case.isCaseOpen()
169  && Case.getCurrentCase() != null
170  && CentralRepository.getInstance().getCase(Case.getCurrentCase()) != null;
171  } catch (CentralRepoException ex) {
172  LOGGER.log(Level.SEVERE, "Unexpected exception while checking for EamDB enabled.", ex);
173  }
174  return false;
175  }
176 
177  @Override
178  public void update(Observable o, Object arg) {
179  checkFileTypeCheckBoxState();
180  }
181 
189  private static Long getNumberOfDataSourcesAvailable() {
190  try {
191  if (CentralRepository.isEnabled()
192  && CentralRepository.getInstance() != null) {
193  return CentralRepository.getInstance().getCountUniqueDataSources();
194  }
195  } catch (CentralRepoException ex) {
196  LOGGER.log(Level.SEVERE, "Unexpected exception while checking for EamDB enabled.", ex);
197  }
198  return 0L;
199  }
200 
205  private void disableIntercaseSearch() {
206  this.intraCaseRadio.setSelected(true);
207  this.interCaseRadio.setEnabled(false);
208  }
209 
213  @NbBundle.Messages({
214  "CommonAttributePanel.search.results.pathText=Common Properties Results",
215  "CommonAttributePanel.search.done.searchProgressGathering=Gathering Common Properties Results.",
216  "CommonAttributePanel.search.done.searchProgressDisplay=Displaying Common Properties Results.",
217  "CommonAttributePanel.search.done.tskCoreException=Unable to run query against DB.",
218  "CommonAttributePanel.search.done.noCurrentCaseException=Unable to open case file.",
219  "CommonAttributePanel.search.done.exception=Unexpected exception running Find Common Properties.",
220  "CommonAttributePanel.search.done.interupted=Something went wrong finding common properties.",
221  "CommonAttributePanel.search.done.sqlException=Unable to query db for properties or data sources.",
222  "CommonAttributePanel.search.done.noResults=No results found."})
223  private void searchByCount() {
224  new SwingWorker<CommonAttributeCountSearchResults, Void>() {
225 
226  private String tabTitle;
227  private ProgressHandle progress;
228 
229  @Override
230  protected CommonAttributeCountSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, CentralRepoException {
231  progress = ProgressHandle.createHandle(Bundle.CommonAttributePanel_search_done_searchProgressGathering());
232  progress.start();
233  progress.switchToIndeterminate();
234 
235  Long dataSourceId = intraCasePanel.getSelectedDataSourceId();
236  Integer caseId = interCasePanel.getSelectedCaseId();
237 
238  AbstractCommonAttributeSearcher builder;
239  CommonAttributeCountSearchResults metadata;
240 
241  boolean filterByMedia = false;
242  boolean filterByDocuments = false;
243 
244  int percentageThreshold = CommonAttributePanel.this.percentageThresholdValue;
245 
246  if (!CommonAttributePanel.this.percentageThresholdCheck.isSelected()) {
247  //0 has the effect of disabling the feature
248  percentageThreshold = 0;
249  }
250 
251  if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
252  CorrelationAttributeInstance.Type corType = interCasePanel.getSelectedCorrelationType();
253  if (interCasePanel.fileCategoriesButtonIsSelected()) {
254  filterByMedia = interCasePanel.pictureVideoCheckboxIsSelected();
255  filterByDocuments = interCasePanel.documentsCheckboxIsSelected();
256  }
257  if (corType == null) {
258  corType = CentralRepository.getInstance().getDefinedCorrelationTypes().get(0);
259  }
260  if (caseId == InterCasePanel.NO_CASE_SELECTED) {
261  builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments, corType, percentageThreshold);
262  } else {
263 
264  builder = new SingleInterCaseCommonAttributeSearcher(caseId, filterByMedia, filterByDocuments, corType, percentageThreshold);
265  }
266 
267  } else {
268  if (intraCasePanel.fileCategoriesButtonIsSelected()) {
269  filterByMedia = intraCasePanel.pictureVideoCheckboxIsSelected();
270  filterByDocuments = intraCasePanel.documentsCheckboxIsSelected();
271  }
272  if (Objects.equals(dataSourceId, CommonAttributePanel.NO_DATA_SOURCE_SELECTED)) {
273  builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
274  } else {
275  builder = new SingleIntraCaseCommonAttributeSearcher(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
276  }
277 
278  }
279  metadata = builder.findMatchesByCount();
280  metadata.filterMetadata();
281  this.tabTitle = builder.getTabTitle();
282  return metadata;
283  }
284 
285  @Override
286  protected void done() {
287  try {
288  super.done();
289  CommonAttributeCountSearchResults metadata = this.get();
290  boolean noKeysExist = metadata.getMetadata().keySet().isEmpty();
291  if (noKeysExist) {
292  Node commonFilesNode = new TableFilterNode(new EmptyNode(Bundle.CommonAttributePanel_search_done_noResults()), true);
293  progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
294  DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), commonFilesNode, 1);
295  } else {
296  // -3969
297  CorrelationAttributeInstance.Type correlationType = null;
298  if (interCaseRadio.isSelected()){
299  correlationType = interCasePanel.getSelectedCorrelationType();
300  }
301  Node commonFilesNode = new CommonAttributeSearchResultRootNode(metadata, correlationType);
302  DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonAttributePanel.this));
303  TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3);
304  DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable();
305  Collection<DataResultViewer> viewers = new ArrayList<>(1);
306  viewers.add(table);
307  progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
308  DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), tableFilterWithDescendantsNode, metadata.size(), viewers);
309  }
310 
311  } catch (InterruptedException ex) {
312  LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex);
313  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_search_done_interupted());
314  } catch (ExecutionException ex) {
315  String errorMessage;
316  Throwable inner = ex.getCause();
317  if (inner instanceof TskCoreException) {
318  LOGGER.log(Level.SEVERE, "Failed to load files from database.", ex);
319  errorMessage = Bundle.CommonAttributePanel_search_done_tskCoreException();
320  } else if (inner instanceof NoCurrentCaseException) {
321  LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
322  errorMessage = Bundle.CommonAttributePanel_search_done_noCurrentCaseException();
323  } else if (inner instanceof SQLException) {
324  LOGGER.log(Level.SEVERE, "Unable to query db for files.", ex);
325  errorMessage = Bundle.CommonAttributePanel_search_done_sqlException();
326  } else {
327  LOGGER.log(Level.SEVERE, "Unexpected exception while running Common Files Search.", ex);
328  errorMessage = Bundle.CommonAttributePanel_search_done_exception();
329  }
330  MessageNotifyUtil.Message.error(errorMessage);
331  } finally {
332  progress.finish();
333  }
334  }
335  }.execute();
336  }
337 
341  private void searchByCase() {
342  new SwingWorker<CommonAttributeCaseSearchResults, Void>() {
343  private String tabTitle;
344  private ProgressHandle progress;
345 
346  @Override
347  protected CommonAttributeCaseSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, CentralRepoException {
348  progress = ProgressHandle.createHandle(Bundle.CommonAttributePanel_search_done_searchProgressGathering());
349  progress.start();
350  progress.switchToIndeterminate();
351  Long dataSourceId = intraCasePanel.getSelectedDataSourceId();
352  Integer caseId = interCasePanel.getSelectedCaseId();
353  AbstractCommonAttributeSearcher builder;
354  CommonAttributeCaseSearchResults metadata;
355  boolean filterByMedia = false;
356  boolean filterByDocuments = false;
357  int percentageThreshold = CommonAttributePanel.this.percentageThresholdValue;
358  if (!CommonAttributePanel.this.percentageThresholdCheck.isSelected()) {
359  //0 has the effect of disabling the feature
360  percentageThreshold = 0;
361  }
362  if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
363  CorrelationAttributeInstance.Type corType = interCasePanel.getSelectedCorrelationType();
364  if (interCasePanel.fileCategoriesButtonIsSelected()) {
365  filterByMedia = interCasePanel.pictureVideoCheckboxIsSelected();
366  filterByDocuments = interCasePanel.documentsCheckboxIsSelected();
367  }
368  if (corType == null) {
369  corType = CentralRepository.getInstance().getDefinedCorrelationTypes().get(0);
370  }
371  if (caseId == InterCasePanel.NO_CASE_SELECTED) {
372  builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments, corType, percentageThreshold);
373  } else {
374  builder = new SingleInterCaseCommonAttributeSearcher(caseId, filterByMedia, filterByDocuments, corType, percentageThreshold);
375  }
376  } else {
377  if (intraCasePanel.fileCategoriesButtonIsSelected()) {
378  filterByMedia = intraCasePanel.pictureVideoCheckboxIsSelected();
379  filterByDocuments = intraCasePanel.documentsCheckboxIsSelected();
380  }
381  if (Objects.equals(dataSourceId, CommonAttributePanel.NO_DATA_SOURCE_SELECTED)) {
382  builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
383  } else {
384  builder = new SingleIntraCaseCommonAttributeSearcher(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
385  }
386  }
387  metadata = builder.findMatchesByCase();
388  this.tabTitle = builder.getTabTitle();
389  return metadata;
390  }
391 
392  @Override
393  protected void done() {
394  try {
395  super.done();
396  CommonAttributeCaseSearchResults metadata = this.get();
397  if (metadata.getMetadata().keySet().isEmpty()) {
398  Node commonFilesNode = new TableFilterNode(new EmptyNode(Bundle.CommonAttributePanel_search_done_noResults()), true);
399  progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
400  DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), commonFilesNode, 1);
401  } else {
402  // -3969
403  Node commonFilesNode = new CommonAttributeSearchResultRootNode(metadata);
404  DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonAttributePanel.this));
405  TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3);
406  DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable();
407  Collection<DataResultViewer> viewers = new ArrayList<>(1);
408  viewers.add(table);
409  progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
410  //0 passed as arguement due to JIRA-4502 ensuring the value is never displayed JIRA-TODO
411  DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), tableFilterWithDescendantsNode, 0, viewers);
412  }
413  } catch (InterruptedException ex) {
414  LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex);
415  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_search_done_interupted());
416  } catch (ExecutionException ex) {
417  String errorMessage;
418  Throwable inner = ex.getCause();
419  if (inner instanceof TskCoreException) {
420  LOGGER.log(Level.SEVERE, "Failed to load files from database.", ex);
421  errorMessage = Bundle.CommonAttributePanel_search_done_tskCoreException();
422  } else if (inner instanceof NoCurrentCaseException) {
423  LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
424  errorMessage = Bundle.CommonAttributePanel_search_done_noCurrentCaseException();
425  } else if (inner instanceof SQLException) {
426  LOGGER.log(Level.SEVERE, "Unable to query db for files.", ex);
427  errorMessage = Bundle.CommonAttributePanel_search_done_sqlException();
428  } else {
429  LOGGER.log(Level.SEVERE, "Unexpected exception while running Common Files Search.", ex);
430  errorMessage = Bundle.CommonAttributePanel_search_done_exception();
431  }
432  MessageNotifyUtil.Message.error(errorMessage);
433  } finally {
434  progress.finish();
435  }
436  }
437  }.execute();
438  }
439 
447  @NbBundle.Messages({
448  "CommonAttributePanel.setupDataSources.done.tskCoreException=Unable to run query against DB.",
449  "CommonAttributePanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.",
450  "CommonAttributePanel.setupDataSources.done.exception=Unexpected exception loading data sources.",
451  "CommonAttributePanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.",
452  "CommonAttributePanel.setupDataSources.done.sqlException=Unable to query db for data sources.",
453  "CommonAttributePanel.setupDataSources.updateUi.noDataSources=No data sources were found."})
454 
455  private void setupDataSources() {
456 
457  new SwingWorker<Map<Long, String>, Void>() {
458 
463  private void updateUi() {
464 
465  final Map<Long, String> dataSourceMap = CommonAttributePanel.this.intraCasePanel.getDataSourceMap();
466 
467  String[] dataSourcesNames = new String[dataSourceMap.size()];
468 
469  //only enable all this stuff if we actually have datasources
470  if (dataSourcesNames.length > 0) {
471  dataSourcesNames = dataSourceMap.values().toArray(dataSourcesNames);
472  CommonAttributePanel.this.intraCasePanel.setDatasourceComboboxModel(new DataSourceComboBoxModel(dataSourcesNames));
473 
474  if (!this.caseHasMultipleSources()) { //disable intra case search when only 1 data source in current case
475  intraCaseRadio.setEnabled(false);
476  interCaseRadio.setSelected(true);
477  }
478  CommonAttributePanel.this.updateErrorTextAndSearchButton();
479  }
480  }
481 
488  private boolean caseHasMultipleSources() {
489  return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 1;
490  }
491 
492  @Override
493  protected Map<Long, String> doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException {
494  return DataSourceLoader.getAllDataSources();
495  }
496 
497  @Override
498  protected void done() {
499 
500  try {
501  CommonAttributePanel.this.intraCasePanel.setDataSourceMap(this.get());
502  updateUi();
503 
504  } catch (InterruptedException ex) {
505  LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
506  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupDataSources_done_interupted());
507  } catch (ExecutionException ex) {
508  String errorMessage;
509  Throwable inner = ex.getCause();
510  if (inner instanceof TskCoreException) {
511  LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex);
512  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_tskCoreException();
513  } else if (inner instanceof NoCurrentCaseException) {
514  LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
515  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_noCurrentCaseException();
516  } else if (inner instanceof SQLException) {
517  LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex);
518  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_sqlException();
519  } else {
520  LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex);
521  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_exception();
522  }
523  MessageNotifyUtil.Message.error(errorMessage);
524  }
525  }
526  }.execute();
527  }
528 
534  private void switchInnerPanel(JPanel panel) {
535  containerPanel.removeAll();
536  containerPanel.add(panel);
537  caseResultsRadioButton.setVisible(this.interCaseRadio.isSelected());
538  countResultsRadioButton.setVisible(this.interCaseRadio.isSelected());
539  displayResultsLabel.setVisible(this.interCaseRadio.isSelected());
540  this.revalidate();
541  this.repaint();
542  }
543 
544  @NbBundle.Messages({
545  "CommonAttributePanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.",
546  "CommonAttributePanel.setupCases.done.exeutionException=Unexpected exception loading cases."})
547  private void setupCases() {
548 
549  new SwingWorker<Map<Integer, String>, Void>() {
550 
555  private void updateUi() {
556 
557  final Map<Integer, String> caseMap = CommonAttributePanel.this.interCasePanel.getCaseMap();
558 
559  String[] caseNames = new String[caseMap.size()];
560 
561  if (caseNames.length > 0) {
562  caseNames = caseMap.values().toArray(caseNames);
563  CommonAttributePanel.this.interCasePanel.setCaseComboboxModel(new DataSourceComboBoxModel(caseNames));
564  } else {
565  CommonAttributePanel.this.disableIntercaseSearch();
566  }
567  }
568 
578  private Map<Integer, String> mapCases(List<CorrelationCase> cases) throws CentralRepoException {
579  Map<Integer, String> casemap = new HashMap<>();
580  CorrelationCase currentCorCase = CentralRepository.getInstance().getCase(Case.getCurrentCase());
581  for (CorrelationCase correlationCase : cases) {
582  if (currentCorCase.getID() != correlationCase.getID()) { // if not the current Case
583  casemap.put(correlationCase.getID(), correlationCase.getDisplayName());
584  }
585  }
586  return casemap;
587  }
588 
589  @Override
590  protected Map<Integer, String> doInBackground() throws CentralRepoException {
591 
592  List<CorrelationCase> dataSources = CentralRepository.getInstance().getCases();
593  Map<Integer, String> caseMap = mapCases(dataSources);
594 
595  return caseMap;
596  }
597 
598  @Override
599  protected void done() {
600  try {
601  Map<Integer, String> cases = this.get();
602  CommonAttributePanel.this.interCasePanel.setCaseMap(cases);
603  this.updateUi();
604  } catch (InterruptedException ex) {
605  LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
606  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_interruptedException());
607  } catch (ExecutionException ex) {
608  LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog.", ex);
609  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_exeutionException());
610  }
611  }
612 
613  }.execute();
614  }
615 
621  @SuppressWarnings("unchecked")
622  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
623  private void initComponents() {
624 
625  interIntraButtonGroup = new javax.swing.ButtonGroup();
626  displayResultsButtonGroup = new javax.swing.ButtonGroup();
627  jPanel1 = new javax.swing.JPanel();
628  commonItemSearchDescription = new javax.swing.JLabel();
629  scopeLabel = new javax.swing.JLabel();
630  intraCaseRadio = new javax.swing.JRadioButton();
631  interCaseRadio = new javax.swing.JRadioButton();
632  containerPanel = new javax.swing.JPanel();
633  percentageThresholdCheck = new javax.swing.JCheckBox();
634  percentageThresholdInputBox = new javax.swing.JTextField();
635  percentageThresholdTextTwo = new javax.swing.JLabel();
636  dataSourcesLabel = new javax.swing.JLabel();
637  errorText = new javax.swing.JLabel();
638  searchButton = new javax.swing.JButton();
639  caseResultsRadioButton = new javax.swing.JRadioButton();
640  countResultsRadioButton = new javax.swing.JRadioButton();
641  displayResultsLabel = new javax.swing.JLabel();
642 
643  setMinimumSize(new java.awt.Dimension(450, 570));
644  setResizable(false);
645  addWindowListener(new java.awt.event.WindowAdapter() {
646  public void windowClosed(java.awt.event.WindowEvent evt) {
647  formWindowClosed(evt);
648  }
649  });
650 
651  jPanel1.setMaximumSize(null);
652  jPanel1.setPreferredSize(new java.awt.Dimension(450, 646));
653  jPanel1.setRequestFocusEnabled(false);
654 
655  org.openide.awt.Mnemonics.setLocalizedText(commonItemSearchDescription, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonItemSearchDescription.text")); // NOI18N
656  commonItemSearchDescription.setFocusable(false);
657 
658  org.openide.awt.Mnemonics.setLocalizedText(scopeLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.scopeLabel.text")); // NOI18N
659  scopeLabel.setFocusable(false);
660 
661  interIntraButtonGroup.add(intraCaseRadio);
662  intraCaseRadio.setSelected(true);
663  org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCaseRadio.text")); // NOI18N
664  intraCaseRadio.addActionListener(new java.awt.event.ActionListener() {
665  public void actionPerformed(java.awt.event.ActionEvent evt) {
666  intraCaseRadioActionPerformed(evt);
667  }
668  });
669 
670  interIntraButtonGroup.add(interCaseRadio);
671  org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N
672  interCaseRadio.addActionListener(new java.awt.event.ActionListener() {
673  public void actionPerformed(java.awt.event.ActionEvent evt) {
674  interCaseRadioActionPerformed(evt);
675  }
676  });
677 
678  containerPanel.setBackground(new java.awt.Color(0, 0, 0));
679  containerPanel.setOpaque(false);
680 
681  javax.swing.GroupLayout containerPanelLayout = new javax.swing.GroupLayout(containerPanel);
682  containerPanel.setLayout(containerPanelLayout);
683  containerPanelLayout.setHorizontalGroup(
684  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
685  .addGap(0, 430, Short.MAX_VALUE)
686  );
687  containerPanelLayout.setVerticalGroup(
688  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
689  .addGap(0, 326, Short.MAX_VALUE)
690  );
691 
692  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdCheck, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdCheck.text_1_1")); // NOI18N
693  percentageThresholdCheck.addActionListener(new java.awt.event.ActionListener() {
694  public void actionPerformed(java.awt.event.ActionEvent evt) {
695  percentageThresholdCheckActionPerformed(evt);
696  }
697  });
698 
699  percentageThresholdInputBox.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
700  percentageThresholdInputBox.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdInputBox.text")); // NOI18N
701  percentageThresholdInputBox.setMaximumSize(new java.awt.Dimension(40, 24));
702  percentageThresholdInputBox.setMinimumSize(new java.awt.Dimension(40, 24));
703  percentageThresholdInputBox.setPreferredSize(new java.awt.Dimension(40, 24));
704 
705  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N
706 
707  org.openide.awt.Mnemonics.setLocalizedText(dataSourcesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.dataSourcesLabel.text")); // NOI18N
708 
709  errorText.setForeground(new java.awt.Color(255, 0, 0));
710  org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.errorText.text")); // NOI18N
711  errorText.setVerticalAlignment(javax.swing.SwingConstants.TOP);
712 
713  org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N
714  searchButton.setEnabled(false);
715  searchButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
716  searchButton.addActionListener(new java.awt.event.ActionListener() {
717  public void actionPerformed(java.awt.event.ActionEvent evt) {
718  searchButtonActionPerformed(evt);
719  }
720  });
721 
722  displayResultsButtonGroup.add(caseResultsRadioButton);
723  caseResultsRadioButton.setSelected(true);
724  org.openide.awt.Mnemonics.setLocalizedText(caseResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.caseResultsRadioButton.text")); // NOI18N
725  caseResultsRadioButton.addActionListener(new java.awt.event.ActionListener() {
726  public void actionPerformed(java.awt.event.ActionEvent evt) {
727  caseResultsRadioButtonActionPerformed(evt);
728  }
729  });
730 
731  displayResultsButtonGroup.add(countResultsRadioButton);
732  org.openide.awt.Mnemonics.setLocalizedText(countResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.countResultsRadioButton.text")); // NOI18N
733 
734  org.openide.awt.Mnemonics.setLocalizedText(displayResultsLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.displayResultsLabel.text_2")); // NOI18N
735 
736  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
737  jPanel1.setLayout(jPanel1Layout);
738  jPanel1Layout.setHorizontalGroup(
739  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
740  .addGroup(jPanel1Layout.createSequentialGroup()
741  .addContainerGap()
742  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
743  .addGroup(jPanel1Layout.createSequentialGroup()
744  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
745  .addContainerGap())
746  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
747  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
748  .addGroup(jPanel1Layout.createSequentialGroup()
749  .addGap(0, 0, Short.MAX_VALUE)
750  .addComponent(intraCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))
751  .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
752  .addGap(37, 37, 37))
753  .addGroup(jPanel1Layout.createSequentialGroup()
754  .addComponent(percentageThresholdCheck)
755  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
756  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
757  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
758  .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
759  .addContainerGap())
760  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
761  .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, 330, javax.swing.GroupLayout.PREFERRED_SIZE)
762  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
763  .addComponent(searchButton)
764  .addContainerGap())
765  .addGroup(jPanel1Layout.createSequentialGroup()
766  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
767  .addComponent(containerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
768  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
769  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING)
770  .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
771  .addGap(20, 20, 20)
772  .addComponent(interCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))))
773  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
774  .addGroup(jPanel1Layout.createSequentialGroup()
775  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
776  .addGroup(jPanel1Layout.createSequentialGroup()
777  .addContainerGap()
778  .addComponent(displayResultsLabel))
779  .addGroup(jPanel1Layout.createSequentialGroup()
780  .addGap(30, 30, 30)
781  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
782  .addComponent(caseResultsRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 410, javax.swing.GroupLayout.PREFERRED_SIZE)
783  .addComponent(countResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
784  .addGap(10, 10, 10))
785  );
786  jPanel1Layout.setVerticalGroup(
787  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
788  .addGroup(jPanel1Layout.createSequentialGroup()
789  .addContainerGap()
790  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
791  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
792  .addComponent(scopeLabel)
793  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
794  .addComponent(intraCaseRadio)
795  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
796  .addComponent(interCaseRadio)
797  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
798  .addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
799  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
800  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
801  .addComponent(percentageThresholdCheck)
802  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
803  .addComponent(percentageThresholdTextTwo))
804  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
805  .addComponent(displayResultsLabel)
806  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
807  .addComponent(caseResultsRadioButton)
808  .addGap(0, 0, 0)
809  .addComponent(countResultsRadioButton)
810  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
811  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
812  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
813  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
814  .addComponent(searchButton)
815  .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
816  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
817  );
818 
819  getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
820  }// </editor-fold>//GEN-END:initComponents
821 
822  private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
823  this.dispose();
824  }//GEN-LAST:event_formWindowClosed
825 
826  private void percentageThresholdCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_percentageThresholdCheckActionPerformed
827  if (this.percentageThresholdCheck.isSelected()) {
828  this.percentageThresholdInputBox.setEnabled(true);
829  } else {
830  this.percentageThresholdInputBox.setEnabled(false);
831  }
832 
833  this.handleFrequencyPercentageState();
834  }//GEN-LAST:event_percentageThresholdCheckActionPerformed
835 
836  private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
837  switchInnerPanel(interCasePanel);
838  }//GEN-LAST:event_interCaseRadioActionPerformed
839 
840  private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
841  switchInnerPanel(intraCasePanel);
842  }//GEN-LAST:event_intraCaseRadioActionPerformed
843 
844  private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
845  checkDataSourcesAndSearch();
846  this.dispose();
847  }//GEN-LAST:event_searchButtonActionPerformed
848 
849  private void caseResultsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseResultsRadioButtonActionPerformed
850  // TODO add your handling code here:
851  }//GEN-LAST:event_caseResultsRadioButtonActionPerformed
852 
867  @Messages({"CommonAttributePanel.incompleteResults.introText=Results may be incomplete. Not all data sources in the current case were ingested into the current Central Repository. The following data sources have not been processed:",
868  "CommonAttributePanel.incompleteResults.continueText=\n\n Continue with search anyway?",
869  "CommonAttributePanel.incompleteResults.title=Search may be incomplete"
870  })
871  private void checkDataSourcesAndSearch() {
872  new SwingWorker<List<String>, Void>() {
873 
874  @Override
875  protected List<String> doInBackground() throws Exception {
876  List<String> unCorrelatedDataSources = new ArrayList<>();
877  if (!interCaseRadio.isSelected() || !CentralRepository.isEnabled() || CentralRepository.getInstance() == null) {
878  return unCorrelatedDataSources;
879  }
880  //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr
881  HashMap<DataSource, CorrelatedStatus> dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested
882  String correlationEngineModuleName = CentralRepoIngestModuleFactory.getModuleName();
883  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
884  List<CorrelationDataSource> correlatedDataSources = CentralRepository.getInstance().getDataSources();
885  List<IngestJobInfo> ingestJobs = skCase.getIngestJobs();
886  for (IngestJobInfo jobInfo : ingestJobs) {
887  //get the data source for each ingest job
888  DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId());
889  String deviceID = dataSource.getDeviceId();
890  //add its status as not_correlated for now if this is the first time the data source was processed
891  dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED);
892  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) {
893  //if the datasource was previously processed we do not need to perform this check
894  for (CorrelationDataSource correlatedDataSource : correlatedDataSources) {
895  if (deviceID.equals(correlatedDataSource.getDeviceID())) {
896  //if the datasource exists in the central repository it may of been processed with the correlation engine
897  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO);
898  break;
899  }
900  }
901  }
902  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) {
903  //if the data source was in the central repository check if any of the modules run on it were the correlation engine
904  for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) {
905  if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) {
906  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED);
907  break;
908  }
909  }
910  }
911  }
912  //convert the keys of the map which have not been correlated to a list
913  for (DataSource dataSource : dataSourceCorrelationMap.keySet()) {
914  if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) {
915  unCorrelatedDataSources.add(dataSource.getName());
916  }
917  }
918  return unCorrelatedDataSources;
919  }
920 
921  @Override
922  protected void done() {
923  super.done();
924  try {
925  List<String> unProcessedDataSources = get();
926  boolean performSearch = true;
927  if (!unProcessedDataSources.isEmpty()) {
928  String warning = Bundle.CommonAttributePanel_incompleteResults_introText();
929  warning = unProcessedDataSources.stream().map((dataSource) -> "\n - " + dataSource).reduce(warning, String::concat);
930  warning += Bundle.CommonAttributePanel_incompleteResults_continueText();
931  //let user know which data sources in the current case were not processed into a central repository
932  NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(warning, Bundle.CommonAttributePanel_incompleteResults_title(), NotifyDescriptor.YES_NO_OPTION);
933  performSearch = DialogDisplayer.getDefault().notify(descriptor) == NotifyDescriptor.YES_OPTION;
934  }
935  if (performSearch) {
936  if (interCaseRadio.isSelected() && caseResultsRadioButton.isSelected()) {
937  searchByCase();
938  } else {
939  searchByCount();
940  }
941  }
942  } catch (InterruptedException | ExecutionException ex) {
943  LOGGER.log(Level.SEVERE, "Unexpected exception while looking for common properties", ex); //NON-NLS
944  }
945  }
946  }.execute();
947  }
948 
953  private void percentageThresholdChanged() {
954  String percentageString = this.percentageThresholdInputBox.getText();
955 
956  try {
957  this.percentageThresholdValue = Integer.parseInt(percentageString);
958 
959  } catch (NumberFormatException ignored) {
960  this.percentageThresholdValue = -1;
961  }
962 
963  this.handleFrequencyPercentageState();
964  }
965 
970  private void updateErrorTextAndSearchButton() {
971  if (this.errorManager.anyErrors()) {
972  this.searchButton.setEnabled(false);
973  //grab the first error error and show it
974  this.errorText.setText(this.errorManager.getErrors().get(0));
975  this.errorText.setVisible(true);
976  } else {
977  this.searchButton.setEnabled(true);
978  this.errorText.setVisible(false);
979  }
980  }
981 
989  @NbBundle.Messages({
990  "# {0} - number of datasources",
991  "CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s)."})
992  private void updatePercentageOptions(Long numberOfDataSources) {
993  boolean enabled = numberOfDataSources > 0L;
994  String numberOfDataSourcesText = enabled ? Bundle.CommonAttributePanel_dataSourcesLabel_text(numberOfDataSources) : "";
995  this.dataSourcesLabel.setText(numberOfDataSourcesText);
996  this.percentageThresholdInputBox.setEnabled(enabled);
997  this.percentageThresholdCheck.setEnabled(enabled);
998  this.percentageThresholdCheck.setSelected(enabled);
999  this.percentageThresholdTextTwo.setEnabled(enabled);
1000 
1001  }
1002 
1008  private void handleFrequencyPercentageState() {
1009  if (this.percentageThresholdValue > 0 && this.percentageThresholdValue <= 100) {
1010  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, false);
1011  } else {
1012 
1013  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, true);
1014  }
1015  this.updateErrorTextAndSearchButton();
1016  }
1017 
1018  // Variables declaration - do not modify//GEN-BEGIN:variables
1019  private javax.swing.JRadioButton caseResultsRadioButton;
1020  private javax.swing.JLabel commonItemSearchDescription;
1021  private javax.swing.JPanel containerPanel;
1022  private javax.swing.JRadioButton countResultsRadioButton;
1023  private javax.swing.JLabel dataSourcesLabel;
1024  private javax.swing.ButtonGroup displayResultsButtonGroup;
1025  private javax.swing.JLabel displayResultsLabel;
1026  private javax.swing.JLabel errorText;
1027  private javax.swing.JRadioButton interCaseRadio;
1028  private javax.swing.ButtonGroup interIntraButtonGroup;
1029  private javax.swing.JRadioButton intraCaseRadio;
1030  private javax.swing.JPanel jPanel1;
1031  private javax.swing.JCheckBox percentageThresholdCheck;
1032  private javax.swing.JTextField percentageThresholdInputBox;
1033  private javax.swing.JLabel percentageThresholdTextTwo;
1034  private javax.swing.JLabel scopeLabel;
1035  private javax.swing.JButton searchButton;
1036  // End of variables declaration//GEN-END:variables
1037 
1042  void observeSubPanels() {
1043  intraCasePanel.addObserver(this);
1044  interCasePanel.addObserver(this);
1045  }
1046 
1052  private void checkFileTypeCheckBoxState() {
1053  boolean validCheckBoxState = true;
1054  if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
1055  if (interCasePanel.fileCategoriesButtonIsSelected()) {
1056  validCheckBoxState = interCasePanel.pictureVideoCheckboxIsSelected() || interCasePanel.documentsCheckboxIsSelected();
1057  }
1058  } else {
1059  if (intraCasePanel.fileCategoriesButtonIsSelected()) {
1060  validCheckBoxState = intraCasePanel.pictureVideoCheckboxIsSelected() || intraCasePanel.documentsCheckboxIsSelected();
1061  }
1062  }
1063  if (validCheckBoxState) {
1064  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
1065  } else {
1066  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true);
1067  }
1068  this.updateErrorTextAndSearchButton();
1069  }
1070 
1075  private enum CorrelatedStatus {
1078  CORRELATED
1079  }
1080 }

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.