19 package org.sleuthkit.autopsy.casemodule;
 
   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;
 
   32 @SuppressWarnings(
"PMD.SingularField") 
 
   33 class UnpackagePortableCaseDialog extends javax.swing.JDialog {
 
   35     private final String[] PORTABLE_CASE_EXTENSIONS = 
new String[]{
"zip", 
"001"}; 
 
   36     private final JFileChooser caseFileChooser;
 
   37     private final JFileChooser outputFolderChooser;
 
   43         "UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001)",
 
   44         "UnpackagePortableCaseDialog.title.text=Unpackage Portable Case",
 
   46     UnpackagePortableCaseDialog(java.awt.Frame parent) {
 
   47         super(parent, Bundle.UnpackagePortableCaseDialog_title_text(), 
true);
 
   50         FileNameExtensionFilter pkgFilter = 
new FileNameExtensionFilter(
 
   51                 Bundle.UnpackagePortableCaseDialog_UnpackagePortableCaseDialog_extensions(), PORTABLE_CASE_EXTENSIONS);
 
   52         caseFileChooser = 
new JFileChooser();
 
   53         caseFileChooser.setFileFilter(pkgFilter);
 
   55         outputFolderChooser = 
new JFileChooser();
 
   56         outputFolderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
 
   58         caseErrorLabel.setText(
""); 
 
   59         outputErrorLabel.setText(
""); 
 
   60         unpackageButton.setEnabled(
false);
 
   65         caseTextField.getDocument().addDocumentListener(
new DocumentListener() {
 
   67             public void changedUpdate(DocumentEvent e) {
 
   72             public void insertUpdate(DocumentEvent e) {
 
   77             public void removeUpdate(DocumentEvent e) {
 
   81         outputTextField.getDocument().addDocumentListener(
new DocumentListener() {
 
   83             public void changedUpdate(DocumentEvent e) {
 
   88             public void insertUpdate(DocumentEvent e) {
 
   93             public void removeUpdate(DocumentEvent e) {
 
  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",
 
  112     private void validatePaths() {
 
  113         boolean isValid = 
true;
 
  115         File portableCasePackage = 
new File(caseTextField.getText());
 
  116         File outputDir = 
new File(outputTextField.getText());
 
  119         if (caseTextField.getText().isEmpty()) {
 
  120             caseErrorLabel.setText(
""); 
 
  123             if (! portableCasePackage.exists()) {
 
  124                 caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseNotFound());
 
  126             } 
else if (! portableCasePackage.isFile()) {
 
  127                 caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseIsNotFile());
 
  131                 if (portableCasePackage.getAbsolutePath().endsWith(
".001")) { 
 
  132                     if (portableCasePackage.getAbsolutePath().endsWith(
".zip.001")) {
 
  133                         caseErrorLabel.setText(
""); 
 
  135                         caseErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_badExtension());
 
  139                     caseErrorLabel.setText(
""); 
 
  145         if (outputTextField.getText().isEmpty()) {
 
  146             outputErrorLabel.setText(
""); 
 
  149             if (! outputDir.exists()) {
 
  150                 outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_folderNotFound());
 
  152             } 
else if (! outputDir.isDirectory()) {
 
  153                 outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_notAFolder());
 
  158                     String caseFolderName = portableCasePackage.getName();
 
  159                     if (caseFolderName.endsWith(
".zip.001")) { 
 
  160                         caseFolderName = caseFolderName.substring(0, caseFolderName.length() - 8);
 
  161                     } 
else if (caseFolderName.endsWith(
".zip")) { 
 
  162                         caseFolderName = caseFolderName.substring(0, caseFolderName.length() - 4);
 
  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) + 
"\""; 
 
  171                         outputErrorLabel.setText(Bundle.UnpackagePortableCaseDialog_validatePaths_caseFolderExists(pathToDisplay));
 
  174                          outputErrorLabel.setText(
""); 
 
  180         unpackageButton.setEnabled(isValid);
 
  188     @SuppressWarnings(
"unchecked")
 
  190     private 
void initComponents() {
 
  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();
 
  205         setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
 
  207         org.openide.awt.Mnemonics.setLocalizedText(desc1Label, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.desc1Label.text")); 
 
  209         org.openide.awt.Mnemonics.setLocalizedText(desc2Label, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.desc2Label.text")); 
 
  211         org.openide.awt.Mnemonics.setLocalizedText(caseLabel, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.caseLabel.text")); 
 
  213         caseTextField.setText(
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.caseTextField.text")); 
 
  215         org.openide.awt.Mnemonics.setLocalizedText(extractLabel, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.extractLabel.text")); 
 
  217         outputTextField.setText(
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.outputTextField.text")); 
 
  219         org.openide.awt.Mnemonics.setLocalizedText(outputSelectButton, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.outputSelectButton.text")); 
 
  220         outputSelectButton.addActionListener(
new java.awt.event.ActionListener() {
 
  221             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  222                 outputSelectButtonActionPerformed(evt);
 
  226         org.openide.awt.Mnemonics.setLocalizedText(caseSelectButton, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.caseSelectButton.text")); 
 
  227         caseSelectButton.addActionListener(
new java.awt.event.ActionListener() {
 
  228             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  229                 caseSelectButtonActionPerformed(evt);
 
  233         org.openide.awt.Mnemonics.setLocalizedText(unpackageButton, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.unpackageButton.text")); 
 
  234         unpackageButton.addActionListener(
new java.awt.event.ActionListener() {
 
  235             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  236                 unpackageButtonActionPerformed(evt);
 
  240         org.openide.awt.Mnemonics.setLocalizedText(exitButton, 
org.openide.util.NbBundle.getMessage(UnpackagePortableCaseDialog.class, 
"UnpackagePortableCaseDialog.exitButton.text")); 
 
  241         exitButton.addActionListener(
new java.awt.event.ActionListener() {
 
  242             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  243                 exitButtonActionPerformed(evt);
 
  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")); 
 
  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")); 
 
  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()
 
  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)
 
  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)
 
  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)))
 
  288         layout.setVerticalGroup(
 
  289             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  290             .addGroup(layout.createSequentialGroup()
 
  292                 .addComponent(desc1Label)
 
  294                 .addComponent(desc2Label)
 
  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))
 
  321     private void outputSelectButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  322         if (! outputTextField.getText().isEmpty()) {
 
  323             outputFolderChooser.setCurrentDirectory(
new File(outputTextField.getText()));
 
  325         int returnVal = outputFolderChooser.showOpenDialog(
this);
 
  326         if (returnVal == JFileChooser.APPROVE_OPTION) {
 
  327             outputTextField.setText(outputFolderChooser.getSelectedFile().getAbsolutePath());
 
  331     private void caseSelectButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  332         if (! caseTextField.getText().isEmpty()) {
 
  333             caseFileChooser.setCurrentDirectory(
new File(caseTextField.getText()));
 
  335         int returnVal = caseFileChooser.showOpenDialog(
this);
 
  336         if (returnVal == JFileChooser.APPROVE_OPTION) {
 
  337             caseTextField.setText(caseFileChooser.getSelectedFile().getAbsolutePath());
 
  340             File tempCase = 
new File(caseTextField.getText());
 
  341             if (tempCase.exists()) {
 
  342                 outputTextField.setText(tempCase.getParent());
 
  347     private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  351     private void unpackageButtonActionPerformed(java.awt.event.ActionEvent evt) {
 
  352         UnpackagePortableCaseProgressDialog dialog = 
new UnpackagePortableCaseProgressDialog();
 
  353         dialog.unpackageCase(caseTextField.getText(), outputTextField.getText());
 
  354         if (dialog.isSuccess()) {
 
  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;