19 package org.sleuthkit.autopsy.casemodule;
22 import java.util.Calendar;
23 import java.util.List;
24 import javax.swing.JFileChooser;
25 import javax.swing.JOptionPane;
26 import javax.swing.JPanel;
27 import javax.swing.JTextField;
28 import javax.swing.event.DocumentEvent;
29 import javax.swing.event.DocumentListener;
30 import javax.swing.filechooser.FileFilter;
31 import org.apache.commons.lang3.StringUtils;
32 import org.openide.util.NbBundle;
45 @SuppressWarnings(
"PMD.SingularField")
48 private static final long serialVersionUID = 1L;
49 private static final String PROP_LASTIMAGE_PATH =
"LBL_LastImage_PATH";
50 private static final String[] SECTOR_SIZE_CHOICES = {
"Auto Detect",
"512",
"1024",
"2048",
"4096"};
51 private final JFileChooser fileChooser =
new JFileChooser();
62 private ImageFilePanel(String context, List<FileFilter> fileChooserFilters) {
63 this.contextName = context;
70 for (String choice : SECTOR_SIZE_CHOICES) {
71 sectorSizeComboBox.addItem(choice);
73 sectorSizeComboBox.setSelectedIndex(0);
75 errorLabel.setVisible(
false);
77 fileChooser.setDragEnabled(
false);
78 fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
79 fileChooser.setMultiSelectionEnabled(
false);
80 fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
81 if (fileChooserFilters.isEmpty() ==
false) {
82 fileChooser.setFileFilter(fileChooserFilters.get(0));
92 for (String timeZone : timeZoneList) {
93 timeZoneComboBox.addItem(timeZone);
121 return pathTextField;
125 return md5HashTextField;
129 return sha1HashTextField;
133 return sha256HashTextField;
144 pathLabel =
new javax.swing.JLabel();
145 browseButton =
new javax.swing.JButton();
146 pathTextField =
new javax.swing.JTextField();
147 timeZoneLabel =
new javax.swing.JLabel();
148 timeZoneComboBox =
new javax.swing.JComboBox<>();
149 noFatOrphansCheckbox =
new javax.swing.JCheckBox();
150 errorLabel =
new javax.swing.JLabel();
151 sectorSizeLabel =
new javax.swing.JLabel();
152 sectorSizeComboBox =
new javax.swing.JComboBox<>();
153 sha256HashLabel =
new javax.swing.JLabel();
154 sha256HashTextField =
new javax.swing.JTextField();
155 sha1HashTextField =
new javax.swing.JTextField();
156 md5HashTextField =
new javax.swing.JTextField();
157 sha1HashLabel =
new javax.swing.JLabel();
158 md5HashLabel =
new javax.swing.JLabel();
160 setMinimumSize(
new java.awt.Dimension(0, 65));
161 setPreferredSize(
new java.awt.Dimension(403, 65));
163 org.openide.awt.Mnemonics.setLocalizedText(pathLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.pathLabel.text"));
165 org.openide.awt.Mnemonics.setLocalizedText(browseButton,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.browseButton.text"));
166 browseButton.addActionListener(
new java.awt.event.ActionListener() {
167 public void actionPerformed(java.awt.event.ActionEvent evt) {
168 browseButtonActionPerformed(evt);
172 pathTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.pathTextField.text"));
174 org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.timeZoneLabel.text"));
176 timeZoneComboBox.setMaximumRowCount(30);
178 org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.noFatOrphansCheckbox.text"));
179 noFatOrphansCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.noFatOrphansCheckbox.toolTipText"));
181 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
182 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.errorLabel.text"));
184 org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.sectorSizeLabel.text"));
186 org.openide.awt.Mnemonics.setLocalizedText(sha256HashLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.sha256HashLabel.text"));
188 sha256HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.sha256HashTextField.text"));
190 sha1HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.sha1HashTextField.text"));
192 md5HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.md5HashTextField.text"));
194 org.openide.awt.Mnemonics.setLocalizedText(sha1HashLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.sha1HashLabel.text"));
196 org.openide.awt.Mnemonics.setLocalizedText(md5HashLabel,
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class,
"ImageFilePanel.md5HashLabel.text"));
198 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
199 this.setLayout(layout);
200 layout.setHorizontalGroup(
201 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
202 .addGroup(layout.createSequentialGroup()
203 .addComponent(pathTextField)
204 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
205 .addComponent(browseButton)
207 .addGroup(layout.createSequentialGroup()
208 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
209 .addComponent(sha256HashLabel)
210 .addComponent(sha1HashLabel)
211 .addComponent(md5HashLabel)
212 .addComponent(sectorSizeLabel)
213 .addComponent(timeZoneLabel))
214 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
215 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
216 .addComponent(sha256HashTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 455, Short.MAX_VALUE)
217 .addComponent(sha1HashTextField)
218 .addComponent(md5HashTextField)
219 .addComponent(sectorSizeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
220 .addComponent(timeZoneComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
221 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
222 .addGroup(layout.createSequentialGroup()
223 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
224 .addComponent(pathLabel)
225 .addComponent(errorLabel)
226 .addComponent(noFatOrphansCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE))
227 .addGap(0, 325, Short.MAX_VALUE))
229 layout.setVerticalGroup(
230 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
231 .addGroup(layout.createSequentialGroup()
232 .addComponent(pathLabel)
233 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
234 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
235 .addComponent(browseButton)
236 .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
237 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
238 .addComponent(noFatOrphansCheckbox)
239 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
240 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
241 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
242 .addComponent(timeZoneLabel))
243 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
244 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
245 .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
246 .addComponent(sectorSizeLabel))
247 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
248 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
249 .addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
250 .addComponent(md5HashLabel))
251 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
252 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
253 .addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
254 .addComponent(sha1HashLabel))
255 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
256 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
257 .addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
258 .addComponent(sha256HashLabel))
260 .addComponent(errorLabel)
261 .addContainerGap(23, Short.MAX_VALUE))
265 @NbBundle.Messages({
"ImageFilePanel.000.confirmationMessage=The selected file"
266 +
" has extenson .001 but there is a .000 file in the sequence of raw images."
267 +
"\nShould the .000 file be used as the start, instead of the selected .001 file?\n"})
269 String oldText = getContentPaths();
271 File currentDir =
new File(oldText);
272 if (currentDir.exists()) {
273 fileChooser.setCurrentDirectory(currentDir);
276 if (fileChooser.showOpenDialog(
this) == JFileChooser.APPROVE_OPTION) {
277 String path = fileChooser.getSelectedFile().getPath();
278 if (path.endsWith(
".001")) {
279 String zeroX3_path = StringUtils.removeEnd(path,
".001") +
".000";
280 if (
new File(zeroX3_path).exists()) {
281 int showConfirmDialog = JOptionPane.showConfirmDialog(
this,
282 Bundle.ImageFilePanel_000_confirmationMessage(),
283 "Choose .001 file?", JOptionPane.YES_NO_OPTION);
284 if (showConfirmDialog == JOptionPane.YES_OPTION) {
289 setContentPath(path);
319 return pathTextField.getText();
328 pathTextField.setText(s);
337 int sectorSizeSelectionIndex = sectorSizeComboBox.getSelectedIndex();
339 if (sectorSizeSelectionIndex == 0) {
343 return Integer.valueOf((String) sectorSizeComboBox.getSelectedItem());
347 String tz = timeZoneComboBox.getSelectedItem().toString();
348 return tz.substring(tz.indexOf(
')') + 2).trim();
352 return noFatOrphansCheckbox.isSelected();
356 return this.md5HashTextField.getText();
360 return this.sha1HashTextField.getText();
364 return this.sha256HashTextField.getText();
369 pathTextField.setText(null);
378 "ImageFilePanel.validatePanel.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
379 "ImageFilePanel.validatePanel.invalidMD5=Invalid MD5 hash",
380 "ImageFilePanel.validatePanel.invalidSHA1=Invalid SHA1 hash",
381 "ImageFilePanel.validatePanel.invalidSHA256=Invalid SHA256 hash",})
383 errorLabel.setVisible(
false);
385 String path = getContentPaths();
390 if (!StringUtils.isBlank(getMd5()) && !HashUtility.isValidMd5Hash(getMd5())) {
391 errorLabel.setVisible(
true);
392 errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidMD5());
396 if (!StringUtils.isBlank(getSha1()) && !HashUtility.isValidSha1Hash(getSha1())) {
397 errorLabel.setVisible(
true);
398 errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA1());
402 if (!StringUtils.isBlank(getSha256()) && !HashUtility.isValidSha256Hash(getSha256())) {
403 errorLabel.setVisible(
true);
404 errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA256());
409 errorLabel.setVisible(
true);
410 errorLabel.setText(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
417 String imagePathName = getContentPaths();
418 if (null != imagePathName) {
419 String imagePath = imagePathName.substring(0, imagePathName.lastIndexOf(File.separator) + 1);
426 if (StringUtils.isNotBlank(lastImagePath)) {
427 setContentPath(lastImagePath);
452 @NbBundle.Messages({
"ImageFilePanel.moduleErr=Module Error",
453 "ImageFilePanel.moduleErr.msg=A module caused an error listening to ImageFilePanel updates."
454 +
" See log to determine which module. Some data could be incomplete.\n"})
463 pathTextField.requestFocusInWindow();
static boolean isPhysicalDrive(String path)
static boolean isValidForMultiUserCase(String path, Case.CaseType caseType)
boolean getNoFatOrphans()
JTextField getSha256TextField()
javax.swing.JLabel timeZoneLabel
static List< String > createTimeZoneList()
javax.swing.JLabel pathLabel
JTextField getSha1TextField()
javax.swing.JTextField sha256HashTextField
javax.swing.JComboBox< String > sectorSizeComboBox
static synchronized ImageFilePanel createInstance(String context, List< FileFilter > fileChooserFilters)
javax.swing.JLabel sha1HashLabel
javax.swing.JTextField sha1HashTextField
javax.swing.JLabel sha256HashLabel
JTextField getMd5TextFieldField()
void createTimeZoneList()
static String createTimeZoneString(TimeZone timeZone)
void setContentPath(String s)
void browseButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JLabel sectorSizeLabel
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
javax.swing.JTextField md5HashTextField
javax.swing.JLabel md5HashLabel
ImageFilePanel(String context, List< FileFilter > fileChooserFilters)
javax.swing.JComboBox< String > timeZoneComboBox
void changedUpdate(DocumentEvent e)
JTextField getPathTextField()
static String getConfigSetting(String moduleName, String settingName)
javax.swing.JButton browseButton
static boolean isPartition(String path)
javax.swing.JTextField pathTextField
static Case getCurrentCase()
javax.swing.JLabel errorLabel
javax.swing.JCheckBox noFatOrphansCheckbox
void removeUpdate(DocumentEvent e)
void insertUpdate(DocumentEvent e)