Autopsy  4.4
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 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.Dimension;
22 import java.awt.Toolkit;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.WindowAdapter;
26 import java.awt.event.WindowEvent;
27 import java.io.File;
28 import java.io.IOException;
29 import java.text.DateFormat;
30 import java.text.SimpleDateFormat;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.Date;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import java.util.concurrent.ExecutionException;
38 import java.util.logging.Level;
39 import javax.swing.JDialog;
40 import javax.swing.JFrame;
41 import javax.swing.SwingWorker;
42 import org.openide.filesystems.FileUtil;
43 import org.openide.util.NbBundle;
44 import org.openide.windows.WindowManager;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import org.sleuthkit.datamodel.SleuthkitCase;
52 import org.sleuthkit.datamodel.TskCoreException;
53 import org.sleuthkit.datamodel.TskData;
54 
55 class ReportGenerator {
56 
57  private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
58 
59  private Case currentCase = Case.getCurrentCase();
60 
64  private ReportProgressPanel progressPanel;
65 
66  private final String reportPath;
67  private final ReportGenerationPanel reportGenerationPanel = new ReportGenerationPanel();
68 
69  static final String REPORTS_DIR = "Reports"; //NON-NLS
70 
71  private List<String> errorList;
72 
77  private void displayReportErrors() {
78  if (!errorList.isEmpty()) {
79  String errorString = "";
80  for (String error : errorList) {
81  errorString += error + "\n";
82  }
83  MessageNotifyUtil.Notify.error(
84  NbBundle.getMessage(this.getClass(), "ReportGenerator.notifyErr.errsDuringRptGen"), errorString);
85  }
86  }
87 
91  ReportGenerator() {
92  // Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
93  DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
94  Date date = new Date();
95  String dateNoTime = dateFormat.format(date);
96  this.reportPath = currentCase.getReportDirectory() + File.separator + currentCase.getDisplayName() + " " + dateNoTime + File.separator;
97 
98  this.errorList = new ArrayList<>();
99 
100  // Create the root reports directory.
101  try {
102  FileUtil.createFolder(new File(this.reportPath));
103  } catch (IOException ex) {
104  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
105  logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
106  }
107  }
108 
113  private void displayProgressPanel() {
114  final JDialog dialog = new JDialog((JFrame) WindowManager.getDefault().getMainWindow(), true);
115  dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
116  dialog.setTitle(NbBundle.getMessage(this.getClass(), "ReportGenerator.displayProgress.title.text"));
117  dialog.add(this.reportGenerationPanel);
118  dialog.pack();
119 
120  reportGenerationPanel.addCloseAction(new ActionListener() {
121  @Override
122  public void actionPerformed(ActionEvent e) {
123  dialog.dispose();
124  }
125  });
126 
127  dialog.addWindowListener(new WindowAdapter() {
128  @Override
129  public void windowClosing(WindowEvent e) {
130  reportGenerationPanel.close();
131  }
132  });
133 
134  Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
135  int w = dialog.getSize().width;
136  int h = dialog.getSize().height;
137 
138  // set the location of the popUp Window on the center of the screen
139  dialog.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
140  dialog.setVisible(true);
141  }
142 
146  void generateGeneralReport(GeneralReportModule generalReportModule) {
147  if (generalReportModule != null) {
148  setupProgressPanel(generalReportModule);
149  ReportWorker worker = new ReportWorker(() -> {
150  generalReportModule.generateReport(reportPath, progressPanel);
151  });
152  worker.execute();
153  displayProgressPanel();
154  }
155  }
156 
165  void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) {
166  if (tableReport != null && null != artifactTypeSelections) {
167  setupProgressPanel(tableReport);
168  ReportWorker worker = new ReportWorker(() -> {
169  tableReport.startReport(reportPath);
170  TableReportGenerator generator = new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport);
171  generator.execute();
172  tableReport.endReport();
173  // finish progress, wrap up
174  progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
175  errorList = generator.getErrorList();
176  });
177  worker.execute();
178  displayProgressPanel();
179  }
180  }
181 
188  void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) {
189  if (fileReportModule != null && null != enabledInfo) {
190  List<FileReportDataTypes> enabled = new ArrayList<>();
191  for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
192  if (e.getValue()) {
193  enabled.add(e.getKey());
194  }
195  }
196  setupProgressPanel(fileReportModule);
197  ReportWorker worker = new ReportWorker(() -> {
198  if (progressPanel.getStatus() != ReportStatus.CANCELED) {
199  progressPanel.start();
200  progressPanel.updateStatusLabel(
201  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.queryingDb.text"));
202  }
203 
204  List<AbstractFile> files = getFiles();
205  int numFiles = files.size();
206  if (progressPanel.getStatus() != ReportStatus.CANCELED) {
207  fileReportModule.startReport(reportPath);
208  fileReportModule.startTable(enabled);
209  }
210  progressPanel.setIndeterminate(false);
211  progressPanel.setMaximumProgress(numFiles);
212 
213  int i = 0;
214  // Add files to report.
215  for (AbstractFile file : files) {
216  // Check to see if any reports have been cancelled.
217  if (progressPanel.getStatus() == ReportStatus.CANCELED) {
218  return;
219  } else {
220  fileReportModule.addRow(file, enabled);
221  progressPanel.increment();
222  }
223 
224  if ((i % 100) == 0) {
225  progressPanel.updateStatusLabel(
226  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingFile.text",
227  file.getName()));
228  }
229  i++;
230  }
231 
232  fileReportModule.endTable();
233  fileReportModule.endReport();
234  progressPanel.complete(ReportStatus.COMPLETE);
235  });
236  worker.execute();
237  displayProgressPanel();
238  }
239  }
240 
246  private List<AbstractFile> getFiles() {
247  List<AbstractFile> absFiles;
248  try {
249  SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
250  absFiles = skCase.findAllFilesWhere("meta_type != " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()); //NON-NLS
251  return absFiles;
252  } catch (TskCoreException ex) {
253  MessageNotifyUtil.Notify.show(
254  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
255  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
256  MessageNotifyUtil.MessageType.ERROR);
257  logger.log(Level.SEVERE, "failed to generate reports. Unable to get all files in the image.", ex); //NON-NLS
258  return Collections.<AbstractFile>emptyList();
259  }
260  }
261 
262  private void setupProgressPanel(ReportModule module) {
263  String reportFilePath = module.getRelativeFilePath();
264  if (!reportFilePath.isEmpty()) {
265  this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportPath + reportFilePath);
266  } else {
267  this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
268  }
269  }
270 
271  private class ReportWorker extends SwingWorker<Void, Void> {
272 
273  private final Runnable doInBackground;
274 
275  private ReportWorker(Runnable doInBackground) {
276  this.doInBackground = doInBackground;
277  }
278 
279  @Override
280  protected Void doInBackground() throws Exception {
281  doInBackground.run();
282  return null;
283  }
284 
285  @Override
286  protected void done() {
287  try {
288  get();
289  } catch (InterruptedException | ExecutionException ex) {
291  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
292  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
294  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
295  } // catch and ignore if we were cancelled
296  catch (java.util.concurrent.CancellationException ex) {
297  } finally {
298  displayReportErrors();
299  errorList.clear();
300  }
301  }
302 
303  }
304 }
static void show(String title, String message, MessageType type, ActionListener actionListener)

Copyright © 2012-2016 Basis Technology. Generated on: Tue Jun 13 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.