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.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger; 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.DataFetchResult;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;

View File

@ -4,17 +4,10 @@ DataSourceSummaryReport.endReport.srcModuleName.text=Excel Report
# {0} - sheetNumber # {0} - sheetNumber
ExcelExport_writeExcel_noSheetName=Sheet {0} ExcelExport_writeExcel_noSheetName=Sheet {0}
ExcelExportAction_exportToXLSX_beginExport=Beginning Export... ExcelExportAction_exportToXLSX_beginExport=Beginning Export...
# {0} - tabName ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data
ExcelExportAction_exportToXLSX_gatheringTabData=Fetching Data for {0} Tab...
ExcelExportAction_exportToXLSX_writingToFile=Writing to File... ExcelExportAction_exportToXLSX_writingToFile=Writing to File...
ExcelExportAction_getXLSXPath_directory=DataSourceSummary ExcelExportAction_getXLSXPath_directory=DataSourceSummary
ExcelExportAction_moduleName=Data Source Summary 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_domain=Domain
RecentFilePanel_col_header_path=Path RecentFilePanel_col_header_path=Path
RecentFilePanel_col_header_sender=Sender RecentFilePanel_col_header_sender=Sender

View File

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

View File

@ -250,21 +250,6 @@ class ExcelExport {
void renderSheet(Sheet sheet, WorksheetEnv env) throws ExcelExportException; 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() { private ExcelExport() {
} }
@ -280,7 +265,7 @@ class ExcelExport {
"# {0} - sheetNumber", "# {0} - sheetNumber",
"ExcelExport_writeExcel_noSheetName=Sheet {0}" "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 // Create a Workbook
Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file

View File

@ -18,34 +18,24 @@
*/ */
package org.sleuthkit.autopsy.report.modules.datasourcesummaryexport; package org.sleuthkit.autopsy.report.modules.datasourcesummaryexport;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; 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 java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.FileUtil; import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger; 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.ExcelExportException;
import org.sleuthkit.autopsy.report.modules.datasourcesummaryexport.ExcelExport.ExcelSheetExport; 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.DataSource;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -54,61 +44,16 @@ import org.sleuthkit.datamodel.TskCoreException;
*/ */
@Messages({ @Messages({
"ExcelExportAction_moduleName=Data Source Summary",}) "ExcelExportAction_moduleName=Data Source Summary",})
class ExcelExportAction implements Consumer<DataSource> { class ExcelExportAction {
private static final Logger logger = Logger.getLogger(ExcelExportAction.class.getName()); 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. * Main constructor.
* *
* @param tabExports The different tabs that may have excel exports. * @param tabExports The different tabs that may have excel exports.
*/ */
ExcelExportAction(List<? extends ExportableTab> tabExports) { ExcelExportAction() {
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);
} }
/** /**
@ -140,99 +85,10 @@ class ExcelExportAction implements Consumer<DataSource> {
return null; 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. * 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 dataSource The data source to be exported.
* @param path The path of the excel export. * @param path The path of the excel export.
* @throws InterruptedException * @throws InterruptedException
@ -241,57 +97,52 @@ class ExcelExportAction implements Consumer<DataSource> {
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"ExcelExportAction_exportToXLSX_beginExport=Beginning Export...", "ExcelExportAction_exportToXLSX_beginExport=Beginning Export...",
"# {0} - tabName", "ExcelExportAction_exportToXLSX_gatheringRecentActivityData=Fetching Recent Activity Data",
"ExcelExportAction_exportToXLSX_gatheringTabData=Fetching Data for {0} Tab...",
"ExcelExportAction_exportToXLSX_writingToFile=Writing to File...",}) "ExcelExportAction_exportToXLSX_writingToFile=Writing to File...",})
private void exportToXLSX(ProgressIndicator progressIndicator, DataSource dataSource, File path) void exportToXLSX(ReportProgressPanel progressPanel, DataSource dataSource, String path)
throws InterruptedException, IOException, ExcelExport.ExcelExportException { throws IOException, ExcelExport.ExcelExportException {
int exportWeight = 3; File reportFile = new File(path);
int totalWeight = tabExports.size() + exportWeight; int totalWeight = 10;
progressIndicator.start(Bundle.ExcelExportAction_exportToXLSX_beginExport(), totalWeight); progressPanel.setIndeterminate(false);
progressPanel.setMaximumProgress(totalWeight);
progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_beginExport());
List<ExcelExport.ExcelSheetExport> sheetExports = new ArrayList<>(); 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); progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_gatheringRecentActivityData());
progressIndicator.progress(Bundle.ExcelExportAction_exportToXLSX_gatheringTabData(tab == null ? "" : tab.getTabTitle()), i); progressPanel.setProgress(1);
List<ExcelExport.ExcelSheetExport> exports = tab.getExcelExports(dataSource); // Export Recent Activity data
List<ExcelExport.ExcelSheetExport> exports = ExportRecentFiles.getExports(dataSource);
if (exports != null) { if (exports != null) {
sheetExports.addAll(exports); sheetExports.addAll(exports);
} }
}
if (Thread.interrupted()) { progressPanel.updateStatusLabel(Bundle.ExcelExportAction_exportToXLSX_writingToFile());
throw new InterruptedException("Export has been cancelled."); progressPanel.setProgress(2);
} ExcelExport.writeExcel(sheetExports, reportFile);
progressIndicator.progress(Bundle.ExcelExportAction_exportToXLSX_writingToFile(), tabExports.size()); progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE, "");
excelExport.writeExcel(sheetExports, path);
progressIndicator.finish();
try { try {
// add to reports // add to reports
Case curCase = Case.getCurrentCaseThrows(); Case curCase = Case.getCurrentCaseThrows();
curCase.addReport(path.getParent(), curCase.addReport(reportFile.getParent(),
Bundle.ExcelExportAction_moduleName(), Bundle.ExcelExportAction_moduleName(),
path.getName(), reportFile.getName(),
dataSource); dataSource);
// and show finished dialog // and show finished dialog
/* ELTODO SwingUtilities.invokeLater(() -> { /*
ExcelExportDialog dialog = new ExcelExportDialog(WindowManager.getDefault().getMainWindow(), path); * ELTODO SwingUtilities.invokeLater(() -> { ExcelExportDialog
dialog.setResizable(false); * dialog = new
dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); * ExcelExportDialog(WindowManager.getDefault().getMainWindow(),
dialog.setVisible(true); * path); dialog.setResizable(false);
dialog.toFront(); * dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
});*/ * dialog.setVisible(true); dialog.toFront();
});
*/
} catch (NoCurrentCaseException | TskCoreException ex) { } catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.WARNING, "There was an error attaching report to case.", 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 String DATETIME_FORMAT_STR = "yyyy/MM/dd HH:mm:ss";
private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat(DATETIME_FORMAT_STR, Locale.getDefault()); private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat(DATETIME_FORMAT_STR, Locale.getDefault());
private final DataFetcher<DataSource, List<RecentFileDetails>> docsFetcher; private static final List<ColumnModel<RecentFileDetails, DefaultCellModel<?>>> docsTemplate = Arrays.asList(
private final DataFetcher<DataSource, List<RecentDownloadDetails>> downloadsFetcher;
private final DataFetcher<DataSource, List<RecentAttachmentDetails>> attachmentsFetcher;
private final List<ColumnModel<RecentFileDetails, DefaultCellModel<?>>> docsTemplate = Arrays.asList(
new ColumnModel<>(Bundle.RecentFilePanel_col_header_path(), new ColumnModel<>(Bundle.RecentFilePanel_col_header_path(),
(prog) -> { (prog) -> {
return new DefaultCellModel<>(prog.getPath()); return new DefaultCellModel<>(prog.getPath());
@ -59,7 +55,7 @@ final class ExportRecentFiles {
getDateFunct(), getDateFunct(),
80)); 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(), new ColumnModel<>(Bundle.RecentFilePanel_col_header_domain(),
(prog) -> { (prog) -> {
return new DefaultCellModel<>(prog.getWebDomain()); return new DefaultCellModel<>(prog.getWebDomain());
@ -72,7 +68,7 @@ final class ExportRecentFiles {
getDateFunct(), getDateFunct(),
80)); 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(), new ColumnModel<>(Bundle.RecentFilePanel_col_header_path(),
(prog) -> { (prog) -> {
return new DefaultCellModel<>(prog.getPath()); return new DefaultCellModel<>(prog.getPath());
@ -96,13 +92,7 @@ final class ExportRecentFiles {
"RecentFilePanel_emailParserModuleName=Email Parser" "RecentFilePanel_emailParserModuleName=Email Parser"
}) })
/** private ExportRecentFiles() {
* Creates new form RecentFilesPanel
*/
ExportRecentFiles() {
docsFetcher = (dataSource) -> RecentFilesSummary.getRecentlyOpenedDocuments(dataSource, 10);
downloadsFetcher = (dataSource) -> RecentFilesSummary.getRecentDownloads(dataSource, 10);
attachmentsFetcher = (dataSource) -> RecentFilesSummary.getRecentAttachments(dataSource, 10);
} }
/** /**
@ -111,14 +101,19 @@ final class ExportRecentFiles {
* *
* @return The function that determines the date cell from a RecentFileDetails object. * @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) -> { return (T lastAccessed) -> {
Function<Date, String> dateParser = (dt) -> dt == null ? "" : DATETIME_FORMAT.format(dt); Function<Date, String> dateParser = (dt) -> dt == null ? "" : DATETIME_FORMAT.format(dt);
return new DefaultCellModel<>(new Date(lastAccessed.getDateAsLong() * 1000), dateParser, DATETIME_FORMAT_STR); 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( return Stream.of(
ExcelExportAction.getTableExport(docsFetcher, docsTemplate, Bundle.RecentFilesPanel_docsTable_tabName(), dataSource), ExcelExportAction.getTableExport(docsFetcher, docsTemplate, Bundle.RecentFilesPanel_docsTable_tabName(), dataSource),
ExcelExportAction.getTableExport(downloadsFetcher, downloadsTemplate, Bundle.RecentFilesPanel_downloadsTable_tabName(), dataSource), ExcelExportAction.getTableExport(downloadsFetcher, downloadsTemplate, Bundle.RecentFilesPanel_downloadsTable_tabName(), dataSource),