Autopsy  4.19.1
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  setMaximumSize(new java.awt.Dimension(499, 646));
644  setMinimumSize(new java.awt.Dimension(499, 646));
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(new java.awt.Dimension(499, 646));
653  jPanel1.setMinimumSize(new java.awt.Dimension(499, 646));
654  jPanel1.setPreferredSize(new java.awt.Dimension(499, 646));
655  jPanel1.setRequestFocusEnabled(false);
656 
657  org.openide.awt.Mnemonics.setLocalizedText(commonItemSearchDescription, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonItemSearchDescription.text")); // NOI18N
658  commonItemSearchDescription.setFocusable(false);
659 
660  org.openide.awt.Mnemonics.setLocalizedText(scopeLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.scopeLabel.text")); // NOI18N
661  scopeLabel.setFocusable(false);
662 
663  interIntraButtonGroup.add(intraCaseRadio);
664  intraCaseRadio.setSelected(true);
665  org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCaseRadio.text")); // NOI18N
666  intraCaseRadio.addActionListener(new java.awt.event.ActionListener() {
667  public void actionPerformed(java.awt.event.ActionEvent evt) {
668  intraCaseRadioActionPerformed(evt);
669  }
670  });
671 
672  interIntraButtonGroup.add(interCaseRadio);
673  org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N
674  interCaseRadio.addActionListener(new java.awt.event.ActionListener() {
675  public void actionPerformed(java.awt.event.ActionEvent evt) {
676  interCaseRadioActionPerformed(evt);
677  }
678  });
679 
680  containerPanel.setBackground(new java.awt.Color(0, 0, 0));
681  containerPanel.setOpaque(false);
682  containerPanel.setPreferredSize(new java.awt.Dimension(477, 326));
683 
684  javax.swing.GroupLayout containerPanelLayout = new javax.swing.GroupLayout(containerPanel);
685  containerPanel.setLayout(containerPanelLayout);
686  containerPanelLayout.setHorizontalGroup(
687  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
688  .addGap(0, 0, Short.MAX_VALUE)
689  );
690  containerPanelLayout.setVerticalGroup(
691  containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
692  .addGap(0, 326, Short.MAX_VALUE)
693  );
694 
695  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdCheck, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdCheck.text_1_1")); // NOI18N
696  percentageThresholdCheck.addActionListener(new java.awt.event.ActionListener() {
697  public void actionPerformed(java.awt.event.ActionEvent evt) {
698  percentageThresholdCheckActionPerformed(evt);
699  }
700  });
701 
702  percentageThresholdInputBox.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
703  percentageThresholdInputBox.setText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdInputBox.text")); // NOI18N
704  percentageThresholdInputBox.setMaximumSize(new java.awt.Dimension(40, 24));
705  percentageThresholdInputBox.setMinimumSize(new java.awt.Dimension(40, 24));
706  percentageThresholdInputBox.setPreferredSize(new java.awt.Dimension(40, 24));
707 
708  org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N
709  percentageThresholdTextTwo.setMaximumSize(new java.awt.Dimension(260, 16));
710 
711  org.openide.awt.Mnemonics.setLocalizedText(dataSourcesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.dataSourcesLabel.text")); // NOI18N
712 
713  errorText.setForeground(new java.awt.Color(255, 0, 0));
714  org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.errorText.text")); // NOI18N
715  errorText.setVerticalAlignment(javax.swing.SwingConstants.TOP);
716 
717  org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N
718  searchButton.setEnabled(false);
719  searchButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
720  searchButton.setMaximumSize(new java.awt.Dimension(100, 25));
721  searchButton.setMinimumSize(new java.awt.Dimension(100, 25));
722  searchButton.setPreferredSize(new java.awt.Dimension(100, 25));
723  searchButton.addActionListener(new java.awt.event.ActionListener() {
724  public void actionPerformed(java.awt.event.ActionEvent evt) {
725  searchButtonActionPerformed(evt);
726  }
727  });
728 
729  displayResultsButtonGroup.add(caseResultsRadioButton);
730  caseResultsRadioButton.setSelected(true);
731  org.openide.awt.Mnemonics.setLocalizedText(caseResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.caseResultsRadioButton.text")); // NOI18N
732  caseResultsRadioButton.addActionListener(new java.awt.event.ActionListener() {
733  public void actionPerformed(java.awt.event.ActionEvent evt) {
734  caseResultsRadioButtonActionPerformed(evt);
735  }
736  });
737 
738  displayResultsButtonGroup.add(countResultsRadioButton);
739  org.openide.awt.Mnemonics.setLocalizedText(countResultsRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.countResultsRadioButton.text")); // NOI18N
740 
741  org.openide.awt.Mnemonics.setLocalizedText(displayResultsLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.displayResultsLabel.text_2")); // NOI18N
742 
743  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
744  jPanel1.setLayout(jPanel1Layout);
745  jPanel1Layout.setHorizontalGroup(
746  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
747  .addGroup(jPanel1Layout.createSequentialGroup()
748  .addContainerGap()
749  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
750  .addGroup(jPanel1Layout.createSequentialGroup()
751  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
752  .addContainerGap())
753  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
754  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
755  .addGroup(jPanel1Layout.createSequentialGroup()
756  .addGap(20, 20, 20)
757  .addComponent(intraCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
758  .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
759  .addGap(37, 37, 37))
760  .addGroup(jPanel1Layout.createSequentialGroup()
761  .addComponent(percentageThresholdCheck, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE)
762  .addGap(1, 1, 1)
763  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
764  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
765  .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE)
766  .addContainerGap())
767  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
768  .addComponent(errorText)
769  .addGap(6, 6, 6)
770  .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
771  .addContainerGap())
772  .addGroup(jPanel1Layout.createSequentialGroup()
773  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
774  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING)
775  .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
776  .addGap(20, 20, 20)
777  .addComponent(interCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
778  .addGap(84, 84, 84))
779  .addGroup(jPanel1Layout.createSequentialGroup()
780  .addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
781  .addContainerGap())))
782  .addGroup(jPanel1Layout.createSequentialGroup()
783  .addGap(30, 30, 30)
784  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
785  .addGroup(jPanel1Layout.createSequentialGroup()
786  .addComponent(caseResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
787  .addGap(49, 49, 49))
788  .addComponent(countResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
789  .addGap(10, 10, 10))
790  .addGroup(jPanel1Layout.createSequentialGroup()
791  .addContainerGap()
792  .addComponent(displayResultsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
793  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
794  );
795  jPanel1Layout.setVerticalGroup(
796  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
797  .addGroup(jPanel1Layout.createSequentialGroup()
798  .addContainerGap()
799  .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
800  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
801  .addComponent(scopeLabel)
802  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
803  .addComponent(intraCaseRadio)
804  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
805  .addComponent(interCaseRadio)
806  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
807  .addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
808  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
809  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
810  .addComponent(percentageThresholdCheck)
811  .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
812  .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
813  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
814  .addComponent(displayResultsLabel)
815  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
816  .addComponent(caseResultsRadioButton)
817  .addGap(0, 0, 0)
818  .addComponent(countResultsRadioButton)
819  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
820  .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
821  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
822  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
823  .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
824  .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
825  .addGap(14, 14, 14))
826  );
827 
828  getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
829  }// </editor-fold>//GEN-END:initComponents
830 
831  private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
832  this.dispose();
833  }//GEN-LAST:event_formWindowClosed
834 
835  private void percentageThresholdCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_percentageThresholdCheckActionPerformed
836  if (this.percentageThresholdCheck.isSelected()) {
837  this.percentageThresholdInputBox.setEnabled(true);
838  } else {
839  this.percentageThresholdInputBox.setEnabled(false);
840  }
841 
842  this.handleFrequencyPercentageState();
843  }//GEN-LAST:event_percentageThresholdCheckActionPerformed
844 
845  private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
846  switchInnerPanel(interCasePanel);
847  }//GEN-LAST:event_interCaseRadioActionPerformed
848 
849  private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
850  switchInnerPanel(intraCasePanel);
851  }//GEN-LAST:event_intraCaseRadioActionPerformed
852 
853  private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
854  checkDataSourcesAndSearch();
855  this.dispose();
856  }//GEN-LAST:event_searchButtonActionPerformed
857 
858  private void caseResultsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseResultsRadioButtonActionPerformed
859  // TODO add your handling code here:
860  }//GEN-LAST:event_caseResultsRadioButtonActionPerformed
861 
876  @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:",
877  "CommonAttributePanel.incompleteResults.continueText=\n\n Continue with search anyway?",
878  "CommonAttributePanel.incompleteResults.title=Search may be incomplete"
879  })
880  private void checkDataSourcesAndSearch() {
881  new SwingWorker<List<String>, Void>() {
882 
883  @Override
884  protected List<String> doInBackground() throws Exception {
885  List<String> unCorrelatedDataSources = new ArrayList<>();
886  if (!interCaseRadio.isSelected() || !CentralRepository.isEnabled() || CentralRepository.getInstance() == null) {
887  return unCorrelatedDataSources;
888  }
889  //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr
890  HashMap<DataSource, CorrelatedStatus> dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested
891  String correlationEngineModuleName = CentralRepoIngestModuleFactory.getModuleName();
892  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
893  List<CorrelationDataSource> correlatedDataSources = CentralRepository.getInstance().getDataSources();
894  List<IngestJobInfo> ingestJobs = skCase.getIngestJobs();
895  for (IngestJobInfo jobInfo : ingestJobs) {
896  //get the data source for each ingest job
897  DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId());
898  String deviceID = dataSource.getDeviceId();
899  //add its status as not_correlated for now if this is the first time the data source was processed
900  dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED);
901  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) {
902  //if the datasource was previously processed we do not need to perform this check
903  for (CorrelationDataSource correlatedDataSource : correlatedDataSources) {
904  if (deviceID.equals(correlatedDataSource.getDeviceID())) {
905  //if the datasource exists in the central repository it may of been processed with the Central Repository
906  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO);
907  break;
908  }
909  }
910  }
911  if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) {
912  //if the data source was in the central repository check if any of the modules run on it were the Central Repository
913  for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) {
914  if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) {
915  dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED);
916  break;
917  }
918  }
919  }
920  }
921  //convert the keys of the map which have not been correlated to a list
922  for (DataSource dataSource : dataSourceCorrelationMap.keySet()) {
923  if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) {
924  unCorrelatedDataSources.add(dataSource.getName());
925  }
926  }
927  return unCorrelatedDataSources;
928  }
929 
930  @Override
931  protected void done() {
932  super.done();
933  try {
934  List<String> unProcessedDataSources = get();
935  boolean performSearch = true;
936  if (!unProcessedDataSources.isEmpty()) {
937  String warning = Bundle.CommonAttributePanel_incompleteResults_introText();
938  warning = unProcessedDataSources.stream().map((dataSource) -> "\n - " + dataSource).reduce(warning, String::concat);
939  warning += Bundle.CommonAttributePanel_incompleteResults_continueText();
940  //let user know which data sources in the current case were not processed into a central repository
941  NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(warning, Bundle.CommonAttributePanel_incompleteResults_title(), NotifyDescriptor.YES_NO_OPTION);
942  performSearch = DialogDisplayer.getDefault().notify(descriptor) == NotifyDescriptor.YES_OPTION;
943  }
944  if (performSearch) {
945  if (interCaseRadio.isSelected() && caseResultsRadioButton.isSelected()) {
946  searchByCase();
947  } else {
948  searchByCount();
949  }
950  }
951  } catch (InterruptedException | ExecutionException ex) {
952  LOGGER.log(Level.SEVERE, "Unexpected exception while looking for common properties", ex); //NON-NLS
953  }
954  }
955  }.execute();
956  }
957 
962  private void percentageThresholdChanged() {
963  String percentageString = this.percentageThresholdInputBox.getText();
964 
965  try {
966  this.percentageThresholdValue = Integer.parseInt(percentageString);
967 
968  } catch (NumberFormatException ignored) {
969  this.percentageThresholdValue = -1;
970  }
971 
972  this.handleFrequencyPercentageState();
973  }
974 
979  private void updateErrorTextAndSearchButton() {
980  if (this.errorManager.anyErrors()) {
981  this.searchButton.setEnabled(false);
982  //grab the first error error and show it
983  this.errorText.setText(this.errorManager.getErrors().get(0));
984  this.errorText.setVisible(true);
985  } else {
986  this.searchButton.setEnabled(true);
987  this.errorText.setVisible(false);
988  }
989  }
990 
998  @NbBundle.Messages({
999  "# {0} - number of datasources",
1000  "CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s)."})
1001  private void updatePercentageOptions(Long numberOfDataSources) {
1002  boolean enabled = numberOfDataSources > 0L;
1003  String numberOfDataSourcesText = enabled ? Bundle.CommonAttributePanel_dataSourcesLabel_text(numberOfDataSources) : "";
1004  this.dataSourcesLabel.setText(numberOfDataSourcesText);
1005  this.percentageThresholdInputBox.setEnabled(enabled);
1006  this.percentageThresholdCheck.setEnabled(enabled);
1007  this.percentageThresholdCheck.setSelected(enabled);
1008  this.percentageThresholdTextTwo.setEnabled(enabled);
1009 
1010  }
1011 
1017  private void handleFrequencyPercentageState() {
1018  if (this.percentageThresholdValue > 0 && this.percentageThresholdValue <= 100) {
1019  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, false);
1020  } else {
1021 
1022  this.errorManager.setError(UserInputErrorManager.FREQUENCY_PERCENTAGE_OUT_OF_RANGE_KEY, true);
1023  }
1024  this.updateErrorTextAndSearchButton();
1025  }
1026 
1027  // Variables declaration - do not modify//GEN-BEGIN:variables
1028  private javax.swing.JRadioButton caseResultsRadioButton;
1029  private javax.swing.JLabel commonItemSearchDescription;
1030  private javax.swing.JPanel containerPanel;
1031  private javax.swing.JRadioButton countResultsRadioButton;
1032  private javax.swing.JLabel dataSourcesLabel;
1033  private javax.swing.ButtonGroup displayResultsButtonGroup;
1034  private javax.swing.JLabel displayResultsLabel;
1035  private javax.swing.JLabel errorText;
1036  private javax.swing.JRadioButton interCaseRadio;
1037  private javax.swing.ButtonGroup interIntraButtonGroup;
1038  private javax.swing.JRadioButton intraCaseRadio;
1039  private javax.swing.JPanel jPanel1;
1040  private javax.swing.JCheckBox percentageThresholdCheck;
1041  private javax.swing.JTextField percentageThresholdInputBox;
1042  private javax.swing.JLabel percentageThresholdTextTwo;
1043  private javax.swing.JLabel scopeLabel;
1044  private javax.swing.JButton searchButton;
1045  // End of variables declaration//GEN-END:variables
1046 
1051  void observeSubPanels() {
1052  intraCasePanel.addObserver(this);
1053  interCasePanel.addObserver(this);
1054  }
1055 
1061  private void checkFileTypeCheckBoxState() {
1062  boolean validCheckBoxState = true;
1063  if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
1064  if (interCasePanel.fileCategoriesButtonIsSelected()) {
1065  validCheckBoxState = interCasePanel.pictureVideoCheckboxIsSelected() || interCasePanel.documentsCheckboxIsSelected();
1066  }
1067  } else {
1068  if (intraCasePanel.fileCategoriesButtonIsSelected()) {
1069  validCheckBoxState = intraCasePanel.pictureVideoCheckboxIsSelected() || intraCasePanel.documentsCheckboxIsSelected();
1070  }
1071  }
1072  if (validCheckBoxState) {
1073  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
1074  } else {
1075  this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, true);
1076  }
1077  this.updateErrorTextAndSearchButton();
1078  }
1079 
1084  private enum CorrelatedStatus {
1087  CORRELATED
1088  }
1089 }

Copyright © 2012-2021 Basis Technology. Generated on: Thu Sep 30 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.