Making excel reports work in report module

This commit is contained in:
Eugene Livis 2021-08-05 14:59:07 -04:00
parent 356206bf50
commit 1e2a8efbc5
6 changed files with 76 additions and 233 deletions

View File

@ -38,7 +38,6 @@ import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ColumnModel;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;

View File

@ -4,17 +4,10 @@ DataSourceSummaryReport.endReport.srcModuleName.text=Excel Report
# {0} - sheetNumber
ExcelExport_writeExcel_noSheetName=Sheet {0}
ExcelExportAction_exportToXLSX_beginExport=Beginning Export...
# {0} - tabName
ExcelExportAction_exportToXLSX_gatheringTabData=Fetching Data for {0} Tab...
ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data
ExcelExportAction_exportToXLSX_writingToFile=Writing to File...
ExcelExportAction_getXLSXPath_directory=DataSourceSummary
ExcelExportAction_moduleName=Data Source Summary
ExcelExportAction_runXLSXExport_errorMessage=There was an error while exporting.
ExcelExportAction_runXLSXExport_errorTitle=Error While Exporting
ExcelExportAction_runXLSXExport_progressCancelActionTitle=Cancelling...
ExcelExportAction_runXLSXExport_progressCancelTitle=Cancel
# {0} - dataSource
ExcelExportAction_runXLSXExport_progressTitle=Exporting {0} to XLSX
RecentFilePanel_col_header_domain=Domain
RecentFilePanel_col_header_path=Path
RecentFilePanel_col_header_sender=Sender

View File

@ -18,10 +18,13 @@
*/
package org.sleuthkit.autopsy.report.modules.datasourcesummaryexport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import javax.swing.JPanel;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -30,6 +33,7 @@ import org.sleuthkit.autopsy.report.GeneralReportModule;
import org.sleuthkit.autopsy.report.GeneralReportSettings;
import org.sleuthkit.autopsy.report.ReportProgressPanel;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
class DataSourceSummaryReport implements GeneralReportModule {
@ -79,6 +83,7 @@ class DataSourceSummaryReport implements GeneralReportModule {
@Override
public void generateReport(GeneralReportSettings settings, ReportProgressPanel progressPanel) {
progressPanel.start();
Case currentCase = null;
try {
currentCase = Case.getCurrentCaseThrows();
@ -87,31 +92,46 @@ class DataSourceSummaryReport implements GeneralReportModule {
return;
}
String errorMessage = "";
ReportProgressPanel.ReportStatus result = ReportProgressPanel.ReportStatus.COMPLETE;
List<Content> selectedDataSources = new ArrayList<>();
if(settings.getSelectedDataSources() == null) {
// Process all data sources if the list is null.
try {
List<Long> selectedDataSources = currentCase.getDataSources()
.stream()
.map(Content::getId)
.collect(Collectors.toList());
settings.setSelectedDataSources(selectedDataSources);
selectedDataSources = currentCase.getDataSources();
// ELTODO settings.setSelectedDataSources(selectedDataSources);
} catch (TskCoreException ex) {
result = ReportProgressPanel.ReportStatus.ERROR;
// ELTODO errorMessage = Bundle.KMLReport_failedToCompleteReport();
logger.log(Level.SEVERE, "Could not get the datasources from the case", ex);
progressPanel.complete(result, errorMessage);
return;
}
}
String baseReportDir = settings.getReportDirectoryPath();
// Start the progress bar and setup the report
progressPanel.setIndeterminate(true);
progressPanel.start();
// ELTODO progressPanel.setIndeterminate(true);
//progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.querying"));
String reportFullPath = baseReportDir + getRelativeFilePath(); //NON-NLS
String errorMessage = "";
//progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.loading"));
// looop over all data sources
for (Content dataSource : selectedDataSources){
if (dataSource instanceof DataSource) {
try {
new ExcelExportAction().exportToXLSX(progressPanel, (DataSource) dataSource, reportFullPath);
} catch (IOException | ExcelExport.ExcelExportException ex) {
// ELTODO errorMessage = Bundle.KMLReport_kmlFileWriteError();
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR, errorMessage);
return;
}
}
}
ReportProgressPanel.ReportStatus result = ReportProgressPanel.ReportStatus.COMPLETE;
progressPanel.complete(result, errorMessage);
}
}

View File

@ -250,21 +250,6 @@ class ExcelExport {
void renderSheet(Sheet sheet, WorksheetEnv env) throws ExcelExportException;
}
private static ExcelExport instance = null;
/**
* Retrieves a singleton instance of this class.
*
* @return The instance.
*/
static ExcelExport getInstance() {
if (instance == null) {
instance = new ExcelExport();
}
return instance;
}
private ExcelExport() {
}
@ -280,7 +265,7 @@ class ExcelExport {
"# {0} - sheetNumber",
"ExcelExport_writeExcel_noSheetName=Sheet {0}"
})
void writeExcel(List<ExcelSheetExport> exports, File path) throws IOException, ExcelExportException {
static void writeExcel(List<ExcelSheetExport> exports, File path) throws IOException, ExcelExportException {
// Create a Workbook
Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file

View File

@ -18,34 +18,24 @@
*/
package org.sleuthkit.autopsy.report.modules.datasourcesummaryexport;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.report.ReportProgressPanel;
import org.sleuthkit.autopsy.report.modules.datasourcesummaryexport.ExcelExport.ExcelExportException;
import org.sleuthkit.autopsy.report.modules.datasourcesummaryexport.ExcelExport.ExcelSheetExport;
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
@ -54,61 +44,16 @@ import org.sleuthkit.datamodel.TskCoreException;
*/
@Messages({
"ExcelExportAction_moduleName=Data Source Summary",})
class ExcelExportAction implements Consumer<DataSource> {
class ExcelExportAction {
private static final Logger logger = Logger.getLogger(ExcelExportAction.class.getName());
/**
* A tab that can be exported.
*/
interface ExportableTab {
/**
* Returns the name of the tab.
*
* @return The tab name.
*/
String getTabTitle();
/**
* Given the data source, provides the excel exports for this tab.
*
* @param dataSource The data source.
* @return The excel exports or null.
*/
List<ExcelSheetExport> getExcelExports(DataSource dataSource);
}
private final ExcelExport excelExport = ExcelExport.getInstance();
private final List<? extends ExportableTab> tabExports;
/**
* Main constructor.
*
* @param tabExports The different tabs that may have excel exports.
*/
ExcelExportAction(List<? extends ExportableTab> tabExports) {
this.tabExports = Collections.unmodifiableList(new ArrayList<>(tabExports));
}
/**
* Accepts the data source for which this export pertains, prompts user for
* output location, and exports the data.
*
* @param ds The data source.
*/
@Override
public void accept(DataSource ds) {
if (ds == null) {
return;
}
File outputLoc = getXLSXPath(ds.getName());
if (outputLoc == null) {
return;
}
runXLSXExport(ds, outputLoc);
ExcelExportAction() {
}
/**
@ -140,99 +85,10 @@ class ExcelExportAction implements Consumer<DataSource> {
return null;
}
/**
* An action listener that handles cancellation of the export process.
*/
private class CancelExportListener implements ActionListener {
private SwingWorker<Boolean, Void> worker = null;
@Override
public void actionPerformed(ActionEvent e) {
if (worker != null && !worker.isCancelled() && !worker.isDone()) {
worker.cancel(true);
}
}
/**
* Returns the swing worker that could be cancelled.
*
* @return The swing worker that could be cancelled.
*/
SwingWorker<Boolean, Void> getWorker() {
return worker;
}
/**
* Sets the swing worker that could be cancelled.
*
* @param worker The swing worker that could be cancelled.
*/
void setWorker(SwingWorker<Boolean, Void> worker) {
this.worker = worker;
}
}
/**
* Handles managing the gui and exporting data from the tabs into an excel
* document.
*
* @param dataSource The data source.
* @param path The output path.
*/
@NbBundle.Messages({
"# {0} - dataSource",
"ExcelExportAction_runXLSXExport_progressTitle=Exporting {0} to XLSX",
"ExcelExportAction_runXLSXExport_progressCancelTitle=Cancel",
"ExcelExportAction_runXLSXExport_progressCancelActionTitle=Cancelling...",
"ExcelExportAction_runXLSXExport_errorTitle=Error While Exporting",
"ExcelExportAction_runXLSXExport_errorMessage=There was an error while exporting.",
})
private void runXLSXExport(DataSource dataSource, File path) {
CancelExportListener cancelButtonListener = new CancelExportListener();
ProgressIndicator progressIndicator = new ModalDialogProgressIndicator(
WindowManager.getDefault().getMainWindow(),
Bundle.ExcelExportAction_runXLSXExport_progressTitle(dataSource.getName()),
new String[]{Bundle.ExcelExportAction_runXLSXExport_progressCancelTitle()},
Bundle.ExcelExportAction_runXLSXExport_progressCancelTitle(),
cancelButtonListener
);
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
exportToXLSX(progressIndicator, dataSource, path);
return true;
}
@Override
protected void done() {
try {
get();
} catch (ExecutionException ex) {
logger.log(Level.WARNING, "Error while trying to export data source summary to xlsx.", ex);
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
Bundle.ExcelExportAction_runXLSXExport_errorMessage(),
Bundle.ExcelExportAction_runXLSXExport_errorTitle(),
JOptionPane.ERROR_MESSAGE);
} catch (InterruptedException | CancellationException ex) {
// no op on cancellation
} finally {
progressIndicator.finish();
}
}
};
cancelButtonListener.setWorker(worker);
worker.execute();
}
/**
* Action that handles updating progress and exporting data from the tabs.
*
* @param progressIndicator The progress indicator.
* @param progressPanel The progress indicator.
* @param dataSource The data source to be exported.
* @param path The path of the excel export.
* @throws InterruptedException
@ -241,57 +97,52 @@ class ExcelExportAction implements Consumer<DataSource> {
*/
@NbBundle.Messages({
"ExcelExportAction_exportToXLSX_beginExport=Beginning Export...",
"# {0} - tabName",
"ExcelExportAction_exportToXLSX_gatheringTabData=Fetching Data for {0} Tab...",
"ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data",
"ExcelExportAction_exportToXLSX_writingToFile=Writing to File...",})
private void exportToXLSX(ProgressIndicator progressIndicator, DataSource dataSource, File path)
throws InterruptedException, IOException, ExcelExport.ExcelExportException {
void exportToXLSX(ReportProgressPanel progressPanel, DataSource dataSource, String path)
throws IOException, ExcelExport.ExcelExportException {
int exportWeight = 3;
int totalWeight = tabExports.size() + exportWeight;
progressIndicator.start(Bundle.ExcelExportAction_exportToXLSX_beginExport(), totalWeight);
File reportFile = new File(path);
int totalWeight = 10;
progressPanel.setIndeterminate(false);
progressPanel.setMaximumProgress(totalWeight);
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_beginExport());
List<ExcelExport.ExcelSheetExport> sheetExports = new ArrayList<>();
for (int i = 0; i < tabExports.size(); i++) {
if (Thread.interrupted()) {
throw new InterruptedException("Export has been cancelled.");
}
ExportableTab tab = tabExports.get(i);
progressIndicator.progress(Bundle.ExcelExportAction_exportToXLSX_gatheringTabData(tab == null ? "" : tab.getTabTitle()), i);
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_gatheringRecentActivityData());
progressPanel.setProgress(1);
List<ExcelExport.ExcelSheetExport> exports = tab.getExcelExports(dataSource);
if (exports != null) {
sheetExports.addAll(exports);
}
// Export Recent Activity data
List<ExcelExport.ExcelSheetExport> exports = ExportRecentFiles.getExports(dataSource);
if (exports != null) {
sheetExports.addAll(exports);
}
if (Thread.interrupted()) {
throw new InterruptedException("Export has been cancelled.");
}
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_writingToFile());
progressPanel.setProgress(2);
ExcelExport.writeExcel(sheetExports, reportFile);
progressIndicator.progress(Bundle.ExcelExportAction_exportToXLSX_writingToFile(), tabExports.size());
excelExport.writeExcel(sheetExports, path);
progressIndicator.finish();
progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE, "");
try {
// add to reports
Case curCase = Case.getCurrentCaseThrows();
curCase.addReport(path.getParent(),
curCase.addReport(reportFile.getParent(),
Bundle.ExcelExportAction_moduleName(),
path.getName(),
reportFile.getName(),
dataSource);
// and show finished dialog
/* ELTODO SwingUtilities.invokeLater(() -> {
ExcelExportDialog dialog = new ExcelExportDialog(WindowManager.getDefault().getMainWindow(), path);
dialog.setResizable(false);
dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
dialog.setVisible(true);
dialog.toFront();
});*/
/*
* ELTODO SwingUtilities.invokeLater(() -> { ExcelExportDialog
* dialog = new
* ExcelExportDialog(WindowManager.getDefault().getMainWindow(),
* path); dialog.setResizable(false);
* dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
* dialog.setVisible(true); dialog.toFront();
});
*/
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.WARNING, "There was an error attaching report to case.", ex);
}

View File

@ -46,11 +46,7 @@ final class ExportRecentFiles {
private static final String DATETIME_FORMAT_STR = "yyyy/MM/dd HH:mm:ss";
private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat(DATETIME_FORMAT_STR, Locale.getDefault());
private final DataFetcher<DataSource, List<RecentFileDetails>> docsFetcher;
private final DataFetcher<DataSource, List<RecentDownloadDetails>> downloadsFetcher;
private final DataFetcher<DataSource, List<RecentAttachmentDetails>> attachmentsFetcher;
private final List<ColumnModel<RecentFileDetails, DefaultCellModel<?>>> docsTemplate = Arrays.asList(
private static final List<ColumnModel<RecentFileDetails, DefaultCellModel<?>>> docsTemplate = Arrays.asList(
new ColumnModel<>(Bundle.RecentFilePanel_col_header_path(),
(prog) -> {
return new DefaultCellModel<>(prog.getPath());
@ -59,7 +55,7 @@ final class ExportRecentFiles {
getDateFunct(),
80));
private final List<ColumnModel<RecentDownloadDetails, DefaultCellModel<?>>> downloadsTemplate = Arrays.asList(
private static final List<ColumnModel<RecentDownloadDetails, DefaultCellModel<?>>> downloadsTemplate = Arrays.asList(
new ColumnModel<>(Bundle.RecentFilePanel_col_header_domain(),
(prog) -> {
return new DefaultCellModel<>(prog.getWebDomain());
@ -72,7 +68,7 @@ final class ExportRecentFiles {
getDateFunct(),
80));
private final List<ColumnModel<RecentAttachmentDetails, DefaultCellModel<?>>> attachmentsTemplate = Arrays.asList(
private static final List<ColumnModel<RecentAttachmentDetails, DefaultCellModel<?>>> attachmentsTemplate = Arrays.asList(
new ColumnModel<>(Bundle.RecentFilePanel_col_header_path(),
(prog) -> {
return new DefaultCellModel<>(prog.getPath());
@ -96,13 +92,7 @@ final class ExportRecentFiles {
"RecentFilePanel_emailParserModuleName=Email Parser"
})
/**
* Creates new form RecentFilesPanel
*/
ExportRecentFiles() {
docsFetcher = (dataSource) -> RecentFilesSummary.getRecentlyOpenedDocuments(dataSource, 10);
downloadsFetcher = (dataSource) -> RecentFilesSummary.getRecentDownloads(dataSource, 10);
attachmentsFetcher = (dataSource) -> RecentFilesSummary.getRecentAttachments(dataSource, 10);
private ExportRecentFiles() {
}
/**
@ -111,14 +101,19 @@ final class ExportRecentFiles {
*
* @return The function that determines the date cell from a RecentFileDetails object.
*/
private <T extends RecentFileDetails> Function<T, DefaultCellModel<?>> getDateFunct() {
private static <T extends RecentFileDetails> Function<T, DefaultCellModel<?>> getDateFunct() {
return (T lastAccessed) -> {
Function<Date, String> dateParser = (dt) -> dt == null ? "" : DATETIME_FORMAT.format(dt);
return new DefaultCellModel<>(new Date(lastAccessed.getDateAsLong() * 1000), dateParser, DATETIME_FORMAT_STR);
};
}
List<ExcelExport.ExcelSheetExport> getExports(DataSource dataSource) {
static List<ExcelExport.ExcelSheetExport> getExports(DataSource dataSource) {
DataFetcher<DataSource, List<RecentFileDetails>> docsFetcher = (ds) -> RecentFilesSummary.getRecentlyOpenedDocuments(ds, 10);
DataFetcher<DataSource, List<RecentDownloadDetails>> downloadsFetcher = (ds) -> RecentFilesSummary.getRecentDownloads(ds, 10);
DataFetcher<DataSource, List<RecentAttachmentDetails>> attachmentsFetcher = (ds) -> RecentFilesSummary.getRecentAttachments(ds, 10);
return Stream.of(
ExcelExportAction.getTableExport(docsFetcher, docsTemplate, Bundle.RecentFilesPanel_docsTable_tabName(), dataSource),
ExcelExportAction.getTableExport(downloadsFetcher, downloadsTemplate, Bundle.RecentFilesPanel_downloadsTable_tabName(), dataSource),