Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
TypesPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.datasourcesummary.ui;
20 
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;
45 
46 import org.sleuthkit.datamodel.DataSource;
47 import org.sleuthkit.datamodel.TskCoreException;
48 
53 @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 {
74 
78  private static class TypesPieChartData {
79 
80  private final List<PieChartItem> pieSlices;
81  private final boolean usefulContent;
82 
90  TypesPieChartData(List<PieChartItem> pieSlices, boolean usefulContent) {
91  this.pieSlices = pieSlices;
92  this.usefulContent = usefulContent;
93  }
94 
98  List<PieChartItem> getPieSlices() {
99  return pieSlices;
100  }
101 
105  boolean isUsefulContent() {
106  return usefulContent;
107  }
108  }
109 
110  private static final long serialVersionUID = 1L;
111  private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#");
112 
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;
121 
122  // All file type categories.
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)
130  );
131 
132  private final DataFetcher<DataSource, String> usageFetcher;
133  private final DataFetcher<DataSource, String> osFetcher;
134  private final DataFetcher<DataSource, Long> sizeFetcher;
135 
136  private final DataFetcher<DataSource, TypesPieChartData> typesFetcher;
137 
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;
142 
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());
146 
147  private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title());
148 
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());
153 
154  // all loadable components
155  private final List<LoadableComponent<?>> loadables = Arrays.asList(
156  usageLabel,
157  osLabel,
158  sizeLabel,
159  fileMimeTypesChart,
160  allocatedLabel,
161  unallocatedLabel,
162  slackLabel,
163  directoriesLabel
164  );
165 
166  private final IngestRunningLabel ingestRunningLabel = new IngestRunningLabel();
167 
168  // all of the means for obtaining data for the gui components.
169  private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
170 
174  TypesPanel() {
175  this(new MimeTypeSummaryGetter(), new TypesSummaryGetter(), new ContainerSummaryGetter());
176  }
177 
178  @Override
179  public void close() {
180  ingestRunningLabel.unregister();
181  super.close();
182  }
183 
191  TypesPanel(
192  MimeTypeSummaryGetter mimeTypeData,
193  TypesSummaryGetter typeData,
194  ContainerSummaryGetter containerData) {
195 
196  super(mimeTypeData, typeData, containerData);
197 
198  this.usageFetcher = containerData::getDataSourceType;
199  this.osFetcher = containerData::getOperatingSystems;
200 
201  this.sizeFetcher = (dataSource) -> dataSource == null ? null : dataSource.getSize();
202 
203  this.typesFetcher = (dataSource) -> getMimeTypeCategoriesModel(mimeTypeData, dataSource);
204 
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);
209 
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))))
226  );
227 
228  initComponents();
229  }
230 
231  @Override
232  protected void fetchInformation(DataSource dataSource) {
233  fetchInformation(dataFetchComponents, dataSource);
234  }
235 
236  @Override
237  protected void onNewDataSource(DataSource dataSource) {
238  onNewDataSource(dataFetchComponents, loadables, dataSource);
239  }
240 
249  private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummaryGetter mimeTypeData, DataSource dataSource)
250  throws SQLException, SleuthkitCaseProviderException, TskCoreException {
251 
252  if (dataSource == null) {
253  return null;
254  }
255 
256  // for each category of file types, get the counts of files
257  List<PieChartItem> fileCategoryItems = new ArrayList<>();
258  long categoryTotalCount = 0;
259 
260  for (FileTypeCategoryData cat : FILE_MIME_TYPE_CATEGORIES) {
261  long thisValue = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
262  categoryTotalCount += thisValue;
263 
264  fileCategoryItems.add(new PieChartItem(
265  cat.getLabel(),
266  thisValue,
267  cat.getColor()));
268  }
269 
270  // get a count of all files with no mime type
271  long noMimeTypeCount = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
272 
273  // get a count of all regular files
274  long allRegularFiles = DataSourceInfoUtilities.getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
275 
276  // create entry for mime types in other category
277  long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
278  PieChartItem otherPieItem = new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_other_title(),
279  otherCount, OTHER_COLOR);
280 
281  // check at this point to see if these are all 0; if so, we don't have useful content.
282  boolean usefulContent = categoryTotalCount > 0 || otherCount > 0;
283 
284  // create entry for not analyzed mime types category
285  PieChartItem notAnalyzedItem = new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(),
286  noMimeTypeCount, NOT_ANALYZED_COLOR);
287 
288  // combine categories with 'other' and 'not analyzed'
289  List<PieChartItem> items = Stream.concat(
290  fileCategoryItems.stream(),
291  Stream.of(otherPieItem, notAnalyzedItem))
292  // remove items that have no value
293  .filter(slice -> slice.getValue() > 0)
294  .collect(Collectors.toList());
295 
296  return new TypesPieChartData(items, usefulContent);
297  }
298 
307  private void showMimeTypeCategories(DataFetchResult<TypesPieChartData> result) {
308  if (result == null) {
309  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
310  return;
311  }
312 
313  // if error, show error
314  if (result.getResultType() == ResultType.ERROR) {
315  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getErrorResult(result.getException()));
316  return;
317  }
318 
319  TypesPieChartData data = result.getData();
320  if (data == null) {
321  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
322  } else {
323  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(data.getPieSlices()));
324  }
325  }
326 
332  @SuppressWarnings("unchecked")
333  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
334  private void initComponents() {
335 
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));
349 
350  setLayout(new java.awt.BorderLayout());
351 
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));
356 
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);
362 
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(""); // NOI18N
367  usagePanel.setPreferredSize(new java.awt.Dimension(800, 20));
368  contentParent.add(usagePanel);
369 
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);
375 
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);
381 
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);
389 
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);
395 
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);
401 
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);
407 
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);
414 
415  scrollParent.setViewportView(contentParent);
416 
417  add(scrollParent, java.awt.BorderLayout.CENTER);
418  }// </editor-fold>//GEN-END:initComponents
419 
420 
421  // Variables declaration - do not modify//GEN-BEGIN:variables
422  // End of variables declaration//GEN-END:variables
423 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.