19 package org.sleuthkit.autopsy.report;
 
   21 import java.awt.event.ActionEvent;
 
   22 import java.awt.event.ActionListener;
 
   23 import java.awt.event.WindowAdapter;
 
   24 import java.awt.event.WindowEvent;
 
   26 import java.io.IOException;
 
   27 import java.text.DateFormat;
 
   28 import java.text.SimpleDateFormat;
 
   29 import java.util.ArrayList;
 
   30 import java.util.Collections;
 
   31 import java.util.Date;
 
   32 import java.util.List;
 
   34 import java.util.Map.Entry;
 
   35 import java.util.concurrent.ExecutionException;
 
   36 import java.util.logging.Level;
 
   37 import javax.swing.JDialog;
 
   38 import javax.swing.JFrame;
 
   39 import javax.swing.SwingWorker;
 
   40 import org.openide.filesystems.FileUtil;
 
   41 import org.openide.util.NbBundle;
 
   42 import org.openide.windows.WindowManager;
 
   54 class ReportGenerator {
 
   56     private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
 
   61     private ReportProgressPanel progressPanel;
 
   63     private static final String REPORT_PATH_FMT_STR = 
"%s" + File.separator + 
"%s %s %s" + File.separator;
 
   64     private final ReportGenerationPanel reportGenerationPanel = 
new ReportGenerationPanel();
 
   66     static final String REPORTS_DIR = 
"Reports"; 
 
   68     private List<String> errorList;
 
   74     private void displayReportErrors() {
 
   75         if (!errorList.isEmpty()) {
 
   76             String errorString = 
"";
 
   77             for (String error : errorList) {
 
   78                 errorString += error + 
"\n";
 
   80             MessageNotifyUtil.Notify.error(
 
   81                     NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.notifyErr.errsDuringRptGen"), errorString);
 
   89         this.errorList = 
new ArrayList<>();
 
   97     private void displayProgressPanel() {
 
   98         final JDialog dialog = 
new JDialog((JFrame) WindowManager.getDefault().getMainWindow(), 
true);
 
   99         dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
 
  100         dialog.setTitle(NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.displayProgress.title.text"));
 
  101         dialog.add(this.reportGenerationPanel);
 
  104         reportGenerationPanel.addCloseAction(
new ActionListener() {
 
  106             public void actionPerformed(ActionEvent e) {
 
  111         dialog.addWindowListener(
new WindowAdapter() {
 
  113             public void windowClosing(WindowEvent e) {
 
  114                 reportGenerationPanel.close();
 
  118         dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
 
  119         dialog.setVisible(
true);
 
  125     void generateGeneralReport(GeneralReportModule generalReportModule) 
throws IOException {
 
  126         if (generalReportModule != null) {
 
  127             String reportDir = createReportDirectory(generalReportModule);
 
  128             setupProgressPanel(generalReportModule, reportDir);
 
  129             ReportWorker worker = 
new ReportWorker(() -> {
 
  130                 generalReportModule.generateReport(reportDir, progressPanel);
 
  133             displayProgressPanel();
 
  145     void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) 
throws IOException {
 
  146         if (tableReport != null && null != artifactTypeSelections) {
 
  147             String reportDir = createReportDirectory(tableReport);
 
  148             setupProgressPanel(tableReport, reportDir);
 
  149             ReportWorker worker = 
new ReportWorker(() -> {
 
  150                 tableReport.startReport(reportDir);
 
  151                 TableReportGenerator generator = 
new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport);
 
  153                 tableReport.endReport();
 
  155                 progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
 
  156                 errorList = generator.getErrorList();
 
  159             displayProgressPanel();
 
  169     void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) 
throws IOException {
 
  170         if (fileReportModule != null && null != enabledInfo) {
 
  171             String reportDir = createReportDirectory(fileReportModule);
 
  172             List<FileReportDataTypes> enabled = 
new ArrayList<>();
 
  173             for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
 
  175                     enabled.add(e.getKey());
 
  178             setupProgressPanel(fileReportModule, reportDir);
 
  179             ReportWorker worker = 
new ReportWorker(() -> {
 
  180                 if (progressPanel.getStatus() != ReportStatus.CANCELED) {
 
  181                     progressPanel.start();
 
  182                     progressPanel.updateStatusLabel(
 
  183                             NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.progress.queryingDb.text"));
 
  186                 List<AbstractFile> files = getFiles();
 
  187                 int numFiles = files.size();
 
  188                 if (progressPanel.getStatus() != ReportStatus.CANCELED) {
 
  189                     fileReportModule.startReport(reportDir);
 
  190                     fileReportModule.startTable(enabled);
 
  192                 progressPanel.setIndeterminate(
false);
 
  193                 progressPanel.setMaximumProgress(numFiles);
 
  197                 for (AbstractFile file : files) {
 
  199                     if (progressPanel.getStatus() == ReportStatus.CANCELED) {
 
  202                         fileReportModule.addRow(file, enabled);
 
  203                         progressPanel.increment();
 
  206                     if ((i % 100) == 0) {
 
  207                         progressPanel.updateStatusLabel(
 
  208                                 NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.progress.processingFile.text",
 
  214                 fileReportModule.endTable();
 
  215                 fileReportModule.endReport();
 
  216                 progressPanel.complete(ReportStatus.COMPLETE);
 
  219             displayProgressPanel();
 
  228     private List<AbstractFile> getFiles() {
 
  229         List<AbstractFile> absFiles;
 
  231             SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
 
  232             absFiles = skCase.findAllFilesWhere(
"meta_type != " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()); 
 
  234         } 
catch (TskCoreException | NoCurrentCaseException ex) {
 
  235             MessageNotifyUtil.Notify.show(
 
  236                     NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.errors.reportErrorTitle"),
 
  237                     NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
 
  238                     MessageNotifyUtil.MessageType.ERROR);
 
  239             logger.log(Level.SEVERE, 
"failed to generate reports. Unable to get all files in the image.", ex); 
 
  240             return Collections.<AbstractFile>emptyList();
 
  244     private void setupProgressPanel(ReportModule module, String reportDir) {
 
  245         String reportFilePath = module.getRelativeFilePath();
 
  246         if (!reportFilePath.isEmpty()) {
 
  247             this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir + reportFilePath);
 
  249             this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
 
  253     private static String createReportDirectory(ReportModule module) 
throws IOException {
 
  256             currentCase = Case.getCurrentCaseThrows();
 
  257         } 
catch (NoCurrentCaseException ex) {
 
  258             throw new IOException(
"Exception while getting open case.", ex);
 
  261         DateFormat dateFormat = 
new SimpleDateFormat(
"MM-dd-yyyy-HH-mm-ss");
 
  262         Date date = 
new Date();
 
  263         String dateNoTime = dateFormat.format(date);
 
  264         String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), module.getName(), dateNoTime);
 
  267             FileUtil.createFolder(
new File(reportPath));
 
  268         } 
catch (IOException ex) {
 
  269             throw new IOException(
"Failed to make report folder, unable to generate reports.", ex);
 
  284             doInBackground.run();
 
  292             } 
catch (InterruptedException | ExecutionException ex) {
 
  294                         NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.errors.reportErrorTitle"),
 
  295                         NbBundle.getMessage(
this.getClass(), 
"ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
 
  297                 logger.log(Level.SEVERE, 
"failed to generate reports", ex); 
 
  299             catch (java.util.concurrent.CancellationException ex) {
 
  301                 displayReportErrors();
 
static void show(String title, String message, MessageType type, ActionListener actionListener)
final Runnable doInBackground
ReportWorker(Runnable doInBackground)