Autopsy  4.4.1
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-2017 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 public class ImageFilePanel extends JPanel implements DocumentListener {
49 
50  private static final Logger logger = Logger.getLogger(ImageFilePanel.class.getName());
51  private static final String PROP_LASTIMAGE_PATH = "LBL_LastImage_PATH"; //NON-NLS
52 
53  private final JFileChooser fileChooser = new JFileChooser();
54 
58  private final String contextName;
59 
68  private ImageFilePanel(String context, List<FileFilter> fileChooserFilters) {
69  this.contextName = context;
71 
72  // Populate the drop down list of time zones
73  for (String id : SimpleTimeZone.getAvailableIDs()) {
74  timeZoneComboBox.addItem(timeZoneToString(TimeZone.getTimeZone(id)));
75  }
76  // set the selected timezone to the current timezone
77  timeZoneComboBox.setSelectedItem(timeZoneToString(Calendar.getInstance().getTimeZone()));
78 
79  errorLabel.setVisible(false);
80 
81  fileChooser.setDragEnabled(false);
82  fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
83  fileChooser.setMultiSelectionEnabled(false);
84  fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
85  if (fileChooserFilters.isEmpty() == false) {
86  fileChooser.setFileFilter(fileChooserFilters.get(0));
87  }
88  }
89 
100  public static synchronized ImageFilePanel createInstance(String context, List<FileFilter> fileChooserFilters) {
101  ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters);
102  // post-constructor initialization of listener support without leaking references of uninitialized objects
103  instance.pathTextField.getDocument().addDocumentListener(instance);
104  return instance;
105  }
106 
112  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
113  private void initComponents() {
114 
115  pathLabel = new javax.swing.JLabel();
116  browseButton = new javax.swing.JButton();
117  pathTextField = new javax.swing.JTextField();
118  timeZoneLabel = new javax.swing.JLabel();
119  timeZoneComboBox = new javax.swing.JComboBox<String>();
120  noFatOrphansCheckbox = new javax.swing.JCheckBox();
121  descLabel = new javax.swing.JLabel();
122  errorLabel = new javax.swing.JLabel();
123 
124  setMinimumSize(new java.awt.Dimension(0, 65));
125  setPreferredSize(new java.awt.Dimension(403, 65));
126 
127  org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathLabel.text")); // NOI18N
128 
129  org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.browseButton.text")); // NOI18N
130  browseButton.addActionListener(new java.awt.event.ActionListener() {
131  public void actionPerformed(java.awt.event.ActionEvent evt) {
133  }
134  });
135 
136  pathTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathTextField.text")); // NOI18N
137 
138  org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.timeZoneLabel.text")); // NOI18N
139 
140  timeZoneComboBox.setMaximumRowCount(30);
141 
142  org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.text")); // NOI18N
143  noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
144 
145  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.descLabel.text")); // NOI18N
146 
147  errorLabel.setForeground(new java.awt.Color(255, 0, 0));
148  org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.errorLabel.text")); // NOI18N
149 
150  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
151  this.setLayout(layout);
152  layout.setHorizontalGroup(
153  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
154  .addGroup(layout.createSequentialGroup()
155  .addComponent(pathTextField)
156  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
157  .addComponent(browseButton)
158  .addGap(2, 2, 2))
159  .addGroup(layout.createSequentialGroup()
160  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
161  .addGroup(layout.createSequentialGroup()
162  .addComponent(timeZoneLabel)
163  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
164  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
165  .addComponent(pathLabel)
166  .addComponent(noFatOrphansCheckbox)
167  .addGroup(layout.createSequentialGroup()
168  .addGap(21, 21, 21)
169  .addComponent(descLabel))
170  .addComponent(errorLabel))
171  .addGap(0, 20, Short.MAX_VALUE))
172  );
173  layout.setVerticalGroup(
174  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
175  .addGroup(layout.createSequentialGroup()
176  .addComponent(pathLabel)
177  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
178  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
179  .addComponent(browseButton)
180  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
181  .addGap(3, 3, 3)
182  .addComponent(errorLabel)
183  .addGap(1, 1, 1)
184  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
185  .addComponent(timeZoneLabel)
186  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
187  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
188  .addComponent(noFatOrphansCheckbox)
189  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
190  .addComponent(descLabel)
191  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
192  );
193  }// </editor-fold>//GEN-END:initComponents
194 
195  @NbBundle.Messages({"ImageFilePanel.000.confirmationMessage=The selected file"
196  + " has extenson .001 but there is a .000 file in the sequence of raw images."
197  + "\nShould the .000 file be used as the start, instead of the selected .001 file?\n"})
198  private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
199  String oldText = getContentPaths();
200  // set the current directory of the FileChooser if the ImagePath Field is valid
201  File currentDir = new File(oldText);
202  if (currentDir.exists()) {
203  fileChooser.setCurrentDirectory(currentDir);
204  }
205 
206  if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
207  String path = fileChooser.getSelectedFile().getPath();
208  if (path.endsWith(".001")) {
209  String zeroX3_path = StringUtils.removeEnd(path, ".001") + ".000";
210  if (new File(zeroX3_path).exists()) {
211  int showConfirmDialog = JOptionPane.showConfirmDialog(this,
212  Bundle.ImageFilePanel_000_confirmationMessage(),
213  "Choose .001 file?", JOptionPane.YES_NO_OPTION);
214  if (showConfirmDialog == JOptionPane.YES_OPTION) {
215  path = zeroX3_path;
216  }
217  }
218  }
219  setContentPath(path);
220  }
221 
222  updateHelper();
223  }//GEN-LAST:event_browseButtonActionPerformed
224 
225  // Variables declaration - do not modify//GEN-BEGIN:variables
226  private javax.swing.JButton browseButton;
227  private javax.swing.JLabel descLabel;
228  private javax.swing.JLabel errorLabel;
229  private javax.swing.JCheckBox noFatOrphansCheckbox;
230  private javax.swing.JLabel pathLabel;
231  private javax.swing.JTextField pathTextField;
232  private javax.swing.JComboBox<String> timeZoneComboBox;
233  private javax.swing.JLabel timeZoneLabel;
234  // End of variables declaration//GEN-END:variables
235 
241  public String getContentPaths() {
242  return pathTextField.getText();
243  }
244 
250  public void setContentPath(String s) {
251  pathTextField.setText(s);
252  }
253 
254  public String getTimeZone() {
255  String tz = timeZoneComboBox.getSelectedItem().toString();
256  return tz.substring(tz.indexOf(')') + 2).trim();
257  }
258 
259  public boolean getNoFatOrphans() {
260  return noFatOrphansCheckbox.isSelected();
261  }
262 
263  public void reset() {
264  //reset the UI elements to default
265  pathTextField.setText(null);
266  }
267 
273  @NbBundle.Messages("DataSourceOnCDriveError.text=Warning: Path to multi-user data source is on \"C:\" drive")
274  public boolean validatePanel() {
275  errorLabel.setVisible(false);
276  String path = getContentPaths();
277  if (StringUtils.isBlank(path)) {
278  return false;
279  }
280 
281  // display warning if there is one (but don't disable "next" button)
282  if (false == PathValidator.isValid(path, Case.getCurrentCase().getCaseType())) {
283  errorLabel.setVisible(true);
284  errorLabel.setText(Bundle.DataSourceOnCDriveError_text());
285  }
286 
287  return new File(path).isFile()
288  || DriveUtils.isPhysicalDrive(path)
289  || DriveUtils.isPartition(path);
290  }
291 
292  public void storeSettings() {
293  String imagePathName = getContentPaths();
294  if (null != imagePathName) {
295  String imagePath = imagePathName.substring(0, imagePathName.lastIndexOf(File.separator) + 1);
296  ModuleSettings.setConfigSetting(contextName, PROP_LASTIMAGE_PATH, imagePath);
297  }
298  }
299 
300  public void readSettings() {
301  String lastImagePath = ModuleSettings.getConfigSetting(contextName, PROP_LASTIMAGE_PATH);
302  if (StringUtils.isNotBlank(lastImagePath)) {
303  setContentPath(lastImagePath);
304  }
305  }
306 
315  static private String timeZoneToString(TimeZone zone) {
316  int offset = zone.getRawOffset() / 1000;
317  int hour = offset / 3600;
318  int minutes = (offset % 3600) / 60;
319  return String.format("(GMT%+d:%02d) %s", hour, minutes, zone.getID()); //NON-NLS
320  }
321 
322  @Override
323  public void insertUpdate(DocumentEvent e) {
324  updateHelper();
325  }
326 
327  @Override
328  public void removeUpdate(DocumentEvent e) {
329  updateHelper();
330  }
331 
332  @Override
333  public void changedUpdate(DocumentEvent e) {
334  updateHelper();
335  }
336 
343  @NbBundle.Messages({"ImageFilePanel.moduleErr=Module Error",
344  "ImageFilePanel.moduleErr.msg=A module caused an error listening to ImageFilePanel updates."
345  + " See log to determine which module. Some data could be incomplete.\n"})
346  private void updateHelper() {
347  try {
348  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
349  } catch (Exception e) {
350  logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", e); //NON-NLS
351  MessageNotifyUtil.Notify.error(ImageFilePanel_moduleErr(), ImageFilePanel_moduleErr_msg());
352  }
353  }
354 
358  public void select() {
359  pathTextField.requestFocusInWindow();
360  }
361 }
static boolean isPhysicalDrive(String path)
Definition: DriveUtils.java:43
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:161

Copyright © 2012-2016 Basis Technology. Generated on: Fri Sep 29 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.