Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
LocalDiskPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.casemodule;
20 
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.Font;
25 import java.beans.PropertyChangeListener;
26 import java.beans.PropertyChangeSupport;
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.List;
30 import java.util.SimpleTimeZone;
31 import java.util.TimeZone;
32 import java.util.concurrent.CancellationException;
33 import java.util.logging.Level;
34 import javax.swing.ComboBoxModel;
35 import javax.swing.JLabel;
36 import javax.swing.JList;
37 import javax.swing.JPanel;
38 import javax.swing.JSeparator;
39 import javax.swing.ListCellRenderer;
40 import javax.swing.SwingWorker;
41 import javax.swing.border.EmptyBorder;
42 import javax.swing.event.ListDataListener;
43 import org.openide.util.NbBundle;
49 
54 final class LocalDiskPanel extends JPanel {
55 
56  private static final Logger logger = Logger.getLogger(LocalDiskPanel.class.getName());
57 
58  private static LocalDiskPanel instance;
59 
60  private PropertyChangeSupport pcs = null;
61 
62  private List<LocalDisk> disks;
63 
64  private LocalDiskModel model;
65 
66  private boolean enableNext = false;
67 
71  public LocalDiskPanel() {
72  this.disks = new ArrayList<>();
73  initComponents();
74  customInit();
75 
76  createTimeZoneList();
77 
78  }
79 
83  public static synchronized LocalDiskPanel getDefault() {
84  if (instance == null) {
85  instance = new LocalDiskPanel();
86  }
87  return instance;
88  }
89 
90  @SuppressWarnings("unchecked")
91  private void customInit() {
92  model = new LocalDiskModel();
93  diskComboBox.setModel(model);
94  diskComboBox.setRenderer(model);
95 
96  errorLabel.setText("");
97  diskComboBox.setEnabled(false);
98 
99  }
100 
106  @SuppressWarnings("unchecked")
107  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
108  private void initComponents() {
109 
110  diskLabel = new javax.swing.JLabel();
111  diskComboBox = new javax.swing.JComboBox<>();
112  errorLabel = new javax.swing.JLabel();
113  timeZoneLabel = new javax.swing.JLabel();
114  timeZoneComboBox = new javax.swing.JComboBox<String>();
115  noFatOrphansCheckbox = new javax.swing.JCheckBox();
116  descLabel = new javax.swing.JLabel();
117 
118  setMinimumSize(new java.awt.Dimension(0, 65));
119  setPreferredSize(new java.awt.Dimension(485, 65));
120 
121  org.openide.awt.Mnemonics.setLocalizedText(diskLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.diskLabel.text")); // NOI18N
122 
123  errorLabel.setForeground(new java.awt.Color(255, 0, 0));
124  org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.errorLabel.text")); // NOI18N
125 
126  org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.timeZoneLabel.text")); // NOI18N
127 
128  timeZoneComboBox.setMaximumRowCount(30);
129 
130  org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.text")); // NOI18N
131  noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
132 
133  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.descLabel.text")); // NOI18N
134 
135  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
136  this.setLayout(layout);
137  layout.setHorizontalGroup(
138  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
139  .addGroup(layout.createSequentialGroup()
140  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
141  .addComponent(diskLabel)
142  .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
143  .addComponent(errorLabel)
144  .addGroup(layout.createSequentialGroup()
145  .addComponent(timeZoneLabel)
146  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
147  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
148  .addComponent(noFatOrphansCheckbox)
149  .addGroup(layout.createSequentialGroup()
150  .addGap(21, 21, 21)
151  .addComponent(descLabel)))
152  .addGap(0, 102, Short.MAX_VALUE))
153  );
154  layout.setVerticalGroup(
155  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
156  .addGroup(layout.createSequentialGroup()
157  .addComponent(diskLabel)
158  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
159  .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
160  .addGap(13, 13, 13)
161  .addComponent(errorLabel)
162  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
163  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
164  .addComponent(timeZoneLabel)
165  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
166  .addGap(18, 18, 18)
167  .addComponent(noFatOrphansCheckbox)
168  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
169  .addComponent(descLabel)
170  .addContainerGap(21, Short.MAX_VALUE))
171  );
172  }// </editor-fold>//GEN-END:initComponents
173  // Variables declaration - do not modify//GEN-BEGIN:variables
174  private javax.swing.JLabel descLabel;
175  private javax.swing.JComboBox<LocalDisk> diskComboBox;
176  private javax.swing.JLabel diskLabel;
177  private javax.swing.JLabel errorLabel;
178  private javax.swing.JCheckBox noFatOrphansCheckbox;
179  private javax.swing.JComboBox<String> timeZoneComboBox;
180  private javax.swing.JLabel timeZoneLabel;
181  // End of variables declaration//GEN-END:variables
182 
188  //@Override
189  public String getContentPaths() {
190  if (disks.size() > 0) {
191  LocalDisk selected = (LocalDisk) diskComboBox.getSelectedItem();
192  return selected.getPath();
193  } else {
194  return "";
195  }
196  }
197 
201  // @Override
202  public void setContentPath(String s) {
203  for (int i = 0; i < disks.size(); i++) {
204  if (disks.get(i).getPath().equals(s)) {
205  diskComboBox.setSelectedIndex(i);
206  }
207  }
208  }
209 
210  public String getTimeZone() {
211  String tz = timeZoneComboBox.getSelectedItem().toString();
212  return tz.substring(tz.indexOf(")") + 2).trim();
213 
214  }
215 
216  boolean getNoFatOrphans() {
217  return noFatOrphansCheckbox.isSelected();
218  }
219 
226  //@Override
227  public boolean validatePanel() {
228  return enableNext;
229  }
230 
231  //@Override
232  public void reset() {
233  //nothing to reset
234 
235  }
236 
240  // @Override
241  public void select() {
242  diskComboBox.requestFocusInWindow();
243  model.loadDisks();
244 
245  }
246 
247  @Override
248  public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
249  super.addPropertyChangeListener(pcl);
250 
251  if (pcs == null) {
252  pcs = new PropertyChangeSupport(this);
253  }
254 
255  pcs.addPropertyChangeListener(pcl);
256  }
257 
258  @Override
259  public void removePropertyChangeListener(PropertyChangeListener pcl) {
260  super.removePropertyChangeListener(pcl);
261 
262  pcs.removePropertyChangeListener(pcl);
263  }
264 
269  public void createTimeZoneList() {
270  // load and add all timezone
271  String[] ids = SimpleTimeZone.getAvailableIDs();
272  for (String id : ids) {
273  TimeZone zone = TimeZone.getTimeZone(id);
274  int offset = zone.getRawOffset() / 1000;
275  int hour = offset / 3600;
276  int minutes = (offset % 3600) / 60;
277  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id); //NON-NLS
278 
279  /*
280  * DateFormat dfm = new SimpleDateFormat("z");
281  * dfm.setTimeZone(zone); boolean hasDaylight =
282  * zone.useDaylightTime(); String first = dfm.format(new Date(2010,
283  * 1, 1)); String second = dfm.format(new Date(2011, 6, 6)); int mid
284  * = hour * -1; String result = first + Integer.toString(mid);
285  * if(hasDaylight){ result = result + second; }
286  * timeZoneComboBox.addItem(item + " (" + result + ")");
287  */
288  timeZoneComboBox.addItem(item);
289  }
290  // get the current timezone
291  TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
292  int thisOffset = thisTimeZone.getRawOffset() / 1000;
293  int thisHour = thisOffset / 3600;
294  int thisMinutes = (thisOffset % 3600) / 60;
295  String formatted = String.format("(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID()); //NON-NLS
296 
297  // set the selected timezone
298  timeZoneComboBox.setSelectedItem(formatted);
299  }
300 
301  @SuppressWarnings("rawtypes")
302  private class LocalDiskModel implements ComboBoxModel, ListCellRenderer {
303 
304  private Object selected;
305 
306  private boolean ready = false;
307 
308  private volatile boolean loadingDisks = false;
309 
310  List<LocalDisk> physicalDrives = new ArrayList<>();
311  List<LocalDisk> partitions = new ArrayList<>();
312 
313  //private String SELECT = "Select a local disk:";
314  private String LOADING = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.loading.msg");
315  private String NO_DRIVES = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.nodrives.msg");
316 
317  LocalDiskThread worker = null;
318 
319  private void loadDisks() {
320 
321  // if there is a worker already building the lists, then cancel it first.
322  if (loadingDisks && worker != null) {
323  worker.cancel(false);
324  }
325 
326  // Clear the lists
327  errorLabel.setText("");
328  disks = new ArrayList<>();
329  physicalDrives = new ArrayList<>();
330  partitions = new ArrayList<>();
331  diskComboBox.setEnabled(false);
332  ready = false;
333  enableNext = false;
334  loadingDisks = true;
335 
336  worker = new LocalDiskThread();
337  worker.execute();
338 
339  }
340 
341  @Override
342  public void setSelectedItem(Object anItem) {
343  if (ready) {
344  selected = (LocalDisk) anItem;
345  enableNext = true;
346 
347  try {
348  pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
349  } catch (Exception e) {
350  logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS
351  MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"),
352  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"),
354  }
355  }
356  }
357 
358  @Override
359  public Object getSelectedItem() {
360  if (ready) {
361  if (disks.isEmpty()) {
362  return NO_DRIVES;
363  }
364  return selected;
365  }
366  else {
367  return LOADING;
368  }
369  }
370 
371  @Override
372  public int getSize() {
373  if (ready) {
374  if (disks.isEmpty()) {
375  return 1;
376  }
377  return disks.size();
378  }
379  else {
380  return 1;
381  }
382  }
383 
384  @Override
385  public Object getElementAt(int index) {
386  if (ready) {
387  if (disks.isEmpty()) {
388  return NO_DRIVES;
389  }
390  return disks.get(index);
391  }
392  else {
393  return LOADING;
394  }
395  }
396 
397  @Override
398  public void addListDataListener(ListDataListener l) {
399  }
400 
401  @Override
402  public void removeListDataListener(ListDataListener l) {
403  }
404 
405  @SuppressWarnings("rawtypes")
406  @Override
407  public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
408  JPanel panel = new JPanel(new BorderLayout());
409  JLabel label = new JLabel();
410  if ((index == physicalDrives.size() - 1) && (physicalDrives.size() > 0)) {
411  panel.add(new JSeparator(JSeparator.HORIZONTAL), BorderLayout.SOUTH);
412  }
413 
414  if (isSelected) {
415  label.setBackground(list.getSelectionBackground());
416  label.setForeground(list.getSelectionForeground());
417  } else {
418  label.setBackground(list.getBackground());
419  label.setForeground(list.getForeground());
420  }
421 
422  if (value != null) {
423  String localDiskString = value.toString();
424  label.setText(value.toString());
425  if ((localDiskString.equals(LOADING)) || (localDiskString.equals(NO_DRIVES))) {
426  label.setFont(label.getFont().deriveFont(Font.ITALIC));
427  label.setBackground(Color.GRAY);
428  }
429  }
430  label.setOpaque(true);
431  label.setBorder(new EmptyBorder(2, 2, 2, 2));
432 
433  panel.add(label, BorderLayout.CENTER);
434  return panel;
435  }
436 
437  class LocalDiskThread extends SwingWorker<Object, Void> {
438 
439  private Logger logger = Logger.getLogger(LocalDiskThread.class.getName());
440 
441  @Override
442  protected Object doInBackground() throws Exception {
443  // Populate the lists
444  physicalDrives = PlatformUtil.getPhysicalDrives();
445  partitions = PlatformUtil.getPartitions();
446 
447  return null;
448  }
449 
450  private void displayErrors() {
451  if (physicalDrives.isEmpty() && partitions.isEmpty()) {
452  if (PlatformUtil.isWindowsOS()) {
453  errorLabel.setText(
454  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.disksNotDetected.text"));
455  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
456  "LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
457  } else {
458  errorLabel.setText(
459  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.drivesNotDetected.text"));
460  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
461  "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
462  }
463  diskComboBox.setEnabled(false);
464  } else if (physicalDrives.isEmpty()) {
465  errorLabel.setText(
466  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.someDisksNotDetected.text"));
467  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
468  "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
469  }
470  }
471 
472  @Override
473  protected void done() {
474  try {
475  super.get(); //block and get all exceptions thrown while doInBackground()
476  } catch (CancellationException ex) {
477  logger.log(Level.INFO, "Loading local disks was canceled, which should not be possible."); //NON-NLS
478  } catch (InterruptedException ex) {
479  logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS
480  } catch (Exception ex) {
481  logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS
482  } finally {
483  if (!this.isCancelled()) {
484  enableNext = false;
485  displayErrors();
486 
487  worker = null;
488  loadingDisks = false;
489 
490  disks.addAll(physicalDrives);
491  disks.addAll(partitions);
492 
493  if (disks.size() > 0) {
494  diskComboBox.setEnabled(true);
495  diskComboBox.setSelectedIndex(0);
496  }
497  ready = true;
498  } else {
499  logger.log(Level.INFO, "Loading local disks was canceled, which should not be possible."); //NON-NLS
500  }
501  }
502  }
503  }
504  }
505 }
UPDATE_UI
the content of JPanel has changed that MAY warrant updates to the caller UI
static List< LocalDisk > getPhysicalDrives()
Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
static void show(String title, String message, MessageType type, ActionListener actionListener)
static Logger getLogger(String name)
Definition: Logger.java:131

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.