Autopsy  4.11.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 
84  @NbBundle.Messages({"UnpackagePortableCaseProgressDialog.propertyChange.success=Successfully unpacked case",})
85  @Override
86  public void propertyChange(PropertyChangeEvent evt) {
87 
88  if ("state".equals(evt.getPropertyName())
89  && (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) { // NON-NLS
90 
91  // The worker is done processing
92  // Disable cancel button and enable ok
93  cancelButton.setEnabled(false);
94  okButton.setEnabled(true);
95 
96  if (worker.isSuccess()) {
97  progressBar.setIndeterminate(false);
98  progressBar.setValue(progressBar.getMaximum());
99  resultLabel.setText(Bundle.UnpackagePortableCaseProgressDialog_propertyChange_success());
100  } else {
101  // If there was an error, reset the progress bar and display an error message
102  progressBar.setIndeterminate(false);
103  progressBar.setValue(0);
104  resultLabel.setForeground(Color.red);
105  resultLabel.setText(worker.getDisplayError());
106  }
107  }
108  }
109 
113  private class UnpackageWorker extends SwingWorker<Void, Void> {
114 
115  private final String packagedCase;
116  private final String outputFolder;
117 
118  private final AtomicBoolean success = new AtomicBoolean();
119  private String lastError = "";
120 
121  UnpackageWorker(String packagedCase, String outputFolder) {
122  this.packagedCase = packagedCase;
123  this.outputFolder = outputFolder;
124  this.success.set(false);
125  }
126 
127  @NbBundle.Messages({
128  "UnpackageWorker.doInBackground.errorFinding7zip=Could not locate 7-Zip executable",
129  "UnpackageWorker.doInBackground.errorCompressingCase=Error unpackaging case",
130  "UnpackageWorker.doInBackground.canceled=Unpackaging canceled by user",
131  })
132  @Override
133  protected Void doInBackground() throws Exception {
134 
135  // Find 7-Zip
136  File sevenZipExe = locate7ZipExecutable();
137  if (sevenZipExe == null) {
138  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorFinding7zip());
139  throw new TskCoreException("Error finding 7-Zip executable"); // NON-NLS
140  }
141 
142  String outputFolderSwitch = "-o" + outputFolder; // NON-NLS
143  ProcessBuilder procBuilder = new ProcessBuilder();
144  procBuilder.command(
145  sevenZipExe.getAbsolutePath(),
146  "x", // Extract
147  packagedCase,
148  outputFolderSwitch
149  );
150 
151  try {
152  Process process = procBuilder.start();
153 
154  while (process.isAlive()) {
155  if (this.isCancelled()) {
156  setDisplayError(Bundle.UnpackageWorker_doInBackground_canceled());
157  return null;
158  }
159  Thread.sleep(200);
160  }
161 
162  int exitCode = process.exitValue();
163  if (exitCode != 0) {
164  // Save any errors so they can be logged
165  StringBuilder sb = new StringBuilder();
166  try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
167  String line;
168  while ((line = br.readLine()) != null) {
169  sb.append(line).append(System.getProperty("line.separator")); // NON-NLS
170  }
171  }
172 
173  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorCompressingCase());
174  throw new TskCoreException("Error unpackaging case. 7-Zip output: " + sb.toString()); // NON-NLS
175  }
176  } catch (IOException | InterruptedException ex) {
177  setDisplayError(Bundle.UnpackageWorker_doInBackground_errorCompressingCase());
178  throw new TskCoreException("Error unpackaging case", ex); // NON-NLS
179  }
180 
181  success.set(true);
182  return null;
183  }
184 
185  @Override
186  synchronized protected void done() {
187  if (this.isCancelled()) {
188  return;
189  }
190 
191  try {
192  get();
193  } catch (Exception ex) {
194  Logger.getLogger(UnpackagePortableCaseProgressDialog.class.getName()).log(Level.SEVERE, "Error unpackaging portable case", ex); // NON-NLS
195  }
196  }
197 
203  private synchronized void setDisplayError(String errorStr) {
204  lastError = errorStr;
205  }
206 
211  private synchronized String getDisplayError() {
212  return lastError;
213  }
214 
215  private boolean isSuccess() {
216  return success.get();
217  }
218 
224  private File locate7ZipExecutable() {
225  if (!PlatformUtil.isWindowsOS()) {
226  return null;
227  }
228 
229  String executableToFindName = Paths.get("7-Zip", "7z.exe").toString(); // NON-NLS
230  File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, UnpackagePortableCaseProgressDialog.class.getPackage().getName(), false);
231  if (null == exeFile) {
232  return null;
233  }
234 
235  if (!exeFile.canExecute()) {
236  return null;
237  }
238 
239  return exeFile;
240  }
241  }
242 
248  @SuppressWarnings("unchecked")
249  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
250  private void initComponents() {
251 
252  progressBar = new javax.swing.JProgressBar();
253  cancelButton = new javax.swing.JButton();
254  okButton = new javax.swing.JButton();
255  resultLabel = new javax.swing.JLabel();
256 
257  setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
258 
259  org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.cancelButton.text")); // NOI18N
260  cancelButton.addActionListener(new java.awt.event.ActionListener() {
261  public void actionPerformed(java.awt.event.ActionEvent evt) {
262  cancelButtonActionPerformed(evt);
263  }
264  });
265 
266  org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.okButton.text")); // NOI18N
267  okButton.addActionListener(new java.awt.event.ActionListener() {
268  public void actionPerformed(java.awt.event.ActionEvent evt) {
269  okButtonActionPerformed(evt);
270  }
271  });
272 
273  org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(UnpackagePortableCaseProgressDialog.class, "UnpackagePortableCaseProgressDialog.resultLabel.text")); // NOI18N
274 
275  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
276  getContentPane().setLayout(layout);
277  layout.setHorizontalGroup(
278  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
279  .addGroup(layout.createSequentialGroup()
280  .addContainerGap()
281  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
282  .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE)
283  .addGroup(layout.createSequentialGroup()
284  .addComponent(resultLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
285  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
286  .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
287  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
288  .addComponent(cancelButton)))
289  .addContainerGap())
290  );
291  layout.setVerticalGroup(
292  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
293  .addGroup(layout.createSequentialGroup()
294  .addContainerGap()
295  .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
296  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
297  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
298  .addComponent(cancelButton)
299  .addComponent(okButton)
300  .addComponent(resultLabel))
301  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
302  );
303 
304  pack();
305  }// </editor-fold>//GEN-END:initComponents
306 
307  private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
308  worker.cancel(true);
309  dispose();
310  }//GEN-LAST:event_cancelButtonActionPerformed
311 
312  private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
313  dispose();
314  }//GEN-LAST:event_okButtonActionPerformed
315 
316  // Variables declaration - do not modify//GEN-BEGIN:variables
317  private javax.swing.JButton cancelButton;
318  private javax.swing.JButton okButton;
319  private javax.swing.JProgressBar progressBar;
320  private javax.swing.JLabel resultLabel;
321  // End of variables declaration//GEN-END:variables
322 }
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

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