19 package org.sleuthkit.autopsy.allcasessearch;
 
   21 import java.awt.Color;
 
   22 import java.awt.event.ItemEvent;
 
   23 import java.awt.event.ItemListener;
 
   24 import java.util.ArrayList;
 
   25 import java.util.Collection;
 
   26 import java.util.List;
 
   27 import java.util.concurrent.ExecutionException;
 
   28 import java.util.logging.Level;
 
   29 import javax.swing.JFrame;
 
   30 import javax.swing.SwingWorker;
 
   31 import javax.swing.event.DocumentEvent;
 
   32 import javax.swing.event.DocumentListener;
 
   33 import org.openide.nodes.Node;
 
   34 import org.openide.util.NbBundle.Messages;
 
   35 import org.openide.windows.TopComponent;
 
   36 import org.openide.windows.WindowManager;
 
   51     "AllCasesSearchDialog.dialogTitle.text=Search All Cases",
 
   52     "AllCasesSearchDialog.resultsTitle.text=All Cases",
 
   53     "AllCasesSearchDialog.resultsDescription.text=All Cases Search",
 
   54     "AllCasesSearchDialog.emptyNode.text=No results found.",
 
   55     "AllCasesSearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash.",
 
   56     "AllCasesSearchDialog.validation.invalidEmail=The supplied value is not a valid e-mail address.",
 
   57     "AllCasesSearchDialog.validation.invalidDomain=The supplied value is not a valid domain.",
 
   58     "AllCasesSearchDialog.validation.invalidPhone=The supplied value is not a valid phone number.",
 
   59     "AllCasesSearchDialog.validation.invalidSsid=The supplied value is not a valid wireless network.",
 
   60     "AllCasesSearchDialog.validation.invalidMac=The supplied value is not a valid MAC address.",
 
   61     "AllCasesSearchDialog.validation.invalidImei=The supplied value is not a valid IMEI number.",
 
   62     "AllCasesSearchDialog.validation.invalidImsi=The supplied value is not a valid IMSI number.",
 
   63     "AllCasesSearchDialog.validation.invalidIccid=The supplied value is not a valid ICCID number.",
 
   64     "AllCasesSearchDialog.validation.genericMessage=The supplied value is not valid.",
 
   65     "# {0} - number of cases",
 
   66     "AllCasesSearchDialog.caseLabel.text=The current Central Repository contains {0} case(s)." 
   72 @SuppressWarnings(
"PMD.SingularField") 
 
   73 final class AllCasesSearchDialog extends javax.swing.JDialog {
 
   75     private static final Logger logger = Logger.getLogger(AllCasesSearchDialog.class.getName());
 
   76     private static final long serialVersionUID = 1L;
 
   78     private final List<CorrelationAttributeInstance.Type> correlationTypes;
 
   79     private CorrelationAttributeInstance.Type selectedCorrelationType;
 
   80     private TextPrompt correlationValueTextFieldPrompt;
 
   85     AllCasesSearchDialog() {
 
   86         super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.AllCasesSearchDialog_dialogTitle_text(), 
true);
 
   87         this.correlationTypes = 
new ArrayList<>();
 
   89         customizeComponents();
 
   98     private void search(CorrelationAttributeInstance.Type type, String value) {
 
   99         new SwingWorker<List<CorrelationAttributeInstance>, Void>() {
 
  102             protected List<CorrelationAttributeInstance> doInBackground() {
 
  103                 List<CorrelationAttributeInstance> correlationInstances = 
new ArrayList<>();
 
  106                     correlationInstances = EamDb.getInstance().getArtifactInstancesByTypeValue(type, value);
 
  107                 } 
catch (EamDbException ex) {
 
  108                     logger.log(Level.SEVERE, 
"Unable to connect to the Central Repository database.", ex);
 
  109                 } 
catch (CorrelationAttributeNormalizationException ex) {
 
  110                     logger.log(Level.SEVERE, 
"Unable to retrieve data from the Central Repository.", ex);
 
  113                 return correlationInstances;
 
  117             protected void done() {
 
  120                     List<CorrelationAttributeInstance> correlationInstances = this.
get();
 
  121                     DataResultViewerTable table = 
new DataResultViewerTable();
 
  122                     Collection<DataResultViewer> viewers = 
new ArrayList<>(1);
 
  125                     AllCasesSearchNode searchNode = 
new AllCasesSearchNode(correlationInstances);
 
  126                     TableFilterNode tableFilterNode = 
new TableFilterNode(searchNode, 
true, searchNode.getName());
 
  128                     String resultsText = String.format(
"%s (%s; \"%s\")",
 
  129                             Bundle.AllCasesSearchDialog_resultsTitle_text(), type.getDisplayName(), value);
 
  130                     final TopComponent searchResultWin;
 
  131                     if (correlationInstances.isEmpty()) {
 
  132                         Node emptyNode = 
new TableFilterNode(
 
  133                                 new EmptyNode(Bundle.AllCasesSearchDialog_emptyNode_text()), 
true);
 
  134                         searchResultWin = DataResultTopComponent.createInstance(
 
  135                                 resultsText, Bundle.AllCasesSearchDialog_resultsDescription_text(), emptyNode, 0);
 
  137                         searchResultWin = DataResultTopComponent.createInstance(
 
  138                                 resultsText, Bundle.AllCasesSearchDialog_resultsDescription_text(), tableFilterNode, correlationInstances.size(), viewers);
 
  140                     searchResultWin.requestActive(); 
 
  141                 } 
catch (ExecutionException | InterruptedException ex) {
 
  142                     logger.log(Level.SEVERE, 
"Unable to get CorrelationAttributeInstances.", ex);
 
  153     @SuppressWarnings(
"unchecked")
 
  155     private 
void initComponents() {
 
  157         correlationValueLabel = 
new javax.swing.JLabel();
 
  158         correlationValueTextField = 
new javax.swing.JTextField();
 
  159         searchButton = 
new javax.swing.JButton();
 
  160         correlationTypeComboBox = 
new javax.swing.JComboBox<>();
 
  161         correlationTypeLabel = 
new javax.swing.JLabel();
 
  162         errorLabel = 
new javax.swing.JLabel();
 
  163         descriptionLabel = 
new javax.swing.JLabel();
 
  164         casesLabel = 
new javax.swing.JLabel();
 
  166         setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
 
  169         org.openide.awt.Mnemonics.setLocalizedText(correlationValueLabel, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.correlationValueLabel.text")); 
 
  171         correlationValueTextField.setText(
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.correlationValueTextField.text")); 
 
  172         correlationValueTextField.addKeyListener(
new java.awt.event.KeyAdapter() {
 
  173             public void keyReleased(java.awt.event.KeyEvent evt) {
 
  174                 valueFieldKeyReleaseListener(evt);
 
  178         org.openide.awt.Mnemonics.setLocalizedText(searchButton, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.searchButton.text")); 
 
  179         searchButton.addActionListener(
new java.awt.event.ActionListener() {
 
  180             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  181                 searchButtonActionPerformed(evt);
 
  185         correlationTypeComboBox.addActionListener(
new java.awt.event.ActionListener() {
 
  186             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  187                 correlationTypeComboBoxActionPerformed(evt);
 
  191         org.openide.awt.Mnemonics.setLocalizedText(correlationTypeLabel, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.correlationTypeLabel.text")); 
 
  193         errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
 
  194         org.openide.awt.Mnemonics.setLocalizedText(errorLabel, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.errorLabel.text")); 
 
  196         org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.descriptionLabel.text")); 
 
  198         casesLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
 
  199         org.openide.awt.Mnemonics.setLocalizedText(casesLabel, 
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.casesLabel.text")); 
 
  201         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(getContentPane());
 
  202         getContentPane().setLayout(layout);
 
  203         layout.setHorizontalGroup(
 
  204             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  205             .addGroup(layout.createSequentialGroup()
 
  207                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  208                     .addComponent(descriptionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
 
  209                     .addGroup(layout.createSequentialGroup()
 
  210                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  211                             .addComponent(correlationValueLabel)
 
  212                             .addComponent(correlationTypeLabel))
 
  213                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  214                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  215                             .addComponent(correlationTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  216                             .addComponent(correlationValueTextField)
 
  217                             .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
 
  218                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 
  219                         .addComponent(casesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  221                         .addComponent(searchButton)))
 
  224         layout.setVerticalGroup(
 
  225             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  226             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 
  228                 .addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  230                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  231                     .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  232                     .addComponent(correlationTypeLabel))
 
  234                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  235                     .addComponent(correlationValueTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  236                     .addComponent(correlationValueLabel))
 
  237                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  238                 .addComponent(errorLabel)
 
  239                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
 
  240                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  241                     .addComponent(searchButton)
 
  242                     .addComponent(casesLabel))
 
  246         searchButton.getAccessibleContext().setAccessibleName(
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.searchButton.AccessibleContext.accessibleName")); 
 
  247         searchButton.getAccessibleContext().setAccessibleDescription(
org.openide.util.NbBundle.getMessage(AllCasesSearchDialog.class, 
"AllCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription")); 
 
  252     private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  253         CorrelationAttributeInstance.Type correlationType = selectedCorrelationType;
 
  254         String correlationValue = correlationValueTextField.getText().trim();
 
  256         if (validateInputs(correlationType, correlationValue)) {
 
  257             search(correlationType, correlationValue);
 
  260             String validationMessage;
 
  261             switch (correlationType.getId()) {
 
  262                 case CorrelationAttributeInstance.FILES_TYPE_ID:
 
  263                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidHash();
 
  265                 case CorrelationAttributeInstance.DOMAIN_TYPE_ID:
 
  266                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidDomain();
 
  268                 case CorrelationAttributeInstance.EMAIL_TYPE_ID:
 
  269                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidEmail();
 
  271                 case CorrelationAttributeInstance.PHONE_TYPE_ID:
 
  272                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidPhone();
 
  274                 case CorrelationAttributeInstance.SSID_TYPE_ID:
 
  275                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidSsid();
 
  277                 case CorrelationAttributeInstance.MAC_TYPE_ID:
 
  278                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidMac();
 
  280                 case CorrelationAttributeInstance.IMEI_TYPE_ID:
 
  281                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImei();
 
  283                 case CorrelationAttributeInstance.IMSI_TYPE_ID:
 
  284                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidImsi();
 
  286                 case CorrelationAttributeInstance.ICCID_TYPE_ID:
 
  287                     validationMessage = Bundle.AllCasesSearchDialog_validation_invalidIccid();
 
  290                     validationMessage = Bundle.AllCasesSearchDialog_validation_genericMessage();
 
  294             errorLabel.setText(validationMessage);
 
  295             searchButton.setEnabled(
false);
 
  296             correlationValueTextField.grabFocus();
 
  300     private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  302         errorLabel.setText(
"");
 
  305     private void valueFieldKeyReleaseListener(java.awt.event.KeyEvent evt) {
 
  307         errorLabel.setText(
"");
 
  318     private boolean validateInputs(CorrelationAttributeInstance.Type type, String value) {
 
  320             CorrelationAttributeNormalizer.normalize(type, value);
 
  321         } 
catch (CorrelationAttributeNormalizationException ex) {
 
  332     private void customizeComponents() {
 
  333         searchButton.setEnabled(
false);
 
  339             EamDb dbManager = EamDb.getInstance();
 
  340             correlationTypes.clear();
 
  341             correlationTypes.addAll(dbManager.getDefinedCorrelationTypes());
 
  342             int numberOfCases = dbManager.getCases().size();
 
  343             casesLabel.setText(Bundle.AllCasesSearchDialog_caseLabel_text(numberOfCases));
 
  344         } 
catch (EamDbException ex) {
 
  345             logger.log(Level.SEVERE, 
"Unable to connect to the Central Repository database.", ex);
 
  348         for (CorrelationAttributeInstance.Type type : correlationTypes) {
 
  349             correlationTypeComboBox.addItem(type.getDisplayName());
 
  351         correlationTypeComboBox.setSelectedIndex(0);
 
  353         correlationTypeComboBox.addItemListener(
new ItemListener() {
 
  355             public void itemStateChanged(ItemEvent e) {
 
  356                 updateSelectedType();
 
  357                 updateCorrelationValueTextFieldPrompt();
 
  358                 updateSearchButton();
 
  362         updateSelectedType();
 
  367         correlationValueTextField.getDocument().addDocumentListener(
new DocumentListener() {
 
  369             public void changedUpdate(DocumentEvent e) {
 
  370                 updateSearchButton();
 
  374             public void insertUpdate(DocumentEvent e) {
 
  375                 updateSearchButton();
 
  379             public void removeUpdate(DocumentEvent e) {
 
  380                 updateSearchButton();
 
  384         updateCorrelationValueTextFieldPrompt();
 
  388         "AllCasesSearchDialog.correlationValueTextField.filesExample=Example: \"f0e1d2c3b4a5968778695a4b3c2d1e0f\"",
 
  389         "AllCasesSearchDialog.correlationValueTextField.domainExample=Example: \"domain.com\"",
 
  390         "AllCasesSearchDialog.correlationValueTextField.emailExample=Example: \"user@host.com\"",
 
  391         "AllCasesSearchDialog.correlationValueTextField.phoneExample=Example: \"(800)123-4567\"",
 
  392         "AllCasesSearchDialog.correlationValueTextField.usbExample=Example: \"4&1234567&0\"",
 
  393         "AllCasesSearchDialog.correlationValueTextField.ssidExample=Example: \"WirelessNetwork-5G\"",
 
  394         "AllCasesSearchDialog.correlationValueTextField.macExample=Example: \"0C-14-F2-01-AF-45\"",
 
  395         "AllCasesSearchDialog.correlationValueTextField.imeiExample=Example: \"351756061523999\"",
 
  396         "AllCasesSearchDialog.correlationValueTextField.imsiExample=Example: \"310150123456789\"",
 
  397         "AllCasesSearchDialog.correlationValueTextField.iccidExample=Example: \"89 91 19 1299 99 329451 0\"" 
  403     private void updateCorrelationValueTextFieldPrompt() {
 
  408         switch (selectedCorrelationType.getId()) {
 
  409             case CorrelationAttributeInstance.FILES_TYPE_ID:
 
  410                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_filesExample();
 
  412             case CorrelationAttributeInstance.DOMAIN_TYPE_ID:
 
  413                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_domainExample();
 
  415             case CorrelationAttributeInstance.EMAIL_TYPE_ID:
 
  416                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_emailExample();
 
  418             case CorrelationAttributeInstance.PHONE_TYPE_ID:
 
  419                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_phoneExample();
 
  421             case CorrelationAttributeInstance.USBID_TYPE_ID:
 
  422                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_usbExample();
 
  424             case CorrelationAttributeInstance.SSID_TYPE_ID:
 
  425                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_ssidExample();
 
  427             case CorrelationAttributeInstance.MAC_TYPE_ID:
 
  428                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_macExample();
 
  430             case CorrelationAttributeInstance.IMEI_TYPE_ID:
 
  431                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_imeiExample();
 
  433             case CorrelationAttributeInstance.IMSI_TYPE_ID:
 
  434                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_imsiExample();
 
  436             case CorrelationAttributeInstance.ICCID_TYPE_ID:
 
  437                 text = Bundle.AllCasesSearchDialog_correlationValueTextField_iccidExample();
 
  443         correlationValueTextFieldPrompt = 
new TextPrompt(text, correlationValueTextField);
 
  448         correlationValueTextFieldPrompt.setForeground(Color.LIGHT_GRAY);
 
  449         correlationValueTextFieldPrompt.changeAlpha(0.9f); 
 
  459     private void updateSelectedType() {
 
  460         for (CorrelationAttributeInstance.Type type : correlationTypes) {
 
  461             if (type.getDisplayName().equals((String) correlationTypeComboBox.getSelectedItem())) {
 
  462                 selectedCorrelationType = type;
 
  472     private void updateSearchButton() {
 
  473         searchButton.setEnabled(correlationValueTextField.getText().isEmpty() == 
false);
 
  479     public void display() {
 
  480         this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
 
  485     private javax.swing.JLabel casesLabel;
 
  486     private javax.swing.JComboBox<String> correlationTypeComboBox;
 
  487     private javax.swing.JLabel correlationTypeLabel;
 
  488     private javax.swing.JLabel correlationValueLabel;
 
  489     private javax.swing.JTextField correlationValueTextField;
 
  490     private javax.swing.JLabel descriptionLabel;
 
  491     private javax.swing.JLabel errorLabel;
 
  492     private javax.swing.JButton searchButton;