mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
commenting
This commit is contained in:
parent
26091c4c58
commit
72c1e5a224
@ -47,7 +47,7 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.EventUpdateHandler;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelExportException;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelSheetExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelTableExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelTableExport.ExcelCellModel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelCellModel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.GuiCellModel.DefaultMenuItem;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.GuiCellModel.MenuItem;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent;
|
||||
|
@ -37,7 +37,6 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.ContainerSummary;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||
import static org.sleuthkit.autopsy.datasourcesummary.ui.BaseDataSourceSummaryPanel.getFetchResult;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.ui.SizeRepresentationUtil.SizeUnit;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult.ResultType;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetcher;
|
||||
@ -45,6 +44,7 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultCellModel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelSheetExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.ExcelItemExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.KeyValueItemExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.SingleCellExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.TitledExportable;
|
||||
@ -61,6 +61,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
})
|
||||
class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
|
||||
/**
|
||||
* View model data for data source images.
|
||||
*/
|
||||
private static class ImageViewModel {
|
||||
|
||||
private final long unallocatedSize;
|
||||
@ -75,7 +78,20 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
private final String sha1Hash;
|
||||
private final String sha256Hash;
|
||||
|
||||
public ImageViewModel(long unallocatedSize, long size, long sectorSize,
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param unallocatedSize Size in bytes of unallocated space.
|
||||
* @param size Total size in bytes.
|
||||
* @param sectorSize Sector size in bytes.
|
||||
* @param timeZone The time zone.
|
||||
* @param imageType The type of image.
|
||||
* @param paths The source paths for the image.
|
||||
* @param md5Hash The md5 hash or null.
|
||||
* @param sha1Hash The sha1 hash or null.
|
||||
* @param sha256Hash The sha256 hash or null.
|
||||
*/
|
||||
ImageViewModel(long unallocatedSize, long size, long sectorSize,
|
||||
String timeZone, String imageType, List<String> paths, String md5Hash,
|
||||
String sha1Hash, String sha256Hash) {
|
||||
this.unallocatedSize = unallocatedSize;
|
||||
@ -89,44 +105,73 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
this.sha256Hash = sha256Hash;
|
||||
}
|
||||
|
||||
public long getUnallocatedSize() {
|
||||
/**
|
||||
* @return Size in bytes of unallocated space.
|
||||
*/
|
||||
long getUnallocatedSize() {
|
||||
return unallocatedSize;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
/**
|
||||
* @return Total size in bytes.
|
||||
*/
|
||||
long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public long getSectorSize() {
|
||||
/**
|
||||
* @return Sector size in bytes.
|
||||
*/
|
||||
long getSectorSize() {
|
||||
return sectorSize;
|
||||
}
|
||||
|
||||
public String getTimeZone() {
|
||||
/**
|
||||
* @return The time zone.
|
||||
*/
|
||||
String getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public String getImageType() {
|
||||
/**
|
||||
* @return The type of image.
|
||||
*/
|
||||
String getImageType() {
|
||||
return imageType;
|
||||
}
|
||||
|
||||
public List<String> getPaths() {
|
||||
/**
|
||||
* @return The source paths for the image.
|
||||
*/
|
||||
List<String> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
public String getMd5Hash() {
|
||||
/**
|
||||
* @return The md5 hash or null.
|
||||
*/
|
||||
String getMd5Hash() {
|
||||
return md5Hash;
|
||||
}
|
||||
|
||||
public String getSha1Hash() {
|
||||
/**
|
||||
* @return The sha1 hash or null.
|
||||
*/
|
||||
String getSha1Hash() {
|
||||
return sha1Hash;
|
||||
}
|
||||
|
||||
public String getSha256Hash() {
|
||||
/**
|
||||
* @return The sha256 hash or null.
|
||||
*/
|
||||
String getSha256Hash() {
|
||||
return sha256Hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* View model for container data.
|
||||
*/
|
||||
private static class ContainerViewModel {
|
||||
|
||||
private final String displayName;
|
||||
@ -135,6 +180,17 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
private final String acquisitionDetails;
|
||||
private final ImageViewModel imageViewModel;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param displayName The display name for this data source.
|
||||
* @param originalName The original name for this data source.
|
||||
* @param deviceIdValue The device id value for this data source.
|
||||
* @param acquisitionDetails The acquisition details for this data
|
||||
* source or null.
|
||||
* @param imageViewModel If the data source is an image, the image view
|
||||
* model for this data source or null if non-image.
|
||||
*/
|
||||
ContainerViewModel(String displayName, String originalName, String deviceIdValue,
|
||||
String acquisitionDetails, ImageViewModel imageViewModel) {
|
||||
this.displayName = displayName;
|
||||
@ -144,22 +200,38 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
this.imageViewModel = imageViewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The display name for this data source.
|
||||
*/
|
||||
String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The original name for this data source.
|
||||
*/
|
||||
String getOriginalName() {
|
||||
return originalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The device id value for this data source.
|
||||
*/
|
||||
String getDeviceId() {
|
||||
return deviceIdValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The acquisition details for this data source or null.
|
||||
*/
|
||||
String getAcquisitionDetails() {
|
||||
return acquisitionDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the data source is an image, the image view model for this
|
||||
* data source or null if non-image.
|
||||
*/
|
||||
ImageViewModel getImageViewModel() {
|
||||
return imageViewModel;
|
||||
}
|
||||
@ -241,11 +313,29 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
fetchInformation(dataFetchComponents, dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* A means of retrieving data that could potentially throw an exception.
|
||||
*/
|
||||
private interface Retriever<O> {
|
||||
|
||||
/**
|
||||
* Retrieves data of a certain type and possibly throws an exception.
|
||||
*
|
||||
* @return The data type.
|
||||
* @throws TskCoreException
|
||||
* @throws SleuthkitCaseProviderException
|
||||
* @throws SQLException
|
||||
*/
|
||||
O retrieve() throws TskCoreException, SleuthkitCaseProviderException, SQLException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data of a particular type and handles any exceptions that may
|
||||
* be thrown by logging.
|
||||
*
|
||||
* @param retriever The retrieving function.
|
||||
* @return The retrieved data.
|
||||
*/
|
||||
private static <O> O retrieve(Retriever<O> retriever) {
|
||||
try {
|
||||
return retriever.retrieve();
|
||||
@ -255,6 +345,14 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a container view model object containing data to display about
|
||||
* the data source.
|
||||
*
|
||||
* @param containerSummary The service providing data about the data source.
|
||||
* @param ds The data source.
|
||||
* @return The generated view model.
|
||||
*/
|
||||
private static ContainerViewModel getContainerViewModel(ContainerSummary containerSummary, DataSource ds) {
|
||||
if (ds == null) {
|
||||
return null;
|
||||
@ -269,6 +367,14 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an image view model object containing data to display about the
|
||||
* image.
|
||||
*
|
||||
* @param containerSummary The service providing data about the image.
|
||||
* @param image The image.
|
||||
* @return The generated view model.
|
||||
*/
|
||||
private static ImageViewModel getImageViewModel(ContainerSummary containerSummary, Image image) {
|
||||
if (image == null) {
|
||||
return null;
|
||||
@ -287,6 +393,11 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
return new ImageViewModel(unallocSize, size, sectorSize, timeZone, imageType, paths, md5, sha1, sha256);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the swing components with fetched data.
|
||||
*
|
||||
* @param viewModel The data source view model data.
|
||||
*/
|
||||
private void updateDetailsPanelData(ContainerViewModel viewModel) {
|
||||
clearTableValues();
|
||||
if (viewModel == null) {
|
||||
@ -307,6 +418,9 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets image-only fields to N/A.
|
||||
*/
|
||||
@Messages({
|
||||
"ContainerPanel_setFieldsForNonImageDataSource_na=N/A"
|
||||
})
|
||||
@ -326,6 +440,11 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
sha256HashValue.setText(NA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fields for images.
|
||||
*
|
||||
* @param viewModel The image view model data.
|
||||
*/
|
||||
private void setFieldsForImage(ImageViewModel viewModel) {
|
||||
unallocatedSizeValue.setText(SizeRepresentationUtil.getSizeString(viewModel.getUnallocatedSize()));
|
||||
imageTypeValue.setText(viewModel.getImageType());
|
||||
@ -361,29 +480,25 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||
((DefaultTableModel) filePathsTable.getModel()).setRowCount(0);
|
||||
}
|
||||
|
||||
private static List<KeyValueItemExportable> getAcquisitionDetails(String acquisitionDetails) {
|
||||
/**
|
||||
* Divides acquisition details into key/value pairs to be displayed in
|
||||
* separate cells in an excel export.
|
||||
*
|
||||
* @param acquisitionDetails The acquisition details.
|
||||
* @return The list of key value pairs that can be incorporated into the
|
||||
* excel export.
|
||||
*/
|
||||
private static List<? extends ExcelItemExportable> getAcquisitionDetails(String acquisitionDetails) {
|
||||
if (StringUtils.isBlank(acquisitionDetails)) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Stream.of(acquisitionDetails.split("\\r?\\n"))
|
||||
.map((line) -> {
|
||||
if (StringUtils.isBlank(line)) {
|
||||
return null;
|
||||
} else {
|
||||
int colonIdx = line.indexOf(':');
|
||||
if (colonIdx >= 0) {
|
||||
return new KeyValueItemExportable(new DefaultCellModel<>(line.substring(0, colonIdx + 1).trim()),
|
||||
new DefaultCellModel<>(line.substring(colonIdx + 1, line.length()).trim()));
|
||||
} else {
|
||||
return new KeyValueItemExportable(new DefaultCellModel<>(""), new DefaultCellModel<>(line));
|
||||
}
|
||||
}
|
||||
})
|
||||
.map((line) -> (StringUtils.isBlank(line)) ? null : new SingleCellExportable(line))
|
||||
.filter(item -> item != null)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Messages({
|
||||
"ContainerPanel_export_displayName=Display Name:",
|
||||
|
@ -68,7 +68,6 @@ public class DataSourceSummaryTabbedPane extends javax.swing.JPanel {
|
||||
*
|
||||
* @param tabTitle The title of the tab.
|
||||
* @param panel The component to be displayed in the tab.
|
||||
* @param notifyParentClose Notifies parent to trigger a close.
|
||||
*/
|
||||
DataSourceTab(String tabTitle, BaseDataSourceSummaryPanel panel) {
|
||||
this(tabTitle, panel, panel::setDataSource, panel::getExports, panel::close);
|
||||
@ -138,10 +137,10 @@ public class DataSourceSummaryTabbedPane extends javax.swing.JPanel {
|
||||
|
||||
private Runnable notifyParentClose = null;
|
||||
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
||||
|
||||
|
||||
// create an export panel whose button triggers the export to XLSX action
|
||||
private final ExportPanel exportPanel = new ExportPanel();
|
||||
|
||||
|
||||
private final List<DataSourceTab> tabs = Arrays.asList(
|
||||
new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_typesTab_title(), new TypesPanel()),
|
||||
new DataSourceTab(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new UserActivityPanel()),
|
||||
@ -165,10 +164,10 @@ public class DataSourceSummaryTabbedPane extends javax.swing.JPanel {
|
||||
null,
|
||||
null)
|
||||
);
|
||||
|
||||
|
||||
// the action that does the export
|
||||
private final ExcelExportAction exportAction = new ExcelExportAction(tabs);
|
||||
|
||||
|
||||
private DataSource dataSource = null;
|
||||
private CardLayout cardLayout;
|
||||
|
||||
@ -222,7 +221,7 @@ public class DataSourceSummaryTabbedPane extends javax.swing.JPanel {
|
||||
|
||||
// set this to no datasource initially
|
||||
cardLayout.show(this, NO_DATASOURCE_PANE);
|
||||
|
||||
|
||||
// set action for when user requests xlsx export
|
||||
exportPanel.setXlsxExportAction(() -> exportAction.accept(getDataSource()));
|
||||
}
|
||||
@ -270,7 +269,6 @@ public class DataSourceSummaryTabbedPane extends javax.swing.JPanel {
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), caseEventsListener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
|
@ -1,7 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||
|
||||
@ -17,8 +30,6 @@ import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
@ -33,8 +44,7 @@ import org.sleuthkit.datamodel.IngestModuleInfo;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
* Class that handles exporting information in IngestJobInfoPanel to excel.
|
||||
*/
|
||||
@Messages({
|
||||
"IngestJobExcelExport_startTimeColumn=Start Time",
|
||||
@ -46,6 +56,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
})
|
||||
class IngestJobExcelExport {
|
||||
|
||||
/**
|
||||
* An entry to display in an excel export.
|
||||
*/
|
||||
private static class IngestJobEntry {
|
||||
|
||||
private final Date startTime;
|
||||
@ -54,6 +67,15 @@ class IngestJobExcelExport {
|
||||
private final String ingestModule;
|
||||
private final String ingestModuleVersion;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param startTime The ingest start time.
|
||||
* @param endTime The ingest stop time.
|
||||
* @param status The ingest status.
|
||||
* @param ingestModule The ingest module.
|
||||
* @param ingestModuleVersion The ingest module version.
|
||||
*/
|
||||
IngestJobEntry(Date startTime, Date endTime, String status, String ingestModule, String ingestModuleVersion) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
@ -62,22 +84,37 @@ class IngestJobExcelExport {
|
||||
this.ingestModuleVersion = ingestModuleVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ingest start time.
|
||||
*/
|
||||
Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ingest stop time.
|
||||
*/
|
||||
Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ingest status.
|
||||
*/
|
||||
String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ingest module.
|
||||
*/
|
||||
String getIngestModule() {
|
||||
return ingestModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ingest module version.
|
||||
*/
|
||||
String getIngestModuleVersion() {
|
||||
return ingestModuleVersion;
|
||||
}
|
||||
@ -87,6 +124,7 @@ class IngestJobExcelExport {
|
||||
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());
|
||||
|
||||
// columns in the excel export table to be created.
|
||||
private static final List<ColumnModel<IngestJobEntry, DefaultCellModel<?>>> COLUMNS = Arrays.asList(
|
||||
new ColumnModel<>(
|
||||
Bundle.IngestJobExcelExport_startTimeColumn(),
|
||||
@ -105,11 +143,23 @@ class IngestJobExcelExport {
|
||||
(entry) -> new DefaultCellModel<>(entry.getIngestModuleVersion()))
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieves data for a date cell.
|
||||
*
|
||||
* @param date The date.
|
||||
* @return The data cell to be used in the excel export.
|
||||
*/
|
||||
private static DefaultCellModel<?> getDateCell(Date date) {
|
||||
Function<Date, String> dateParser = (dt) -> dt == null ? "" : DATETIME_FORMAT.format(dt);
|
||||
return new DefaultCellModel<>(date, dateParser, DATETIME_FORMAT_STR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the ingest job modules and versions for a job.
|
||||
*
|
||||
* @param job The ingest job.
|
||||
* @return All of the corresponding entries sorted by module name.
|
||||
*/
|
||||
private static List<IngestJobEntry> getEntries(IngestJobInfo job) {
|
||||
List<IngestModuleInfo> infoList = job.getIngestModuleInfo();
|
||||
if (infoList == null) {
|
||||
@ -135,6 +185,13 @@ class IngestJobExcelExport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For output, show ingest job details in first row present. Otherwise, set
|
||||
* to null.
|
||||
*
|
||||
* @param list The list of entries for an ingest job.
|
||||
* @return The stream of entries to be displayed.
|
||||
*/
|
||||
private static Stream<IngestJobEntry> showFirstRowOnly(List<IngestJobEntry> list) {
|
||||
return IntStream.range(0, list.size())
|
||||
.mapToObj(idx -> {
|
||||
@ -148,6 +205,12 @@ class IngestJobExcelExport {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of sheets to be exported for the Ingest History tab.
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
* @return The list of sheets to be included in an export.
|
||||
*/
|
||||
static List<ExcelSheetExport> getExports(DataSource dataSource) {
|
||||
if (dataSource == null) {
|
||||
return Collections.emptyList();
|
||||
@ -167,6 +230,7 @@ class IngestJobExcelExport {
|
||||
List<IngestJobEntry> toDisplay = info.stream()
|
||||
.filter(job -> job != null && dataSource.getId() == job.getObjectId())
|
||||
.sorted((a, b) -> {
|
||||
// sort ingest jobs by time.
|
||||
boolean aIsNull = a.getStartDateTime() == null;
|
||||
boolean bIsNull = b.getStartDateTime() == null;
|
||||
if (aIsNull || bIsNull) {
|
||||
@ -183,4 +247,7 @@ class IngestJobExcelExport {
|
||||
|
||||
return Arrays.asList(new ExcelTableExport<>(Bundle.IngestJobExcelExport_sheetName(), COLUMNS, toDisplay));
|
||||
}
|
||||
|
||||
private IngestJobExcelExport() {
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ public final class SizeRepresentationUtil {
|
||||
private static final int SIZE_CONVERSION_CONSTANT = 1000;
|
||||
private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##");
|
||||
|
||||
// based on https://www.mrexcel.com/board/threads/how-do-i-format-cells-to-show-gb-mb-kb.140135/
|
||||
/**
|
||||
* A size unit corresponding to orders of magnitude of bytes (kilobyte, gigabytes, etc.).
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"SizeRepresentationUtil_units_bytes=bytes",
|
||||
"SizeRepresentationUtil_units_kilobytes=KB",
|
||||
@ -54,20 +56,37 @@ public final class SizeRepresentationUtil {
|
||||
private final String excelFormatString;
|
||||
private final long divisor;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* @param suffix The string suffix to use for size unit.
|
||||
* @param excelFormatString The excel format string to use for this size unit.
|
||||
* @param power The power of 1000 of bytes for this size unit.
|
||||
*/
|
||||
SizeUnit(String suffix, String excelFormatString, int power) {
|
||||
this.suffix = suffix;
|
||||
|
||||
// based on https://www.mrexcel.com/board/threads/how-do-i-format-cells-to-show-gb-mb-kb.140135/
|
||||
this.excelFormatString = String.format("%s \"%s\"", excelFormatString, suffix);
|
||||
this.divisor = (long) Math.pow(SIZE_CONVERSION_CONSTANT, power);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The string suffix to use for size unit.
|
||||
*/
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The excel format string to use for this size unit.
|
||||
*/
|
||||
public String getExcelFormatString() {
|
||||
return excelFormatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The divisor to convert from bytes to this unit.
|
||||
*/
|
||||
public long getDivisor() {
|
||||
return divisor;
|
||||
}
|
||||
@ -85,6 +104,11 @@ public final class SizeRepresentationUtil {
|
||||
return getSizeString(size, APPROXIMATE_SIZE_FORMAT, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the relevant size unit that should be used for a particular size.
|
||||
* @param size The size in bytes.
|
||||
* @return The relevant size unit.
|
||||
*/
|
||||
static SizeUnit getSizeUnit(Long size) {
|
||||
if (size == null) {
|
||||
return SizeUnit.values()[0];
|
||||
@ -135,7 +159,11 @@ public final class SizeRepresentationUtil {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a default cell model using size units.
|
||||
* @param bytes The number of bytes.
|
||||
* @return The default cell model.
|
||||
*/
|
||||
static DefaultCellModel<?> getBytesCell(Long bytes) {
|
||||
if (bytes == null) {
|
||||
return new DefaultCellModel<>("");
|
||||
|
@ -31,7 +31,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.FileTypeUtils.FileTypeCategory;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TypesSummary;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.ContainerSummary;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.MimeTypeSummary;
|
||||
@ -50,7 +49,6 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableLabel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.PieChartPanel.PieChartItem;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
||||
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
@ -173,9 +171,8 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#");
|
||||
private static final String COMMA_FORMAT_STR = "#,###";
|
||||
|
||||
|
||||
private static final DecimalFormat COMMA_FORMATTER = new DecimalFormat(COMMA_FORMAT_STR);
|
||||
private static final Logger logger = Logger.getLogger(TypesPanel.class.getName());
|
||||
|
||||
private static final Color IMAGES_COLOR = new Color(156, 39, 176);
|
||||
private static final Color VIDEOS_COLOR = Color.YELLOW;
|
||||
@ -412,14 +409,31 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
|
||||
return longVal == null ? "0" : COMMA_FORMATTER.format(longVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a key value pair to be exported in a sheet.
|
||||
*
|
||||
* @param fetcher The means of fetching the data.
|
||||
* @param key The key to use.
|
||||
* @param dataSource The data source containing the data.
|
||||
* @return The key value pair to be exported.
|
||||
*/
|
||||
private static KeyValueItemExportable getStrExportable(DataFetcher<DataSource, String> fetcher, String key, DataSource dataSource) {
|
||||
String result = getFetchResult(fetcher, "Types", dataSource);
|
||||
return (result == null) ? null : new KeyValueItemExportable(key, new DefaultCellModel<>(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a key value pair to be exported in a sheet formatting the long
|
||||
* with commas separated by orders of 1000.
|
||||
*
|
||||
* @param fetcher The means of fetching the data.
|
||||
* @param key The string key for this key value pair.
|
||||
* @param dataSource The data source.
|
||||
* @return The key value pair.
|
||||
*/
|
||||
private static KeyValueItemExportable getCountExportable(DataFetcher<DataSource, Long> fetcher, String key, DataSource dataSource) {
|
||||
Long count = getFetchResult(fetcher, "Types", dataSource);
|
||||
return (count == null) ? null : new KeyValueItemExportable(key,
|
||||
return (count == null) ? null : new KeyValueItemExportable(key,
|
||||
new DefaultCellModel<Long>(count, COMMA_FORMATTER::format, COMMA_FORMAT_STR));
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
|
||||
/**
|
||||
* Basic interface for a cell model.
|
||||
@ -29,20 +30,23 @@ public interface CellModel {
|
||||
* Describes the horizontal alignment.
|
||||
*/
|
||||
public enum HorizontalAlign {
|
||||
LEFT(JLabel.LEFT),
|
||||
CENTER(JLabel.CENTER),
|
||||
RIGHT(JLabel.RIGHT);
|
||||
LEFT(JLabel.LEFT, HorizontalAlignment.LEFT),
|
||||
CENTER(JLabel.CENTER, HorizontalAlignment.CENTER),
|
||||
RIGHT(JLabel.RIGHT, HorizontalAlignment.RIGHT);
|
||||
|
||||
private final int jlabelAlignment;
|
||||
private final HorizontalAlignment poiAlignment;
|
||||
|
||||
/**
|
||||
* Constructor for a HorizontalAlign enum.
|
||||
*
|
||||
* @param jlabelAlignment The corresponding JLabel horizontal alignment
|
||||
* number.
|
||||
* @param poiAlignment Horizontal alignment for Apache POI.
|
||||
*/
|
||||
HorizontalAlign(int jlabelAlignment) {
|
||||
HorizontalAlign(int jlabelAlignment, HorizontalAlignment poiAlignment) {
|
||||
this.jlabelAlignment = jlabelAlignment;
|
||||
this.poiAlignment = poiAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,6 +56,13 @@ public interface CellModel {
|
||||
int getJLabelAlignment() {
|
||||
return this.jlabelAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Horizontal alignment for Apache POI.
|
||||
*/
|
||||
HorizontalAlignment getPoiAlignment() {
|
||||
return poiAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,21 +24,21 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelTableExport.ExcelCellModel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelCellModel;
|
||||
|
||||
/**
|
||||
* The default cell model.
|
||||
*/
|
||||
public class DefaultCellModel<T> implements GuiCellModel, ExcelCellModel {
|
||||
|
||||
private final T data;
|
||||
private final Function<T, String> stringConverter;
|
||||
final T data;
|
||||
final Function<T, String> stringConverter;
|
||||
String tooltip;
|
||||
CellModel.HorizontalAlign horizontalAlignment;
|
||||
Insets insets;
|
||||
List<MenuItem> popupMenu;
|
||||
Supplier<List<MenuItem>> menuItemSupplier;
|
||||
private final String excelFormatString;
|
||||
final String excelFormatString;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
|
@ -26,8 +26,8 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
@ -37,6 +37,7 @@ import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModel.HorizontalAlign;
|
||||
|
||||
/**
|
||||
* Class for handling Excel exporting.
|
||||
@ -68,6 +69,87 @@ public class ExcelExport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cell style key that can be used with the WorksheetEnv to generate a
|
||||
* cell style to be used in a POI excel document.
|
||||
*/
|
||||
static class CellStyleKey {
|
||||
|
||||
private final String formatString;
|
||||
private final CellStyle cellStyle;
|
||||
private final HorizontalAlign alignment;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param formatString The format string or null if no special
|
||||
* formatting.
|
||||
* @param cellStyle The base cell style or null if default is to be
|
||||
* used.
|
||||
* @param alignment The horizontal alignment or null if default is to be
|
||||
* used.
|
||||
*/
|
||||
CellStyleKey(String formatString, CellStyle cellStyle, HorizontalAlign alignment) {
|
||||
this.formatString = formatString;
|
||||
this.cellStyle = cellStyle;
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The format string or null if no special formatting.
|
||||
*/
|
||||
String getFormatString() {
|
||||
return formatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The base cell style or null if default is to be used.
|
||||
*/
|
||||
CellStyle getCellStyle() {
|
||||
return cellStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The horizontal alignment or null if default is to be used.
|
||||
*/
|
||||
HorizontalAlign getAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 29 * hash + Objects.hashCode(this.formatString);
|
||||
hash = 29 * hash + Objects.hashCode(this.cellStyle);
|
||||
hash = 29 * hash + Objects.hashCode(this.alignment);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CellStyleKey other = (CellStyleKey) obj;
|
||||
if (!Objects.equals(this.formatString, other.formatString)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.cellStyle, other.cellStyle)) {
|
||||
return false;
|
||||
}
|
||||
if (this.alignment != other.alignment) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class detailing aspects of the worksheet.
|
||||
*/
|
||||
@ -76,10 +158,10 @@ public class ExcelExport {
|
||||
private final CellStyle headerStyle;
|
||||
private final Workbook parentWorkbook;
|
||||
private final CellStyle defaultStyle;
|
||||
|
||||
|
||||
// maps a data format string / original cell style combination to a created cell style
|
||||
private final Map<Pair<String, CellStyle>, CellStyle> cellStyleCache = new HashMap<>();
|
||||
|
||||
private final Map<CellStyleKey, CellStyle> cellStyleCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
@ -92,17 +174,29 @@ public class ExcelExport {
|
||||
this.defaultStyle = defaultStyle;
|
||||
this.parentWorkbook = parentWorkbook;
|
||||
}
|
||||
|
||||
|
||||
public CellStyle getCellStyle(CellStyle baseStyle, String dataFormat) {
|
||||
return cellStyleCache.computeIfAbsent(Pair.of(dataFormat, baseStyle), (pair) -> {
|
||||
|
||||
/**
|
||||
* Returns a cell style signified by the given cell style key. If the
|
||||
* key is already present, a cached version is returned.
|
||||
*
|
||||
* @param cellStyleKey The key.
|
||||
* @return The cell style representing this key.
|
||||
*/
|
||||
public CellStyle getCellStyle(CellStyleKey cellStyleKey) {
|
||||
return cellStyleCache.computeIfAbsent(cellStyleKey, (pair) -> {
|
||||
CellStyle computed = this.parentWorkbook.createCellStyle();
|
||||
computed.cloneStyleFrom(pair.getRight() == null ? defaultStyle : pair.getRight());
|
||||
computed.setDataFormat(this.parentWorkbook.getCreationHelper().createDataFormat().getFormat(dataFormat));
|
||||
computed.cloneStyleFrom(cellStyleKey.getCellStyle() == null ? defaultStyle : cellStyleKey.getCellStyle());
|
||||
|
||||
if (cellStyleKey.getAlignment() != null) {
|
||||
computed.setAlignment(cellStyleKey.getAlignment().getPoiAlignment());
|
||||
}
|
||||
|
||||
if (cellStyleKey.getFormatString() != null) {
|
||||
computed.setDataFormat(this.parentWorkbook.getCreationHelper().createDataFormat().getFormat(cellStyleKey.getFormatString()));
|
||||
}
|
||||
return computed;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the cell style to use for headers.
|
||||
@ -115,13 +209,13 @@ public class ExcelExport {
|
||||
|
||||
/**
|
||||
* Returns the cell style for default items.
|
||||
*
|
||||
*
|
||||
* @return The cell style for default items.
|
||||
*/
|
||||
public CellStyle getDefaultCellStyle() {
|
||||
return defaultStyle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the parent workbook.
|
||||
*
|
||||
@ -160,6 +254,7 @@ public class ExcelExport {
|
||||
|
||||
/**
|
||||
* Retrieves a singleton instance of this class.
|
||||
*
|
||||
* @return The instance.
|
||||
*/
|
||||
public static ExcelExport getInstance() {
|
||||
@ -176,10 +271,11 @@ public class ExcelExport {
|
||||
|
||||
/**
|
||||
* Writes the exports to a workbook.
|
||||
*
|
||||
* @param exports The sheets to export.
|
||||
* @param path The path to the output file.
|
||||
* @throws IOException
|
||||
* @throws ExcelExportException
|
||||
* @throws ExcelExportException
|
||||
*/
|
||||
@Messages({
|
||||
"# {0} - sheetNumber",
|
||||
@ -199,7 +295,7 @@ public class ExcelExport {
|
||||
CellStyle headerCellStyle = workbook.createCellStyle();
|
||||
headerCellStyle.setFont(headerFont);
|
||||
headerCellStyle.setAlignment(alignment);
|
||||
|
||||
|
||||
CellStyle defaultCellStyle = workbook.createCellStyle();
|
||||
defaultCellStyle.setAlignment(alignment);
|
||||
|
||||
@ -231,7 +327,6 @@ public class ExcelExport {
|
||||
workbook.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an excel cell given the model.
|
||||
*
|
||||
@ -242,13 +337,13 @@ public class ExcelExport {
|
||||
* @param cellStyle The style to use.
|
||||
* @return The created cell.
|
||||
*/
|
||||
static Cell createCell(WorksheetEnv env, Row row, int colNum, ExcelTableExport.ExcelCellModel cellModel, Optional<CellStyle> cellStyle) {
|
||||
static Cell createCell(WorksheetEnv env, Row row, int colNum, ExcelCellModel cellModel, Optional<CellStyle> cellStyle) {
|
||||
CellStyle cellStyleToUse = cellStyle.orElse(env.getDefaultCellStyle());
|
||||
|
||||
if (cellModel.getExcelFormatString() != null) {
|
||||
cellStyleToUse = env.getCellStyle(cellStyleToUse, cellModel.getExcelFormatString());
|
||||
|
||||
if (cellModel.getExcelFormatString() != null || cellModel.getHorizontalAlignment() != null) {
|
||||
cellStyleToUse = env.getCellStyle(new CellStyleKey(cellModel.getExcelFormatString(), cellStyleToUse, cellModel.getHorizontalAlignment()));
|
||||
}
|
||||
|
||||
|
||||
Object cellData = cellModel.getData();
|
||||
Cell cell = row.createCell(colNum);
|
||||
if (cellData instanceof Calendar) {
|
||||
|
@ -1,7 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
@ -11,14 +24,16 @@ import java.util.Optional;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelExportException;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelTableExport.ExcelCellModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
* An excel export that has special row-by-row formatting.
|
||||
*/
|
||||
public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
|
||||
/**
|
||||
* The dimensions consumed by an item in an ExcelSpecialFormatExport list of
|
||||
* items to be rendered.
|
||||
*/
|
||||
public static class ItemDimensions {
|
||||
|
||||
private final int rowStart;
|
||||
@ -26,6 +41,14 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
private final int colStart;
|
||||
private final int colEnd;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param rowStart The starting excel row of the item.
|
||||
* @param colStart The starting excel column of the item.
|
||||
* @param rowEnd The last excel row of the the item.
|
||||
* @param colEnd The last excel column of the item.
|
||||
*/
|
||||
public ItemDimensions(int rowStart, int colStart, int rowEnd, int colEnd) {
|
||||
this.rowStart = rowStart;
|
||||
this.colStart = colStart;
|
||||
@ -33,36 +56,74 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
this.colEnd = colEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The starting excel row of the item.
|
||||
*/
|
||||
public int getRowStart() {
|
||||
return rowStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last excel row of the the item.
|
||||
*/
|
||||
public int getRowEnd() {
|
||||
return rowEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The starting excel column of the item.
|
||||
*/
|
||||
public int getColStart() {
|
||||
return colStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last excel column of the item.
|
||||
*/
|
||||
public int getColEnd() {
|
||||
return colEnd;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An item to be exported in a specially formatted excel export.
|
||||
*/
|
||||
public interface ExcelItemExportable {
|
||||
|
||||
/**
|
||||
* Writes the item to the sheet in the special format export sheet.
|
||||
*
|
||||
* @param sheet The sheet.
|
||||
* @param rowStart The starting row to start writing.
|
||||
* @param colStart The starting column to start writing.
|
||||
* @param env The excel export context.
|
||||
* @return The dimensions of what has been written.
|
||||
* @throws ExcelExportException
|
||||
*/
|
||||
ItemDimensions write(Sheet sheet, int rowStart, int colStart, ExcelExport.WorksheetEnv env) throws ExcelExportException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to a single cell in a specially formatted excel export.
|
||||
*/
|
||||
public static class SingleCellExportable implements ExcelItemExportable {
|
||||
|
||||
private final ExcelCellModel item;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param key The text to be written.
|
||||
*/
|
||||
public SingleCellExportable(String key) {
|
||||
this(new DefaultCellModel<>(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param item The cell model to be written.
|
||||
*/
|
||||
public SingleCellExportable(ExcelCellModel item) {
|
||||
this.item = item;
|
||||
}
|
||||
@ -75,15 +136,31 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a row consisting of first column as a key and second column as a
|
||||
* value.
|
||||
*/
|
||||
public static class KeyValueItemExportable implements ExcelItemExportable {
|
||||
|
||||
private final ExcelCellModel key;
|
||||
private final ExcelCellModel value;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param key The string key to be exported.
|
||||
* @param value The cell model to be exported.
|
||||
*/
|
||||
public KeyValueItemExportable(String key, ExcelCellModel value) {
|
||||
this(new DefaultCellModel<>(key), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param key The cell key to be exported.
|
||||
* @param value The cell model to be exported.
|
||||
*/
|
||||
public KeyValueItemExportable(ExcelCellModel key, ExcelCellModel value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
@ -98,14 +175,17 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
}
|
||||
}
|
||||
|
||||
private final String sheetName;
|
||||
private final List<ExcelItemExportable> exports;
|
||||
|
||||
public ExcelSpecialFormatExport(String sheetName, List<ExcelItemExportable> exports) {
|
||||
this.sheetName = sheetName;
|
||||
this.exports = exports == null ? Collections.emptyList() : exports;
|
||||
}
|
||||
|
||||
/**
|
||||
* A special format excel export item that shows a title and a list of items
|
||||
* indented one column.
|
||||
*
|
||||
* i.e.
|
||||
* <pre>
|
||||
* title
|
||||
* item 1
|
||||
* item 2
|
||||
* </pre>
|
||||
*/
|
||||
public static class TitledExportable implements ExcelItemExportable {
|
||||
|
||||
private static final int DEFAULT_INDENT = 1;
|
||||
@ -113,6 +193,12 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
private final String title;
|
||||
private final List<? extends ExcelItemExportable> children;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param title The title for the export.
|
||||
* @param children The children to be indented and enumerated.
|
||||
*/
|
||||
public TitledExportable(String title, List<? extends ExcelItemExportable> children) {
|
||||
this.title = title;
|
||||
this.children = children;
|
||||
@ -135,7 +221,20 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
||||
|
||||
return new ItemDimensions(rowStart, colStart, curRow - 1, maxCol);
|
||||
}
|
||||
}
|
||||
|
||||
private final String sheetName;
|
||||
private final List<ExcelItemExportable> exports;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param sheetName The name of the sheet.
|
||||
* @param exports The row-by-row items to be exported.
|
||||
*/
|
||||
public ExcelSpecialFormatExport(String sheetName, List<ExcelItemExportable> exports) {
|
||||
this.sheetName = sheetName;
|
||||
this.exports = exports == null ? Collections.emptyList() : exports;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,37 +19,21 @@
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelExportException;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelSheetExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.ExcelItemExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.ItemDimensions;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelTableExport.ExcelCellModel;
|
||||
|
||||
/**
|
||||
* An excel sheet export of table data.
|
||||
*/
|
||||
public class ExcelTableExport<T, C extends ExcelCellModel> implements ExcelSheetExport, ExcelItemExportable {
|
||||
|
||||
/**
|
||||
* Basic interface for a cell model.
|
||||
*/
|
||||
public interface ExcelCellModel extends CellModel {
|
||||
|
||||
/**
|
||||
* @return The format string to be used with Apache POI during excel
|
||||
* export or null if none necessary.
|
||||
*/
|
||||
String getExcelFormatString();
|
||||
}
|
||||
|
||||
private final String sheetName;
|
||||
private final List<ColumnModel<T, C>> columns;
|
||||
private final List<T> data;
|
||||
@ -66,7 +50,16 @@ public class ExcelTableExport<T, C extends ExcelCellModel> implements ExcelSheet
|
||||
public ExcelTableExport(String sheetName, List<ColumnModel<T, C>> columns, List<T> data) {
|
||||
this(sheetName, columns, data, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param sheetName The name of the sheet. NOTE: There can be no duplicates
|
||||
* in a workbook.
|
||||
* @param columns The columns of the table.
|
||||
* @param data The data to export.
|
||||
* @param columnIndent The column indent.
|
||||
*/
|
||||
public ExcelTableExport(String sheetName, List<ColumnModel<T, C>> columns, List<T> data, int columnIndent) {
|
||||
this.sheetName = sheetName;
|
||||
this.columns = columns;
|
||||
@ -129,7 +122,7 @@ public class ExcelTableExport<T, C extends ExcelCellModel> implements ExcelSheet
|
||||
// freeze header row
|
||||
sheet.createFreezePane(0, 1);
|
||||
// Create Cell Style for each column (if one is needed)
|
||||
|
||||
|
||||
for (int rowNum = 0; rowNum < safeData.size(); rowNum++) {
|
||||
T rowData = safeData.get(rowNum);
|
||||
Row row = sheet.createRow(rowNum + rowStart + 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user