Autopsy  4.12.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ReportGenerator.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-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.report;
20 
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.awt.event.WindowAdapter;
24 import java.awt.event.WindowEvent;
25 import java.io.File;
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;
33 import java.util.Map;
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;
48 import org.sleuthkit.datamodel.AbstractFile;
49 import org.sleuthkit.datamodel.BlackboardArtifact;
50 import org.sleuthkit.datamodel.SleuthkitCase;
51 import org.sleuthkit.datamodel.TskCoreException;
52 import org.sleuthkit.datamodel.TskData;
53 
54 class ReportGenerator {
55 
56  private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
57 
62  private ReportProgressPanel progressPanel;
63 
64  private static final String REPORT_PATH_FMT_STR = "%s" + File.separator + "%s %s %s" + File.separator;
65  private final ReportGenerationPanel reportGenerationPanel = new ReportGenerationPanel();
66 
67  static final String REPORTS_DIR = "Reports"; //NON-NLS
68 
69  private List<String> errorList;
70 
75  private void displayReportErrors() {
76  if (!errorList.isEmpty()) {
77  String errorString = "";
78  for (String error : errorList) {
79  errorString += error + "\n";
80  }
81  MessageNotifyUtil.Notify.error(
82  NbBundle.getMessage(this.getClass(), "ReportGenerator.notifyErr.errsDuringRptGen"), errorString);
83  }
84  }
85 
89  ReportGenerator() {
90  this.errorList = new ArrayList<>();
91  }
92 
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);
102  dialog.pack();
103 
104  reportGenerationPanel.addCloseAction(new ActionListener() {
105  @Override
106  public void actionPerformed(ActionEvent e) {
107  dialog.dispose();
108  }
109  });
110 
111  dialog.addWindowListener(new WindowAdapter() {
112  @Override
113  public void windowClosing(WindowEvent e) {
114  reportGenerationPanel.close();
115  }
116  });
117 
118  dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
119  dialog.setVisible(true);
120  }
121 
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);
131  });
132  worker.execute();
133  displayProgressPanel();
134  }
135  }
136 
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);
152  generator.execute();
153  tableReport.endReport();
154  // finish progress, wrap up
155  progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
156  errorList = generator.getErrorList();
157  });
158  worker.execute();
159  displayProgressPanel();
160  }
161  }
162 
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()) {
174  if (e.getValue()) {
175  enabled.add(e.getKey());
176  }
177  }
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"));
184  }
185 
186  List<AbstractFile> files = getFiles();
187  int numFiles = files.size();
188  if (progressPanel.getStatus() != ReportStatus.CANCELED) {
189  fileReportModule.startReport(reportDir);
190  fileReportModule.startTable(enabled);
191  }
192  progressPanel.setIndeterminate(false);
193  progressPanel.setMaximumProgress(numFiles);
194 
195  int i = 0;
196  // Add files to report.
197  for (AbstractFile file : files) {
198  // Check to see if any reports have been cancelled.
199  if (progressPanel.getStatus() == ReportStatus.CANCELED) {
200  return;
201  } else {
202  fileReportModule.addRow(file, enabled);
203  progressPanel.increment();
204  }
205 
206  if ((i % 100) == 0) {
207  progressPanel.updateStatusLabel(
208  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingFile.text",
209  file.getName()));
210  }
211  i++;
212  }
213 
214  fileReportModule.endTable();
215  fileReportModule.endReport();
216  progressPanel.complete(ReportStatus.COMPLETE);
217  });
218  worker.execute();
219  displayProgressPanel();
220  }
221  }
222 
226  void generatePortableCaseReport(PortableCaseReportModule portableCaseReportModule, PortableCaseReportModule.PortableCaseOptions options) throws IOException {
227  if (portableCaseReportModule != null) {
228  String reportDir = createReportDirectory(portableCaseReportModule);
229  setupProgressPanel(portableCaseReportModule, reportDir);
230  ReportWorker worker = new ReportWorker(() -> {
231  portableCaseReportModule.generateReport(reportDir, options, progressPanel);
232  });
233  worker.execute();
234  displayProgressPanel();
235  }
236  }
237 
243  private List<AbstractFile> getFiles() {
244  List<AbstractFile> absFiles;
245  try {
246  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
247  absFiles = skCase.findAllFilesWhere("meta_type != " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()); //NON-NLS
248  return absFiles;
249  } catch (TskCoreException | NoCurrentCaseException ex) {
250  MessageNotifyUtil.Notify.show(
251  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
252  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
253  MessageNotifyUtil.MessageType.ERROR);
254  logger.log(Level.SEVERE, "failed to generate reports. Unable to get all files in the image.", ex); //NON-NLS
255  return Collections.<AbstractFile>emptyList();
256  }
257  }
258 
259  private void setupProgressPanel(ReportModule module, String reportDir) {
260  String reportFilePath = module.getRelativeFilePath();
261  if (reportFilePath == null) {
262  this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
263  } else if (reportFilePath.isEmpty()) {
264  this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir);
265  } else {
266  this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir + reportFilePath);
267  }
268  }
269 
270  private static String createReportDirectory(ReportModule module) throws IOException {
271  Case currentCase;
272  try {
273  currentCase = Case.getCurrentCaseThrows();
274  } catch (NoCurrentCaseException ex) {
275  throw new IOException("Exception while getting open case.", ex);
276  }
277  // Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
278  DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
279  Date date = new Date();
280  String dateNoTime = dateFormat.format(date);
281  String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), module.getName(), dateNoTime);
282  // Create the root reports directory.
283  try {
284  FileUtil.createFolder(new File(reportPath));
285  } catch (IOException ex) {
286  throw new IOException("Failed to make report folder, unable to generate reports.", ex);
287  }
288  return reportPath;
289  }
290 
291  private class ReportWorker extends SwingWorker<Void, Void> {
292 
293  private final Runnable doInBackground;
294 
295  private ReportWorker(Runnable doInBackground) {
296  this.doInBackground = doInBackground;
297  }
298 
299  @Override
300  protected Void doInBackground() throws Exception {
301  doInBackground.run();
302  return null;
303  }
304 
305  @Override
306  protected void done() {
307  try {
308  get();
309  } catch (InterruptedException | ExecutionException ex) {
311  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
312  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
314  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
315  } // catch and ignore if we were cancelled
316  catch (java.util.concurrent.CancellationException ex) {
317  } finally {
318  displayReportErrors();
319  errorList.clear();
320  }
321  }
322 
323  }
324 }
static void show(String title, String message, MessageType type, ActionListener actionListener)

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.