Autopsy  4.7.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ImageFilePanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 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.io.File;
22 import java.util.Calendar;
23 import java.util.List;
24 import java.util.SimpleTimeZone;
25 import java.util.TimeZone;
26 import java.util.logging.Level;
27 import javax.swing.JFileChooser;
28 import javax.swing.JOptionPane;
29 import javax.swing.JPanel;
30 import javax.swing.event.DocumentEvent;
31 import javax.swing.event.DocumentListener;
32 import javax.swing.filechooser.FileFilter;
33 import org.apache.commons.lang3.StringUtils;
34 import org.openide.util.NbBundle;
35 import static org.sleuthkit.autopsy.casemodule.Bundle.*;
42 
48 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
49 public class ImageFilePanel extends JPanel implements DocumentListener {
50 
51  private static final Logger logger = Logger.getLogger(ImageFilePanel.class.getName());
52  private static final String PROP_LASTIMAGE_PATH = "LBL_LastImage_PATH"; //NON-NLS
53  private static final String[] SECTOR_SIZE_CHOICES = {"Auto Detect", "512", "1024", "2048", "4096"};
54 
55  private final JFileChooser fileChooser = new JFileChooser();
56 
60  private final String contextName;
61 
70  private ImageFilePanel(String context, List<FileFilter> fileChooserFilters) {
71  this.contextName = context;
72  initComponents();
73 
74  // Populate the drop down list of time zones
75  for (String id : SimpleTimeZone.getAvailableIDs()) {
76  timeZoneComboBox.addItem(timeZoneToString(TimeZone.getTimeZone(id)));
77  }
78  // set the selected timezone to the current timezone
79  timeZoneComboBox.setSelectedItem(timeZoneToString(Calendar.getInstance().getTimeZone()));
80 
81  // Populate the drop down list of sector size options
82  for (String choice : SECTOR_SIZE_CHOICES) {
83  sectorSizeComboBox.addItem(choice);
84  }
85  sectorSizeComboBox.setSelectedIndex(0);
86 
87  pathErrorLabel.setVisible(false);
88 
89  fileChooser.setDragEnabled(false);
90  fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
91  fileChooser.setMultiSelectionEnabled(false);
92  fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
93  if (fileChooserFilters.isEmpty() == false) {
94  fileChooser.setFileFilter(fileChooserFilters.get(0));
95  }
96  }
97 
108  public static synchronized ImageFilePanel createInstance(String context, List<FileFilter> fileChooserFilters) {
109  ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters);
110  // post-constructor initialization of listener support without leaking references of uninitialized objects
111  instance.pathTextField.getDocument().addDocumentListener(instance);
112  return instance;
113  }
114 
120  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
121  private void initComponents() {
122 
123  pathLabel = new javax.swing.JLabel();
124  browseButton = new javax.swing.JButton();
125  pathTextField = new javax.swing.JTextField();
126  timeZoneLabel = new javax.swing.JLabel();
127  timeZoneComboBox = new javax.swing.JComboBox<>();
128  noFatOrphansCheckbox = new javax.swing.JCheckBox();
129  descLabel = new javax.swing.JLabel();
130  pathErrorLabel = new javax.swing.JLabel();
131  sectorSizeLabel = new javax.swing.JLabel();
132  sectorSizeComboBox = new javax.swing.JComboBox<>();
133 
134  setMinimumSize(new java.awt.Dimension(0, 65));
135  setPreferredSize(new java.awt.Dimension(403, 65));
136 
137  org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathLabel.text")); // NOI18N
138 
139  org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.browseButton.text")); // NOI18N
140  browseButton.addActionListener(new java.awt.event.ActionListener() {
141  public void actionPerformed(java.awt.event.ActionEvent evt) {
142  browseButtonActionPerformed(evt);
143  }
144  });
145 
146  pathTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathTextField.text")); // NOI18N
147 
148  org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.timeZoneLabel.text")); // NOI18N
149 
150  timeZoneComboBox.setMaximumRowCount(30);
151 
152  org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.text")); // NOI18N
153  noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
154 
155  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.descLabel.text")); // NOI18N
156 
157  pathErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
158  org.openide.awt.Mnemonics.setLocalizedText(pathErrorLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathErrorLabel.text")); // NOI18N
159 
160  org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sectorSizeLabel.text")); // NOI18N
161 
162  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
163  this.setLayout(layout);
164  layout.setHorizontalGroup(
165  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
166  .addGroup(layout.createSequentialGroup()
167  .addComponent(pathTextField)
168  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
169  .addComponent(browseButton)
170  .addGap(2, 2, 2))
171  .addGroup(layout.createSequentialGroup()
172  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
173  .addGroup(layout.createSequentialGroup()
174  .addComponent(timeZoneLabel)
175  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
176  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
177  .addComponent(pathLabel)
178  .addComponent(noFatOrphansCheckbox)
179  .addGroup(layout.createSequentialGroup()
180  .addGap(21, 21, 21)
181  .addComponent(descLabel))
182  .addComponent(pathErrorLabel)
183  .addGroup(layout.createSequentialGroup()
184  .addComponent(sectorSizeLabel)
185  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
186  .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)))
187  .addGap(0, 20, Short.MAX_VALUE))
188  );
189  layout.setVerticalGroup(
190  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
191  .addGroup(layout.createSequentialGroup()
192  .addComponent(pathLabel)
193  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
194  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
195  .addComponent(browseButton)
196  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
197  .addGap(3, 3, 3)
198  .addComponent(pathErrorLabel)
199  .addGap(1, 1, 1)
200  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
201  .addComponent(timeZoneLabel)
202  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
203  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
204  .addComponent(noFatOrphansCheckbox)
205  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
206  .addComponent(descLabel)
207  .addGap(18, 18, 18)
208  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
209  .addComponent(sectorSizeLabel)
210  .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
211  .addContainerGap(43, Short.MAX_VALUE))
212  );
213  }// </editor-fold>//GEN-END:initComponents
214 
215  @NbBundle.Messages({"ImageFilePanel.000.confirmationMessage=The selected file"
216  + " has extenson .001 but there is a .000 file in the sequence of raw images."
217  + "\nShould the .000 file be used as the start, instead of the selected .001 file?\n"})
218  private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
219  String oldText = getContentPaths();
220  // set the current directory of the FileChooser if the ImagePath Field is valid
221  File currentDir = new File(oldText);
222  if (currentDir.exists()) {
223  fileChooser.setCurrentDirectory(currentDir);
224  }
225 
226  if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
227  String path = fileChooser.getSelectedFile().getPath();
228  if (path.endsWith(".001")) {
229  String zeroX3_path = StringUtils.removeEnd(path, ".001") + ".000";
230  if (new File(zeroX3_path).exists()) {
231  int showConfirmDialog = JOptionPane.showConfirmDialog(this,
232  Bundle.ImageFilePanel_000_confirmationMessage(),
233  "Choose .001 file?", JOptionPane.YES_NO_OPTION);
234  if (showConfirmDialog == JOptionPane.YES_OPTION) {
235  path = zeroX3_path;
236  }
237  }
238  }
239  setContentPath(path);
240  }
241 
242  updateHelper();
243  }//GEN-LAST:event_browseButtonActionPerformed
244 
245  // Variables declaration - do not modify//GEN-BEGIN:variables
246  private javax.swing.JButton browseButton;
247  private javax.swing.JLabel descLabel;
248  private javax.swing.JCheckBox noFatOrphansCheckbox;
249  private javax.swing.JLabel pathErrorLabel;
250  private javax.swing.JLabel pathLabel;
251  private javax.swing.JTextField pathTextField;
252  private javax.swing.JComboBox<String> sectorSizeComboBox;
253  private javax.swing.JLabel sectorSizeLabel;
254  private javax.swing.JComboBox<String> timeZoneComboBox;
255  private javax.swing.JLabel timeZoneLabel;
256  // End of variables declaration//GEN-END:variables
257 
263  public String getContentPaths() {
264  return pathTextField.getText();
265  }
266 
272  public void setContentPath(String s) {
273  pathTextField.setText(s);
274  }
275 
281  public int getSectorSize() {
282  int sectorSizeSelectionIndex = sectorSizeComboBox.getSelectedIndex();
283 
284  if (sectorSizeSelectionIndex == 0) {
285  return 0;
286  }
287 
288  return Integer.valueOf((String) sectorSizeComboBox.getSelectedItem());
289  }
290 
291  public String getTimeZone() {
292  String tz = timeZoneComboBox.getSelectedItem().toString();
293  return tz.substring(tz.indexOf(')') + 2).trim();
294  }
295 
296  public boolean getNoFatOrphans() {
297  return noFatOrphansCheckbox.isSelected();
298  }
299 
300  public void reset() {
301  //reset the UI elements to default
302  pathTextField.setText(null);
303  }
304 
310  @NbBundle.Messages({"ImageFilePanel.pathValidation.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
311  "ImageFilePanel.pathValidation.getOpenCase.Error=Warning: Exception while getting open case."
312  })
313  public boolean validatePanel() {
314  pathErrorLabel.setVisible(false);
315  String path = getContentPaths();
316  if (StringUtils.isBlank(path)) {
317  return false;
318  }
319 
320  // Display warning if there is one (but don't disable "next" button)
321  try {
322  if (false == PathValidator.isValid(path, Case.getCurrentCaseThrows().getCaseType())) {
323  pathErrorLabel.setVisible(true);
324  pathErrorLabel.setText(Bundle.ImageFilePanel_pathValidation_dataSourceOnCDriveError());
325  }
326  } catch (NoCurrentCaseException ex) {
327  pathErrorLabel.setVisible(true);
328  pathErrorLabel.setText(Bundle.ImageFilePanel_pathValidation_getOpenCase_Error());
329  }
330 
331  return new File(path).isFile()
332  || DriveUtils.isPhysicalDrive(path)
333  || DriveUtils.isPartition(path);
334  }
335 
336  public void storeSettings() {
337  String imagePathName = getContentPaths();
338  if (null != imagePathName) {
339  String imagePath = imagePathName.substring(0, imagePathName.lastIndexOf(File.separator) + 1);
340  ModuleSettings.setConfigSetting(contextName, PROP_LASTIMAGE_PATH, imagePath);
341  }
342  }
343 
344  public void readSettings() {
345  String lastImagePath = ModuleSettings.getConfigSetting(contextName, PROP_LASTIMAGE_PATH);
346  if (StringUtils.isNotBlank(lastImagePath)) {
347  setContentPath(lastImagePath);
348  }
349  }
350 
359  static private String timeZoneToString(TimeZone zone) {
360  int offset = zone.getRawOffset() / 1000;
361  int hour = offset / 3600;
362  int minutes = (offset % 3600) / 60;
363  return String.format("(GMT%+d:%02d) %s", hour, minutes, zone.getID()); //NON-NLS
364  }
365 
366  @Override
367  public void insertUpdate(DocumentEvent e) {
368  updateHelper();
369  }
370 
371  @Override
372  public void removeUpdate(DocumentEvent e) {
373  updateHelper();
374  }
375 
376  @Override
377  public void changedUpdate(DocumentEvent e) {
378  updateHelper();
379  }
380 
387  @NbBundle.Messages({"ImageFilePanel.moduleErr=Module Error",
388  "ImageFilePanel.moduleErr.msg=A module caused an error listening to ImageFilePanel updates."
389  + " See log to determine which module. Some data could be incomplete.\n"})
390  private void updateHelper() {
391  try {
392  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
393  } catch (Exception e) {
394  logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", e); //NON-NLS
395  MessageNotifyUtil.Notify.error(ImageFilePanel_moduleErr(), ImageFilePanel_moduleErr_msg());
396  }
397  }
398 
402  public void select() {
403  pathTextField.requestFocusInWindow();
404  }
405 }
static boolean isPhysicalDrive(String path)
Definition: DriveUtils.java:43
javax.swing.JComboBox< String > sectorSizeComboBox
static synchronized ImageFilePanel createInstance(String context, List< FileFilter > fileChooserFilters)
static boolean isValid(String path, Case.CaseType caseType)
void browseButtonActionPerformed(java.awt.event.ActionEvent evt)
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
ImageFilePanel(String context, List< FileFilter > fileChooserFilters)
javax.swing.JComboBox< String > timeZoneComboBox
static String getConfigSetting(String moduleName, String settingName)
static void error(String title, String message)
static boolean isPartition(String path)
Definition: DriveUtils.java:54
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2016 Basis Technology. Generated on: Mon Jun 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.