Autopsy  4.10.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 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;
63 import org.sleuthkit.datamodel.DataSource;
64 import org.sleuthkit.datamodel.IngestJobInfo;
65 import org.sleuthkit.datamodel.IngestModuleInfo;
66 import org.sleuthkit.datamodel.SleuthkitCase;
67 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 EamDb.isEnabled()
166  && EamDb.getInstance() != null
167  && EamDb.getInstance().getCases().size() > 1
168  && Case.isCaseOpen()
169  && Case.getCurrentCase() != null
170  && EamDb.getInstance().getCase(Case.getCurrentCase()) != null;
171  } catch (EamDbException 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 (EamDb.isEnabled()
192  && EamDb.getInstance() != null) {
193  return EamDb.getInstance().getCountUniqueDataSources();
194  }
195  } catch (EamDbException 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, EamDbException {
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 = CorrelationAttributeInstance.getDefaultCorrelationTypes().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, EamDbException {
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 = CorrelationAttributeInstance.getDefaultCorrelationTypes().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  DataSourceLoader loader = new DataSourceLoader();
495  return loader.getDataSourceMap();
496  }
497 
498  @Override
499  protected void done() {
500 
501  try {
502  CommonAttributePanel.this.intraCasePanel.setDataSourceMap(this.get());
503  updateUi();
504 
505  } catch (InterruptedException ex) {
506  LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
507  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupDataSources_done_interupted());
508  } catch (ExecutionException ex) {
509  String errorMessage;
510  Throwable inner = ex.getCause();
511  if (inner instanceof TskCoreException) {
512  LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex);
513  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_tskCoreException();
514  } else if (inner instanceof NoCurrentCaseException) {
515  LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
516  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_noCurrentCaseException();
517  } else if (inner instanceof SQLException) {
518  LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex);
519  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_sqlException();
520  } else {
521  LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex);
522  errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_exception();
523  }
524  MessageNotifyUtil.Message.error(errorMessage);
525  }
526  }
527  }.execute();
528  }
529 
535  private void switchInnerPanel(JPanel panel) {
536  containerPanel.removeAll();
537  containerPanel.add(panel);
538  caseResultsRadioButton.setVisible(this.interCaseRadio.isSelected());
539  countResultsRadioButton.setVisible(this.interCaseRadio.isSelected());
540  displayResultsLabel.setVisible(this.interCaseRadio.isSelected());
541  this.revalidate();
542  this.repaint();
543  }
544 
545  @NbBundle.Messages({
546  "CommonAttributePanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.",
547  "CommonAttributePanel.setupCases.done.exeutionException=Unexpected exception loading cases."})
548  private void setupCases() {
549 
550  new SwingWorker<Map<Integer, String>, Void>() {
551 
556  private void updateUi() {
557 
558  final Map<Integer, String> caseMap = CommonAttributePanel.this.interCasePanel.getCaseMap();
559 
560  String[] caseNames = new String[caseMap.size()];
561 
562  if (caseNames.length > 0) {
563  caseNames = caseMap.values().toArray(caseNames);
564  CommonAttributePanel.this.interCasePanel.setCaseComboboxModel(new DataSourceComboBoxModel(caseNames));
565  } else {
566  CommonAttributePanel.this.disableIntercaseSearch();
567  }
568  }
569 
579  private Map<Integer, String> mapCases(List<CorrelationCase> cases) throws EamDbException {
580  Map<Integer, String> casemap = new HashMap<>();
581  CorrelationCase currentCorCase = EamDb.getInstance().getCase(Case.getCurrentCase());
582  for (CorrelationCase correlationCase : cases) {
583  if (currentCorCase.getID() != correlationCase.getID()) { // if not the current Case
584  casemap.put(correlationCase.getID(), correlationCase.getDisplayName());
585  }
586  }
587  return casemap;
588  }
589 
590  @Override
591  protected Map<Integer, String> doInBackground() throws EamDbException {
592 
593  List<CorrelationCase> dataSources = EamDb.getInstance().getCases();
594  Map<Integer, String> caseMap = mapCases(dataSources);
595 
596  return caseMap;
597  }
598 
599  @Override
600  protected void done() {
601  try {
602  Map<Integer, String> cases = this.get();
603  CommonAttributePanel.this.interCasePanel.setCaseMap(cases);
604  this.updateUi();
605  } catch (InterruptedException ex) {
606  LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
607  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_interruptedException());
608  } catch (ExecutionException ex) {
609  LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog.", ex);
610  MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_exeutionException());
611  }
612  }
613 
614  }.execute();
615  }
616 
622  @SuppressWarnings("unchecked")
623  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
624  private void initComponents() {
625 
626  interIntraButtonGroup = new javax.swing.ButtonGroup();
627  displayResultsButtonGroup = new javax.swing.ButtonGroup();
628  jPanel1 = new javax.swing.JPanel();
629  commonItemSearchDescription = new javax.swing.JLabel();
630  scopeLabel = new javax.swing.JLabel();
631  intraCaseRadio = new javax.swing.JRadioButton();
632  interCaseRadio = new javax.swing.JRadioButton();
633  containerPanel = new javax.swing.JPanel();
634  percentageThresholdCheck = new javax.swing.JCheckBox();
635  percentageThresholdInputBox = new javax.swing.JTextField();
636  percentageThresholdTextTwo = new javax.swing.JLabel();
637  dataSourcesLabel = new javax.swing.JLabel();
638  errorText = new javax.swing.JLabel();
639  searchButton = new javax.swing.JButton();
640  caseResultsRadioButton = new javax.swing.JRadioButton();
641  countResultsRadioButton = new javax.swing.JRadioButton();
642  displayResultsLabel = new javax.swing.JLabel();
643 
644  setMinimumSize(new java.awt.Dimension(450, 570));
645  setResizable(false);
646  addWindowListener(new java.awt.event.WindowAdapter() {
647  public void windowClosed(java.awt.event.WindowEvent evt) {
648  formWindowClosed(evt);
649  }
650  });
651 
652  jPanel1.setMaximumSize(null);
653  jPanel1.setPreferredSize(new java.awt.Dimension(450, 646));
654  jPanel1.setRequestFocusEnabled(false);
655 
656  org.openide.awt.Mnemonics.setLocalizedText(commonItemSearchDescription, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonItemSearchDescription.text")); // NOI18N
657  commonItemSearchDescription.setFocusable(false);
658 
659  org.openide.awt.Mnemonics.setLocalizedText(scopeLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.scopeLabel.text")); // NOI18N
660  scopeLabel.setFocusable(false);
661 
662  interIntraButtonGroup.add(intraCaseRadio);
663  intraCaseRadio.setSelected(true);
664  org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCaseRadio.text")); // NOI18N
665  intraCaseRadio.addActionListener(new java.awt.event.ActionListener() {
666  public void actionPerformed(java.awt.event.ActionEvent evt) {
667  intraCaseRadioActionPerformed(evt);
668  }
669  });
670 
671  interIntraButtonGroup.add(interCaseRadio);
672  org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N
673  interCaseRadio.addActionListener(new java.awt.event.ActionListener() {
674  public void actionPerformed(java.awt.event.ActionEvent evt) {
675  interCaseRadioActionPerformed(evt);
676  }
677  });
678 
679  containerPanel.setBackground(new java.awt.Color(0, 0, 0));
680  containerPanel.setOpaque(false);
681 
682  javax.swing.GroupLayout containerPanelLayout = new javax.swing.GroupLayout(containerPanel);
683  containerPanel.setLayout(containerPanelLayout);
684  containerPanelLayout.setHorizontalGroup(
685  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
686  .addGap(0, 430, Short.MAX_VALUE)
687  );
688  containerPanelLayout.setVerticalGroup(
689  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
690  .addGap(0, 326, Short.MAX_VALUE)
691  );
692 
693  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdCheck, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdCheck.text_1_1")); // NOI18N
694  percentageThresholdCheck.addActionListener(new java.awt.event.ActionListener() {
695  public void actionPerformed(java.awt.event.ActionEvent evt) {
696  percentageThresholdCheckActionPerformed(evt);
697  }
698  });
699 
700  percentageThresholdInputBox.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
701  percentageThresholdInputBox.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdInputBox.text")); // NOI18N
702  percentageThresholdInputBox.setMaximumSize(new java.awt.Dimension(40, 24));
703  percentageThresholdInputBox.setMinimumSize(new java.awt.Dimension(40, 24));
704  percentageThresholdInputBox.setPreferredSize(new java.awt.Dimension(40, 24));
705 
706  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N
707 
708  org.openide.awt.Mnemonics.setLocalizedText(dataSourcesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.dataSourcesLabel.text")); // NOI18N
709 
710  errorText.setForeground(new java.awt.Color(255, 0, 0));
711  org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.errorText.text")); // NOI18N
712  errorText.setVerticalAlignment(javax.swing.SwingConstants.TOP);
713 
714  org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N
715  searchButton.setEnabled(false);
716  searchButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
717  searchButton.addActionListener(new java.awt.event.ActionListener() {
718  public void actionPerformed(java.awt.event.ActionEvent evt) {
719  searchButtonActionPerformed(evt);
720  }
721  });
722 
723  displayResultsButtonGroup.add(caseResultsRadioButton);
724  caseResultsRadioButton.setSelected(true);
725  org.openide.awt.Mnemonics.setLocalizedText(caseResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.caseResultsRadioButton.text")); // NOI18N
726  caseResultsRadioButton.addActionListener(new java.awt.event.ActionListener() {
727  public void actionPerformed(java.awt.event.ActionEvent evt) {
728  caseResultsRadioButtonActionPerformed(evt);
729  }
730  });
731 
732  displayResultsButtonGroup.add(countResultsRadioButton);
733  org.openide.awt.Mnemonics.setLocalizedText(countResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.countResultsRadioButton.text")); // NOI18N
734 
735  org.openide.awt.Mnemonics.setLocalizedText(displayResultsLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.displayResultsLabel.text_2")); // NOI18N
736 
737  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
738  jPanel1.setLayout(jPanel1Layout);
739  jPanel1Layout.setHorizontalGroup(
740  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
741  .addGroup(jPanel1Layout.createSequentialGroup()
742  .addContainerGap()
743  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
744  .addGroup(jPanel1Layout.createSequentialGroup()
745  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
746  .addContainerGap())
747  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
748  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
749  .addGroup(jPanel1Layout.createSequentialGroup()
750  .addGap(0, 0, Short.MAX_VALUE)
751  .addComponent(intraCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))
752  .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
753  .addGap(37, 37, 37))
754  .addGroup(jPanel1Layout.createSequentialGroup()
755  .addComponent(percentageThresholdCheck)
756  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
757  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
758  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
759  .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
760  .addContainerGap())
761  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
762  .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, 330, javax.swing.GroupLayout.PREFERRED_SIZE)
763  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
764  .addComponent(searchButton)
765  .addContainerGap())
766  .addGroup(jPanel1Layout.createSequentialGroup()
767  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
768  .addComponent(containerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
769  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
770  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING)
771  .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
772  .addGap(20, 20, 20)
773  .addComponent(interCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))))
774  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
775  .addGroup(jPanel1Layout.createSequentialGroup()
776  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
777  .addGroup(jPanel1Layout.createSequentialGroup()
778  .addContainerGap()
779  .addComponent(displayResultsLabel))
780  .addGroup(jPanel1Layout.createSequentialGroup()
781  .addGap(30, 30, 30)
782  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
783  .addComponent(caseResultsRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 410, javax.swing.GroupLayout.PREFERRED_SIZE)
784  .addComponent(countResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
785  .addGap(10, 10, 10))
786  );
787  jPanel1Layout.setVerticalGroup(
788  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
789  .addGroup(jPanel1Layout.createSequentialGroup()
790  .addContainerGap()
791  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
792  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
793  .addComponent(scopeLabel)
794  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
795  .addComponent(intraCaseRadio)
796  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
797  .addComponent(interCaseRadio)
798  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
799  .addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
800  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
801  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
802  .addComponent(percentageThresholdCheck)
803  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
804  .addComponent(percentageThresholdTextTwo))
805  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
806  .addComponent(displayResultsLabel)
807  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
808  .addComponent(caseResultsRadioButton)
809  .addGap(0, 0, 0)
810  .addComponent(countResultsRadioButton)
811  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
812  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
813  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
814  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
815  .addComponent(searchButton)
816  .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
817  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
818  );
819 
820  getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
821  }// </editor-fold>//GEN-END:initComponents
822 
823  private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
824  this.dispose();
825  }//GEN-LAST:event_formWindowClosed
826 
827  private void percentageThresholdCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_percentageThresholdCheckActionPerformed
828  if (this.percentageThresholdCheck.isSelected()) {
829  this.percentageThresholdInputBox.setEnabled(true);
830  } else {
831  this.percentageThresholdInputBox.setEnabled(false);
832  }
833 
834  this.handleFrequencyPercentageState();
835  }//GEN-LAST:event_percentageThresholdCheckActionPerformed
836 
837  private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
838  switchInnerPanel(interCasePanel);
839  }//GEN-LAST:event_interCaseRadioActionPerformed
840 
841  private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
842  switchInnerPanel(intraCasePanel);
843  }//GEN-LAST:event_intraCaseRadioActionPerformed
844 
845  private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
846  checkDataSourcesAndSearch();
847  this.dispose();
848  }//GEN-LAST:event_searchButtonActionPerformed
849 
850  private void caseResultsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseResultsRadioButtonActionPerformed
851  // TODO add your handling code here:
852  }//GEN-LAST:event_caseResultsRadioButtonActionPerformed
853 
868  @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:",
869  "CommonAttributePanel.incompleteResults.continueText=\n\n Continue with search anyway?",
870  "CommonAttributePanel.incompleteResults.title=Search may be incomplete"
871  })
872  private void checkDataSourcesAndSearch() {
873  new SwingWorker<List<String>, Void>() {
874 
875  @Override
876  protected List<String> doInBackground() throws Exception {
877  List<String> unCorrelatedDataSources = new ArrayList<>();
878  if (!interCaseRadio.isSelected() || !EamDb.isEnabled() || EamDb.getInstance() == null) {
879  return unCorrelatedDataSources;
880  }
881  //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr
882  HashMap<DataSource, CorrelatedStatus> dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested
883  String correlationEngineModuleName = CentralRepoIngestModuleFactory.getModuleName();
884  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
885  List<CorrelationDataSource> correlatedDataSources = EamDb.getInstance().getDataSources();
886  List<IngestJobInfo> ingestJobs = skCase.getIngestJobs();
887  for (IngestJobInfo jobInfo : ingestJobs) {
888  //get the data source for each ingest job
889  DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId());
890  String deviceID = dataSource.getDeviceId();
891  //add its status as not_correlated for now if this is the first time the data source was processed
892  dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED);
893  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) {
894  //if the datasource was previously processed we do not need to perform this check
895  for (CorrelationDataSource correlatedDataSource : correlatedDataSources) {
896  if (deviceID.equals(correlatedDataSource.getDeviceID())) {
897  //if the datasource exists in the central repository it may of been processed with the correlation engine
898  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO);
899  break;
900  }
901  }
902  }
903  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) {
904  //if the data source was in the central repository check if any of the modules run on it were the correlation engine
905  for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) {
906  if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) {
907  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED);
908  break;
909  }
910  }
911  }
912  }
913  //convert the keys of the map which have not been correlated to a list
914  for (DataSource dataSource : dataSourceCorrelationMap.keySet()) {
915  if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) {
916  unCorrelatedDataSources.add(dataSource.getName());
917  }
918  }
919  return unCorrelatedDataSources;
920  }
921 
922  @Override
923  protected void done() {
924  super.done();
925  try {
926  List<String> unProcessedDataSources = get();
927  boolean performSearch = true;
928  if (!unProcessedDataSources.isEmpty()) {
929  String warning = Bundle.CommonAttributePanel_incompleteResults_introText();
930  warning = unProcessedDataSources.stream().map((dataSource) -> "\n - " + dataSource).reduce(warning, String::concat);
931  warning += Bundle.CommonAttributePanel_incompleteResults_continueText();
932  //let user know which data sources in the current case were not processed into a central repository
933  NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(warning, Bundle.CommonAttributePanel_incompleteResults_title(), NotifyDescriptor.YES_NO_OPTION);
934  performSearch = DialogDisplayer.getDefault().notify(descriptor) == NotifyDescriptor.YES_OPTION;
935  }
936  if (performSearch) {
937  if (interCaseRadio.isSelected() && caseResultsRadioButton.isSelected()) {
938  searchByCase();
939  } else {
940  searchByCount();
941  }
942  }
943  } catch (InterruptedException | ExecutionException ex) {
944  LOGGER.log(Level.SEVERE, "Unexpected exception while looking for common properties", ex); //NON-NLS
945  }
946  }
947  }.execute();
948  }
949 
954  private void percentageThresholdChanged() {
955  String percentageString = this.percentageThresholdInputBox.getText();
956 
957  try {
958  this.percentageThresholdValue = Integer.parseInt(percentageString);
959 
960  } catch (NumberFormatException ignored) {
961  this.percentageThresholdValue = -1;
962  }
963 
964  this.handleFrequencyPercentageState();
965  }
966 
971  private void updateErrorTextAndSearchButton() {
972  if (this.errorManager.anyErrors()) {
973  this.searchButton.setEnabled(false);
974  //grab the first error error and show it
975  this.errorText.setText(this.errorManager.getErrors().get(0));
976  this.errorText.setVisible(true);
977  } else {
978  this.searchButton.setEnabled(true);
979  this.errorText.setVisible(false);
980  }
981  }
982 
990  @NbBundle.Messages({
991  "# {0} - number of datasources",
992  "CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s)."})
993  private void updatePercentageOptions(Long numberOfDataSources) {
994  boolean enabled = numberOfDataSources > 0L;
995  String numberOfDataSourcesText = enabled ? Bundle.CommonAttributePanel_dataSourcesLabel_text(numberOfDataSources) : "";
996  this.dataSourcesLabel.setText(numberOfDataSourcesText);
997  this.percentageThresholdInputBox.setEnabled(enabled);
998  this.percentageThresholdCheck.setEnabled(enabled);
999  this.percentageThresholdCheck.setSelected(enabled);
1000  this.percentageThresholdTextTwo.setEnabled(enabled);
1001 
1002  }
1003 
1009  private void handleFrequencyPercentageState() {
1010  if (this.percentageThresholdValue > 0 && this.percentageThresholdValue <= 100) {
1011  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, false);
1012  } else {
1013 
1014  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, true);
1015  }
1016  this.updateErrorTextAndSearchButton();
1017  }
1018 
1019  // Variables declaration - do not modify//GEN-BEGIN:variables
1020  private javax.swing.JRadioButton caseResultsRadioButton;
1021  private javax.swing.JLabel commonItemSearchDescription;
1022  private javax.swing.JPanel containerPanel;
1023  private javax.swing.JRadioButton countResultsRadioButton;
1024  private javax.swing.JLabel dataSourcesLabel;
1025  private javax.swing.ButtonGroup displayResultsButtonGroup;
1026  private javax.swing.JLabel displayResultsLabel;
1027  private javax.swing.JLabel errorText;
1028  private javax.swing.JRadioButton interCaseRadio;
1029  private javax.swing.ButtonGroup interIntraButtonGroup;
1030  private javax.swing.JRadioButton intraCaseRadio;
1031  private javax.swing.JPanel jPanel1;
1032  private javax.swing.JCheckBox percentageThresholdCheck;
1033  private javax.swing.JTextField percentageThresholdInputBox;
1034  private javax.swing.JLabel percentageThresholdTextTwo;
1035  private javax.swing.JLabel scopeLabel;
1036  private javax.swing.JButton searchButton;
1037  // End of variables declaration//GEN-END:variables
1038 
1043  void observeSubPanels() {
1044  intraCasePanel.addObserver(this);
1045  interCasePanel.addObserver(this);
1046  }
1047 
1053  private void checkFileTypeCheckBoxState() {
1054  boolean validCheckBoxState = true;
1055  if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
1056  if (interCasePanel.fileCategoriesButtonIsSelected()) {
1057  validCheckBoxState = interCasePanel.pictureVideoCheckboxIsSelected() || interCasePanel.documentsCheckboxIsSelected();
1058  }
1059  } else {
1060  if (intraCasePanel.fileCategoriesButtonIsSelected()) {
1061  validCheckBoxState = intraCasePanel.pictureVideoCheckboxIsSelected() || intraCasePanel.documentsCheckboxIsSelected();
1062  }
1063  }
1064  if (validCheckBoxState) {
1065  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
1066  } else {
1067  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true);
1068  }
1069  this.updateErrorTextAndSearchButton();
1070  }
1071 
1076  private enum CorrelatedStatus {
1079  CORRELATED
1080  }
1081 }

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.