mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 19:14:55 +00:00
working through container panel
This commit is contained in:
parent
9fdfac8d5a
commit
67f33ba57c
@ -19,6 +19,8 @@
|
|||||||
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
package org.sleuthkit.autopsy.datasourcesummary.ui;
|
||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -33,15 +35,18 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.ContainerSummary;
|
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 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.DataFetchResult.ResultType;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetcher;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetcher;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultCellModel;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultCellModel;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport.ExcelSheetExport;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.KeyValueItemExportable;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.KeyValueItemExportable;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.SingleCellExportable;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.TitledExportable;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.TitledExportable;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.UpdateGovernor;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.UpdateGovernor;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
@ -56,37 +61,107 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
})
|
})
|
||||||
class ContainerPanel extends BaseDataSourceSummaryPanel {
|
class ContainerPanel extends BaseDataSourceSummaryPanel {
|
||||||
|
|
||||||
/**
|
private static class ImageViewModel {
|
||||||
* Data payload for the Container panel.
|
|
||||||
*/
|
|
||||||
private static class ContainerPanelData {
|
|
||||||
|
|
||||||
private final DataSource dataSource;
|
private final long unallocatedSize;
|
||||||
private final Long unallocatedFilesSize;
|
private final long size;
|
||||||
|
private final long sectorSize;
|
||||||
|
|
||||||
/**
|
private final String timeZone;
|
||||||
* Main constructor.
|
private final String imageType;
|
||||||
*
|
|
||||||
* @param dataSource The original datasource.
|
private final List<String> paths;
|
||||||
* @param unallocatedFilesSize The unallocated file size.
|
private final String md5Hash;
|
||||||
*/
|
private final String sha1Hash;
|
||||||
ContainerPanelData(DataSource dataSource, Long unallocatedFilesSize) {
|
private final String sha256Hash;
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.unallocatedFilesSize = unallocatedFilesSize;
|
public ImageViewModel(long unallocatedSize, long size, long sectorSize,
|
||||||
|
String timeZone, String imageType, List<String> paths, String md5Hash,
|
||||||
|
String sha1Hash, String sha256Hash) {
|
||||||
|
this.unallocatedSize = unallocatedSize;
|
||||||
|
this.size = size;
|
||||||
|
this.sectorSize = sectorSize;
|
||||||
|
this.timeZone = timeZone;
|
||||||
|
this.imageType = imageType;
|
||||||
|
this.paths = paths == null ? Collections.emptyList() : new ArrayList<>(paths);
|
||||||
|
this.md5Hash = md5Hash;
|
||||||
|
this.sha1Hash = sha1Hash;
|
||||||
|
this.sha256Hash = sha256Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public long getUnallocatedSize() {
|
||||||
* @return The original datasource.
|
return unallocatedSize;
|
||||||
*/
|
|
||||||
DataSource getDataSource() {
|
|
||||||
return dataSource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public long getSize() {
|
||||||
* @return The unallocated file size.
|
return size;
|
||||||
*/
|
}
|
||||||
Long getUnallocatedFilesSize() {
|
|
||||||
return unallocatedFilesSize;
|
public long getSectorSize() {
|
||||||
|
return sectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimeZone() {
|
||||||
|
return timeZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImageType() {
|
||||||
|
return imageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPaths() {
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMd5Hash() {
|
||||||
|
return md5Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSha1Hash() {
|
||||||
|
return sha1Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSha256Hash() {
|
||||||
|
return sha256Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ContainerViewModel {
|
||||||
|
|
||||||
|
private final String displayName;
|
||||||
|
private final String originalName;
|
||||||
|
private final String deviceIdValue;
|
||||||
|
private final String acquisitionDetails;
|
||||||
|
private final ImageViewModel imageViewModel;
|
||||||
|
|
||||||
|
ContainerViewModel(String displayName, String originalName, String deviceIdValue,
|
||||||
|
String acquisitionDetails, ImageViewModel imageViewModel) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.originalName = originalName;
|
||||||
|
this.deviceIdValue = deviceIdValue;
|
||||||
|
this.acquisitionDetails = acquisitionDetails;
|
||||||
|
this.imageViewModel = imageViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getOriginalName() {
|
||||||
|
return originalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDeviceId() {
|
||||||
|
return deviceIdValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getAcquisitionDetails() {
|
||||||
|
return acquisitionDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageViewModel getImageViewModel() {
|
||||||
|
return imageViewModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +190,7 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
private static final Logger logger = Logger.getLogger(ContainerPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(ContainerPanel.class.getName());
|
||||||
|
|
||||||
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
||||||
private final DataFetcher<DataSource, ContainerPanelData> containerDataFetcher;
|
private final DataFetcher<DataSource, ContainerViewModel> containerDataFetcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new form ContainerPanel.
|
* Creates a new form ContainerPanel.
|
||||||
@ -130,23 +205,15 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
ContainerPanel(ContainerSummary containerSummary) {
|
ContainerPanel(ContainerSummary containerSummary) {
|
||||||
super(containerSummary, CONTAINER_UPDATES);
|
super(containerSummary, CONTAINER_UPDATES);
|
||||||
|
|
||||||
containerDataFetcher = (dataSource) -> {
|
containerDataFetcher = (dataSource) -> getContainerViewModel(containerSummary, dataSource);
|
||||||
return new ContainerPanelData(
|
|
||||||
dataSource,
|
|
||||||
containerSummary.getSizeOfUnallocatedFiles(dataSource)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
dataFetchComponents = Arrays.asList(
|
dataFetchComponents = Arrays.asList(
|
||||||
new DataFetchComponents<>(
|
new DataFetchComponents<>(
|
||||||
containerDataFetcher,
|
containerDataFetcher,
|
||||||
(result) -> {
|
(result) -> {
|
||||||
if (result != null && result.getResultType() == ResultType.SUCCESS) {
|
if (result != null && result.getResultType() == ResultType.SUCCESS) {
|
||||||
ContainerPanelData data = result.getData();
|
ContainerViewModel data = result.getData();
|
||||||
DataSource dataSource = (data == null) ? null : data.getDataSource();
|
updateDetailsPanelData(data);
|
||||||
Long unallocatedFileSize = (data == null) ? null : data.getUnallocatedFilesSize();
|
|
||||||
|
|
||||||
updateDetailsPanelData(dataSource, unallocatedFileSize);
|
|
||||||
} else {
|
} else {
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.log(Level.WARNING, "No data fetch result was provided to the ContainerPanel.");
|
logger.log(Level.WARNING, "No data fetch result was provided to the ContainerPanel.");
|
||||||
@ -154,8 +221,7 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
logger.log(Level.WARNING, "An exception occurred while attempting to fetch data for the ContainerPanel.",
|
logger.log(Level.WARNING, "An exception occurred while attempting to fetch data for the ContainerPanel.",
|
||||||
result.getException());
|
result.getException());
|
||||||
}
|
}
|
||||||
|
updateDetailsPanelData(null);
|
||||||
updateDetailsPanelData(null, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -175,30 +241,68 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
fetchInformation(dataFetchComponents, dataSource);
|
fetchInformation(dataFetchComponents, dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private interface Retriever<O> {
|
||||||
* Update which DataSource this panel should display details about
|
|
||||||
*
|
|
||||||
* @param selectedDataSource the DataSource to display details about.
|
|
||||||
*/
|
|
||||||
private void updateDetailsPanelData(DataSource selectedDataSource, Long unallocatedFilesSize) {
|
|
||||||
clearTableValues();
|
|
||||||
if (selectedDataSource != null) {
|
|
||||||
displayNameValue.setText(selectedDataSource.getName());
|
|
||||||
originalNameValue.setText(selectedDataSource.getName());
|
|
||||||
deviceIdValue.setText(selectedDataSource.getDeviceId());
|
|
||||||
|
|
||||||
try {
|
O retrieve() throws TskCoreException, SleuthkitCaseProviderException, SQLException;
|
||||||
acquisitionDetailsTextArea.setText(selectedDataSource.getAcquisitionDetails());
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get acquisition details for selected data source", ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedDataSource instanceof Image) {
|
private static <O> O retrieve(Retriever<O> retriever) {
|
||||||
setFieldsForImage((Image) selectedDataSource, unallocatedFilesSize);
|
try {
|
||||||
|
return retriever.retrieve();
|
||||||
|
} catch (TskCoreException | SleuthkitCaseProviderException | SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error while retrieving data.", ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ContainerViewModel getContainerViewModel(ContainerSummary containerSummary, DataSource ds) {
|
||||||
|
if (ds == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ContainerViewModel(
|
||||||
|
ds.getName(),
|
||||||
|
ds.getName(),
|
||||||
|
ds.getDeviceId(),
|
||||||
|
retrieve(() -> ds.getAcquisitionDetails()),
|
||||||
|
ds instanceof Image ? getImageViewModel(containerSummary, (Image) ds) : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageViewModel getImageViewModel(ContainerSummary containerSummary, Image image) {
|
||||||
|
if (image == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long unallocSize = retrieve(() -> containerSummary.getSizeOfUnallocatedFiles(image));
|
||||||
|
String imageType = image.getType().getName();
|
||||||
|
Long size = image.getSize();
|
||||||
|
Long sectorSize = image.getSsize();
|
||||||
|
String timeZone = image.getTimeZone();
|
||||||
|
List<String> paths = image.getPaths() == null ? Collections.emptyList() : Arrays.asList(image.getPaths());
|
||||||
|
String md5 = retrieve(() -> image.getMd5());
|
||||||
|
String sha1 = retrieve(() -> image.getSha1());
|
||||||
|
String sha256 = retrieve(() -> image.getSha256());
|
||||||
|
|
||||||
|
return new ImageViewModel(unallocSize, size, sectorSize, timeZone, imageType, paths, md5, sha1, sha256);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDetailsPanelData(ContainerViewModel viewModel) {
|
||||||
|
clearTableValues();
|
||||||
|
if (viewModel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayNameValue.setText(viewModel.getDisplayName());
|
||||||
|
originalNameValue.setText(viewModel.getOriginalName());
|
||||||
|
deviceIdValue.setText(viewModel.getDeviceId());
|
||||||
|
acquisitionDetailsTextArea.setText(viewModel.getAcquisitionDetails());
|
||||||
|
|
||||||
|
if (viewModel.getImageViewModel() != null) {
|
||||||
|
setFieldsForImage(viewModel.getImageViewModel());
|
||||||
} else {
|
} else {
|
||||||
setFieldsForNonImageDataSource();
|
setFieldsForNonImageDataSource();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
@ -222,55 +326,20 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
sha256HashValue.setText(NA);
|
sha256HashValue.setText(NA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void setFieldsForImage(ImageViewModel viewModel) {
|
||||||
* Sets text fields for an image. This should be called after
|
unallocatedSizeValue.setText(SizeRepresentationUtil.getSizeString(viewModel.getUnallocatedSize()));
|
||||||
* clearTableValues and before updateFieldVisibility to ensure the proper
|
imageTypeValue.setText(viewModel.getImageType());
|
||||||
* rendering.
|
sizeValue.setText(SizeRepresentationUtil.getSizeString(viewModel.getSize()));
|
||||||
*
|
sectorSizeValue.setText(SizeRepresentationUtil.getSizeString(viewModel.getSectorSize()));
|
||||||
* @param selectedImage The selected image.
|
timeZoneValue.setText(viewModel.getTimeZone());
|
||||||
* @param unallocatedFilesSize Unallocated file size in bytes.
|
|
||||||
*/
|
|
||||||
private void setFieldsForImage(Image selectedImage, Long unallocatedFilesSize) {
|
|
||||||
unallocatedSizeValue.setText(SizeRepresentationUtil.getSizeString(unallocatedFilesSize));
|
|
||||||
imageTypeValue.setText(selectedImage.getType().getName());
|
|
||||||
sizeValue.setText(SizeRepresentationUtil.getSizeString(selectedImage.getSize()));
|
|
||||||
sectorSizeValue.setText(SizeRepresentationUtil.getSizeString(selectedImage.getSsize()));
|
|
||||||
timeZoneValue.setText(selectedImage.getTimeZone());
|
|
||||||
|
|
||||||
for (String path : selectedImage.getPaths()) {
|
for (String path : viewModel.getPaths()) {
|
||||||
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
md5HashLabel.setText(viewModel.getMd5Hash());
|
||||||
//older databases may have null as the hash values
|
sha1HashValue.setText(viewModel.getSha1Hash());
|
||||||
String md5String = selectedImage.getMd5();
|
sha256HashValue.setText(viewModel.getSha256Hash());
|
||||||
if (md5String == null) {
|
|
||||||
md5String = "";
|
|
||||||
}
|
|
||||||
md5HashValue.setText(md5String);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String sha1String = selectedImage.getSha1();
|
|
||||||
if (sha1String == null) {
|
|
||||||
sha1String = "";
|
|
||||||
}
|
|
||||||
sha1HashValue.setText(sha1String);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String sha256String = selectedImage.getSha256();
|
|
||||||
if (sha256String == null) {
|
|
||||||
sha256String = "";
|
|
||||||
}
|
|
||||||
sha256HashValue.setText(sha256String);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,7 +361,6 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
((DefaultTableModel) filePathsTable.getModel()).setRowCount(0);
|
((DefaultTableModel) filePathsTable.getModel()).setRowCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static List<KeyValueItemExportable> getAcquisitionDetails(String acquisitionDetails) {
|
private static List<KeyValueItemExportable> getAcquisitionDetails(String acquisitionDetails) {
|
||||||
if (StringUtils.isBlank(acquisitionDetails)) {
|
if (StringUtils.isBlank(acquisitionDetails)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -316,34 +384,58 @@ class ContainerPanel extends BaseDataSourceSummaryPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DefaultCellModel<?> getBytesCell(Long bytes) {
|
||||||
|
if (bytes == null) {
|
||||||
|
return new DefaultCellModel<>("");
|
||||||
|
} else {
|
||||||
|
SizeUnit unit = SizeRepresentationUtil.getSizeUnit(bytes);
|
||||||
|
return new DefaultCellModel<>(bytes, unit.getExcelFormatString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<ExcelExport.ExcelSheetExport> getExports(DataSource ds) {
|
protected List<ExcelSheetExport> getExports(DataSource ds) {
|
||||||
ContainerPanelData result = getFetchResult(containerDataFetcher, "Container sheets", ds);
|
ContainerViewModel result = getFetchResult(containerDataFetcher, "Container sheets", ds);
|
||||||
if (ds == null || result == null) {
|
if (ds == null || result == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String NA = Bundle.ContainerPanel_setFieldsForNonImageDataSource_na();
|
||||||
|
DefaultCellModel<?> NACell = new DefaultCellModel<>(NA);
|
||||||
|
|
||||||
|
ImageViewModel imageModel = result.getImageViewModel();
|
||||||
|
boolean hasImage = imageModel != null;
|
||||||
|
|
||||||
|
DefaultCellModel<?> timeZone = hasImage ? new DefaultCellModel<>(imageModel.getTimeZone()) : NACell;
|
||||||
|
DefaultCellModel<?> imageType = hasImage ? new DefaultCellModel<>(imageModel.getImageType()) : NACell;
|
||||||
|
DefaultCellModel<?> size = hasImage ? getBytesCell(imageModel.getSize()) : NACell;
|
||||||
|
DefaultCellModel<?> sectorSize = hasImage ? getBytesCell(imageModel.getSectorSize()) : NACell;
|
||||||
|
DefaultCellModel<?> md5 = hasImage ? new DefaultCellModel<>(imageModel.getMd5Hash()) : NACell;
|
||||||
|
DefaultCellModel<?> sha1 = hasImage ? new DefaultCellModel<>(imageModel.getSha1Hash()) : NACell;
|
||||||
|
DefaultCellModel<?> sha256 = hasImage ? new DefaultCellModel<>(imageModel.getSha256Hash()) : NACell;
|
||||||
|
DefaultCellModel<?> unallocatedSize = hasImage ? getBytesCell(imageModel.getUnallocatedSize()) : NACell;
|
||||||
|
List<String> paths = result.getImageViewModel() == null ? Collections.singletonList(NA) : result.getImageViewModel().getPaths();
|
||||||
|
List<SingleCellExportable> cellPaths = paths.stream()
|
||||||
|
.map(SingleCellExportable::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new ExcelSpecialFormatExport(Bundle.ContainerPanel_tabName(), Arrays.asList(
|
new ExcelSpecialFormatExport(Bundle.ContainerPanel_tabName(), Arrays.asList(
|
||||||
new KeyValueItemExportable(Bundle.ContainerPanel_export_displayName(), ds.getName()),
|
new KeyValueItemExportable(Bundle.ContainerPanel_displayNameLabel_text(), result.getDisplayName()),
|
||||||
new KeyValueItemExportable(Bundle.ContainerPanel_export_originalName(), ds.getName()),
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_originalName(), result.getOriginalName()),
|
||||||
new KeyValueItemExportable(Bundle.ContainerPanel_export_deviceId(), ds.getDeviceId()),
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_deviceId(), result.getDeviceId()),
|
||||||
new KeyValueItemExportable(Bundle.ContainerPanel_export_timeZone(), ds.getTimeZone()),
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_timeZone(), timeZone),
|
||||||
|
new TitledExportable(Bundle.ContainerPanel_export_acquisitionDetails(), getAcquisitionDetails(result.getAcquisitionDetails())),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_imageType(), imageType),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_size(), size),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_sectorSize(), sectorSize),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_md5(), md5),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_sha1(), sha1),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_sha256(), sha256),
|
||||||
|
new KeyValueItemExportable(Bundle.ContainerPanel_export_unallocatedSize(), unallocatedSize),
|
||||||
|
new TitledExportable(Bundle.ContainerPanel_export_filePaths(), cellPaths)
|
||||||
|
)));
|
||||||
|
|
||||||
new TitledExportable(Bundle.ContainerPanel_export_acquisitionDetails(), getAcquisitionDetails(ds.getAcquisitionDetails())),
|
|
||||||
|
|
||||||
new KeyValueItemExportable()
|
|
||||||
imageTypeValue.setText("");
|
|
||||||
sizeValue.setText("");
|
|
||||||
sectorSizeValue.setText("");
|
|
||||||
md5HashValue.setText("");
|
|
||||||
sha1HashValue.setText("");
|
|
||||||
sha256HashValue.setText("");
|
|
||||||
unallocatedSizeValue.setText("");
|
|
||||||
((DefaultTableModel) filePathsTable.getModel()).setRowCount(0);
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,14 +32,45 @@ public final class SizeRepresentationUtil {
|
|||||||
private static final int SIZE_CONVERSION_CONSTANT = 1000;
|
private static final int SIZE_CONVERSION_CONSTANT = 1000;
|
||||||
private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##");
|
private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##");
|
||||||
|
|
||||||
private static List<String> UNITS = Arrays.asList(
|
// based on https://www.mrexcel.com/board/threads/how-do-i-format-cells-to-show-gb-mb-kb.140135/
|
||||||
Bundle.SizeRepresentationUtil_units_bytes(),
|
@NbBundle.Messages({
|
||||||
Bundle.SizeRepresentationUtil_units_kilobytes(),
|
"SizeRepresentationUtil_units_bytes=bytes",
|
||||||
Bundle.SizeRepresentationUtil_units_megabytes(),
|
"SizeRepresentationUtil_units_kilobytes=KB",
|
||||||
Bundle.SizeRepresentationUtil_units_gigabytes(),
|
"SizeRepresentationUtil_units_megabytes=MB",
|
||||||
Bundle.SizeRepresentationUtil_units_terabytes(),
|
"SizeRepresentationUtil_units_gigabytes=GB",
|
||||||
Bundle.SizeRepresentationUtil_units_petabytes()
|
"SizeRepresentationUtil_units_terabytes=TB",
|
||||||
);
|
"SizeRepresentationUtil_units_petabytes=PB"
|
||||||
|
})
|
||||||
|
public enum SizeUnit {
|
||||||
|
B(Bundle.SizeRepresentationUtil_units_bytes(), "#", 0),
|
||||||
|
KB(Bundle.SizeRepresentationUtil_units_kilobytes(), "#,##0.0,", 1),
|
||||||
|
MB(Bundle.SizeRepresentationUtil_units_megabytes(), "#,##0.0,,", 2),
|
||||||
|
GB(Bundle.SizeRepresentationUtil_units_gigabytes(), "#,##0.0,,,", 3),
|
||||||
|
TB(Bundle.SizeRepresentationUtil_units_terabytes(), "#,##0.0,,,,", 4),
|
||||||
|
PB(Bundle.SizeRepresentationUtil_units_petabytes(), "#,##0.0,,,,,", 5);
|
||||||
|
|
||||||
|
private final String suffix;
|
||||||
|
private final String excelFormatString;
|
||||||
|
private final long divisor;
|
||||||
|
|
||||||
|
SizeUnit(String suffix, String excelFormatString, int power) {
|
||||||
|
this.suffix = suffix;
|
||||||
|
this.excelFormatString = String.format("%s \"%s\"", excelFormatString, suffix);
|
||||||
|
this.divisor = (long) Math.pow(SIZE_CONVERSION_CONSTANT, power);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSuffix() {
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExcelFormatString() {
|
||||||
|
return excelFormatString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDivisor() {
|
||||||
|
return divisor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a long size in bytes as a string formated to be read by users.
|
* Get a long size in bytes as a string formated to be read by users.
|
||||||
@ -53,6 +84,22 @@ public final class SizeRepresentationUtil {
|
|||||||
return getSizeString(size, APPROXIMATE_SIZE_FORMAT, true);
|
return getSizeString(size, APPROXIMATE_SIZE_FORMAT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SizeUnit getSizeUnit(Long size) {
|
||||||
|
if (size == null) {
|
||||||
|
return SizeUnit.values()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int unitsIndex = 0; unitsIndex < SizeUnit.values().length; unitsIndex++) {
|
||||||
|
SizeUnit unit = SizeUnit.values()[unitsIndex];
|
||||||
|
long result = size / unit.getDivisor();
|
||||||
|
if (result < SIZE_CONVERSION_CONSTANT) {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizeUnit.values()[SizeUnit.values().length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a long size in bytes as a string formated to be read by users.
|
* Get a long size in bytes as a string formated to be read by users.
|
||||||
*
|
*
|
||||||
@ -64,33 +111,15 @@ public final class SizeRepresentationUtil {
|
|||||||
* @return Return a string formated with a user friendly version of the size
|
* @return Return a string formated with a user friendly version of the size
|
||||||
* as a string, returns empty String when provided empty size.
|
* as a string, returns empty String when provided empty size.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
|
||||||
"SizeRepresentationUtil_units_bytes= bytes",
|
|
||||||
"SizeRepresentationUtil_units_kilobytes= kB",
|
|
||||||
"SizeRepresentationUtil_units_megabytes= MB",
|
|
||||||
"SizeRepresentationUtil_units_gigabytes= GB",
|
|
||||||
"SizeRepresentationUtil_units_terabytes= TB",
|
|
||||||
"SizeRepresentationUtil_units_petabytes= PB"
|
|
||||||
})
|
|
||||||
public static String getSizeString(Long size, DecimalFormat format, boolean showFullSize) {
|
public static String getSizeString(Long size, DecimalFormat format, boolean showFullSize) {
|
||||||
if (size == null) {
|
if (size == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
double approximateSize = size;
|
|
||||||
int unitsIndex = 0;
|
|
||||||
for (; unitsIndex < UNITS.size(); unitsIndex++) {
|
|
||||||
if (approximateSize < SIZE_CONVERSION_CONSTANT) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
approximateSize /= SIZE_CONVERSION_CONSTANT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String fullSize = size + UNITS.get(0);
|
SizeUnit sizeUnit = getSizeUnit(size);
|
||||||
String closestUnitSize = format.format(approximateSize) + UNITS.get(unitsIndex);
|
|
||||||
|
|
||||||
if (unitsIndex == 0) {
|
if (sizeUnit == null || sizeUnit.equals(SizeUnit.B)) {
|
||||||
return fullSize;
|
return String.format("%d %s", size, SizeUnit.B.getSuffix());
|
||||||
} else if (showFullSize) {
|
} else if (showFullSize) {
|
||||||
return String.format("%s (%s)", closestUnitSize, fullSize);
|
return String.format("%s (%s)", closestUnitSize, fullSize);
|
||||||
} else {
|
} else {
|
||||||
|
@ -55,20 +55,38 @@ public class ExcelSpecialFormatExport implements ExcelExport.ExcelSheetExport {
|
|||||||
int write(Sheet sheet, int rowStart, int colStart, ExcelExport.WorksheetEnv env) throws ExcelExportException;
|
int write(Sheet sheet, int rowStart, int colStart, ExcelExport.WorksheetEnv env) throws ExcelExportException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SingleCellExportable implements ExcelItemExportable {
|
||||||
|
|
||||||
|
private final ExcelCellModel item;
|
||||||
|
|
||||||
|
public SingleCellExportable(String key) {
|
||||||
|
this(new DefaultCellModel<>(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleCellExportable(ExcelCellModel item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int write(Sheet sheet, int rowStart, int colStart, ExcelExport.WorksheetEnv env) throws ExcelExportException {
|
||||||
|
Row row = sheet.getRow(rowStart);
|
||||||
|
ExcelExport.createCell(row, colStart, item, Optional.empty());
|
||||||
|
return rowStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class KeyValueItemExportable implements ExcelItemExportable {
|
public static class KeyValueItemExportable implements ExcelItemExportable {
|
||||||
|
|
||||||
private final ExcelCellModel key;
|
private final ExcelCellModel key;
|
||||||
private final ExcelCellModel value;
|
private final ExcelCellModel value;
|
||||||
private final int colStart;
|
|
||||||
|
|
||||||
public KeyValueItemExportable(ExcelCellModel key, ExcelCellModel value) {
|
public KeyValueItemExportable(String key, ExcelCellModel value) {
|
||||||
this(key, value, 1);
|
this(new DefaultCellModel<>(key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValueItemExportable(ExcelCellModel key, ExcelCellModel value, int colStart) {
|
public KeyValueItemExportable(ExcelCellModel key, ExcelCellModel value) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.colStart = colStart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user