Autopsy  4.1
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.getName() + " " + 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  errorList = generator.getErrorList();
174  });
175  worker.execute();
176  displayProgressPanel();
177  }
178  }
179 
186  void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) {
187  if (fileReportModule != null && null != enabledInfo) {
188  List<FileReportDataTypes> enabled = new ArrayList<>();
189  for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
190  if (e.getValue()) {
191  enabled.add(e.getKey());
192  }
193  }
194  setupProgressPanel(fileReportModule);
195  ReportWorker worker = new ReportWorker(() -> {
196  if (progressPanel.getStatus() != ReportStatus.CANCELED) {
197  progressPanel.start();
198  progressPanel.updateStatusLabel(
199  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.queryingDb.text"));
200  }
201 
202  List<AbstractFile> files = getFiles();
203  int numFiles = files.size();
204  if (progressPanel.getStatus() != ReportStatus.CANCELED) {
205  fileReportModule.startReport(reportPath);
206  fileReportModule.startTable(enabled);
207  }
208  progressPanel.setIndeterminate(false);
209  progressPanel.setMaximumProgress(numFiles);
210 
211  int i = 0;
212  // Add files to report.
213  for (AbstractFile file : files) {
214  // Check to see if any reports have been cancelled.
215  if (progressPanel.getStatus() == ReportStatus.CANCELED) {
216  return;
217  } else {
218  fileReportModule.addRow(file, enabled);
219  progressPanel.increment();
220  }
221 
222  if ((i % 100) == 0) {
223  progressPanel.updateStatusLabel(
224  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingFile.text",
225  file.getName()));
226  }
227  i++;
228  }
229 
230  fileReportModule.endTable();
231  fileReportModule.endReport();
232  progressPanel.complete(ReportStatus.COMPLETE);
233  });
234  worker.execute();
235  displayProgressPanel();
236  }
237  }
238 
244  private List<AbstractFile> getFiles() {
245  List<AbstractFile> absFiles;
246  try {
247  SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
248  absFiles = skCase.findAllFilesWhere("meta_type != " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()); //NON-NLS
249  return absFiles;
250  } catch (TskCoreException ex) {
251  MessageNotifyUtil.Notify.show(
252  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
253  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
254  MessageNotifyUtil.MessageType.ERROR);
255  logger.log(Level.SEVERE, "failed to generate reports. Unable to get all files in the image.", ex); //NON-NLS
256  return Collections.<AbstractFile>emptyList();
257  }
258  }
259 
260  private void setupProgressPanel(ReportModule module) {
261  String reportFilePath = module.getRelativeFilePath();
262  if (!reportFilePath.isEmpty()) {
263  this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportPath + reportFilePath);
264  } else {
265  this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
266  }
267  }
268 
269  private class ReportWorker extends SwingWorker<Void, Void> {
270 
271  private final Runnable doInBackground;
272 
273  private ReportWorker(Runnable doInBackground) {
274  this.doInBackground = doInBackground;
275  }
276 
277  @Override
278  protected Void doInBackground() throws Exception {
279  doInBackground.run();
280  return null;
281  }
282 
283  @Override
284  protected void done() {
285  try {
286  get();
287  } catch (InterruptedException | ExecutionException ex) {
289  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorTitle"),
290  NbBundle.getMessage(this.getClass(), "ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
292  logger.log(Level.SEVERE, "failed to generate reports", ex); //NON-NLS
293  } // catch and ignore if we were cancelled
294  catch (java.util.concurrent.CancellationException ex) {
295  } finally {
296  displayReportErrors();
297  errorList.clear();
298  }
299  }
300 
301  }
302 }
static void show(String title, String message, MessageType type, ActionListener actionListener)

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