formatting, commenting, and refactoring

This commit is contained in:
Greg DiCristofaro 2021-03-22 08:28:46 -04:00
parent e6500c41ce
commit 2ab62fce47
10 changed files with 199 additions and 63 deletions

View File

@ -18,7 +18,6 @@
*/
package org.sleuthkit.autopsy.datasourcesummary.ui;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
@ -34,6 +33,7 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle;
@ -186,7 +186,9 @@ class ExcelExportAction implements Consumer<DataSource> {
"# {0} - dataSource",
"ExcelExportAction_runXLSXExport_progressTitle=Exporting {0} to XLSX",
"ExcelExportAction_runXLSXExport_progressCancelTitle=Cancel",
"ExcelExportAction_runXLSXExport_progressCancelActionTitle=Cancelling..."
"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) {
@ -213,6 +215,10 @@ class ExcelExportAction implements Consumer<DataSource> {
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 {

View File

@ -291,6 +291,13 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
super.close();
}
/**
* Create a default cell model to be use with excel export in the earliest /
* latest date format.
*
* @param date The date.
* @return The cell model.
*/
private static DefaultCellModel<?> getEarliestLatestCell(Date date) {
return new DefaultCellModel<>(date, (dt) -> dt == null ? "" : EARLIEST_LATEST_FORMAT.format(dt), EARLIEST_LATEST_FORMAT_STR);
}

View File

@ -447,6 +447,7 @@ class TypesPanel extends BaseDataSourceSummaryPanel {
return Collections.emptyList();
}
// Retrieve data to create the types pie chart
TypesPieChartData typesData = TypesPanel.getFetchResult(typesFetcher, "Types", dataSource);
PieChartExport typesChart = (typesData == null || !typesData.isUsefulContent()) ? null :
new PieChartExport(

View File

@ -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;
@ -42,35 +55,26 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.ItemDimensions;
/**
*
* @author gregd
* Class that creates an excel stacked bar chart along with data table.
*/
public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
private final ExcelTableExport<Pair<Object, List<Double>>, ? extends ExcelCellModel> tableExport;
private final int colOffset;
private final int rowPadding;
private final int colSize;
private final int rowSize;
private final String chartTitle;
private final String sheetName;
private final List<BarChartSeries> categories;
private final String keyColumnHeader;
public BarChartExport(String keyColumnHeader,
String valueFormatString,
String chartTitle,
List<BarChartSeries> categories) {
this(keyColumnHeader, valueFormatString, chartTitle, chartTitle, categories, 1, 1, 8, 10);
}
public BarChartExport(String keyColumnHeader, String valueFormatString,
String chartTitle, String sheetName,
List<BarChartSeries> categories,
int colOffset, int rowPadding, int colSize, int rowSize) {
this.keyColumnHeader = keyColumnHeader;
/**
* Creates an excel table model to be written to an excel sheet and used as
* a datasource for the chart.
*
* @param categories The categories with their data.
* @param keyColumnHeader The header column name for the table descriptions
* (i.e. types: file types / artifact types).
* @param valueFormatString The excel format string to use for values.
* @return An excel table export to be used as the data source for the chart
* in the excel document.
*/
private static ExcelTableExport<Pair<Object, List<Double>>, ? extends ExcelCellModel> getTableModel(
List<BarChartSeries> categories, String keyColumnHeader, String chartTitle) {
// get the row keys by finding the series with the largest set of bar items
// (they should all be equal, but just in case)
List<? extends Object> rowKeys = categories.stream()
.filter(cat -> cat != null && cat.getItems() != null)
.map(cat -> cat.getItems())
@ -80,7 +84,7 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
.map((barChartItem) -> barChartItem.getKey())
.collect(Collectors.toList());
// map of (category, item) -> value
// map of (bar chart category index, bar chart item index) -> value
Map<Pair<Integer, Integer>, Double> valueMap = IntStream.range(0, categories.size())
.mapToObj(idx -> Pair.of(idx, categories.get(idx)))
.filter(pair -> pair.getValue() != null && pair.getValue().getItems() != null)
@ -88,11 +92,13 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
return IntStream.range(0, categoryPair.getValue().getItems().size())
.mapToObj(idx -> Pair.of(idx, categoryPair.getValue().getItems().get(idx)))
.map(itemPair -> Pair.of(
Pair.of(categoryPair.getKey(), itemPair.getKey()),
itemPair.getValue() == null ? null : itemPair.getValue().getValue()));
Pair.of(categoryPair.getKey(), itemPair.getKey()),
itemPair.getValue() == null ? null : itemPair.getValue().getValue()));
})
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue(), (v1, v2) -> v1));
// Create rows of data to be displayed where each row is a tuple of the bar chart item
// key and the list of values in category order.
List<Pair<Object, List<Double>>> values = IntStream.range(0, rowKeys.size())
.mapToObj(idx -> Pair.of(idx, rowKeys.get(idx)))
.map((rowPair) -> {
@ -104,20 +110,80 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
})
.collect(Collectors.toList());
ColumnModel<Pair<Object, List<Double>>, DefaultCellModel<?>> categoryColumn = new ColumnModel<>(keyColumnHeader, (row) -> new DefaultCellModel<>(row.getKey()));
// Create the model for the category column
ColumnModel<Pair<Object, List<Double>>, DefaultCellModel<?>> categoryColumn
= new ColumnModel<>(keyColumnHeader, (row) -> new DefaultCellModel<>(row.getKey()));
// create the models for each category of data to be displayed
Stream<ColumnModel<Pair<Object, List<Double>>, DefaultCellModel<?>>> dataColumns = IntStream.range(0, categories.size())
.mapToObj(idx -> new ColumnModel<>(
categories.get(idx).getKey().toString(),
(row) -> new DefaultCellModel<>(row.getValue().get(idx))));
this.tableExport = new ExcelTableExport<Pair<Object, List<Double>>, DefaultCellModel<?>>(
// create table
return new ExcelTableExport<Pair<Object, List<Double>>, DefaultCellModel<?>>(
chartTitle,
Stream.concat(Stream.of(categoryColumn), dataColumns)
.collect(Collectors.toList()),
values
);
}
private static final int DEFAULT_ROW_SIZE = 8;
private static final int DEFAULT_COL_SIZE = 15;
private static final int DEFAULT_ROW_PADDING = 1;
private static final int DEFAULT_COL_OFFSET = 1;
private final ExcelTableExport<Pair<Object, List<Double>>, ? extends ExcelCellModel> tableExport;
private final int colOffset;
private final int rowPadding;
private final int colSize;
private final int rowSize;
private final String chartTitle;
private final String sheetName;
private final List<BarChartSeries> categories;
private final String keyColumnHeader;
/**
* Main constructor that assumes some defaults (i.e. chart size follows
* defaults and sheet name is chart title).
*
* @param keyColumnHeader The header column name for the table descriptions
* (i.e. types: file types / artifact types).
* @param valueFormatString The excel format string to use for values.
* @param chartTitle The title for the chart.
* @param categories The categories along with data.
*/
public BarChartExport(String keyColumnHeader,
String valueFormatString,
String chartTitle,
List<BarChartSeries> categories) {
this(keyColumnHeader, valueFormatString, chartTitle, chartTitle, categories,
DEFAULT_COL_OFFSET, DEFAULT_ROW_PADDING, DEFAULT_COL_SIZE, DEFAULT_ROW_SIZE);
}
/**
* Main constructor.
*
* @param keyColumnHeader The header column name for the table descriptions
* (i.e. types: file types / artifact types).
* @param valueFormatString The excel format string to use for values.
* @param chartTitle The title for the chart.
* @param sheetName The sheet name if used as a sheet export.
* @param categories The categories along with data.
* @param colOffset The column spacing between the table and the chart.
* @param rowPadding The padding between this and data above or below (if
* used as an ExcelItemExportable).
* @param colSize The column size of the chart.
* @param rowSize The row size of the chart.
*/
public BarChartExport(String keyColumnHeader, String valueFormatString,
String chartTitle, String sheetName,
List<BarChartSeries> categories,
int colOffset, int rowPadding, int colSize, int rowSize) {
this.keyColumnHeader = keyColumnHeader;
this.tableExport = getTableModel(categories, keyColumnHeader, chartTitle);
this.colOffset = colOffset;
this.rowPadding = rowPadding;
this.colSize = colSize;
@ -152,7 +218,7 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
int chartColStart = colStart + categories.size() + 1 + colOffset;
//createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
//createAnchor has arguments of (int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, chartColStart, rowStart + rowPadding, chartColStart + colSize, rowStart + rowSize);
XSSFChart chart = drawing.createChart(anchor);
@ -178,6 +244,7 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
data.setBarDirection(BarDirection.COL);
// set data for each series and set color if applicable
for (int i = 0; i < categories.size(); i++) {
XDDFChartData.Series series = data.addSeries(headerSource,
XDDFDataSourcesFactory.fromNumericCellRange(xssfSheet,

View File

@ -39,7 +39,6 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartSeries.BarChartIt
*/
public class BarChartPanel extends AbstractLoadableComponent<List<BarChartSeries>> {
/**
* JFreeChart bar charts don't preserve the order of bars provided to the
* chart, but instead uses the comparable nature to order items. This

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -23,8 +23,7 @@ import java.util.Collections;
import java.util.List;
/**
* Represents a series in a bar chart where all items pertain to one
* category.
* Represents a series in a bar chart where all items pertain to one category.
*/
public class BarChartSeries {
@ -98,5 +97,5 @@ public class BarChartSeries {
public Comparable<?> getKey() {
return key;
}
}

View File

@ -123,7 +123,6 @@ public class ExcelTableExport<T, C extends ExcelCellModel> implements ExcelSheet
}
// 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);

View File

@ -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;
@ -29,10 +42,15 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.
/**
*
* @author gregd
* Class that creates an excel pie chart along with data table.
*/
public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
private static final int DEFAULT_ROW_SIZE = 8;
private static final int DEFAULT_COL_SIZE = 15;
private static final int DEFAULT_ROW_PADDING = 1;
private static final int DEFAULT_COL_OFFSET = 1;
private final ExcelTableExport<PieChartItem, ? extends ExcelCellModel> tableExport;
private final int colOffset;
private final int rowPadding;
@ -41,13 +59,40 @@ public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
private final String chartTitle;
private final String sheetName;
/**
* Main constructor assuming defaults.
*
* @param keyColumnHeader The header column name for the table descriptions
* (i.e. file types).
* @param valueColumnHeader The header column name for the values.
* @param valueFormatString The excel format string to use for values.
* @param chartTitle The title for the chart.
* @param slices The values for the pie slices.
*/
public PieChartExport(String keyColumnHeader,
String valueColumnHeader, String valueFormatString,
String chartTitle,
List<PieChartItem> slices) {
this(keyColumnHeader, valueColumnHeader, valueFormatString, chartTitle, chartTitle, slices, 1, 1, 8, 14);
this(keyColumnHeader, valueColumnHeader, valueFormatString, chartTitle, chartTitle, slices,
DEFAULT_COL_OFFSET, DEFAULT_ROW_PADDING, DEFAULT_COL_SIZE, DEFAULT_ROW_SIZE);
}
/**
* Main constructor.
*
* @param keyColumnHeader The header column name for the table descriptions
* (i.e. file types).
* @param valueColumnHeader The header column name for the values.
* @param valueFormatString The excel format string to use for values.
* @param chartTitle The title for the chart.
* @param sheetName The sheet name if used as a sheet export.
* @param slices The values for the pie slices.
* @param colOffset The column spacing between the table and the chart.
* @param rowPadding The padding between this and data above or below (if
* used as an ExcelItemExportable).
* @param colSize The column size of the chart.
* @param rowSize The row size of the chart.
*/
public PieChartExport(String keyColumnHeader,
String valueColumnHeader, String valueFormatString,
String chartTitle, String sheetName,
@ -93,7 +138,7 @@ public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
int chartColStart = colStart + 2 + colOffset;
//createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
//createAnchor has arguments of (int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, chartColStart, rowStart + rowPadding, chartColStart + colSize, rowStart + rowSize);
XSSFChart chart = drawing.createChart(anchor);
@ -102,7 +147,7 @@ public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.RIGHT);
// (int firstRow, int lastRow, int firstCol, int lastCol)
// CellRangeAddress has arguments of (int firstRow, int lastRow, int firstCol, int lastCol)
XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromStringCellRange(xssfSheet,
new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
tableDimensions.getColStart(), tableDimensions.getColStart()));
@ -111,13 +156,14 @@ public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
tableDimensions.getColStart() + 1, tableDimensions.getColStart() + 1));
// XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
// XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
// NOTE: these can be null parameters to chart.createData in poi >= 4.1.1
//XDDFPieChartData data = (XDDFPieChartData) chart.createData(ChartTypes.PIE, bottomAxis, leftAxis);
// NOTE: There appears to be a classpath issue with POI (a version of 4.0.1 and 4.1.1 simultaneously)
// that is causing conflicts for XDDFPieChartData creation (i.e. the compiler thinks its using 4.1.1
// and the runtime thinks its using 4.0.1) Reflection is used below to use the 4.0.1 method while
// sidestepping compiler issues.
// XDDFPieChartData creation that can be used in poi >= 4.1.1:
// XDDFPieChartData data = (XDDFPieChartData) chart.createData(ChartTypes.PIE, bottomAxis, leftAxis);
// XDDFPieChartData creation that can be used in 4.0.1:
// XDDFPieChartData data = new XDDFPieChartData(chart.getCTChart().getPlotArea().addNewPieChart());
XDDFPieChartData data;
try {
Constructor<XDDFPieChartData> constructor = XDDFPieChartData.class.getConstructor(CTPieChart.class);
@ -126,7 +172,7 @@ public class PieChartExport implements ExcelItemExportable, ExcelSheetExport {
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException | IllegalArgumentException ex) {
throw new ExcelExportException("Error while instantiating chart data.", ex);
}
data.setVaryColors(true);
data.addSeries(cat, val);

View File

@ -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;
@ -50,5 +63,5 @@ public class PieChartItem {
public Color getColor() {
return color;
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019 Basis Technology Corp.
* Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -41,7 +41,6 @@ import org.openide.util.NbBundle.Messages;
})
public class PieChartPanel extends AbstractLoadableComponent<List<PieChartItem>> {
private static final long serialVersionUID = 1L;
private static final Font DEFAULT_FONT = new JLabel().getFont();