19 package org.sleuthkit.autopsy.report;
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;
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;
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;
55 class ReportGenerator {
57 private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
59 private Case currentCase = Case.getCurrentCase();
64 private ReportProgressPanel progressPanel;
66 private static final String REPORT_PATH_FMT_STR =
"%s" + File.separator +
"%s %s %s" + File.separator;
67 private final ReportGenerationPanel reportGenerationPanel =
new ReportGenerationPanel();
69 static final String REPORTS_DIR =
"Reports";
71 private List<String> errorList;
77 private void displayReportErrors() {
78 if (!errorList.isEmpty()) {
79 String errorString =
"";
80 for (String error : errorList) {
81 errorString += error +
"\n";
83 MessageNotifyUtil.Notify.error(
84 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.notifyErr.errsDuringRptGen"), errorString);
92 this.errorList =
new ArrayList<>();
100 private void displayProgressPanel() {
101 final JDialog dialog =
new JDialog((JFrame) WindowManager.getDefault().getMainWindow(),
true);
102 dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
103 dialog.setTitle(NbBundle.getMessage(
this.getClass(),
"ReportGenerator.displayProgress.title.text"));
104 dialog.add(this.reportGenerationPanel);
107 reportGenerationPanel.addCloseAction(
new ActionListener() {
109 public void actionPerformed(ActionEvent e) {
114 dialog.addWindowListener(
new WindowAdapter() {
116 public void windowClosing(WindowEvent e) {
117 reportGenerationPanel.close();
121 Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
122 int w = dialog.getSize().width;
123 int h = dialog.getSize().height;
126 dialog.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
127 dialog.setVisible(
true);
133 void generateGeneralReport(GeneralReportModule generalReportModule)
throws IOException {
134 if (generalReportModule != null) {
135 String reportDir = createReportDirectory(generalReportModule);
136 setupProgressPanel(generalReportModule, reportDir);
137 ReportWorker worker =
new ReportWorker(() -> {
138 generalReportModule.generateReport(reportDir, progressPanel);
141 displayProgressPanel();
153 void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections)
throws IOException {
154 if (tableReport != null && null != artifactTypeSelections) {
155 String reportDir = createReportDirectory(tableReport);
156 setupProgressPanel(tableReport, reportDir);
157 ReportWorker worker =
new ReportWorker(() -> {
158 tableReport.startReport(reportDir);
159 TableReportGenerator generator =
new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport);
161 tableReport.endReport();
163 progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
164 errorList = generator.getErrorList();
167 displayProgressPanel();
177 void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo)
throws IOException {
178 if (fileReportModule != null && null != enabledInfo) {
179 String reportDir = createReportDirectory(fileReportModule);
180 List<FileReportDataTypes> enabled =
new ArrayList<>();
181 for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
183 enabled.add(e.getKey());
186 setupProgressPanel(fileReportModule, reportDir);
187 ReportWorker worker =
new ReportWorker(() -> {
188 if (progressPanel.getStatus() != ReportStatus.CANCELED) {
189 progressPanel.start();
190 progressPanel.updateStatusLabel(
191 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.progress.queryingDb.text"));
194 List<AbstractFile> files = getFiles();
195 int numFiles = files.size();
196 if (progressPanel.getStatus() != ReportStatus.CANCELED) {
197 fileReportModule.startReport(reportDir);
198 fileReportModule.startTable(enabled);
200 progressPanel.setIndeterminate(
false);
201 progressPanel.setMaximumProgress(numFiles);
205 for (AbstractFile file : files) {
207 if (progressPanel.getStatus() == ReportStatus.CANCELED) {
210 fileReportModule.addRow(file, enabled);
211 progressPanel.increment();
214 if ((i % 100) == 0) {
215 progressPanel.updateStatusLabel(
216 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.progress.processingFile.text",
222 fileReportModule.endTable();
223 fileReportModule.endReport();
224 progressPanel.complete(ReportStatus.COMPLETE);
227 displayProgressPanel();
236 private List<AbstractFile> getFiles() {
237 List<AbstractFile> absFiles;
239 SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
240 absFiles = skCase.findAllFilesWhere(
"meta_type != " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue());
242 }
catch (TskCoreException ex) {
243 MessageNotifyUtil.Notify.show(
244 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.errors.reportErrorTitle"),
245 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
246 MessageNotifyUtil.MessageType.ERROR);
247 logger.log(Level.SEVERE,
"failed to generate reports. Unable to get all files in the image.", ex);
248 return Collections.<AbstractFile>emptyList();
252 private void setupProgressPanel(ReportModule module, String reportDir) {
253 String reportFilePath = module.getRelativeFilePath();
254 if (!reportFilePath.isEmpty()) {
255 this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir + reportFilePath);
257 this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
261 private static String createReportDirectory(ReportModule module)
throws IOException {
262 Case currentCase = Case.getCurrentCase();
264 DateFormat dateFormat =
new SimpleDateFormat(
"MM-dd-yyyy-HH-mm-ss");
265 Date date =
new Date();
266 String dateNoTime = dateFormat.format(date);
267 String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), module.getName(), dateNoTime);
270 FileUtil.createFolder(
new File(reportPath));
271 }
catch (IOException ex) {
272 throw new IOException(
"Failed to make report folder, unable to generate reports.", ex);
287 doInBackground.run();
295 }
catch (InterruptedException | ExecutionException ex) {
297 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.errors.reportErrorTitle"),
298 NbBundle.getMessage(
this.getClass(),
"ReportGenerator.errors.reportErrorText") + ex.getLocalizedMessage(),
300 logger.log(Level.SEVERE,
"failed to generate reports", ex);
302 catch (java.util.concurrent.CancellationException ex) {
304 displayReportErrors();
static void show(String title, String message, MessageType type, ActionListener actionListener)
final Runnable doInBackground
ReportWorker(Runnable doInBackground)