Autopsy 4.22.1
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-2021 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 */
19package org.sleuthkit.autopsy.casemodule;
20
21import java.io.File;
22import java.nio.file.Paths;
23import javax.swing.JFileChooser;
24import javax.swing.event.DocumentEvent;
25import javax.swing.event.DocumentListener;
26import javax.swing.filechooser.FileNameExtensionFilter;
27import org.openide.util.NbBundle;
28
32@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
33class 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-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.