19 package org.sleuthkit.autopsy.logicalimager.configuration;
 
   21 import java.awt.Color;
 
   22 import java.awt.event.ActionEvent;
 
   23 import java.awt.event.KeyAdapter;
 
   24 import java.awt.event.KeyEvent;
 
   25 import java.io.IOException;
 
   26 import java.text.ParseException;
 
   27 import java.util.ArrayList;
 
   28 import java.util.List;
 
   29 import java.util.logging.Level;
 
   30 import javax.swing.JButton;
 
   31 import javax.swing.JComboBox;
 
   32 import javax.swing.JComponent;
 
   33 import javax.swing.JOptionPane;
 
   34 import javax.swing.JScrollPane;
 
   35 import javax.swing.JTextArea;
 
   36 import javax.swing.JTextField;
 
   37 import javax.swing.SwingUtilities;
 
   38 import javax.swing.event.DocumentEvent;
 
   39 import javax.swing.event.DocumentListener;
 
   40 import org.apache.commons.lang.StringUtils;
 
   41 import static org.apache.commons.lang.StringUtils.isBlank;
 
   42 import static org.apache.commons.lang3.StringUtils.strip;
 
   43 import org.apache.commons.lang3.tuple.ImmutablePair;
 
   44 import org.openide.util.NbBundle;
 
   50 @SuppressWarnings(
"PMD.SingularField") 
 
   51 final class EditNonFullPathsRulePanel extends javax.swing.JPanel {
 
   53     private static final Logger logger = Logger.
getLogger(EditNonFullPathsRulePanel.class.getName());
 
   54     private static final long serialVersionUID = 1L;
 
   55     private static final Color DISABLED_COLOR = 
new Color(240, 240, 240);
 
   56     private static final int BYTE_UNIT_CONVERSION = 1000;
 
   57     private JButton okButton;
 
   58     private JButton cancelButton;
 
   59     private final javax.swing.JTextArea fileNamesTextArea;
 
   60     private final javax.swing.JTextArea folderNamesTextArea;
 
   66         "EditNonFullPathsRulePanel.example=Example: ",
 
   67         "EditNonFullPathsRulePanel.units.bytes=Bytes",
 
   68         "EditNonFullPathsRulePanel.units.kilobytes=Kilobytes",
 
   69         "EditNonFullPathsRulePanel.units.megabytes=Megabytes",
 
   70         "EditNonFullPathsRulePanel.units.gigabytes=Gigabytes" 
   72     EditNonFullPathsRulePanel(JButton okButton, JButton cancelButton, String ruleName, LogicalImagerRule rule, 
boolean editing) {
 
   75         this.setRule(ruleName, rule);
 
   76         this.setButtons(okButton, cancelButton);
 
   78         setExtensions(rule.getExtensions());
 
   79         fileNamesTextArea = 
new JTextArea();
 
   80         initTextArea(filenamesScrollPane, fileNamesTextArea);
 
   81         setTextArea(fileNamesTextArea, rule.getFilenames());
 
   82         if (rule.getExtensions() != null && !rule.getExtensions().isEmpty()) {
 
   83             extensionsCheckbox.setSelected(
true);
 
   84             extensionsTextField.setEnabled(extensionsCheckbox.isSelected());
 
   85         } 
else if (rule.getFilenames() != null && !rule.getFilenames().isEmpty()) {
 
   86             fileNamesCheckbox.setSelected(
true);
 
   87             fileNamesTextArea.setEnabled(fileNamesCheckbox.isSelected());
 
   89         updateExclusiveConditions();
 
   90         folderNamesTextArea = 
new JTextArea();
 
   91         initTextArea(folderNamesScrollPane, folderNamesTextArea);
 
   92         setTextArea(folderNamesTextArea, rule.getPaths());
 
   93         folderNamesCheckbox.setSelected(!StringUtils.isBlank(folderNamesTextArea.getText()));
 
   94         folderNamesTextArea.setEnabled(folderNamesCheckbox.isSelected());
 
   95         updateTextAreaBackgroundColor(folderNamesTextArea);
 
   96         setModifiedWithin(rule.getMinDays());
 
   98         setupMinMaxSizeOptions(rule);
 
   99         ruleNameTextField.requestFocus();
 
  101         EditRulePanel.setTextFieldPrompts(extensionsTextField, Bundle.EditNonFullPathsRulePanel_example() + 
"gif,jpg,png"); 
 
  102         EditRulePanel.setTextFieldPrompts(fileNamesTextArea, 
"<html>" 
  103                 + Bundle.EditNonFullPathsRulePanel_example()
 
  104                 + 
"<br>filename.txt<br>readme.txt</html>"); 
 
  105         EditRulePanel.setTextFieldPrompts(folderNamesTextArea, 
"<html>" 
  106                 + Bundle.EditNonFullPathsRulePanel_example()
 
  107                 + 
"<br>[USER_FOLDER]/My Documents/Downloads" 
  108                 + 
"<br>/Program Files/Common Files</html>"); 
 
  111         addDocumentListeners();
 
  119     private void setupMinMaxSizeOptions(LogicalImagerRule rule) {
 
  120         String savedMinSize = rule.getMinFileSize() == null ? 
"" : rule.getMinFileSize().toString();
 
  121         setSizeAndUnits(minSizeTextField, minSizeUnitsCombobox, savedMinSize);
 
  122         minSizeCheckbox.setSelected(!StringUtils.isBlank(minSizeTextField.getText()));
 
  123         minSizeTextField.setEnabled(minSizeCheckbox.isSelected());
 
  124         minSizeUnitsCombobox.setEnabled(minSizeCheckbox.isSelected());
 
  126         String savedMaxSize = rule.getMaxFileSize() == null ? 
"" : rule.getMaxFileSize().toString();
 
  127         setSizeAndUnits(maxSizeTextField, maxSizeUnitsCombobox, savedMaxSize);
 
  128         maxSizeCheckbox.setSelected(!StringUtils.isBlank(maxSizeTextField.getText()));
 
  129         maxSizeTextField.setEnabled(maxSizeCheckbox.isSelected());
 
  130         maxSizeUnitsCombobox.setEnabled(maxSizeCheckbox.isSelected());
 
  136     private void addDocumentListeners() {
 
  137         SwingUtilities.invokeLater(() -> {
 
  140         DocumentListener docListener;
 
  141         docListener = 
new DocumentListener() {
 
  143             public void changedUpdate(DocumentEvent e) {
 
  148             public void insertUpdate(DocumentEvent e) {
 
  153             public void removeUpdate(DocumentEvent e) {
 
  157         ruleNameTextField.getDocument().addDocumentListener(docListener);
 
  158         extensionsTextField.getDocument().addDocumentListener(docListener);
 
  159         fileNamesTextArea.getDocument().addDocumentListener(docListener);
 
  160         folderNamesTextArea.getDocument().addDocumentListener(docListener);
 
  161         minSizeTextField.getDocument().addDocumentListener(docListener);
 
  162         maxSizeTextField.getDocument().addDocumentListener(docListener);
 
  163         modifiedWithinTextField.getDocument().addDocumentListener(docListener);
 
  172     private void initTextArea(JScrollPane pane, JTextArea textArea) {
 
  173         textArea.setColumns(20);
 
  175         pane.setViewportView(textArea);
 
  176         textArea.setEnabled(
false);
 
  177         textArea.setEditable(
false);
 
  178         textArea.setBackground(DISABLED_COLOR);
 
  179         textArea.addKeyListener(
new KeyAdapter() {
 
  181             public void keyPressed(KeyEvent e) {
 
  182                 if (e.getKeyCode() == KeyEvent.VK_TAB) {
 
  183                     if (e.getModifiers() > 0) {
 
  184                         textArea.transferFocusBackward();
 
  186                         textArea.transferFocus();
 
  203     private long convertToBytes(
long value, String units) {
 
  204         long convertedValue = value;
 
  205         if (units.equals(Bundle.EditNonFullPathsRulePanel_units_gigabytes())) {
 
  206             convertedValue = convertedValue * BYTE_UNIT_CONVERSION * BYTE_UNIT_CONVERSION * BYTE_UNIT_CONVERSION;
 
  207         } 
else if (units.equals(Bundle.EditNonFullPathsRulePanel_units_megabytes())) {
 
  208             convertedValue = convertedValue * BYTE_UNIT_CONVERSION * BYTE_UNIT_CONVERSION;
 
  209         } 
else if (units.equals(Bundle.EditNonFullPathsRulePanel_units_kilobytes())) {
 
  210             convertedValue *= BYTE_UNIT_CONVERSION;
 
  212         return convertedValue;
 
  223     private void setSizeAndUnits(JTextField sizeField, JComboBox<String> unitsComboBox, String value) {
 
  224         if (StringUtils.isBlank(value)) {
 
  225             unitsComboBox.setSelectedItem(Bundle.EditNonFullPathsRulePanel_units_bytes());
 
  226             sizeField.setText(
"");
 
  229         long longValue = Long.valueOf(value);
 
  230         if (longValue % BYTE_UNIT_CONVERSION != 0) {
 
  231             unitsComboBox.setSelectedItem(Bundle.EditNonFullPathsRulePanel_units_bytes());
 
  232             sizeField.setText(value);  
 
  235         longValue /= BYTE_UNIT_CONVERSION;
 
  236         if (longValue % BYTE_UNIT_CONVERSION != 0) {
 
  237             unitsComboBox.setSelectedItem(Bundle.EditNonFullPathsRulePanel_units_kilobytes());
 
  238             sizeField.setText(String.valueOf(longValue));
 
  241         longValue /= BYTE_UNIT_CONVERSION;
 
  242         if (longValue % BYTE_UNIT_CONVERSION != 0) {
 
  243             unitsComboBox.setSelectedItem(Bundle.EditNonFullPathsRulePanel_units_megabytes());
 
  244             sizeField.setText(String.valueOf(longValue));
 
  247         longValue /= BYTE_UNIT_CONVERSION;
 
  248         unitsComboBox.setSelectedItem(Bundle.EditNonFullPathsRulePanel_units_gigabytes());
 
  249         sizeField.setText(String.valueOf(longValue));
 
  258     private void setModifiedWithin(Integer minDays) {
 
  259         modifiedWithinTextField.setText(minDays == null ? 
"" : minDays.toString());
 
  260         modifiedWithinCheckbox.setSelected(!StringUtils.isBlank(modifiedWithinTextField.getText()));
 
  261         modifiedWithinTextField.setEnabled(modifiedWithinCheckbox.isSelected());
 
  270     private void setTextArea(JTextArea textArea, List<String> list) {
 
  273             text = list.stream().map((s) -> s + System.getProperty(
"line.separator")).reduce(text, String::concat); 
 
  275         textArea.setText(text);
 
  283     private void setExtensions(List<String> extensions) {
 
  284         extensionsTextField.setText(
"");
 
  286         if (extensions != null) {
 
  287             boolean first = 
true;
 
  288             for (String ext : extensions) {
 
  289                 content += (first ? 
"" : 
",") + ext;
 
  293         extensionsCheckbox.setSelected(!StringUtils.isBlank(content));
 
  294         extensionsTextField.setText(content);
 
  302     @SuppressWarnings(
"unchecked")
 
  304     private 
void initComponents() {
 
  306         daysIncludedLabel = 
new javax.swing.JLabel();
 
  307         shouldSaveCheckBox = 
new javax.swing.JCheckBox();
 
  308         shouldAlertCheckBox = 
new javax.swing.JCheckBox();
 
  309         extensionsTextField = 
new javax.swing.JTextField();
 
  310         descriptionTextField = 
new javax.swing.JTextField();
 
  311         ruleNameLabel = 
new javax.swing.JLabel();
 
  312         ruleNameTextField = 
new javax.swing.JTextField();
 
  313         filenamesScrollPane = 
new javax.swing.JScrollPane();
 
  314         folderNamesScrollPane = 
new javax.swing.JScrollPane();
 
  315         minSizeTextField = 
new javax.swing.JFormattedTextField();
 
  316         maxSizeTextField = 
new javax.swing.JFormattedTextField();
 
  317         modifiedWithinTextField = 
new javax.swing.JFormattedTextField();
 
  318         userFolderNote = 
new javax.swing.JLabel();
 
  319         minSizeCheckbox = 
new javax.swing.JCheckBox();
 
  320         maxSizeCheckbox = 
new javax.swing.JCheckBox();
 
  321         modifiedWithinCheckbox = 
new javax.swing.JCheckBox();
 
  322         folderNamesCheckbox = 
new javax.swing.JCheckBox();
 
  323         fileNamesCheckbox = 
new javax.swing.JCheckBox();
 
  324         extensionsCheckbox = 
new javax.swing.JCheckBox();
 
  325         minSizeUnitsCombobox = 
new javax.swing.JComboBox<>();
 
  326         maxSizeUnitsCombobox = 
new javax.swing.JComboBox<>();
 
  327         jSeparator1 = 
new javax.swing.JSeparator();
 
  328         jSeparator2 = 
new javax.swing.JSeparator();
 
  329         descriptionLabel = 
new javax.swing.JLabel();
 
  330         jLabel2 = 
new javax.swing.JLabel();
 
  331         jLabel1 = 
new javax.swing.JLabel();
 
  332         extensionsInfoLabel = 
new javax.swing.JLabel();
 
  333         fileNamesInfoLabel = 
new javax.swing.JLabel();
 
  335         org.openide.awt.Mnemonics.setLocalizedText(daysIncludedLabel, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.daysIncludedLabel.text")); 
 
  337         shouldSaveCheckBox.setSelected(
true);
 
  338         org.openide.awt.Mnemonics.setLocalizedText(shouldSaveCheckBox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.shouldSaveCheckBox.text")); 
 
  339         shouldSaveCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  340             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  341                 shouldSaveCheckBoxActionPerformed(evt);
 
  345         org.openide.awt.Mnemonics.setLocalizedText(shouldAlertCheckBox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.shouldAlertCheckBox.text")); 
 
  346         shouldAlertCheckBox.setActionCommand(
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.shouldAlertCheckBox.actionCommand")); 
 
  347         shouldAlertCheckBox.addActionListener(
new java.awt.event.ActionListener() {
 
  348             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  349                 shouldAlertCheckBoxActionPerformed(evt);
 
  353         extensionsTextField.setEnabled(
false);
 
  355         org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.ruleNameLabel.text")); 
 
  356         ruleNameLabel.setPreferredSize(
new java.awt.Dimension(112, 14));
 
  358         filenamesScrollPane.setToolTipText(
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.filenamesScrollPane.toolTipText")); 
 
  359         filenamesScrollPane.setEnabled(
false);
 
  361         folderNamesScrollPane.setEnabled(
false);
 
  363         minSizeTextField.setFormatterFactory(
new javax.swing.text.DefaultFormatterFactory(
new DefaultToEmptyNumberFormatter(
new java.text.DecimalFormat(
"#,###; "))));
 
  364         minSizeTextField.setEnabled(
false);
 
  366         maxSizeTextField.setFormatterFactory(
new javax.swing.text.DefaultFormatterFactory(
new DefaultToEmptyNumberFormatter(
new java.text.DecimalFormat(
"#,###; "))));
 
  367         maxSizeTextField.setEnabled(
false);
 
  369         modifiedWithinTextField.setFormatterFactory(
new javax.swing.text.DefaultFormatterFactory(
new DefaultToEmptyNumberFormatter(
new java.text.DecimalFormat(
"#,###; "))));
 
  370         modifiedWithinTextField.setEnabled(
false);
 
  372         userFolderNote.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/info-icon-16.png"))); 
 
  373         org.openide.awt.Mnemonics.setLocalizedText(userFolderNote, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.userFolderNote.text")); 
 
  375         org.openide.awt.Mnemonics.setLocalizedText(minSizeCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.minSizeCheckbox.text")); 
 
  376         minSizeCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  377         minSizeCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  378             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  379                 minSizeCheckboxActionPerformed(evt);
 
  383         org.openide.awt.Mnemonics.setLocalizedText(maxSizeCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.maxSizeCheckbox.text")); 
 
  384         maxSizeCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  385         maxSizeCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  386             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  387                 maxSizeCheckboxActionPerformed(evt);
 
  391         org.openide.awt.Mnemonics.setLocalizedText(modifiedWithinCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.modifiedWithinCheckbox.text")); 
 
  392         modifiedWithinCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  393         modifiedWithinCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  394             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  395                 modifiedWithinCheckboxActionPerformed(evt);
 
  399         org.openide.awt.Mnemonics.setLocalizedText(folderNamesCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.folderNamesCheckbox.text")); 
 
  400         folderNamesCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  401         folderNamesCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  402             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  403                 folderNamesCheckboxActionPerformed(evt);
 
  407         org.openide.awt.Mnemonics.setLocalizedText(fileNamesCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.fileNamesCheckbox.text")); 
 
  408         fileNamesCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  409         fileNamesCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  410             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  411                 fileNamesCheckboxActionPerformed(evt);
 
  415         org.openide.awt.Mnemonics.setLocalizedText(extensionsCheckbox, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.extensionsCheckbox.text")); 
 
  416         extensionsCheckbox.setPreferredSize(
new java.awt.Dimension(112, 23));
 
  417         extensionsCheckbox.addActionListener(
new java.awt.event.ActionListener() {
 
  418             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  419                 extensionsCheckboxActionPerformed(evt);
 
  423         minSizeUnitsCombobox.setModel(
new javax.swing.DefaultComboBoxModel<String>(
new String[] { Bundle.EditNonFullPathsRulePanel_units_bytes(), Bundle.EditNonFullPathsRulePanel_units_kilobytes(), Bundle.EditNonFullPathsRulePanel_units_megabytes(), Bundle.EditNonFullPathsRulePanel_units_gigabytes()}));
 
  424         minSizeUnitsCombobox.setEnabled(
false);
 
  426         maxSizeUnitsCombobox.setModel(
new javax.swing.DefaultComboBoxModel<String>(
new String[] { Bundle.EditNonFullPathsRulePanel_units_bytes(), Bundle.EditNonFullPathsRulePanel_units_kilobytes(), Bundle.EditNonFullPathsRulePanel_units_megabytes(), Bundle.EditNonFullPathsRulePanel_units_gigabytes()}));
 
  427         maxSizeUnitsCombobox.setEnabled(
false);
 
  429         org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.descriptionLabel.text")); 
 
  430         descriptionLabel.setPreferredSize(
new java.awt.Dimension(112, 14));
 
  432         org.openide.awt.Mnemonics.setLocalizedText(jLabel2, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.jLabel2.text")); 
 
  434         org.openide.awt.Mnemonics.setLocalizedText(jLabel1, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.jLabel1.text")); 
 
  436         extensionsInfoLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/info-icon-16.png"))); 
 
  437         org.openide.awt.Mnemonics.setLocalizedText(extensionsInfoLabel, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.extensionsInfoLabel.text")); 
 
  439         fileNamesInfoLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/info-icon-16.png"))); 
 
  440         org.openide.awt.Mnemonics.setLocalizedText(fileNamesInfoLabel, 
org.openide.util.NbBundle.getMessage(EditNonFullPathsRulePanel.class, 
"EditNonFullPathsRulePanel.fileNamesInfoLabel.text")); 
 
  442         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  443         this.setLayout(layout);
 
  444         layout.setHorizontalGroup(
 
  445             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  446             .addGroup(layout.createSequentialGroup()
 
  448                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  449                     .addComponent(jSeparator2)
 
  450                     .addComponent(jSeparator1)
 
  451                     .addGroup(layout.createSequentialGroup()
 
  452                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  453                             .addComponent(shouldAlertCheckBox)
 
  454                             .addComponent(shouldSaveCheckBox)
 
  455                             .addComponent(fileNamesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  456                             .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, 
false)
 
  457                                 .addComponent(modifiedWithinCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  458                                 .addComponent(maxSizeCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  459                             .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  460                         .addGap(0, 0, Short.MAX_VALUE))
 
  461                     .addGroup(layout.createSequentialGroup()
 
  462                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  463                             .addComponent(extensionsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  464                             .addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  465                             .addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  466                             .addComponent(minSizeCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  467                             .addComponent(folderNamesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  469                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  470                             .addComponent(ruleNameTextField, javax.swing.GroupLayout.Alignment.TRAILING)
 
  471                             .addComponent(descriptionTextField, javax.swing.GroupLayout.Alignment.TRAILING)
 
  472                             .addComponent(extensionsTextField, javax.swing.GroupLayout.Alignment.TRAILING)
 
  473                             .addComponent(folderNamesScrollPane)
 
  474                             .addComponent(filenamesScrollPane, javax.swing.GroupLayout.Alignment.TRAILING)
 
  475                             .addGroup(layout.createSequentialGroup()
 
  476                                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  477                                     .addComponent(fileNamesInfoLabel)
 
  478                                     .addComponent(extensionsInfoLabel)
 
  479                                     .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
 
  480                                         .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 522, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  481                                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  482                                             .addComponent(userFolderNote)
 
  483                                             .addGroup(layout.createSequentialGroup()
 
  484                                                 .addComponent(minSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  485                                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  486                                                 .addComponent(minSizeUnitsCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  487                                             .addGroup(layout.createSequentialGroup()
 
  488                                                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
 
  489                                                     .addComponent(modifiedWithinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  490                                                     .addComponent(maxSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  491                                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  492                                                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  493                                                     .addComponent(maxSizeUnitsCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  494                                                     .addComponent(daysIncludedLabel))))))
 
  495                                 .addGap(0, 11, Short.MAX_VALUE)))))
 
  499         layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, 
new java.awt.Component[] {maxSizeTextField, minSizeTextField, modifiedWithinTextField});
 
  501         layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, 
new java.awt.Component[] {descriptionLabel, extensionsCheckbox, fileNamesCheckbox, folderNamesCheckbox, maxSizeCheckbox, minSizeCheckbox, modifiedWithinCheckbox, ruleNameLabel});
 
  503         layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, 
new java.awt.Component[] {maxSizeUnitsCombobox, minSizeUnitsCombobox});
 
  505         layout.setVerticalGroup(
 
  506             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  507             .addGroup(layout.createSequentialGroup()
 
  509                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
 
  510                     .addComponent(ruleNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  511                     .addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  512                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  513                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  514                     .addComponent(descriptionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  515                     .addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  516                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  517                 .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  518                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  519                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  520                     .addComponent(extensionsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  521                     .addComponent(extensionsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  522                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  523                 .addComponent(extensionsInfoLabel)
 
  524                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  525                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  526                     .addComponent(filenamesScrollPane)
 
  527                     .addGroup(layout.createSequentialGroup()
 
  528                         .addComponent(fileNamesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  529                         .addGap(0, 0, Short.MAX_VALUE)))
 
  530                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  531                 .addComponent(fileNamesInfoLabel)
 
  532                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  533                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  534                     .addComponent(folderNamesScrollPane)
 
  535                     .addGroup(layout.createSequentialGroup()
 
  536                         .addComponent(folderNamesCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  537                         .addGap(0, 0, Short.MAX_VALUE)))
 
  538                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  539                 .addComponent(userFolderNote, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  540                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  541                 .addComponent(jLabel2)
 
  542                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  543                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  544                     .addComponent(minSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  545                     .addComponent(minSizeCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  546                     .addComponent(minSizeUnitsCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  547                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  548                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  549                     .addComponent(maxSizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  550                     .addComponent(maxSizeCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  551                     .addComponent(maxSizeUnitsCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  552                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  553                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
 
  554                     .addComponent(daysIncludedLabel)
 
  555                     .addComponent(modifiedWithinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  556                     .addComponent(modifiedWithinCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  557                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  558                 .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  559                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  560                 .addComponent(jLabel1)
 
  561                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  562                 .addComponent(shouldSaveCheckBox)
 
  563                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  564                 .addComponent(shouldAlertCheckBox)
 
  569     private void extensionsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  570         if (fileNamesCheckbox.isSelected() && extensionsCheckbox.isSelected()) {
 
  571             fileNamesCheckbox.setSelected(
false);
 
  573         updateExclusiveConditions();
 
  577     private void fileNamesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  578         if (fileNamesCheckbox.isSelected() && extensionsCheckbox.isSelected()) {
 
  579             extensionsCheckbox.setSelected(
false);
 
  581         updateExclusiveConditions();
 
  585     private void folderNamesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  586         folderNamesScrollPane.setEnabled(folderNamesCheckbox.isSelected());
 
  587         folderNamesTextArea.setEditable(folderNamesCheckbox.isSelected());
 
  588         folderNamesTextArea.setEnabled(folderNamesCheckbox.isSelected());
 
  589         updateTextAreaBackgroundColor(folderNamesTextArea);
 
  594     private void minSizeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  595         minSizeTextField.setEnabled(minSizeCheckbox.isSelected());
 
  596         minSizeUnitsCombobox.setEnabled(minSizeCheckbox.isSelected());
 
  600     private void maxSizeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  601         maxSizeTextField.setEnabled(maxSizeCheckbox.isSelected());
 
  602         maxSizeUnitsCombobox.setEnabled(maxSizeCheckbox.isSelected());
 
  606     private void modifiedWithinCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
  607         modifiedWithinTextField.setEnabled(modifiedWithinCheckbox.isSelected());
 
  611     private void shouldSaveCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  615     private void shouldAlertCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
 
  625     private static void updateTextAreaBackgroundColor(JTextArea textArea) {
 
  626         if (textArea.isEnabled()) {
 
  627             textArea.setBackground(Color.WHITE);
 
  629             textArea.setBackground(DISABLED_COLOR);
 
  637     private void updateExclusiveConditions() {
 
  638         extensionsTextField.setEnabled(extensionsCheckbox.isSelected());
 
  639         filenamesScrollPane.setEnabled(fileNamesCheckbox.isSelected());
 
  640         fileNamesTextArea.setEditable(fileNamesCheckbox.isSelected());
 
  641         fileNamesTextArea.setEnabled(fileNamesCheckbox.isSelected());
 
  642         updateTextAreaBackgroundColor(fileNamesTextArea);
 
  646     private javax.swing.JLabel daysIncludedLabel;
 
  647     private javax.swing.JLabel descriptionLabel;
 
  648     private javax.swing.JTextField descriptionTextField;
 
  649     private javax.swing.JCheckBox extensionsCheckbox;
 
  650     private javax.swing.JLabel extensionsInfoLabel;
 
  651     private javax.swing.JTextField extensionsTextField;
 
  652     private javax.swing.JCheckBox fileNamesCheckbox;
 
  653     private javax.swing.JLabel fileNamesInfoLabel;
 
  654     private javax.swing.JScrollPane filenamesScrollPane;
 
  655     private javax.swing.JCheckBox folderNamesCheckbox;
 
  656     private javax.swing.JScrollPane folderNamesScrollPane;
 
  657     private javax.swing.JLabel jLabel1;
 
  658     private javax.swing.JLabel jLabel2;
 
  659     private javax.swing.JSeparator jSeparator1;
 
  660     private javax.swing.JSeparator jSeparator2;
 
  661     private javax.swing.JCheckBox maxSizeCheckbox;
 
  662     private javax.swing.JFormattedTextField maxSizeTextField;
 
  663     private javax.swing.JComboBox<String> maxSizeUnitsCombobox;
 
  664     private javax.swing.JCheckBox minSizeCheckbox;
 
  665     private javax.swing.JFormattedTextField minSizeTextField;
 
  666     private javax.swing.JComboBox<String> minSizeUnitsCombobox;
 
  667     private javax.swing.JCheckBox modifiedWithinCheckbox;
 
  668     private javax.swing.JFormattedTextField modifiedWithinTextField;
 
  669     private javax.swing.JLabel ruleNameLabel;
 
  670     private javax.swing.JTextField ruleNameTextField;
 
  671     private javax.swing.JCheckBox shouldAlertCheckBox;
 
  672     private javax.swing.JCheckBox shouldSaveCheckBox;
 
  673     private javax.swing.JLabel userFolderNote;
 
  682     private void setRule(String ruleName, LogicalImagerRule rule) {
 
  683         ruleNameTextField.setText(ruleName);
 
  684         descriptionTextField.setText(rule.getDescription());
 
  685         shouldAlertCheckBox.setSelected(rule.isShouldAlert());
 
  686         shouldSaveCheckBox.setSelected(rule.isShouldSave());
 
  694         if (this.okButton != null) {
 
  695             this.okButton.setEnabled(!StringUtils.isBlank(ruleNameTextField.getText()) && atLeastOneConditionSet() && (shouldAlertCheckBox.isSelected() || shouldSaveCheckBox.isSelected()));
 
  705     private boolean atLeastOneConditionSet() {
 
  707             return (extensionsCheckbox.isSelected() && !StringUtils.isBlank(extensionsTextField.getText()) && !validateExtensions(extensionsTextField).isEmpty())
 
  708                     || (fileNamesCheckbox.isSelected() && !StringUtils.isBlank(fileNamesTextArea.getText()))
 
  709                     || (folderNamesCheckbox.isSelected() && !StringUtils.isBlank(folderNamesTextArea.getText()))
 
  710                     || (minSizeCheckbox.isSelected() && !StringUtils.isBlank(minSizeTextField.getText()) && isNonZeroLong(minSizeTextField.getValue()))
 
  711                     || (maxSizeCheckbox.isSelected() && !StringUtils.isBlank(maxSizeTextField.getText()) && isNonZeroLong(maxSizeTextField.getValue()))
 
  712                     || (modifiedWithinCheckbox.isSelected() && !StringUtils.isBlank(modifiedWithinTextField.getText()) && isNonZeroLong(modifiedWithinTextField.getValue()));
 
  713         } 
catch (IOException ex) {
 
  714             logger.log(Level.WARNING, 
"Invalid contents of extensionsTextField", ex);
 
  726     private boolean isNonZeroLong(Object numberObject) {
 
  729             if (numberObject instanceof Number) {
 
  730                 value = ((Number) numberObject).longValue();
 
  732         } 
catch (NumberFormatException ignored) {
 
  745     private JOptionPane getOptionPane(JComponent parent) {
 
  747         if (!(parent instanceof JOptionPane)) {
 
  748             pane = getOptionPane((JComponent) parent.getParent());
 
  750             pane = (JOptionPane) parent;
 
  761     private void setButtons(JButton ok, JButton cancel) {
 
  763         this.cancelButton = cancel;
 
  764         okButton.addActionListener((ActionEvent e) -> {
 
  765             JOptionPane pane = getOptionPane(okButton);
 
  766             pane.setValue(okButton);
 
  768         cancelButton.addActionListener((ActionEvent e) -> {
 
  769             JOptionPane pane = getOptionPane(cancelButton);
 
  770             pane.setValue(cancelButton);
 
  784         "EditNonFullPathsRulePanel.modifiedDaysNotPositiveException=Modified days must be a positive",
 
  786         "EditNonFullPathsRulePanel.modifiedDaysMustBeNumberException=Modified days must be a number: {0}",
 
  787         "EditNonFullPathsRulePanel.minFileSizeNotPositiveException=Minimum file size must be a positive",
 
  789         "EditNonFullPathsRulePanel.minFileSizeMustBeNumberException=Minimum file size must be a number: {0}",
 
  790         "EditNonFullPathsRulePanel.maxFileSizeNotPositiveException=Maximum file size must be a positive",
 
  792         "EditNonFullPathsRulePanel.maxFileSizeMustBeNumberException=Maximum file size must be a number: {0}",
 
  793         "# {0} - maxFileSize",
 
  794         "# {1} - minFileSize",
 
  795         "EditNonFullPathsRulePanel.maxFileSizeSmallerThanMinException=Maximum file size: {0} bytes must be bigger than minimum file size: {1} bytes",
 
  796         "EditNonFullPathsRulePanel.fileNames=File names",
 
  797         "EditNonFullPathsRulePanel.folderNames=Folder names",})
 
  798     ImmutablePair<String, LogicalImagerRule> toRule() 
throws IOException {
 
  799         String ruleName = EditRulePanel.validRuleName(ruleNameTextField.getText());
 
  800         List<String> folderNames = folderNamesCheckbox.isSelected() ? EditRulePanel.validateTextList(folderNamesTextArea, Bundle.EditNonFullPathsRulePanel_folderNames()) : null;
 
  802         LogicalImagerRule.Builder builder = 
new LogicalImagerRule.Builder();
 
  803         builder.getName(ruleName)
 
  804                 .getDescription(descriptionTextField.getText())
 
  805                 .getShouldAlert(shouldAlertCheckBox.isSelected())
 
  806                 .getShouldSave(shouldSaveCheckBox.isSelected())
 
  807                 .getPaths(folderNames);
 
  809         if (extensionsCheckbox.isSelected()) {
 
  810             builder.getExtensions(validateExtensions(extensionsTextField));
 
  811         } 
else if (fileNamesCheckbox.isSelected()) {
 
  812             builder.getFilenames(EditRulePanel.validateTextList(fileNamesTextArea, Bundle.EditNonFullPathsRulePanel_fileNames()));
 
  816         if (modifiedWithinCheckbox.isSelected() && !isBlank(modifiedWithinTextField.getText())) {
 
  818                 modifiedWithinTextField.commitEdit();
 
  819                 minDays = ((Number) modifiedWithinTextField.getValue()).intValue();
 
  821                     throw new IOException(Bundle.EditNonFullPathsRulePanel_modifiedDaysNotPositiveException());
 
  823                 builder.getMinDays(minDays);
 
  824             } 
catch (NumberFormatException | ParseException ex) {
 
  825                 throw new IOException(Bundle.EditNonFullPathsRulePanel_modifiedDaysMustBeNumberException(ex.getMessage()), ex);
 
  829         long minFileSize = 0;
 
  830         if (minSizeCheckbox.isSelected() && !isBlank(minSizeTextField.getText())) {
 
  832                 minSizeTextField.commitEdit();
 
  833                 minFileSize = ((Number) minSizeTextField.getValue()).longValue();
 
  834                 if (minFileSize < 0) {
 
  835                     throw new IOException(Bundle.EditNonFullPathsRulePanel_minFileSizeNotPositiveException());
 
  837                 minFileSize = convertToBytes(minFileSize, minSizeUnitsCombobox.getItemAt(minSizeUnitsCombobox.getSelectedIndex()));
 
  838             } 
catch (NumberFormatException | ParseException ex) {
 
  839                 throw new IOException(Bundle.EditNonFullPathsRulePanel_minFileSizeMustBeNumberException(ex.getMessage()), ex);
 
  843         long maxFileSize = 0;
 
  844         if (maxSizeCheckbox.isSelected() && !isBlank(maxSizeTextField.getText())) {
 
  846                 maxSizeTextField.commitEdit();
 
  847                 maxFileSize = ((Number) maxSizeTextField.getValue()).longValue();
 
  848                 if (maxFileSize < 0) {
 
  849                     throw new IOException(Bundle.EditNonFullPathsRulePanel_maxFileSizeNotPositiveException());
 
  851                 maxFileSize = convertToBytes(maxFileSize, maxSizeUnitsCombobox.getItemAt(maxSizeUnitsCombobox.getSelectedIndex()));
 
  852             } 
catch (NumberFormatException | ParseException ex) {
 
  853                 throw new IOException(Bundle.EditNonFullPathsRulePanel_maxFileSizeMustBeNumberException(ex.getMessage()), ex);
 
  857         if (maxFileSize != 0 && (maxFileSize < minFileSize)) {
 
  858             throw new IOException(Bundle.EditNonFullPathsRulePanel_maxFileSizeSmallerThanMinException(maxFileSize, minFileSize));
 
  860         if (minSizeCheckbox.isSelected() && minFileSize != 0) {
 
  861             builder.getMinFileSize(minFileSize);
 
  863         if (maxSizeCheckbox.isSelected() && maxFileSize != 0) {
 
  864             builder.getMaxFileSize(maxFileSize);
 
  867         LogicalImagerRule rule = builder.build();
 
  868         return new ImmutablePair<>(ruleName, rule);
 
  882         "EditNonFullPathsRulePanel.emptyExtensionException=Extensions cannot have an empty entry",})
 
  883     private List<String> validateExtensions(JTextField textField) 
throws IOException {
 
  884         if (isBlank(textField.getText())) {
 
  887         List<String> extensions = 
new ArrayList<>();
 
  888         for (String extension : textField.getText().split(
",")) {
 
  889             String strippedExtension = strip(extension);
 
  890             if (strippedExtension.isEmpty()) {
 
  891                 throw new IOException(Bundle.EditNonFullPathsRulePanel_emptyExtensionException());
 
  893             extensions.add(strippedExtension);
 
  895         if (extensions.isEmpty()) {
 
synchronized static Logger getLogger(String name)