Autopsy  4.0
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.setVisible(false);
97  errorLabel.setText("");
98  diskComboBox.setEnabled(false);
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<>();
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  diskLabel.setFont(diskLabel.getFont().deriveFont(diskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
122  org.openide.awt.Mnemonics.setLocalizedText(diskLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.diskLabel.text")); // NOI18N
123 
124  diskComboBox.setFont(diskComboBox.getFont().deriveFont(diskComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
125 
126  errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
127  errorLabel.setForeground(new java.awt.Color(255, 0, 0));
128  org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.errorLabel.text")); // NOI18N
129 
130  timeZoneLabel.setFont(timeZoneLabel.getFont().deriveFont(timeZoneLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
131  org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.timeZoneLabel.text")); // NOI18N
132 
133  timeZoneComboBox.setFont(timeZoneComboBox.getFont().deriveFont(timeZoneComboBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
134  timeZoneComboBox.setMaximumRowCount(30);
135 
136  noFatOrphansCheckbox.setFont(noFatOrphansCheckbox.getFont().deriveFont(noFatOrphansCheckbox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
137  org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.text")); // NOI18N
138  noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
139 
140  descLabel.setFont(descLabel.getFont().deriveFont(descLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
141  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.descLabel.text")); // NOI18N
142 
143  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
144  this.setLayout(layout);
145  layout.setHorizontalGroup(
146  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
147  .addGroup(layout.createSequentialGroup()
148  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
149  .addComponent(diskLabel)
150  .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
151  .addComponent(errorLabel)
152  .addGroup(layout.createSequentialGroup()
153  .addComponent(timeZoneLabel)
154  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
155  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
156  .addComponent(noFatOrphansCheckbox)
157  .addGroup(layout.createSequentialGroup()
158  .addGap(21, 21, 21)
159  .addComponent(descLabel)))
160  .addGap(0, 102, Short.MAX_VALUE))
161  );
162  layout.setVerticalGroup(
163  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
164  .addGroup(layout.createSequentialGroup()
165  .addComponent(diskLabel)
166  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
167  .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
168  .addGap(13, 13, 13)
169  .addComponent(errorLabel)
170  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
171  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
172  .addComponent(timeZoneLabel)
173  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
174  .addGap(18, 18, 18)
175  .addComponent(noFatOrphansCheckbox)
176  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
177  .addComponent(descLabel)
178  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
179  );
180  }// </editor-fold>//GEN-END:initComponents
181  // Variables declaration - do not modify//GEN-BEGIN:variables
182  private javax.swing.JLabel descLabel;
183  private javax.swing.JComboBox<LocalDisk> diskComboBox;
184  private javax.swing.JLabel diskLabel;
185  private javax.swing.JLabel errorLabel;
186  private javax.swing.JCheckBox noFatOrphansCheckbox;
187  private javax.swing.JComboBox<String> timeZoneComboBox;
188  private javax.swing.JLabel timeZoneLabel;
189  // End of variables declaration//GEN-END:variables
190 
196  //@Override
197  public String getContentPaths() {
198  if (disks.size() > 0) {
199  LocalDisk selected = (LocalDisk) diskComboBox.getSelectedItem();
200  return selected.getPath();
201  } else {
202  return "";
203  }
204  }
205 
209  // @Override
210  public void setContentPath(String s) {
211  for (int i = 0; i < disks.size(); i++) {
212  if (disks.get(i).getPath().equals(s)) {
213  diskComboBox.setSelectedIndex(i);
214  }
215  }
216  }
217 
218  public String getTimeZone() {
219  String tz = timeZoneComboBox.getSelectedItem().toString();
220  return tz.substring(tz.indexOf(")") + 2).trim();
221 
222  }
223 
224  boolean getNoFatOrphans() {
225  return noFatOrphansCheckbox.isSelected();
226  }
227 
234  //@Override
235  public boolean validatePanel() {
236  return enableNext;
237  }
238 
239  //@Override
240  public void reset() {
241  //nothing to reset
242 
243  }
244 
248  // @Override
249  public void select() {
250  diskComboBox.requestFocusInWindow();
251  model.loadDisks();
252 
253  }
254 
255  @Override
256  public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
257  super.addPropertyChangeListener(pcl);
258 
259  if (pcs == null) {
260  pcs = new PropertyChangeSupport(this);
261  }
262 
263  pcs.addPropertyChangeListener(pcl);
264  }
265 
266  @Override
267  public void removePropertyChangeListener(PropertyChangeListener pcl) {
268  super.removePropertyChangeListener(pcl);
269 
270  pcs.removePropertyChangeListener(pcl);
271  }
272 
277  public void createTimeZoneList() {
278  // load and add all timezone
279  String[] ids = SimpleTimeZone.getAvailableIDs();
280  for (String id : ids) {
281  TimeZone zone = TimeZone.getTimeZone(id);
282  int offset = zone.getRawOffset() / 1000;
283  int hour = offset / 3600;
284  int minutes = (offset % 3600) / 60;
285  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id); //NON-NLS
286 
287  /*
288  * DateFormat dfm = new SimpleDateFormat("z");
289  * dfm.setTimeZone(zone); boolean hasDaylight =
290  * zone.useDaylightTime(); String first = dfm.format(new Date(2010,
291  * 1, 1)); String second = dfm.format(new Date(2011, 6, 6)); int mid
292  * = hour * -1; String result = first + Integer.toString(mid);
293  * if(hasDaylight){ result = result + second; }
294  * timeZoneComboBox.addItem(item + " (" + result + ")");
295  */
296  timeZoneComboBox.addItem(item);
297  }
298  // get the current timezone
299  TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
300  int thisOffset = thisTimeZone.getRawOffset() / 1000;
301  int thisHour = thisOffset / 3600;
302  int thisMinutes = (thisOffset % 3600) / 60;
303  String formatted = String.format("(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID()); //NON-NLS
304 
305  // set the selected timezone
306  timeZoneComboBox.setSelectedItem(formatted);
307  }
308 
309  @SuppressWarnings("rawtypes")
310  private class LocalDiskModel implements ComboBoxModel, ListCellRenderer {
311 
312  private Object selected;
313 
314  private boolean ready = false;
315 
316  private volatile boolean loadingDisks = false;
317 
318  List<LocalDisk> physicalDrives = new ArrayList<>();
319  List<LocalDisk> partitions = new ArrayList<>();
320 
321  //private String SELECT = "Select a local disk:";
322  private String LOADING = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.loading.msg");
323  private String NO_DRIVES = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.nodrives.msg");
324 
325  LocalDiskThread worker = null;
326 
327  private void loadDisks() {
328 
329  // if there is a worker already building the lists, then cancel it first.
330  if (loadingDisks && worker != null) {
331  worker.cancel(false);
332  }
333 
334  // Clear the lists
335  errorLabel.setText("");
336  disks = new ArrayList<>();
337  physicalDrives = new ArrayList<>();
338  partitions = new ArrayList<>();
339  diskComboBox.setEnabled(false);
340  ready = false;
341  enableNext = false;
342  loadingDisks = true;
343 
344  worker = new LocalDiskThread();
345  worker.execute();
346 
347  }
348 
349  @Override
350  public void setSelectedItem(Object anItem) {
351  if (ready) {
352  selected = (LocalDisk) anItem;
353  enableNext = true;
354 
355  try {
356  pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
357  } catch (Exception e) {
358  logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS
359  MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"),
360  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"),
362  }
363  }
364  }
365 
366  @Override
367  public Object getSelectedItem() {
368  if (ready) {
369  if (disks.isEmpty()) {
370  return NO_DRIVES;
371  }
372  return selected;
373  } else {
374  return LOADING;
375  }
376  }
377 
378  @Override
379  public int getSize() {
380  if (ready) {
381  if (disks.isEmpty()) {
382  return 1;
383  }
384  return disks.size();
385  } else {
386  return 1;
387  }
388  }
389 
390  @Override
391  public Object getElementAt(int index) {
392  if (ready) {
393  if (disks.isEmpty()) {
394  return NO_DRIVES;
395  }
396  return disks.get(index);
397  } else {
398  return LOADING;
399  }
400  }
401 
402  @Override
403  public void addListDataListener(ListDataListener l) {
404  }
405 
406  @Override
407  public void removeListDataListener(ListDataListener l) {
408  }
409 
410  @SuppressWarnings("rawtypes")
411  @Override
412  public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
413  JPanel panel = new JPanel(new BorderLayout());
414  JLabel label = new JLabel();
415  if ((index == physicalDrives.size() - 1) && (physicalDrives.size() > 0)) {
416  panel.add(new JSeparator(JSeparator.HORIZONTAL), BorderLayout.SOUTH);
417  }
418 
419  if (isSelected) {
420  label.setBackground(list.getSelectionBackground());
421  label.setForeground(list.getSelectionForeground());
422  } else {
423  label.setBackground(list.getBackground());
424  label.setForeground(list.getForeground());
425  }
426 
427  if (value != null) {
428  String localDiskString = value.toString();
429  label.setText(value.toString());
430  if ((localDiskString.equals(LOADING)) || (localDiskString.equals(NO_DRIVES))) {
431  label.setFont(label.getFont().deriveFont(Font.ITALIC));
432  label.setBackground(Color.GRAY);
433  }
434  }
435  label.setOpaque(true);
436  label.setBorder(new EmptyBorder(2, 2, 2, 2));
437 
438  panel.add(label, BorderLayout.CENTER);
439  return panel;
440  }
441 
442  class LocalDiskThread extends SwingWorker<Object, Void> {
443 
444  private Logger logger = Logger.getLogger(LocalDiskThread.class.getName());
445 
446  @Override
447  protected Object doInBackground() throws Exception {
448  // Populate the lists
449  physicalDrives = PlatformUtil.getPhysicalDrives();
450  partitions = PlatformUtil.getPartitions();
451 
452  return null;
453  }
454 
455  private void displayErrors() {
456  if (physicalDrives.isEmpty() && partitions.isEmpty()) {
457  if (PlatformUtil.isWindowsOS()) {
458  errorLabel.setText(
459  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.disksNotDetected.text"));
460  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
461  "LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
462  } else {
463  errorLabel.setText(
464  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.drivesNotDetected.text"));
465  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
466  "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
467  }
468  diskComboBox.setEnabled(false);
469  } else if (physicalDrives.isEmpty()) {
470  errorLabel.setText(
471  NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.someDisksNotDetected.text"));
472  errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
473  "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
474  }
475  }
476 
477  @Override
478  protected void done() {
479  try {
480  super.get(); //block and get all exceptions thrown while doInBackground()
481  } catch (CancellationException ex) {
482  logger.log(Level.INFO, "Loading local disks was canceled, which should not be possible."); //NON-NLS
483  } catch (InterruptedException ex) {
484  logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS
485  } catch (Exception ex) {
486  logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS
487  } finally {
488  if (!this.isCancelled()) {
489  enableNext = false;
490  displayErrors();
491 
492  worker = null;
493  loadingDisks = false;
494 
495  disks.addAll(physicalDrives);
496  disks.addAll(partitions);
497 
498  if (disks.size() > 0) {
499  diskComboBox.setEnabled(true);
500  diskComboBox.setSelectedIndex(0);
501  }
502  ready = true;
503  } else {
504  logger.log(Level.INFO, "Loading local disks was canceled, which should not be possible."); //NON-NLS
505  }
506  }
507  }
508  }
509  }
510 }
static List< LocalDisk > getPhysicalDrives()
Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
synchronized static Logger getLogger(String name)
Definition: Logger.java:166
static void show(String title, String message, MessageType type, ActionListener actionListener)

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.