19 package org.sleuthkit.autopsy.datasourcesummary.ui;
21 import java.awt.BorderLayout;
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;
29 import java.util.logging.Level;
30 import java.util.stream.Collectors;
31 import javax.swing.JLabel;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.lang3.tuple.Pair;
34 import org.openide.util.NbBundle.Messages;
61 "TypesPanel_artifactsTypesPieChart_title=Artifact Types",
62 "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files",
63 "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files",
64 "TypesPanel_filesByCategoryTable_slackRow_title=Slack Files",
65 "TypesPanel_filesByCategoryTable_directoryRow_title=Directories",
66 "TypesPanel_fileMimeTypesChart_title=File Types",
67 "TypesPanel_fileMimeTypesChart_audio_title=Audio",
68 "TypesPanel_fileMimeTypesChart_documents_title=Documents",
69 "TypesPanel_fileMimeTypesChart_executables_title=Executables",
70 "TypesPanel_fileMimeTypesChart_images_title=Images",
71 "TypesPanel_fileMimeTypesChart_videos_title=Videos",
72 "TypesPanel_fileMimeTypesChart_other_title=Other",
73 "TypesPanel_fileMimeTypesChart_unknown_title=Unknown",
74 "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed",
75 "TypesPanel_usageLabel_title=Usage",
76 "TypesPanel_osLabel_title=OS",
77 "TypesPanel_sizeLabel_title=Size"})
78 class TypesPanel extends BaseDataSourceSummaryPanel {
86 private static final long serialVersionUID = 1L;
88 private final JLabel label =
new JLabel();
89 private final String
key;
98 setLayout(
new BorderLayout());
99 add(label, BorderLayout.CENTER);
100 this.showResults(null);
104 String formattedKey = StringUtils.isBlank(key) ?
"" : key;
105 String formattedValue = StringUtils.isBlank(value) ?
"" : value;
106 label.setText(String.format(
"%s: %s", formattedKey, formattedValue));
136 this.pieSlices = pieSlices;
137 this.usefulContent = usefulContent;
151 return usefulContent;
155 private static final long serialVersionUID = 1L;
156 private static final DecimalFormat INTEGER_SIZE_FORMAT =
new DecimalFormat(
"#");
157 private static final DecimalFormat COMMA_FORMATTER =
new DecimalFormat(
"#,###");
163 private static final List<Pair<String, Set<String>>> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
164 Pair.of(Bundle.TypesPanel_fileMimeTypesChart_images_title(),
FileTypeCategory.
IMAGE.getMediaTypes()),
165 Pair.of(Bundle.TypesPanel_fileMimeTypesChart_videos_title(),
FileTypeCategory.
VIDEO.getMediaTypes()),
169 Pair.of(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(),
new HashSet<>(Arrays.asList(
"application/octet-stream")))
172 private final LoadableLabel usageLabel =
new LoadableLabel(Bundle.TypesPanel_usageLabel_title());
173 private final LoadableLabel osLabel =
new LoadableLabel(Bundle.TypesPanel_osLabel_title());
174 private final LoadableLabel sizeLabel =
new LoadableLabel(Bundle.TypesPanel_sizeLabel_title());
178 private final LoadableLabel allocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title());
179 private final LoadableLabel unallocatedLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title());
180 private final LoadableLabel slackLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_slackRow_title());
181 private final LoadableLabel directoriesLabel =
new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title());
184 private final List<LoadableComponent<?>> loadables = Arrays.asList(
198 private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
203 public TypesPanel() {
208 public void close() {
221 MimeTypeSummary mimeTypeData,
222 TypesSummary typeData,
223 ContainerSummary containerData) {
225 super(mimeTypeData, typeData, containerData);
227 this.dataFetchComponents = Arrays.asList(
229 new DataFetchWorker.DataFetchComponents<>(
230 containerData::getDataSourceType,
232 showResultWithModuleCheck(
235 StringUtils::isNotBlank,
236 IngestModuleCheckUtil.RECENT_ACTIVITY_FACTORY,
237 IngestModuleCheckUtil.RECENT_ACTIVITY_MODULE_NAME);
240 new DataFetchWorker.DataFetchComponents<>(
241 containerData::getOperatingSystems,
243 showResultWithModuleCheck(
246 StringUtils::isNotBlank,
247 IngestModuleCheckUtil.RECENT_ACTIVITY_FACTORY,
248 IngestModuleCheckUtil.RECENT_ACTIVITY_MODULE_NAME);
251 new DataFetchWorker.DataFetchComponents<>(
253 Long size = dataSource == null ? null : dataSource.getSize();
254 return SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false);
256 sizeLabel::showDataFetchResult),
258 new DataFetchWorker.DataFetchComponents<>(
259 (dataSource) -> getMimeTypeCategoriesModel(mimeTypeData, dataSource),
260 this::showMimeTypeCategories),
262 new DataFetchWorker.DataFetchComponents<>(
263 (dataSource) -> getStringOrZero(typeData.getCountOfAllocatedFiles(dataSource)),
264 allocatedLabel::showDataFetchResult),
266 new DataFetchWorker.DataFetchComponents<>(
267 (dataSource) -> getStringOrZero(typeData.getCountOfUnallocatedFiles(dataSource)),
268 unallocatedLabel::showDataFetchResult),
270 new DataFetchWorker.DataFetchComponents<>(
271 (dataSource) -> getStringOrZero(typeData.getCountOfSlackFiles(dataSource)),
272 slackLabel::showDataFetchResult),
274 new DataFetchWorker.DataFetchComponents<>(
275 (dataSource) -> getStringOrZero(typeData.getCountOfDirectories(dataSource)),
276 directoriesLabel::showDataFetchResult)
283 protected void fetchInformation(DataSource dataSource) {
284 fetchInformation(dataFetchComponents, dataSource);
288 protected void onNewDataSource(DataSource dataSource) {
289 onNewDataSource(dataFetchComponents, loadables, dataSource);
299 private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummary mimeTypeData, DataSource dataSource)
300 throws SQLException, SleuthkitCaseProviderException, TskCoreException {
302 if (dataSource == null) {
307 List<Pair<String, Long>> fileCategoryItems =
new ArrayList<>();
308 for (Pair<String, Set<String>> strCat : FILE_MIME_TYPE_CATEGORIES) {
309 fileCategoryItems.add(Pair.of(strCat.getLeft(),
310 getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(
311 dataSource, strCat.getRight()))));
315 Long noMimeTypeCount = getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
318 Long categoryTotalCount = getLongOrZero(fileCategoryItems.stream()
319 .collect(Collectors.summingLong((pair) -> pair.getValue())));
322 Long allRegularFiles = getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
325 fileCategoryItems.add(Pair.of(Bundle.TypesPanel_fileMimeTypesChart_other_title(),
326 allRegularFiles - (categoryTotalCount + noMimeTypeCount)));
329 boolean usefulContent = fileCategoryItems.stream().anyMatch((pair) -> pair.getValue() != null && pair.getValue() > 0);
332 fileCategoryItems.add(Pair.of(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(),
336 List<PieChartItem> items = fileCategoryItems.stream()
337 .filter(keyCount -> keyCount.getRight() != null && keyCount.getRight() > 0)
338 .map(keyCount ->
new PieChartItem(keyCount.getLeft(), keyCount.getRight()))
339 .collect(Collectors.toList());
341 return new TypesPieChartData(items, usefulContent);
352 private void showMimeTypeCategories(DataFetchResult<TypesPieChartData> result) {
354 if (result == null) {
355 showPieResultWithModuleCheck(null);
360 if (result.getResultType() == ResultType.ERROR) {
361 this.fileMimeTypesChart.showDataFetchResult(DataFetchResult.getErrorResult(result.getException()));
365 TypesPieChartData data = result.getData();
368 showPieResultWithModuleCheck(null);
369 }
else if (!data.isUsefulContent()) {
371 showPieResultWithModuleCheck(data.getPieSlices());
374 this.fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(data.getPieSlices()));
385 private void showPieResultWithModuleCheck(List<PieChartItem> items) {
386 boolean hasBeenIngested =
false;
388 hasBeenIngested = this.getIngestModuleCheckUtil().isModuleIngested(getDataSource(), FILE_TYPE_FACTORY);
389 }
catch (TskCoreException | SleuthkitCaseProviderException ex) {
390 logger.log(Level.WARNING,
"There was an error fetching whether or not the current data source has been ingested with the file type ingest module.", ex);
393 if (hasBeenIngested) {
394 this.fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(items));
396 this.fileMimeTypesChart.showDataWithMessage(items, getDefaultNoIngestMessage(FILE_TYPE_MODULE_NAME));
407 private static long getLongOrZero(Long longVal) {
408 return longVal == null ? 0 : longVal;
419 private static String getStringOrZero(Long longVal) {
420 return longVal == null ?
"0" : COMMA_FORMATTER.format(longVal);
428 @SuppressWarnings(
"unchecked")
430 private
void initComponents() {
432 javax.swing.JScrollPane scrollParent =
new javax.swing.JScrollPane();
433 javax.swing.JPanel contentParent =
new javax.swing.JPanel();
434 javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
435 javax.swing.JPanel usagePanel = usageLabel;
436 javax.swing.JPanel osPanel = osLabel;
437 javax.swing.JPanel sizePanel = sizeLabel;
438 javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart;
439 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));
440 javax.swing.JPanel allocatedPanel = allocatedLabel;
441 javax.swing.JPanel unallocatedPanel = unallocatedLabel;
442 javax.swing.JPanel slackPanel = slackLabel;
443 javax.swing.JPanel directoriesPanel = directoriesLabel;
444 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));
446 setLayout(
new java.awt.BorderLayout());
448 contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
449 contentParent.setMaximumSize(
new java.awt.Dimension(32787, 32787));
450 contentParent.setMinimumSize(
new java.awt.Dimension(400, 490));
451 contentParent.setLayout(
new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS));
453 ingestRunningPanel.setAlignmentX(0.0F);
454 ingestRunningPanel.setMaximumSize(
new java.awt.Dimension(32767, 25));
455 ingestRunningPanel.setMinimumSize(
new java.awt.Dimension(10, 25));
456 ingestRunningPanel.setPreferredSize(
new java.awt.Dimension(10, 25));
457 contentParent.add(ingestRunningPanel);
459 usagePanel.setAlignmentX(0.0F);
460 usagePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
461 usagePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
462 usagePanel.setName(
"");
463 usagePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
464 contentParent.add(usagePanel);
466 osPanel.setAlignmentX(0.0F);
467 osPanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
468 osPanel.setMinimumSize(
new java.awt.Dimension(10, 20));
469 osPanel.setPreferredSize(
new java.awt.Dimension(800, 20));
470 contentParent.add(osPanel);
472 sizePanel.setAlignmentX(0.0F);
473 sizePanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
474 sizePanel.setMinimumSize(
new java.awt.Dimension(10, 20));
475 sizePanel.setPreferredSize(
new java.awt.Dimension(800, 20));
476 contentParent.add(sizePanel);
478 fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
479 fileMimeTypesPanel.setAlignmentX(0.0F);
480 fileMimeTypesPanel.setMaximumSize(
new java.awt.Dimension(400, 300));
481 fileMimeTypesPanel.setMinimumSize(
new java.awt.Dimension(400, 300));
482 fileMimeTypesPanel.setPreferredSize(
new java.awt.Dimension(400, 300));
483 contentParent.add(fileMimeTypesPanel);
484 contentParent.add(filler2);
486 allocatedPanel.setAlignmentX(0.0F);
487 allocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
488 allocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
489 allocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
490 contentParent.add(allocatedPanel);
492 unallocatedPanel.setAlignmentX(0.0F);
493 unallocatedPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
494 unallocatedPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
495 unallocatedPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
496 contentParent.add(unallocatedPanel);
498 slackPanel.setAlignmentX(0.0F);
499 slackPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
500 slackPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
501 slackPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
502 contentParent.add(slackPanel);
504 directoriesPanel.setAlignmentX(0.0F);
505 directoriesPanel.setMaximumSize(
new java.awt.Dimension(32767, 16));
506 directoriesPanel.setMinimumSize(
new java.awt.Dimension(10, 16));
507 directoriesPanel.setPreferredSize(
new java.awt.Dimension(800, 16));
508 contentParent.add(directoriesPanel);
509 contentParent.add(filler3);
511 scrollParent.setViewportView(contentParent);
513 add(scrollParent, java.awt.BorderLayout.CENTER);
void setMessage(boolean visible, String message)
final List< PieChartItem > pieSlices
boolean isUsefulContent()
List< PieChartItem > getPieSlices()
final boolean usefulContent
TypesPieChartData(List< PieChartItem > pieSlices, boolean usefulContent)
void setValue(String value)
synchronized static Logger getLogger(String name)
static String getModuleName()
void setResults(String data)