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.HashSet;
27 import java.util.List;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30 import org.openide.util.NbBundle.Messages;
54 "TypesPanel_artifactsTypesPieChart_title=Artifact Types",
55 "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files",
56 "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files",
57 "TypesPanel_filesByCategoryTable_slackRow_title=Slack Files",
58 "TypesPanel_filesByCategoryTable_directoryRow_title=Directories",
59 "TypesPanel_fileMimeTypesChart_title=File Types",
60 "TypesPanel_fileMimeTypesChart_valueLabel=Count",
61 "TypesPanel_fileMimeTypesChart_audio_title=Audio",
62 "TypesPanel_fileMimeTypesChart_documents_title=Documents",
63 "TypesPanel_fileMimeTypesChart_executables_title=Executables",
64 "TypesPanel_fileMimeTypesChart_images_title=Images",
65 "TypesPanel_fileMimeTypesChart_videos_title=Videos",
66 "TypesPanel_fileMimeTypesChart_other_title=Other",
67 "TypesPanel_fileMimeTypesChart_unknown_title=Unknown",
68 "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed",
69 "TypesPanel_usageLabel_title=Usage",
70 "TypesPanel_osLabel_title=OS",
71 "TypesPanel_sizeLabel_title=Size",
72 "TypesPanel_excelTabName=Types"})
73 class TypesPanel extends BaseDataSourceSummaryPanel {
91 this.pieSlices = pieSlices;
92 this.usefulContent = usefulContent;
98 List<PieChartItem> getPieSlices() {
105 boolean isUsefulContent() {
106 return usefulContent;
110 private static final long serialVersionUID = 1L;
111 private static final DecimalFormat INTEGER_SIZE_FORMAT =
new DecimalFormat(
"#");
113 private static final Color IMAGES_COLOR =
new Color(156, 39, 176);
114 private static final Color VIDEOS_COLOR = Color.YELLOW;
115 private static final Color AUDIO_COLOR = Color.BLUE;
116 private static final Color DOCUMENTS_COLOR = Color.GREEN;
117 private static final Color EXECUTABLES_COLOR =
new Color(0, 188, 212);
118 private static final Color UNKNOWN_COLOR = Color.ORANGE;
119 private static final Color OTHER_COLOR =
new Color(78, 52, 46);
120 private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
123 private static final List<FileTypeCategoryData> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
124 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
125 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
126 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
127 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
128 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
129 new FileTypeCategoryData(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(),
new HashSet<>(Arrays.asList(
"application/octet-stream")), UNKNOWN_COLOR)
132 private final DataFetcher<DataSource, String> usageFetcher;
133 private final DataFetcher<DataSource, String> osFetcher;
134 private final DataFetcher<DataSource, Long> sizeFetcher;
136 private final DataFetcher<DataSource, TypesPieChartData> typesFetcher;
138 private final DataFetcher<DataSource, Long> allocatedFetcher;
139 private final DataFetcher<DataSource, Long> unallocatedFetcher;
140 private final DataFetcher<DataSource, Long> slackFetcher;
141 private final DataFetcher<DataSource, Long> directoriesFetcher;
143 private final LoadableLabel usageLabel =
new LoadableLabel(Bundle.TypesPanel_usageLabel_title());
144 private final LoadableLabel osLabel =
new LoadableLabel(Bundle.TypesPanel_osLabel_title());
145 private final LoadableLabel sizeLabel =
new LoadableLabel(Bundle.TypesPanel_sizeLabel_title());
147 private final PieChartPanel fileMimeTypesChart =
new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title());
149 private final LoadableLabel allocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title());
150 private final LoadableLabel unallocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title());
151 private final LoadableLabel slackLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_slackRow_title());
152 private final LoadableLabel directoriesLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title());
155 private final List<LoadableComponent<?>> loadables = Arrays.asList(
166 private final IngestRunningLabel ingestRunningLabel =
new IngestRunningLabel();
169 private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
175 this(
new MimeTypeSummaryGetter(),
new TypesSummaryGetter(),
new ContainerSummaryGetter());
179 public void close() {
180 ingestRunningLabel.unregister();
192 MimeTypeSummaryGetter mimeTypeData,
193 TypesSummaryGetter typeData,
194 ContainerSummaryGetter containerData) {
196 super(mimeTypeData, typeData, containerData);
198 this.usageFetcher = containerData::getDataSourceType;
199 this.osFetcher = containerData::getOperatingSystems;
201 this.sizeFetcher = (dataSource) -> dataSource == null ? null : dataSource.getSize();
203 this.typesFetcher = (dataSource) -> getMimeTypeCategoriesModel(mimeTypeData, dataSource);
205 this.allocatedFetcher = (dataSource) -> typeData.getCountOfAllocatedFiles(dataSource);
206 this.unallocatedFetcher = (dataSource) -> typeData.getCountOfUnallocatedFiles(dataSource);
207 this.slackFetcher = (dataSource) -> typeData.getCountOfSlackFiles(dataSource);
208 this.directoriesFetcher = (dataSource) -> typeData.getCountOfDirectories(dataSource);
210 this.dataFetchComponents = Arrays.asList(
211 new DataFetchWorker.DataFetchComponents<>(usageFetcher, usageLabel::showDataFetchResult),
212 new DataFetchWorker.DataFetchComponents<>(osFetcher, osLabel::showDataFetchResult),
213 new DataFetchWorker.DataFetchComponents<>(sizeFetcher,
214 (sizeResult) -> sizeLabel.showDataFetchResult(
215 DataFetchResult.getSubResult(sizeResult,
216 size -> SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT,
false)))),
217 new DataFetchWorker.DataFetchComponents<>(typesFetcher, this::showMimeTypeCategories),
218 new DataFetchWorker.DataFetchComponents<>(allocatedFetcher,
219 countRes -> allocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
220 new DataFetchWorker.DataFetchComponents<>(unallocatedFetcher,
221 countRes -> unallocatedLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
222 new DataFetchWorker.DataFetchComponents<>(slackFetcher,
223 countRes -> slackLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count)))),
224 new DataFetchWorker.DataFetchComponents<>(directoriesFetcher,
225 countRes -> directoriesLabel.showDataFetchResult(DataFetchResult.getSubResult(countRes, (count) -> DataSourceInfoUtilities.getStringOrZero(count))))
232 protected void fetchInformation(DataSource dataSource) {
233 fetchInformation(dataFetchComponents, dataSource);
237 protected void onNewDataSource(DataSource dataSource) {
238 onNewDataSource(dataFetchComponents, loadables, dataSource);
249 private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummaryGetter mimeTypeData, DataSource dataSource)
250 throws SQLException, SleuthkitCaseProviderException, TskCoreException {
252 if (dataSource == null) {
257 List<PieChartItem> fileCategoryItems =
new ArrayList<>();
258 long categoryTotalCount = 0;
260 for (FileTypeCategoryData cat : FILE_MIME_TYPE_CATEGORIES) {
261 long thisValue = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
262 categoryTotalCount += thisValue;
264 fileCategoryItems.add(
new PieChartItem(
271 long noMimeTypeCount = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
274 long allRegularFiles = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
277 long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
278 PieChartItem otherPieItem =
new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_other_title(),
279 otherCount, OTHER_COLOR);
282 boolean usefulContent = categoryTotalCount > 0 || otherCount > 0;
285 PieChartItem notAnalyzedItem =
new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(),
286 noMimeTypeCount, NOT_ANALYZED_COLOR);
289 List<PieChartItem> items = Stream.concat(
290 fileCategoryItems.stream(),
291 Stream.of(otherPieItem, notAnalyzedItem))
293 .filter(slice -> slice.getValue() > 0)
294 .collect(Collectors.toList());
296 return new TypesPieChartData(items, usefulContent);
307 private void showMimeTypeCategories(DataFetchResult<TypesPieChartData> result) {
308 if (result == null) {
309 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
314 if (result.getResultType() == ResultType.ERROR) {
315 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getErrorResult(result.getException()));
319 TypesPieChartData data = result.getData();
321 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
323 fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(data.getPieSlices()));
332 @SuppressWarnings(
"unchecked")
334 private
void initComponents() {
336 javax.swing.JScrollPane scrollParent =
new javax.swing.JScrollPane();
337 javax.swing.JPanel contentParent =
new javax.swing.JPanel();
338 javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
339 javax.swing.JPanel usagePanel = usageLabel;
340 javax.swing.JPanel osPanel = osLabel;
341 javax.swing.JPanel sizePanel = sizeLabel;
342 javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart;
343 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));
344 javax.swing.JPanel allocatedPanel = allocatedLabel;
345 javax.swing.JPanel unallocatedPanel = unallocatedLabel;
346 javax.swing.JPanel slackPanel = slackLabel;
347 javax.swing.JPanel directoriesPanel = directoriesLabel;
348 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));
350 setLayout(
new java.awt.BorderLayout());
352 contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
353 contentParent.setMaximumSize(
new java.awt.Dimension(32787, 32787));
354 contentParent.setMinimumSize(
new java.awt.Dimension(400, 490));
355 contentParent.setLayout(
new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS));
357 ingestRunningPanel.setAlignmentX(0.0F);
358 ingestRunningPanel.setMaximumSize(
new java.awt.Dimension(32767, 25));
359 ingestRunningPanel.setMinimumSize(
new java.awt.Dimension(10, 25));
360 ingestRunningPanel.setPreferredSize(
new java.awt.Dimension(10, 25));
361 contentParent.add(ingestRunningPanel);
363 usagePanel.setAlignmentX(0.0F);
364 usagePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
365 usagePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
366 usagePanel.setName(
"");
367 usagePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
368 contentParent.add(usagePanel);
370 osPanel.setAlignmentX(0.0F);
371 osPanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
372 osPanel.setMinimumSize(
new java.awt.Dimension(10, 20));
373 osPanel.setPreferredSize(
new java.awt.Dimension(800, 20));
374 contentParent.add(osPanel);
376 sizePanel.setAlignmentX(0.0F);
377 sizePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
378 sizePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
379 sizePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
380 contentParent.add(sizePanel);
382 fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
383 fileMimeTypesPanel.setAlignmentX(0.0F);
384 fileMimeTypesPanel.setMaximumSize(
new java.awt.Dimension(400, 300));
385 fileMimeTypesPanel.setMinimumSize(
new java.awt.Dimension(400, 300));
386 fileMimeTypesPanel.setPreferredSize(
new java.awt.Dimension(400, 300));
387 contentParent.add(fileMimeTypesPanel);
388 contentParent.add(filler2);
390 allocatedPanel.setAlignmentX(0.0F);
391 allocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
392 allocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
393 allocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
394 contentParent.add(allocatedPanel);
396 unallocatedPanel.setAlignmentX(0.0F);
397 unallocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
398 unallocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
399 unallocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
400 contentParent.add(unallocatedPanel);
402 slackPanel.setAlignmentX(0.0F);
403 slackPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
404 slackPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
405 slackPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
406 contentParent.add(slackPanel);
408 directoriesPanel.setAlignmentX(0.0F);
409 directoriesPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
410 directoriesPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
411 directoriesPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
412 contentParent.add(directoriesPanel);
413 contentParent.add(filler3);
415 scrollParent.setViewportView(contentParent);
417 add(scrollParent, java.awt.BorderLayout.CENTER);
final List< PieChartItem > pieSlices
final boolean usefulContent