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         selectLocalDiskLabel.setFont(selectLocalDiskLabel.getFont().deriveFont(selectLocalDiskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
 
  115         org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.selectLocalDiskLabel.text")); 
 
  117         errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
 
  118         errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
 
  119         org.openide.awt.Mnemonics.setLocalizedText(errorLabel, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.errorLabel.text")); 
 
  121         localDiskTable.setModel(model);
 
  122         localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
 
  123         localDiskScrollPane.setViewportView(localDiskTable);
 
  125         org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.refreshLocalDisksButton.text")); 
 
  126         refreshLocalDisksButton.addActionListener(
new java.awt.event.ActionListener() {
 
  127             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  128                 refreshLocalDisksButtonActionPerformed(evt);
 
  132         org.openide.awt.Mnemonics.setLocalizedText(okButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.okButton.text")); 
 
  133         okButton.setEnabled(
false);
 
  134         okButton.addActionListener(
new java.awt.event.ActionListener() {
 
  135             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  136                 okButtonActionPerformed(evt);
 
  140         org.openide.awt.Mnemonics.setLocalizedText(cancelButton, 
org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, 
"LocalDiskSelectionDialog.cancelButton.text")); 
 
  141         cancelButton.addActionListener(
new java.awt.event.ActionListener() {
 
  142             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  143                 cancelButtonActionPerformed(evt);
 
  147         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(getContentPane());
 
  148         getContentPane().setLayout(layout);
 
  149         layout.setHorizontalGroup(
 
  150             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  151             .addGroup(layout.createSequentialGroup()
 
  153                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  154                     .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
 
  155                     .addGroup(layout.createSequentialGroup()
 
  156                         .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  157                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  158                         .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  159                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  160                         .addComponent(refreshLocalDisksButton))
 
  161                     .addGroup(layout.createSequentialGroup()
 
  162                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  163                             .addComponent(selectLocalDiskLabel)
 
  164                             .addComponent(errorLabel))
 
  165                         .addGap(0, 0, Short.MAX_VALUE)))
 
  168         layout.setVerticalGroup(
 
  169             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  170             .addGroup(layout.createSequentialGroup()
 
  172                 .addComponent(selectLocalDiskLabel)
 
  174                 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  175                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  176                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  177                     .addComponent(refreshLocalDisksButton)
 
  178                     .addComponent(okButton)
 
  179                     .addComponent(cancelButton))
 
  180                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  181                 .addComponent(errorLabel)
 
  182                 .addContainerGap(27, Short.MAX_VALUE))
 
  188     private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  192     private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  196     private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  197         localDiskTable.clearSelection();
 
  202     private javax.swing.JButton cancelButton;
 
  203     private javax.swing.JLabel errorLabel;
 
  204     private javax.swing.JScrollPane localDiskScrollPane;
 
  205     private javax.swing.JTable localDiskTable;
 
  206     private javax.swing.JButton okButton;
 
  207     private javax.swing.JButton refreshLocalDisksButton;
 
  208     private javax.swing.JLabel selectLocalDiskLabel;
 
  214     private void fireUpdateEvent() {
 
  216             firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), 
false, 
true);
 
  217         } 
catch (Exception e) {
 
  218             logger.log(Level.SEVERE, 
"LocalDiskSelectionDialog listener threw exception", e); 
 
  219             MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
 
  220                     Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
 
  221                     MessageNotifyUtil.MessageType.ERROR);
 
  230     String getContentPaths() {
 
  231         LocalDisk selected = getLocalDiskSelection();
 
  232         if (selected != null) {
 
  233             return selected.getPath();
 
  241     private void refreshTable() {
 
  243         localDiskTable.clearSelection();
 
  251     LocalDisk getLocalDiskSelection() {
 
  252         if (disks.size() > 0) {
 
  253             int selectedRow = localDiskTable.getSelectedRow();
 
  254             if (selectedRow >= 0 && selectedRow < disks.size()) {
 
  255                 return disks.get(selectedRow);
 
  262         "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
 
  263         "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
 
  270         private LocalDiskThread worker = null;
 
  271         private boolean ready = 
false;
 
  272         private volatile boolean loadingDisks = 
false;
 
  277             if (loadingDisks && worker != null) {
 
  278                 worker.cancel(
false);
 
  282             errorLabel.setText(
"");
 
  283             localDiskTable.setEnabled(
false);
 
  286             worker = 
new LocalDiskThread();
 
  292             if (disks.isEmpty()) {
 
  305             "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
 
  306             "LocalDiskSelectionDialog.columnName.diskSize=Disk Size" 
  311             switch (columnIndex) {
 
  313                     return Bundle.LocalDiskSelectionDialog_columnName_diskName();
 
  315                     return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
 
  334                 if (disks.isEmpty()) {
 
  335                     return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
 
  337                 switch (columnIndex) {
 
  339                         return disks.get(rowIndex).getName();
 
  341                         return disks.get(rowIndex).getReadableSize();
 
  343                         return disks.get(rowIndex).getPath();
 
  346                 return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
 
  351         public void setValueAt(Object aValue, 
int rowIndex, 
int columnIndex) {
 
  369         class LocalDiskThread 
extends SwingWorker<Object, Void> {
 
  372             private List<LocalDisk> physicalDrives = 
new ArrayList<>();
 
  373             private List<LocalDisk> partitions = 
new ArrayList<>();
 
  376             protected Object doInBackground() throws Exception {
 
  378                 physicalDrives = 
new ArrayList<>();
 
  379                 partitions = 
new ArrayList<>();
 
  389             private void displayErrors() {
 
  390                 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
 
  392                         errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
 
  393                         errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
 
  395                         errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
 
  396                         errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
 
  398                     errorLabel.setVisible(
true);
 
  399                     localDiskTable.setEnabled(
false);
 
  400                 } 
else if (physicalDrives.isEmpty()) {
 
  401                     errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
 
  402                     errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
 
  403                     errorLabel.setVisible(
true);
 
  408             protected void done() {
 
  411                 } 
catch (CancellationException ex) {
 
  412                     logger.log(Level.INFO, 
"Loading local disks was canceled."); 
 
  413                 } 
catch (InterruptedException ex) {
 
  414                     logger.log(Level.INFO, 
"Loading local disks was interrupted."); 
 
  415                 } 
catch (ExecutionException ex) {
 
  416                     logger.log(Level.SEVERE, 
"Fatal error when loading local disks", ex); 
 
  418                     if (!this.isCancelled()) {
 
  421                         loadingDisks = 
false;
 
  422                         disks = 
new ArrayList<>();
 
  423                         disks.addAll(physicalDrives);
 
  424                         disks.addAll(partitions);
 
  425                         if (disks.size() > 0) {
 
  426                             localDiskTable.setEnabled(
true);
 
  427                             localDiskTable.clearSelection();
 
  430                             String userConfigPath = PlatformUtil.getUserConfigDirectory();
 
  431                             for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
 
  432                                 LocalDisk disk = iterator.next();
 
  433                                 String diskPath = disk.getPath();
 
  434                                 if (diskPath.startsWith(
"\\\\.\\")) {
 
  436                                     diskPath = diskPath.substring(4);
 
  438                                 if (userConfigPath.startsWith(diskPath)) {
 
  443                             Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
 
  449                 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)