Autopsy  4.12.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
UnpackagePortableCaseProgressDialog.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.awt.Color;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.io.BufferedReader;
25 import java.io.File;
26 import java.io.IOException;
27 import java.io.InputStreamReader;
28 import java.nio.file.Paths;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import java.util.logging.Level;
31 import javax.swing.JFrame;
32 import javax.swing.SwingWorker;
33 import org.openide.modules.InstalledFileLocator;
34 import org.openide.util.NbBundle;
35 import org.openide.windows.WindowManager;
38 import org.sleuthkit.datamodel.TskCoreException;
39 
43 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
44 class UnpackagePortableCaseProgressDialog extends javax.swing.JDialog implements PropertyChangeListener {
45 
46  private UnpackageWorker worker;
47 
51  @NbBundle.Messages({"UnpackagePortableCaseProgressDialog.title.text=Unpackage Portable Case Progress",})
52  UnpackagePortableCaseProgressDialog() {
53  super((JFrame) WindowManager.getDefault().getMainWindow(),
54  Bundle.UnpackagePortableCaseProgressDialog_title_text(),
55  true);
56  initComponents();
57  customizeComponents();
58  }
59 
60  private void customizeComponents() {
61  cancelButton.setEnabled(true);
62  okButton.setEnabled(false);
63  progressBar.setIndeterminate(true);
64  resultLabel.setText(""); // NON-NLS
65  }
66 
73  void unpackageCase(String packagedCase, String outputFolder) {
74 
75  worker = new UnpackageWorker(packagedCase, outputFolder);
76  worker.addPropertyChangeListener(this);
77  worker.execute();
78 
79  setLocationRelativeTo((JFrame) WindowManager.getDefault().getMainWindow());
80  this.setVisible(true);
81 
82  }
83 
89  boolean isSuccess() {
90  if (worker == null) {
91  return false;
92  } else {
93  return worker.isSuccess();
94  }
95  }
96 
97  @NbBundle.Messages({"UnpackagePortableCaseProgressDialog.propertyChange.success=Successfully unpacked case",})
98  @Override
99  public void propertyChange(PropertyChangeEvent evt) {
100 
101  if ("state".equals(evt.getPropertyName())
102  && (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) { // NON-NLS
103 
104  // The worker is done processing
105  // Disable cancel button and enable ok
106  cancelButton.setEnabled(false);
107  okButton.setEnabled(true);
108 
109  if (worker.isSuccess()) {
110  progressBar.setIndeterminate(false);
111  progressBar.setValue(progressBar.getMaximum());
112  resultLabel.setText(Bundle.UnpackagePortableCaseProgressDialog_propertyChange_success());
113  } else {
114  // If there was an error, reset the progress bar and display an error message
115  progressBar.setIndeterminate(false);
116  progressBar.setValue(0);
117  resultLabel.setForeground(Color.red);
118  resultLabel.setText(worker.getDisplayError());
119  }
120  }
121  }
122 
126  private class UnpackageWorker extends SwingWorker<Void, Void> {
127 
128  private final String packagedCase;
129  private final String outputFolder;
130 
131  private final AtomicBoolean success = new AtomicBoolean();
132  private String lastError = "";
133 
134  UnpackageWorker(String packagedCase, String outputFolder) {
135  this.packagedCase = packagedCase;
136  this.outputFolder = outputFolder;
137  this.success.set(false);
138  }
139 
140  @NbBundle.Messages({
141  "UnpackageWorker.doInBackground.errorFinding7zip=Could not locate 7-Zip executable",
142  "UnpackageWorker.doInBackground.errorCompressingCase=Error unpackaging case",
143  "UnpackageWorker.doInBackground.canceled=Unpackaging canceled by user",})
144  @Override
145  protected Void doInBackground() throws Exception {
146 
147  // Find 7-Zip
148  File sevenZipExe = locate7ZipExecutable();
149  if (sevenZipExe == null) {
150  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorFinding7zip());
151  throw new TskCoreException("Error finding 7-Zip executable"); // NON-NLS
152  }
153 
154  String outputFolderSwitch = "-o" + outputFolder; // NON-NLS
155  ProcessBuilder procBuilder = new ProcessBuilder();
156  procBuilder.command(
157  sevenZipExe.getAbsolutePath(),
158  "x", // Extract
159  packagedCase,
160  outputFolderSwitch
161  );
162 
163  try {
164  Process process = procBuilder.start();
165 
166  while (process.isAlive()) {
167  if (this.isCancelled()) {
168  setDisplayError(Bundle.UnpackageWorker_doInBackground_canceled());
169  return null;
170  }
171  Thread.sleep(200);
172  }
173 
174  int exitCode = process.exitValue();
175  if (exitCode != 0) {
176  // Save any errors so they can be logged
177  StringBuilder sb = new StringBuilder();
178  try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
179  String line;
180  while ((line = br.readLine()) != null) {
181  sb.append(line).append(System.getProperty("line.separator")); // NON-NLS
182  }
183  }
184 
185  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorCompressingCase());
186  throw new TskCoreException("Error unpackaging case. 7-Zip output: " + sb.toString()); // NON-NLS
187  }
188  } catch (IOException | InterruptedException ex) {
189  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorCompressingCase());
190  throw new TskCoreException("Error unpackaging case", ex); // NON-NLS
191  }
192 
193  success.set(true);
194  return null;
195  }
196 
197  @Override
198  synchronized protected void done() {
199  if (this.isCancelled()) {
200  return;
201  }
202 
203  try {
204  get();
205  } catch (Exception ex) {
206  Logger.getLogger(UnpackagePortableCaseProgressDialog.class.getName()).log(Level.SEVERE, "Error unpackaging portable case", ex); // NON-NLS
207  }
208  }
209 
215  private synchronized void setDisplayError(String errorStr) {
216  lastError = errorStr;
217  }
218 
224  private synchronized String getDisplayError() {
225  return lastError;
226  }
227 
228  protected boolean isSuccess() {
229  return success.get();
230  }
231 
237  private File locate7ZipExecutable() {
238  if (!PlatformUtil.isWindowsOS()) {
239  return null;
240  }
241 
242  String executableToFindName = Paths.get("7-Zip", "7z.exe").toString(); // NON-NLS
243  File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, UnpackagePortableCaseProgressDialog.class.getPackage().getName(), false);
244  if (null == exeFile) {
245  return null;
246  }
247 
248  if (!exeFile.canExecute()) {
249  return null;
250  }
251 
252  return exeFile;
253  }
254  }
255 
261  @SuppressWarnings("unchecked")
262  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
263  private void initComponents() {
264 
265  progressBar = new javax.swing.JProgressBar();
266  cancelButton = new javax.swing.JButton();
267  okButton = new javax.swing.JButton();
268  resultLabel = new javax.swing.JLabel();
269 
270  setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
271 
272  org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.cancelButton.text")); // NOI18N
273  cancelButton.addActionListener(new java.awt.event.ActionListener() {
274  public void actionPerformed(java.awt.event.ActionEvent evt) {
275  cancelButtonActionPerformed(evt);
276  }
277  });
278 
279  org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.okButton.text")); // NOI18N
280  okButton.addActionListener(new java.awt.event.ActionListener() {
281  public void actionPerformed(java.awt.event.ActionEvent evt) {
282  okButtonActionPerformed(evt);
283  }
284  });
285 
286  org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.resultLabel.text")); // NOI18N
287 
288  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
289  getContentPane().setLayout(layout);
290  layout.setHorizontalGroup(
291  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
292  .addGroup(layout.createSequentialGroup()
293  .addContainerGap()
294  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
295  .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE)
296  .addGroup(layout.createSequentialGroup()
297  .addComponent(resultLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
298  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
299  .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
300  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
301  .addComponent(cancelButton)))
302  .addContainerGap())
303  );
304  layout.setVerticalGroup(
305  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
306  .addGroup(layout.createSequentialGroup()
307  .addContainerGap()
308  .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
309  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
310  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
311  .addComponent(cancelButton)
312  .addComponent(okButton)
313  .addComponent(resultLabel))
314  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
315  );
316 
317  pack();
318  }// </editor-fold>//GEN-END:initComponents
319 
320  private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
321  worker.cancel(true);
322  dispose();
323  }//GEN-LAST:event_cancelButtonActionPerformed
324 
325  private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
326  dispose();
327  }//GEN-LAST:event_okButtonActionPerformed
328 
329  // Variables declaration - do not modify//GEN-BEGIN:variables
330  private javax.swing.JButton cancelButton;
331  private javax.swing.JButton okButton;
332  private javax.swing.JProgressBar progressBar;
333  private javax.swing.JLabel resultLabel;
334  // End of variables declaration//GEN-END:variables
335 }
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

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