19 package org.sleuthkit.autopsy.datasourcesummary.ui;
21 import java.awt.Color;
22 import java.sql.SQLException;
23 import java.text.DecimalFormat;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import org.openide.util.NbBundle.Messages;
62 "TypesPanel_artifactsTypesPieChart_title=Artifact Types",
63 "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files",
64 "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files",
65 "TypesPanel_filesByCategoryTable_slackRow_title=Slack Files",
66 "TypesPanel_filesByCategoryTable_directoryRow_title=Directories",
67 "TypesPanel_fileMimeTypesChart_title=File Types",
68 "TypesPanel_fileMimeTypesChart_valueLabel=Count",
69 "TypesPanel_fileMimeTypesChart_audio_title=Audio",
70 "TypesPanel_fileMimeTypesChart_documents_title=Documents",
71 "TypesPanel_fileMimeTypesChart_executables_title=Executables",
72 "TypesPanel_fileMimeTypesChart_images_title=Images",
73 "TypesPanel_fileMimeTypesChart_videos_title=Videos",
74 "TypesPanel_fileMimeTypesChart_other_title=Other",
75 "TypesPanel_fileMimeTypesChart_unknown_title=Unknown",
76 "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed",
77 "TypesPanel_usageLabel_title=Usage",
78 "TypesPanel_osLabel_title=OS",
79 "TypesPanel_sizeLabel_title=Size",
80 "TypesPanel_excelTabName=Types"})
81 class TypesPanel extends BaseDataSourceSummaryPanel {
99 this.pieSlices = pieSlices;
100 this.usefulContent = usefulContent;
114 return usefulContent;
136 this.mimeTypes = mimeTypes;
161 Set<String> getMimeTypes() {
173 private static final long serialVersionUID = 1L;
174 private static final DecimalFormat INTEGER_SIZE_FORMAT =
new DecimalFormat(
"#");
175 private static final String COMMA_FORMAT_STR =
"#,###";
177 private static final DecimalFormat COMMA_FORMATTER =
new DecimalFormat(COMMA_FORMAT_STR);
179 private static final Color IMAGES_COLOR =
new Color(156, 39, 176);
180 private static final Color VIDEOS_COLOR = Color.YELLOW;
181 private static final Color AUDIO_COLOR = Color.BLUE;
182 private static final Color DOCUMENTS_COLOR = Color.GREEN;
183 private static final Color EXECUTABLES_COLOR =
new Color(0, 188, 212);
184 private static final Color UNKNOWN_COLOR = Color.ORANGE;
185 private static final Color OTHER_COLOR =
new Color(78, 52, 46);
186 private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
189 private static final List<TypesPieCategory> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
190 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
191 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
192 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
193 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
194 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
195 new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(),
new HashSet<>(Arrays.asList(
"application/octet-stream")), UNKNOWN_COLOR)
198 private final DataFetcher<DataSource, String> usageFetcher;
199 private final DataFetcher<DataSource, String> osFetcher;
200 private final DataFetcher<DataSource, Long> sizeFetcher;
202 private final DataFetcher<DataSource, TypesPieChartData> typesFetcher;
204 private final DataFetcher<DataSource, Long> allocatedFetcher;
205 private final DataFetcher<DataSource, Long> unallocatedFetcher;
206 private final DataFetcher<DataSource, Long> slackFetcher;
207 private final DataFetcher<DataSource, Long> directoriesFetcher;
209 private final LoadableLabel usageLabel =
new LoadableLabel(Bundle.TypesPanel_usageLabel_title());
210 private final LoadableLabel osLabel =
new LoadableLabel(Bundle.TypesPanel_osLabel_title());
211 private final LoadableLabel sizeLabel =
new LoadableLabel(Bundle.TypesPanel_sizeLabel_title());
213 private final PieChartPanel fileMimeTypesChart =
new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title());
215 private final LoadableLabel allocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title());
216 private final LoadableLabel unallocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title());
217 private final LoadableLabel slackLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_slackRow_title());
218 private final LoadableLabel directoriesLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title());
221 private final List<LoadableComponent<?>> loadables = Arrays.asList(
232 private final IngestRunningLabel ingestRunningLabel =
new IngestRunningLabel();
235 private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
240 public TypesPanel() {
241 this(
new MimeTypeSummary(),
new TypesSummary(),
new ContainerSummary());
245 public void close() {
246 ingestRunningLabel.unregister();
258 MimeTypeSummary mimeTypeData,
259 TypesSummary typeData,
260 ContainerSummary containerData) {
262 super(mimeTypeData, typeData, containerData);
264 this.usageFetcher = containerData::getDataSourceType;
265 this.osFetcher = containerData::getOperatingSystems;
267 this.sizeFetcher = (dataSource) -> dataSource == null ? null : dataSource.getSize();
269 this.typesFetcher = (dataSource) -> getMimeTypeCategoriesModel(mimeTypeData, dataSource);
271 this.allocatedFetcher = (dataSource) -> typeData.getCountOfAllocatedFiles(dataSource);
272 this.unallocatedFetcher = (dataSource) -> typeData.getCountOfUnallocatedFiles(dataSource);
273 this.slackFetcher = (dataSource) -> typeData.getCountOfSlackFiles(dataSource);
274 this.directoriesFetcher = (dataSource) -> typeData.getCountOfDirectories(dataSource);
276 this.dataFetchComponents = Arrays.asList(
277 new DataFetchWorker.DataFetchComponents<>(usageFetcher, usageLabel::showDataFetchResult),
278 new DataFetchWorker.DataFetchComponents<>(osFetcher, osLabel::showDataFetchResult),
279 new DataFetchWorker.DataFetchComponents<>(sizeFetcher,
280 (sizeResult) -> sizeLabel.showDataFetchResult(
281 DataFetchResult.getSubResult(sizeResult,
282 size -> SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT,
false)))),
283 new DataFetchWorker.DataFetchComponents<>(typesFetcher, this::showMimeTypeCategories),
284 new DataFetchWorker.DataFetchComponents<>(allocatedFetcher,
285 countRes -> allocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
286 new DataFetchWorker.DataFetchComponents<>(unallocatedFetcher,
287 countRes -> unallocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
288 new DataFetchWorker.DataFetchComponents<>(slackFetcher,
289 countRes -> slackLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count)))),
290 new DataFetchWorker.DataFetchComponents<>(directoriesFetcher,
291 countRes -> directoriesLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> getStringOrZero(count))))
298 protected void fetchInformation(DataSource dataSource) {
299 fetchInformation(dataFetchComponents, dataSource);
303 protected void onNewDataSource(DataSource dataSource) {
304 onNewDataSource(dataFetchComponents, loadables, dataSource);
315 private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummary mimeTypeData, DataSource dataSource)
316 throws SQLException, SleuthkitCaseProviderException, TskCoreException {
318 if (dataSource == null) {
323 List<PieChartItem> fileCategoryItems =
new ArrayList<>();
324 long categoryTotalCount = 0;
326 for (TypesPieCategory cat : FILE_MIME_TYPE_CATEGORIES) {
327 long thisValue = getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
328 categoryTotalCount += thisValue;
330 fileCategoryItems.add(
new PieChartItem(
337 long noMimeTypeCount = getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
340 long allRegularFiles = getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
343 long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
344 PieChartItem otherPieItem =
new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_other_title(),
345 otherCount, OTHER_COLOR);
348 boolean usefulContent = categoryTotalCount > 0 || otherCount > 0;
351 PieChartItem notAnalyzedItem =
new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(),
352 noMimeTypeCount, NOT_ANALYZED_COLOR);
355 List<PieChartItem> items = Stream.concat(
356 fileCategoryItems.stream(),
357 Stream.of(otherPieItem, notAnalyzedItem))
359 .filter(slice -> slice.getValue() > 0)
360 .collect(Collectors.toList());
362 return new TypesPieChartData(items, usefulContent);
373 private void showMimeTypeCategories(DataFetchResult<TypesPieChartData> result) {
374 if (result == null) {
375 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
380 if (result.getResultType() == ResultType.ERROR) {
381 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getErrorResult(result.getException()));
385 TypesPieChartData data = result.getData();
387 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
389 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(data.getPieSlices()));
400 private static long getLongOrZero(Long longVal) {
401 return longVal == null ? 0 : longVal;
412 private static String getStringOrZero(Long longVal) {
413 return longVal == null ?
"0" : COMMA_FORMATTER.format(longVal);
424 private static KeyValueItemExportable getStrExportable(DataFetcher<DataSource, String> fetcher, String key, DataSource dataSource) {
425 String result = getFetchResult(fetcher,
"Types", dataSource);
426 return (result == null) ? null :
new KeyValueItemExportable(key,
new DefaultCellModel<>(result));
438 private static KeyValueItemExportable getCountExportable(DataFetcher<DataSource, Long> fetcher, String key, DataSource dataSource) {
439 Long count = getFetchResult(fetcher,
"Types", dataSource);
440 return (count == null) ? null :
new KeyValueItemExportable(key,
441 new DefaultCellModel<Long>(count, COMMA_FORMATTER::format, COMMA_FORMAT_STR));
445 List<ExcelExport.ExcelSheetExport> getExports(DataSource dataSource) {
446 if (dataSource == null) {
447 return Collections.emptyList();
451 TypesPieChartData typesData = TypesPanel.getFetchResult(typesFetcher,
"Types", dataSource);
452 PieChartExport typesChart = (typesData == null || !typesData.isUsefulContent()) ? null :
454 Bundle.TypesPanel_fileMimeTypesChart_title(),
455 Bundle.TypesPanel_fileMimeTypesChart_valueLabel(),
457 Bundle.TypesPanel_fileMimeTypesChart_title(),
458 typesData.getPieSlices());
460 return Arrays.asList(
new ExcelSpecialFormatExport(Bundle.TypesPanel_excelTabName(),
462 getStrExportable(usageFetcher, Bundle.TypesPanel_usageLabel_title(), dataSource),
463 getStrExportable(osFetcher, Bundle.TypesPanel_osLabel_title(), dataSource),
464 new KeyValueItemExportable(Bundle.TypesPanel_sizeLabel_title(),
465 SizeRepresentationUtil.getBytesCell(getFetchResult(sizeFetcher,
"Types", dataSource))),
467 getCountExportable(allocatedFetcher, Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title(), dataSource),
468 getCountExportable(unallocatedFetcher, Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title(), dataSource),
469 getCountExportable(slackFetcher, Bundle.TypesPanel_filesByCategoryTable_slackRow_title(), dataSource),
470 getCountExportable(directoriesFetcher, Bundle.TypesPanel_filesByCategoryTable_directoryRow_title(), dataSource))
471 .filter(sheet -> sheet != null)
472 .collect(Collectors.toList())
481 @SuppressWarnings(
"unchecked")
483 private
void initComponents() {
485 javax.swing.JScrollPane scrollParent =
new javax.swing.JScrollPane();
486 javax.swing.JPanel contentParent =
new javax.swing.JPanel();
487 javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
488 javax.swing.JPanel usagePanel = usageLabel;
489 javax.swing.JPanel osPanel = osLabel;
490 javax.swing.JPanel sizePanel = sizeLabel;
491 javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart;
492 javax.swing.Box.Filler filler2 =
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 5),
new java.awt.Dimension(0, 5),
new java.awt.Dimension(32767, 5));
493 javax.swing.JPanel allocatedPanel = allocatedLabel;
494 javax.swing.JPanel unallocatedPanel = unallocatedLabel;
495 javax.swing.JPanel slackPanel = slackLabel;
496 javax.swing.JPanel directoriesPanel = directoriesLabel;
497 javax.swing.Box.Filler filler3 =
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 0),
new java.awt.Dimension(0, 32767));
499 setLayout(
new java.awt.BorderLayout());
501 contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
502 contentParent.setMaximumSize(
new java.awt.Dimension(32787, 32787));
503 contentParent.setMinimumSize(
new java.awt.Dimension(400, 490));
504 contentParent.setLayout(
new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS));
506 ingestRunningPanel.setAlignmentX(0.0F);
507 ingestRunningPanel.setMaximumSize(
new java.awt.Dimension(32767, 25));
508 ingestRunningPanel.setMinimumSize(
new java.awt.Dimension(10, 25));
509 ingestRunningPanel.setPreferredSize(
new java.awt.Dimension(10, 25));
510 contentParent.add(ingestRunningPanel);
512 usagePanel.setAlignmentX(0.0F);
513 usagePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
514 usagePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
515 usagePanel.setName(
"");
516 usagePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
517 contentParent.add(usagePanel);
519 osPanel.setAlignmentX(0.0F);
520 osPanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
521 osPanel.setMinimumSize(
new java.awt.Dimension(10, 20));
522 osPanel.setPreferredSize(
new java.awt.Dimension(800, 20));
523 contentParent.add(osPanel);
525 sizePanel.setAlignmentX(0.0F);
526 sizePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
527 sizePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
528 sizePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
529 contentParent.add(sizePanel);
531 fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
532 fileMimeTypesPanel.setAlignmentX(0.0F);
533 fileMimeTypesPanel.setMaximumSize(
new java.awt.Dimension(400, 300));
534 fileMimeTypesPanel.setMinimumSize(
new java.awt.Dimension(400, 300));
535 fileMimeTypesPanel.setPreferredSize(
new java.awt.Dimension(400, 300));
536 contentParent.add(fileMimeTypesPanel);
537 contentParent.add(filler2);
539 allocatedPanel.setAlignmentX(0.0F);
540 allocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
541 allocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
542 allocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
543 contentParent.add(allocatedPanel);
545 unallocatedPanel.setAlignmentX(0.0F);
546 unallocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
547 unallocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
548 unallocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
549 contentParent.add(unallocatedPanel);
551 slackPanel.setAlignmentX(0.0F);
552 slackPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
553 slackPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
554 slackPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
555 contentParent.add(slackPanel);
557 directoriesPanel.setAlignmentX(0.0F);
558 directoriesPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
559 directoriesPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
560 directoriesPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
561 contentParent.add(directoriesPanel);
562 contentParent.add(filler3);
564 scrollParent.setViewportView(contentParent);
566 add(scrollParent, java.awt.BorderLayout.CENTER);
final List< PieChartItem > pieSlices
boolean isUsefulContent()
List< PieChartItem > getPieSlices()
final boolean usefulContent
ImmutableSet< String > getMediaTypes()
TypesPieChartData(List< PieChartItem > pieSlices, boolean usefulContent)
final Set< String > mimeTypes