19 package org.sleuthkit.autopsy.casemodule;
 
   21 import java.awt.Window;
 
   22 import java.util.ArrayList;
 
   23 import java.util.Collections;
 
   24 import java.util.Iterator;
 
   25 import java.util.List;
 
   26 import java.util.concurrent.CancellationException;
 
   27 import java.util.concurrent.ExecutionException;
 
   28 import java.util.logging.Level;
 
   29 import javax.swing.JDialog;
 
   30 import javax.swing.SwingWorker;
 
   31 import javax.swing.event.ListSelectionEvent;
 
   32 import javax.swing.event.ListSelectionListener;
 
   33 import javax.swing.event.TableModelListener;
 
   34 import javax.swing.table.TableModel;
 
   35 import org.openide.util.NbBundle;
 
   43     "LocalDiskSelectionDialog.moduleErrorMessage.title=Module Error",
 
   44     "LocalDiskSelectionDialog.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.",
 
   45     "LocalDiskSelectionDialog.errorMessage.disksNotDetected=Disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\").",
 
   46     "LocalDiskSelectionDialog.errorMessage.drivesNotDetected=Local drives were not detected. Auto-detection not supported on this OS  or admin privileges required",
 
   47     "LocalDiskSelectionDialog.errorMessage.someDisksNotDetected=Some disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\")." 
   52 @SuppressWarnings(
"PMD.SingularField") 
 
   53 final class LocalDiskSelectionDialog 
extends JDialog {
 
   55     private static final Logger logger = Logger.getLogger(LocalDiskSelectionDialog.class.getName());
 
   56     private static final long serialVersionUID = 1L;
 
   57     private List<LocalDisk> disks;
 
   58     private final LocalDiskModel model;
 
   63     LocalDiskSelectionDialog() {
 
   64         super((Window) LocalDiskPanel.getDefault().getTopLevelAncestor(), ModalityType.MODELESS);
 
   66         this.model = 
new LocalDiskModel();
 
   67         this.disks = 
new ArrayList<>();
 
   72         localDiskTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
 
   74             public void valueChanged(ListSelectionEvent e) {
 
   75                 int selectedRow = localDiskTable.getSelectedRow();
 
   76                 okButton.setEnabled(selectedRow >= 0 && selectedRow < disks.size());
 
   86         setSize(getPreferredSize());
 
   87         setLocationRelativeTo(this.getParent());
 
   88         setAlwaysOnTop(
false);
 
   97     @SuppressWarnings(
"unchecked")
 
   99     private 
void initComponents() {
 
  101         selectLocalDiskLabel = 
new javax.swing.JLabel();
 
  102         errorLabel = 
new javax.swing.JLabel();
 
  103         localDiskScrollPane = 
new javax.swing.JScrollPane();
 
  104         localDiskTable = 
new javax.swing.JTable();
 
  105         refreshLocalDisksButton = 
new javax.swing.JButton();
 
  106         okButton = 
new javax.swing.JButton();
 
  107         cancelButton = 
new javax.swing.JButton();
 
  109         setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
 
  110         setTitle(
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.title")); 
 
  111         setAlwaysOnTop(
true);
 
  114         org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.selectLocalDiskLabel.text")); 
 
  116         errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
 
  117         org.openide.awt.Mnemonics.setLocalizedText(errorLabel, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.errorLabel.text")); 
 
  119         localDiskTable.setModel(model);
 
  120         localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
 
  121         localDiskScrollPane.setViewportView(localDiskTable);
 
  123         org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.refreshLocalDisksButton.text")); 
 
  124         refreshLocalDisksButton.addActionListener(
new java.awt.event.ActionListener() {
 
  125             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  126                 refreshLocalDisksButtonActionPerformed(evt);
 
  130         org.openide.awt.Mnemonics.setLocalizedText(okButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.okButton.text")); 
 
  131         okButton.setEnabled(
false);
 
  132         okButton.addActionListener(
new java.awt.event.ActionListener() {
 
  133             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  134                 okButtonActionPerformed(evt);
 
  138         org.openide.awt.Mnemonics.setLocalizedText(cancelButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.cancelButton.text")); 
 
  139         cancelButton.addActionListener(
new java.awt.event.ActionListener() {
 
  140             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  141                 cancelButtonActionPerformed(evt);
 
  145         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(getContentPane());
 
  146         getContentPane().setLayout(layout);
 
  147         layout.setHorizontalGroup(
 
  148             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  149             .addGroup(layout.createSequentialGroup()
 
  151                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  152                     .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
 
  153                     .addGroup(layout.createSequentialGroup()
 
  154                         .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  155                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  156                         .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  157                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  158                         .addComponent(refreshLocalDisksButton))
 
  159                     .addGroup(layout.createSequentialGroup()
 
  160                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  161                             .addComponent(selectLocalDiskLabel)
 
  162                             .addComponent(errorLabel))
 
  163                         .addGap(0, 0, Short.MAX_VALUE)))
 
  166         layout.setVerticalGroup(
 
  167             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  168             .addGroup(layout.createSequentialGroup()
 
  170                 .addComponent(selectLocalDiskLabel)
 
  172                 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  173                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  174                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  175                     .addComponent(refreshLocalDisksButton)
 
  176                     .addComponent(okButton)
 
  177                     .addComponent(cancelButton))
 
  178                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  179                 .addComponent(errorLabel)
 
  180                 .addContainerGap(27, Short.MAX_VALUE))
 
  186     private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  190     private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  194     private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  195         localDiskTable.clearSelection();
 
  200     private javax.swing.JButton cancelButton;
 
  201     private javax.swing.JLabel errorLabel;
 
  202     private javax.swing.JScrollPane localDiskScrollPane;
 
  203     private javax.swing.JTable localDiskTable;
 
  204     private javax.swing.JButton okButton;
 
  205     private javax.swing.JButton refreshLocalDisksButton;
 
  206     private javax.swing.JLabel selectLocalDiskLabel;
 
  212     private void fireUpdateEvent() {
 
  214             firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), 
false, 
true);
 
  215         } 
catch (Exception e) {
 
  216             logger.log(Level.SEVERE, 
"LocalDiskSelectionDialog listener threw exception", e); 
 
  217             MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
 
  218                     Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
 
  219                     MessageNotifyUtil.MessageType.ERROR);
 
  228     String getContentPaths() {
 
  229         LocalDisk selected = getLocalDiskSelection();
 
  230         if (selected != null) {
 
  231             return selected.getPath();
 
  239     private void refreshTable() {
 
  241         localDiskTable.clearSelection();
 
  249     LocalDisk getLocalDiskSelection() {
 
  250         if (disks.size() > 0) {
 
  251             int selectedRow = localDiskTable.getSelectedRow();
 
  252             if (selectedRow >= 0 && selectedRow < disks.size()) {
 
  253                 return disks.get(selectedRow);
 
  260         "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
 
  261         "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
 
  268         private LocalDiskThread worker = null;
 
  269         private boolean ready = 
false;
 
  270         private volatile boolean loadingDisks = 
false;
 
  275             if (loadingDisks && worker != null) {
 
  276                 worker.cancel(
false);
 
  280             errorLabel.setText(
"");
 
  281             localDiskTable.setEnabled(
false);
 
  284             worker = 
new LocalDiskThread();
 
  290             if (disks.isEmpty()) {
 
  303             "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
 
  304             "LocalDiskSelectionDialog.columnName.diskSize=Disk Size" 
  309             switch (columnIndex) {
 
  311                     return Bundle.LocalDiskSelectionDialog_columnName_diskName();
 
  313                     return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
 
  332                 if (disks.isEmpty()) {
 
  333                     return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
 
  335                 switch (columnIndex) {
 
  337                         return disks.get(rowIndex).getName();
 
  339                         return disks.get(rowIndex).getReadableSize();
 
  341                         return disks.get(rowIndex).getPath();
 
  344                 return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
 
  349         public void setValueAt(Object aValue, 
int rowIndex, 
int columnIndex) {
 
  367         class LocalDiskThread 
extends SwingWorker<Object, Void> {
 
  370             private List<LocalDisk> physicalDrives = 
new ArrayList<>();
 
  371             private List<LocalDisk> partitions = 
new ArrayList<>();
 
  374             protected Object doInBackground() throws Exception {
 
  376                 physicalDrives = 
new ArrayList<>();
 
  377                 partitions = 
new ArrayList<>();
 
  387             private void displayErrors() {
 
  388                 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
 
  390                         errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
 
  391                         errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
 
  393                         errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
 
  394                         errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
 
  396                     errorLabel.setVisible(
true);
 
  397                     localDiskTable.setEnabled(
false);
 
  398                 } 
else if (physicalDrives.isEmpty()) {
 
  399                     errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
 
  400                     errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
 
  401                     errorLabel.setVisible(
true);
 
  406             protected void done() {
 
  409                 } 
catch (CancellationException ex) {
 
  410                     logger.log(Level.INFO, 
"Loading local disks was canceled."); 
 
  411                 } 
catch (InterruptedException ex) {
 
  412                     logger.log(Level.INFO, 
"Loading local disks was interrupted."); 
 
  413                 } 
catch (ExecutionException ex) {
 
  414                     logger.log(Level.SEVERE, 
"Fatal error when loading local disks", ex); 
 
  416                     if (!this.isCancelled()) {
 
  419                         loadingDisks = 
false;
 
  420                         disks = 
new ArrayList<>();
 
  421                         disks.addAll(physicalDrives);
 
  422                         disks.addAll(partitions);
 
  423                         if (disks.size() > 0) {
 
  424                             localDiskTable.setEnabled(
true);
 
  425                             localDiskTable.clearSelection();
 
  428                             String userConfigPath = PlatformUtil.getUserConfigDirectory();
 
  429                             for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
 
  430                                 LocalDisk disk = iterator.next();
 
  431                                 String diskPath = disk.getPath();
 
  432                                 if (diskPath.startsWith(
"\\\\.\\")) {
 
  434                                     diskPath = diskPath.substring(4);
 
  436                                 if (userConfigPath.startsWith(diskPath)) {
 
  441                             Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
 
  447                 localDiskTable.revalidate();
 
void addTableModelListener(TableModelListener l)
Object getValueAt(int rowIndex, int columnIndex)
Class<?> getColumnClass(int columnIndex)
void setValueAt(Object aValue, int rowIndex, int columnIndex)
void removeTableModelListener(TableModelListener l)
String getColumnName(int columnIndex)
synchronized static Logger getLogger(String name)
boolean isCellEditable(int rowIndex, int columnIndex)