Autopsy  4.19.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
UnpackagePortableCaseDialog.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 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.nio.file.Paths;
23 import javax.swing.JFileChooser;
24 import javax.swing.event.DocumentEvent;
25 import javax.swing.event.DocumentListener;
26 import javax.swing.filechooser.FileNameExtensionFilter;
27 import org.openide.util.NbBundle;
28 
32 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
33 class UnpackagePortableCaseDialog extends javax.swing.JDialog {
34 
35  private final String[] PORTABLE_CASE_EXTENSIONS = new String[]{"zip", "001"}; //NON-NLS
36  private final JFileChooser caseFileChooser;
37  private final JFileChooser outputFolderChooser;
38 
42  @NbBundle.Messages({
43  "UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001)",
44  "UnpackagePortableCaseDialog.title.text=Unpackage Portable Case",
45  })
46  UnpackagePortableCaseDialog(java.awt.Frame parent) {
47  super(parent, Bundle.UnpackagePortableCaseDialog_title_text(), true);
48  initComponents();
49 
50  FileNameExtensionFilter pkgFilter = new FileNameExtensionFilter(
51  Bundle.UnpackagePortableCaseDialog_UnpackagePortableCaseDialog_extensions(), PORTABLE_CASE_EXTENSIONS);
52  caseFileChooser = new JFileChooser();
53  caseFileChooser.setFileFilter(pkgFilter);
54 
55  outputFolderChooser = new JFileChooser();
56  outputFolderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
57 
58  caseErrorLabel.setText(""); // NON-NLS
59  outputErrorLabel.setText(""); // NON-NLS
60  unpackageButton.setEnabled(false);
61 
62  /*
63  * Create listenerer for the file paths
64  */
65  caseTextField.getDocument().addDocumentListener(new DocumentListener() {
66  @Override
67  public void changedUpdate(DocumentEvent e) {
68  validatePaths();
69  }
70 
71  @Override
72  public void insertUpdate(DocumentEvent e) {
73  validatePaths();
74  }
75 
76  @Override
77  public void removeUpdate(DocumentEvent e) {
78  validatePaths();
79  }
80  });
81  outputTextField.getDocument().addDocumentListener(new DocumentListener() {
82  @Override
83  public void changedUpdate(DocumentEvent e) {
84  validatePaths();
85  }
86 
87  @Override
88  public void insertUpdate(DocumentEvent e) {
89  validatePaths();
90  }
91 
92  @Override
93  public void removeUpdate(DocumentEvent e) {
94  validatePaths();
95  }
96  });
97 
98  }
99 
103  @NbBundle.Messages({
104  "UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist",
105  "UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file",
106  "UnpackagePortableCaseDialog.validatePaths.folderNotFound=Folder does not exist",
107  "UnpackagePortableCaseDialog.validatePaths.notAFolder=Output location is not a directory",
108  "# {0} - case folder",
109  "UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists",
110  "UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001",
111  })
112  private void validatePaths() {
113  boolean isValid = true;
114 
115  File portableCasePackage = new File(caseTextField.getText());
116  File outputDir = new File(outputTextField.getText());
117 
118  // First test the case package
119  if (caseTextField.getText().isEmpty()) {
120  caseErrorLabel.setText(""); // NON-NLS
121  isValid = false;
122  } else {
123  if (! portableCasePackage.exists()) {
124  caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseNotFound());
125  isValid = false;
126  } else if (! portableCasePackage.isFile()) {
127  caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseIsNotFile());
128  isValid = false;
129  }else {
130  // Do a final check that if the exension is ".001" it is preceeded by ".zip"
131  if (portableCasePackage.getAbsolutePath().endsWith(".001")) { // NON-NLS
132  if (portableCasePackage.getAbsolutePath().endsWith(".zip.001")) {
133  caseErrorLabel.setText(""); // NON-NLS
134  } else {
135  caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_badExtension());
136  isValid = false;
137  }
138  } else {
139  caseErrorLabel.setText(""); // NON-NLS
140  }
141  }
142  }
143 
144  // Now test the output folder
145  if (outputTextField.getText().isEmpty()) {
146  outputErrorLabel.setText(""); // NON-NLS
147  isValid = false;
148  } else {
149  if (! outputDir.exists()) {
150  outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_folderNotFound());
151  isValid = false;
152  } else if (! outputDir.isDirectory()) {
153  outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_notAFolder());
154  isValid = false;
155  } else {
156  // Check if the expected output folder exists if we are in a potentially valid state
157  if (isValid) {
158  String caseFolderName = portableCasePackage.getName();
159  if (caseFolderName.endsWith(".zip.001")) { // NON-NLS
160  caseFolderName = caseFolderName.substring(0, caseFolderName.length() - 8);
161  } else if (caseFolderName.endsWith(".zip")) { // NON-NLS
162  caseFolderName = caseFolderName.substring(0, caseFolderName.length() - 4);
163  }
164 
165  File expectedCaseFolder = Paths.get(outputDir.toString(), caseFolderName).toFile();
166  if (expectedCaseFolder.exists()) {
167  String pathToDisplay = expectedCaseFolder.toString();
168  if (pathToDisplay.length() > 40) {
169  pathToDisplay = "\"..." + pathToDisplay.substring(pathToDisplay.length() - 38) + "\""; // NON-NLS
170  }
171  outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseFolderExists(pathToDisplay));
172  isValid = false;
173  } else {
174  outputErrorLabel.setText(""); // NON-NLS
175  }
176  }
177  }
178  }
179 
180  unpackageButton.setEnabled(isValid);
181  }
182 
188  @SuppressWarnings("unchecked")
189  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
190  private void initComponents() {
191 
192  desc1Label = new javax.swing.JLabel();
193  desc2Label = new javax.swing.JLabel();
194  caseLabel = new javax.swing.JLabel();
195  caseTextField = new javax.swing.JTextField();
196  extractLabel = new javax.swing.JLabel();
197  outputTextField = new javax.swing.JTextField();
198  outputSelectButton = new javax.swing.JButton();
199  caseSelectButton = new javax.swing.JButton();
200  unpackageButton = new javax.swing.JButton();
201  exitButton = new javax.swing.JButton();
202  caseErrorLabel = new javax.swing.JLabel();
203  outputErrorLabel = new javax.swing.JLabel();
204 
205  setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
206 
207  org.openide.awt.Mnemonics.setLocalizedText(desc1Label, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.desc1Label.text")); // NOI18N
208 
209  org.openide.awt.Mnemonics.setLocalizedText(desc2Label, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.desc2Label.text")); // NOI18N
210 
211  org.openide.awt.Mnemonics.setLocalizedText(caseLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.caseLabel.text")); // NOI18N
212 
213  caseTextField.setText(org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.caseTextField.text")); // NOI18N
214 
215  org.openide.awt.Mnemonics.setLocalizedText(extractLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.extractLabel.text")); // NOI18N
216 
217  outputTextField.setText(org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.outputTextField.text")); // NOI18N
218 
219  org.openide.awt.Mnemonics.setLocalizedText(outputSelectButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.outputSelectButton.text")); // NOI18N
220  outputSelectButton.addActionListener(new java.awt.event.ActionListener() {
221  public void actionPerformed(java.awt.event.ActionEvent evt) {
222  outputSelectButtonActionPerformed(evt);
223  }
224  });
225 
226  org.openide.awt.Mnemonics.setLocalizedText(caseSelectButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.caseSelectButton.text")); // NOI18N
227  caseSelectButton.addActionListener(new java.awt.event.ActionListener() {
228  public void actionPerformed(java.awt.event.ActionEvent evt) {
229  caseSelectButtonActionPerformed(evt);
230  }
231  });
232 
233  org.openide.awt.Mnemonics.setLocalizedText(unpackageButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.unpackageButton.text")); // NOI18N
234  unpackageButton.addActionListener(new java.awt.event.ActionListener() {
235  public void actionPerformed(java.awt.event.ActionEvent evt) {
236  unpackageButtonActionPerformed(evt);
237  }
238  });
239 
240  org.openide.awt.Mnemonics.setLocalizedText(exitButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.exitButton.text")); // NOI18N
241  exitButton.addActionListener(new java.awt.event.ActionListener() {
242  public void actionPerformed(java.awt.event.ActionEvent evt) {
243  exitButtonActionPerformed(evt);
244  }
245  });
246 
247  caseErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
248  org.openide.awt.Mnemonics.setLocalizedText(caseErrorLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.caseErrorLabel.text")); // NOI18N
249 
250  outputErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
251  org.openide.awt.Mnemonics.setLocalizedText(outputErrorLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, "UnpackagePortableCaseDialog.outputErrorLabel.text")); // NOI18N
252 
253  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
254  getContentPane().setLayout(layout);
255  layout.setHorizontalGroup(
256  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
257  .addGroup(layout.createSequentialGroup()
258  .addContainerGap()
259  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
260  .addGroup(layout.createSequentialGroup()
261  .addComponent(caseTextField)
262  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
263  .addComponent(caseSelectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE))
264  .addGroup(layout.createSequentialGroup()
265  .addComponent(caseLabel)
266  .addGap(18, 18, 18)
267  .addComponent(caseErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
268  .addGroup(layout.createSequentialGroup()
269  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
270  .addComponent(desc1Label)
271  .addComponent(desc2Label)
272  .addGroup(layout.createSequentialGroup()
273  .addComponent(extractLabel)
274  .addGap(18, 18, 18)
275  .addComponent(outputErrorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 361, javax.swing.GroupLayout.PREFERRED_SIZE)))
276  .addGap(0, 0, Short.MAX_VALUE))
277  .addGroup(layout.createSequentialGroup()
278  .addComponent(outputTextField)
279  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
280  .addComponent(outputSelectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE))
281  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
282  .addGap(0, 0, Short.MAX_VALUE)
283  .addComponent(unpackageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)
284  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
285  .addComponent(exitButton, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)))
286  .addContainerGap())
287  );
288  layout.setVerticalGroup(
289  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
290  .addGroup(layout.createSequentialGroup()
291  .addContainerGap()
292  .addComponent(desc1Label)
293  .addGap(4, 4, 4)
294  .addComponent(desc2Label)
295  .addGap(13, 13, 13)
296  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
297  .addComponent(caseLabel)
298  .addComponent(caseErrorLabel))
299  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
300  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
301  .addComponent(caseTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
302  .addComponent(caseSelectButton))
303  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
304  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
305  .addComponent(extractLabel)
306  .addComponent(outputErrorLabel))
307  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
308  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
309  .addComponent(outputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
310  .addComponent(outputSelectButton))
311  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
312  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
313  .addComponent(exitButton)
314  .addComponent(unpackageButton))
315  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
316  );
317 
318  pack();
319  }// </editor-fold>//GEN-END:initComponents
320 
321  private void outputSelectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputSelectButtonActionPerformed
322  if (! outputTextField.getText().isEmpty()) {
323  outputFolderChooser.setCurrentDirectory(new File(outputTextField.getText()));
324  }
325  int returnVal = outputFolderChooser.showOpenDialog(this);
326  if (returnVal == JFileChooser.APPROVE_OPTION) {
327  outputTextField.setText(outputFolderChooser.getSelectedFile().getAbsolutePath());
328  }
329  }//GEN-LAST:event_outputSelectButtonActionPerformed
330 
331  private void caseSelectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseSelectButtonActionPerformed
332  if (! caseTextField.getText().isEmpty()) {
333  caseFileChooser.setCurrentDirectory(new File(caseTextField.getText()));
334  }
335  int returnVal = caseFileChooser.showOpenDialog(this);
336  if (returnVal == JFileChooser.APPROVE_OPTION) {
337  caseTextField.setText(caseFileChooser.getSelectedFile().getAbsolutePath());
338 
339  // Auto-fill the output field with the case folder
340  File tempCase = new File(caseTextField.getText());
341  if (tempCase.exists()) {
342  outputTextField.setText(tempCase.getParent());
343  }
344  }
345  }//GEN-LAST:event_caseSelectButtonActionPerformed
346 
347  private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitButtonActionPerformed
348  dispose();
349  }//GEN-LAST:event_exitButtonActionPerformed
350 
351  private void unpackageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unpackageButtonActionPerformed
352  UnpackagePortableCaseProgressDialog dialog = new UnpackagePortableCaseProgressDialog();
353  dialog.unpackageCase(caseTextField.getText(), outputTextField.getText());
354  if (dialog.isSuccess()) {
355  dispose();
356  } else {
357  validatePaths(); // The output folder now exists so we need to disable the unpackage button
358  }
359  }//GEN-LAST:event_unpackageButtonActionPerformed
360 
361 
362  // Variables declaration - do not modify//GEN-BEGIN:variables
363  private javax.swing.JLabel caseErrorLabel;
364  private javax.swing.JLabel caseLabel;
365  private javax.swing.JButton caseSelectButton;
366  private javax.swing.JTextField caseTextField;
367  private javax.swing.JLabel desc1Label;
368  private javax.swing.JLabel desc2Label;
369  private javax.swing.JButton exitButton;
370  private javax.swing.JLabel extractLabel;
371  private javax.swing.JLabel outputErrorLabel;
372  private javax.swing.JButton outputSelectButton;
373  private javax.swing.JTextField outputTextField;
374  private javax.swing.JButton unpackageButton;
375  // End of variables declaration//GEN-END:variables
376 }

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.