diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties index 7a051ed6b4..3a923af11d 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties @@ -119,3 +119,4 @@ NewRulePanel.chooseLabel.text=Choose the type of rule ConfigVisualPanel1.configureDriveRadioButton.text_1=Configure selected external drive: ConfigVisualPanel1.configureFolderRadioButton.text_1=Configure in a folder: ConfigVisualPanel1.descriptionTextArea.text=Select a location you will configure for use by the Logical Imager. A config file will be created if one does not already exist, and a copy of the Logical Imager executable will copied to this location. This will also be the location where the Logical Imager executable creates folders containing output. +ConfigVisualPanel1.refreshButton.text=Refresh diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties-MERGED index 5b6cb07e9b..4b6fcbe381 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/Bundle.properties-MERGED @@ -29,6 +29,7 @@ ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty ConfigVisualPanel1.configurationError=Configuration error ConfigVisualPanel1.fileNameExtensionFilter=Configuration JSON File ConfigVisualPanel1.invalidConfigJson=Invalid config JSON: +ConfigVisualPanel1.messageLabel.noExternalDriveFound=No drive found ConfigVisualPanel1.selectConfigurationFile=Select configuration file ConfigVisualPanel2.cancel=Cancel ConfigVisualPanel2.deleteRuleSet=Delete rule @@ -172,9 +173,10 @@ LogicalImagerConfigDeserializer.missingRuleSetException=Missing rule-set # {0} - key LogicalImagerConfigDeserializer.unsupportedKeyException=Unsupported key: {0} NewRulePanel.chooseLabel.text=Choose the type of rule -ConfigVisualPanel1.jTextArea1.text=Select a location you will configure for use by the Logical Imager. A config file will be created if one does not already exist, and a copy of the Logical Imager executable will copied to this location. This will also be the location where the Logical Imager executable creates folders containing its output. ConfigVisualPanel1.configureDriveRadioButton.text_1=Configure selected external drive: ConfigVisualPanel1.configureFolderRadioButton.text_1=Configure in a folder: +ConfigVisualPanel1.descriptionTextArea.text=Select a location you will configure for use by the Logical Imager. A config file will be created if one does not already exist, and a copy of the Logical Imager executable will copied to this location. This will also be the location where the Logical Imager executable creates folders containing output. +ConfigVisualPanel1.refreshButton.text=Refresh NewRuleSetPanel.attributeRule.description=Search for files based on one or more attributes or metadata fields. NewRuleSetPanel.attributeRule.name=Attribute NewRuleSetPanel.fullPathRule.description=Search for files based on full exact match path. diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.form b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.form index 46698626d4..bd7986f7bd 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.form +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.form @@ -23,27 +23,29 @@ - - - - - - + + + + + + + + + + + + + - - - - - - - - + + - + + @@ -54,14 +56,24 @@ - + + + + + + + + + - + + + @@ -73,6 +85,7 @@ + @@ -83,6 +96,7 @@ + @@ -126,6 +140,9 @@ + + + @@ -136,6 +153,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.java index 96ffcc41e4..bcb033a19f 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel1.java @@ -1,7 +1,7 @@ /* - * Autopsy Forensic Browser + * Autopsy * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2019 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,14 +28,22 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.nio.file.FileStore; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.filechooser.FileSystemView; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.logicalimager.dsp.DriveListUtils; /** * Configuration Visual Panel 1 @@ -43,6 +51,7 @@ import org.openide.util.NbBundle; @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class ConfigVisualPanel1 extends JPanel { + private static final long serialVersionUID = 1L; private LogicalImagerConfig config; private String configFilename; private boolean newFile = true; @@ -53,6 +62,10 @@ final class ConfigVisualPanel1 extends JPanel { ConfigVisualPanel1() { initComponents(); configFileTextField.getDocument().addDocumentListener(new MyDocumentListener(this)); + SwingUtilities.invokeLater(() -> { + updateControls(); + }); + refreshDriveList(); } @NbBundle.Messages({ @@ -78,12 +91,18 @@ final class ConfigVisualPanel1 extends JPanel { descriptionTextArea = new javax.swing.JTextArea(); configureDriveRadioButton = new javax.swing.JRadioButton(); configureFolderRadioButton = new javax.swing.JRadioButton(); + driveListScrollPane = new javax.swing.JScrollPane(); + driveList = new javax.swing.JList<>(); + refreshButton = new javax.swing.JButton(); + warningLabel = new javax.swing.JLabel(); configFileTextField.setEditable(false); configFileTextField.setText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configFileTextField.text_1")); // NOI18N + configFileTextField.setEnabled(false); org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.browseButton.text")); // NOI18N browseButton.setToolTipText(org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.browseButton.toolTipText")); // NOI18N + browseButton.setEnabled(false); browseButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { browseButtonActionPerformed(evt); @@ -104,9 +123,43 @@ final class ConfigVisualPanel1 extends JPanel { configurationLocationButtonGroup.add(configureDriveRadioButton); configureDriveRadioButton.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(configureDriveRadioButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configureDriveRadioButton.text_1")); // NOI18N + configureDriveRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + configureDriveRadioButtonActionPerformed(evt); + } + }); configurationLocationButtonGroup.add(configureFolderRadioButton); org.openide.awt.Mnemonics.setLocalizedText(configureFolderRadioButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.configureFolderRadioButton.text_1")); // NOI18N + configureFolderRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + configureFolderRadioButtonActionPerformed(evt); + } + }); + + driveList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + driveList.setEnabled(false); + driveList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseReleased(java.awt.event.MouseEvent evt) { + driveListMouseReleasedSelection(evt); + } + }); + driveList.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + driveListKeyReleasedSelection(evt); + } + }); + driveListScrollPane.setViewportView(driveList); + + org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(ConfigVisualPanel1.class, "ConfigVisualPanel1.refreshButton.text")); // NOI18N + refreshButton.setEnabled(false); + refreshButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + refreshButtonActionPerformed(evt); + } + }); + + warningLabel.setForeground(new java.awt.Color(255, 0, 0)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -115,21 +168,23 @@ final class ConfigVisualPanel1 extends JPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(warningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(descriptionScrollPane) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) - .addComponent(configFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 281, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE) + .addComponent(configFileTextField, javax.swing.GroupLayout.Alignment.LEADING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(browseButton) - .addContainerGap(11, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(refreshButton, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE) + .addComponent(browseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(descriptionScrollPane) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(configureDriveRadioButton) - .addComponent(configureFolderRadioButton)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()))) + .addComponent(configureDriveRadioButton) + .addComponent(configureFolderRadioButton)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -138,13 +193,21 @@ final class ConfigVisualPanel1 extends JPanel { .addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(13, 13, 13) .addComponent(configureDriveRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 60, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(refreshButton) + .addGap(0, 46, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(configureFolderRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(configFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(browseButton)) - .addGap(78, 78, 78)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(warningLabel) + .addContainerGap(70, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -152,21 +215,82 @@ final class ConfigVisualPanel1 extends JPanel { "ConfigVisualPanel1.chooseFileTitle=Select a Logical Imager configuration" }) private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed - chooseFile(Bundle.ConfigVisualPanel1_chooseFileTitle()); + chooseFile(Bundle.ConfigVisualPanel1_chooseFileTitle()); }//GEN-LAST:event_browseButtonActionPerformed + private void configureFolderRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureFolderRadioButtonActionPerformed + updateControls(); + }//GEN-LAST:event_configureFolderRadioButtonActionPerformed + + private void configureDriveRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureDriveRadioButtonActionPerformed + updateControls(); + }//GEN-LAST:event_configureDriveRadioButtonActionPerformed + + private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed + refreshDriveList(); + }//GEN-LAST:event_refreshButtonActionPerformed + + private void driveListKeyReleasedSelection(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_driveListKeyReleasedSelection + // TODO add your handling code here: + }//GEN-LAST:event_driveListKeyReleasedSelection + + private void driveListMouseReleasedSelection(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_driveListMouseReleasedSelection + // TODO add your handling code here: + }//GEN-LAST:event_driveListMouseReleasedSelection + + @Messages({"ConfigVisualPanel1.messageLabel.noExternalDriveFound=No drive found"}) + private void refreshDriveList() { + List listData = new ArrayList<>(); + File[] roots = File.listRoots(); + int firstRemovableDrive = -1; + int i = 0; + for (File root : roots) { + String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root); + long spaceInBytes = root.getTotalSpace(); + String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes, false); + listData.add(root + " (" + description + ") (" + sizeWithUnit + ")"); + if (firstRemovableDrive == -1) { + try { + FileStore fileStore = Files.getFileStore(root.toPath()); + if ((boolean) fileStore.getAttribute("volume:isRemovable")) { //NON-NLS + firstRemovableDrive = i; + } + } catch (IOException ignored) + } + } + i++; + } + driveList.setListData(listData.toArray(new String[listData.size()])); + if (!listData.isEmpty()) { + // auto-select the first external drive, if any + driveList.setSelectedIndex(firstRemovableDrive == -1 ? 0 : firstRemovableDrive); + driveListMouseReleasedSelection(null); + driveList.requestFocusInWindow(); + warningLabel.setText(""); + } else { + warningLabel.setText(Bundle.ConfigVisualPanel1_messageLabel_noExternalDriveFound()); + } + } + + private void updateControls() { + browseButton.setEnabled(configureFolderRadioButton.isSelected()); + + driveList.setEnabled(configureDriveRadioButton.isSelected()); + driveListScrollPane.setEnabled(configureDriveRadioButton.isSelected()); + + } + @NbBundle.Messages({ "ConfigVisualPanel1.fileNameExtensionFilter=Configuration JSON File", "ConfigVisualPanel1.invalidConfigJson=Invalid config JSON: ", - "ConfigVisualPanel1.configurationError=Configuration error", - }) + "ConfigVisualPanel1.configurationError=Configuration error",}) private void chooseFile(String title) { final String jsonExt = ".json"; // NON-NLS JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle(title); fileChooser.setDragEnabled(false); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - FileFilter filter = new FileNameExtensionFilter(Bundle.ConfigVisualPanel1_fileNameExtensionFilter(), new String[] {"json"}); // NON-NLS + FileFilter filter = new FileNameExtensionFilter(Bundle.ConfigVisualPanel1_fileNameExtensionFilter(), new String[]{"json"}); // NON-NLS fileChooser.setFileFilter(filter); fileChooser.setSelectedFile(new File("logical-imager-config.json")); // default fileChooser.setMultiSelectionEnabled(false); @@ -179,10 +303,10 @@ final class ConfigVisualPanel1 extends JPanel { configFileTextField.setText(path); newFile = false; } catch (JsonIOException | JsonSyntaxException | IOException ex) { - JOptionPane.showMessageDialog(this, - Bundle.ConfigVisualPanel1_invalidConfigJson() + ex.getMessage() , - Bundle.ConfigVisualPanel1_configurationError(), - JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(this, + Bundle.ConfigVisualPanel1_invalidConfigJson() + ex.getMessage(), + Bundle.ConfigVisualPanel1_configurationError(), + JOptionPane.ERROR_MESSAGE); } } else { if (!path.endsWith(jsonExt)) { @@ -195,7 +319,7 @@ final class ConfigVisualPanel1 extends JPanel { } } } - + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton browseButton; private javax.swing.JTextField configFileTextField; @@ -204,12 +328,15 @@ final class ConfigVisualPanel1 extends JPanel { private javax.swing.JRadioButton configureFolderRadioButton; private javax.swing.JScrollPane descriptionScrollPane; private javax.swing.JTextArea descriptionTextArea; + private javax.swing.JList driveList; + private javax.swing.JScrollPane driveListScrollPane; + private javax.swing.JButton refreshButton; + private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables @NbBundle.Messages({ "# {0} - filename", - "ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty", - }) + "ConfigVisualPanel1.configFileIsEmpty=Configuration file {0} is empty",}) private void loadConfigFile(String path) throws FileNotFoundException, JsonIOException, JsonSyntaxException, IOException { try (FileInputStream is = new FileInputStream(path)) { InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8); @@ -241,7 +368,8 @@ final class ConfigVisualPanel1 extends JPanel { } boolean isPanelValid() { - return (newFile || !configFileTextField.getText().isEmpty()); + return (configureDriveRadioButton.isSelected() && driveList.getSelectedIndex() >= 0) + || (configureFolderRadioButton.isSelected() && (newFile || !configFileTextField.getText().isEmpty())); } /** @@ -250,7 +378,7 @@ final class ConfigVisualPanel1 extends JPanel { private static class MyDocumentListener implements DocumentListener { private final ConfigVisualPanel1 panel; - + MyDocumentListener(ConfigVisualPanel1 aThis) { this.panel = aThis; } diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel2.java b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel2.java index 6f15333d6a..73f38a176b 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel2.java +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/configuration/ConfigVisualPanel2.java @@ -1,7 +1,7 @@ /* - * Autopsy Forensic Browser + * Autopsy * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2019 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,12 +42,13 @@ import org.openide.util.NbBundle; final class ConfigVisualPanel2 extends JPanel { private static final List EMPTY_LIST = new ArrayList<>(); + private static final long serialVersionUID = 1L; private String configFilename; private LogicalImagerConfig config = null; private final JButton okButton = new JButton(Bundle.ConfigVisualPanel2_ok()); private final JButton cancelButton = new JButton(Bundle.ConfigVisualPanel2_cancel()); private boolean flagEncryptionPrograms = false; - + /** * Creates new form ConfigVisualPanel2 */ @@ -431,9 +432,9 @@ final class ConfigVisualPanel2 extends JPanel { editPanel.setVisible(true); while (true) { - int option = JOptionPane.showOptionDialog(this, editPanel.getPanel(), Bundle.ConfigVisualPanel2_editRuleSet(), - JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, - null, new Object[]{okButton, cancelButton}, okButton); + int option = JOptionPane.showOptionDialog(this, editPanel.getPanel(), Bundle.ConfigVisualPanel2_editRuleSet(), + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, + null, new Object[]{okButton, cancelButton}, okButton); if (option == JOptionPane.OK_OPTION) { try { ImmutablePair ruleMap = editPanel.toRule(); @@ -441,16 +442,16 @@ final class ConfigVisualPanel2 extends JPanel { break; } catch (IOException | NumberFormatException ex) { JOptionPane.showMessageDialog(this, - ex.getMessage(), - Bundle.ConfigVisualPanel2_editRuleError(), - JOptionPane.ERROR_MESSAGE); + ex.getMessage(), + Bundle.ConfigVisualPanel2_editRuleError(), + JOptionPane.ERROR_MESSAGE); // let user fix the error } } else { break; } } - } + } }//GEN-LAST:event_editRuleButtonActionPerformed private void newRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRuleButtonActionPerformed @@ -460,9 +461,9 @@ final class ConfigVisualPanel2 extends JPanel { panel.setVisible(true); while (true) { - int option = JOptionPane.showOptionDialog(this, panel, "New rule", - JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, - null, new Object[]{okButton, cancelButton}, okButton); + int option = JOptionPane.showOptionDialog(this, panel, "New rule", + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, + null, new Object[]{okButton, cancelButton}, okButton); if (option == JOptionPane.OK_OPTION) { try { // Save the new rule @@ -471,30 +472,29 @@ final class ConfigVisualPanel2 extends JPanel { break; } catch (IOException | NumberFormatException ex) { JOptionPane.showMessageDialog(this, - ex.getMessage(), - "New rule error", - JOptionPane.ERROR_MESSAGE); + ex.getMessage(), + "New rule error", + JOptionPane.ERROR_MESSAGE); // let user fix the error } } else { break; } - } + } }//GEN-LAST:event_newRuleButtonActionPerformed @NbBundle.Messages({ "ConfigVisualPanel2.deleteRuleSet=Delete rule ", - "ConfigVisualPanel2.deleteRuleSetConfirmation=Delete rule confirmation", - }) + "ConfigVisualPanel2.deleteRuleSetConfirmation=Delete rule confirmation",}) private void deleteRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteRuleButtonActionPerformed int index = rulesTable.getSelectedRow(); if (index != -1) { String ruleName = (String) rulesTable.getModel().getValueAt(index, 0); - int option = JOptionPane.showOptionDialog(this, - Bundle.ConfigVisualPanel2_deleteRuleSet() + ruleName, - Bundle.ConfigVisualPanel2_deleteRuleSetConfirmation(), - JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); + int option = JOptionPane.showOptionDialog(this, + Bundle.ConfigVisualPanel2_deleteRuleSet() + ruleName, + Bundle.ConfigVisualPanel2_deleteRuleSetConfirmation(), + JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option == JOptionPane.NO_OPTION) { return; } @@ -521,7 +521,7 @@ final class ConfigVisualPanel2 extends JPanel { if (flagEncryptionPrograms) { // add the special rule ImmutablePair ruleMap = createEncryptionProgramsRule(); - appendRow(ruleMap); + appendRow(ruleMap); } else { // remove it int index = ((RulesTableModel) rulesTable.getModel()).findRow(EncryptionProgramsRule.getName()); @@ -535,7 +535,7 @@ final class ConfigVisualPanel2 extends JPanel { } } } - + /* * Create an encryption programs rule */ @@ -596,7 +596,7 @@ final class ConfigVisualPanel2 extends JPanel { } return config.getRuleSets().get(0); } - + private void updatePanel(String configFilePath, LogicalImagerConfig config, String rowSelectionkey) { configFileTextField.setText(configFilePath); finalizeImageWriter.setSelected(config.isFinalizeImageWriter()); @@ -607,7 +607,7 @@ final class ConfigVisualPanel2 extends JPanel { int selectThisRow = 0; Collections.sort(ruleSet.getRules(), new SortRuleByName()); - + for (LogicalImagerRule rule : ruleSet.getRules()) { rulesTableModel.setValueAt(rule.getName(), row, 0); if (rowSelectionkey != null && rowSelectionkey.equals(rule.getName())) { @@ -627,7 +627,7 @@ final class ConfigVisualPanel2 extends JPanel { updateRuleButtons(false); } } - + private void updatePanel(String configFilePath, LogicalImagerConfig config) { updatePanel(configFilePath, config, null); } @@ -638,9 +638,9 @@ final class ConfigVisualPanel2 extends JPanel { String ruleName = (String) rulesTable.getModel().getValueAt(index, 0); String description = (String) rulesTable.getModel().getValueAt(index, 1); updateRuleDetails(ruleName, description, config); - updateRuleButtons(ruleName.equals(EncryptionProgramsRule.getName()) ? false : true); + updateRuleButtons(!ruleName.equals(EncryptionProgramsRule.getName())); } else { - updateRuleButtons(false); + updateRuleButtons(false); } } @@ -685,7 +685,7 @@ final class ConfigVisualPanel2 extends JPanel { } String content = ""; boolean first = true; - for (String ext : extensions) { + for (String ext : extensions) { content += (first ? "" : ",") + ext; first = false; } @@ -750,6 +750,7 @@ final class ConfigVisualPanel2 extends JPanel { */ private class SortRuleByName implements Comparator { + @Override public int compare(LogicalImagerRule a, LogicalImagerRule b) { return a.getName().compareToIgnoreCase(b.getName()); } @@ -760,6 +761,7 @@ final class ConfigVisualPanel2 extends JPanel { */ private class RulesTableModel extends AbstractTableModel { + private static final long serialVersionUID = 1L; private final List ruleName = new ArrayList<>(); private final List ruleDescription = new ArrayList<>(); private final List rule = new ArrayList<>(); @@ -767,7 +769,7 @@ final class ConfigVisualPanel2 extends JPanel { int findRow(String name) { return ruleName.indexOf(name); } - + @Override public int getRowCount() { return ruleName.size(); @@ -849,6 +851,8 @@ final class ConfigVisualPanel2 extends JPanel { */ private class SingleColumnTableModel extends AbstractTableModel { + private static final long serialVersionUID = 1L; + private final List list = new ArrayList<>(); @Override diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/DriveListUtils.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/DriveListUtils.java new file mode 100644 index 0000000000..f77e22519a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/DriveListUtils.java @@ -0,0 +1,39 @@ +/* + * Autopsy + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.logicalimager.dsp; + +public final class DriveListUtils { + + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) { + return bytes + " B"; //NON-NLS + } + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); //NON-NLS + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); //NON-NLS + } + + /** + * Empty private constructor for util class + */ + private DriveListUtils() { + //empty private constructor for util class + } +} diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java index 893138b333..e8403502b2 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java @@ -1,7 +1,7 @@ /* - * Autopsy Forensic Browser + * Autopsy * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2019 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java index 1f7d61bb3c..6ec9205fe5 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java @@ -1,7 +1,7 @@ /* - * Autopsy Forensic Browser + * Autopsy * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2019 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -288,15 +288,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener { ); }// //GEN-END:initComponents - private static String humanReadableByteCount(long bytes, boolean si) { - int unit = si ? 1000 : 1024; - if (bytes < unit) { - return bytes + " B"; //NON-NLS - } - int exp = (int) (Math.log(bytes) / Math.log(unit)); - String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); //NON-NLS - return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); //NON-NLS - } + @Messages({ "# {0} - sparseImageDirectory", @@ -490,7 +482,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener { for (File root : roots) { String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root); long spaceInBytes = root.getTotalSpace(); - String sizeWithUnit = humanReadableByteCount(spaceInBytes, false); + String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes, false); listData.add(root + " (" + description + ") (" + sizeWithUnit + ")"); if (firstRemovableDrive == -1) { try {