Autopsy  4.17.0
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 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.Set;
29 import java.util.stream.Collectors;
30 import java.util.stream.Stream;
31 import org.openide.util.NbBundle.Messages;
48 
49 import org.sleuthkit.datamodel.DataSource;
50 import org.sleuthkit.datamodel.TskCoreException;
51 
56 @Messages({
57  "TypesPanel_artifactsTypesPieChart_title=Artifact Types",
58  "TypesPanel_filesByCategoryTable_allocatedRow_title=Allocated Files",
59  "TypesPanel_filesByCategoryTable_unallocatedRow_title=Unallocated Files",
60  "TypesPanel_filesByCategoryTable_slackRow_title=Slack Files",
61  "TypesPanel_filesByCategoryTable_directoryRow_title=Directories",
62  "TypesPanel_fileMimeTypesChart_title=File Types",
63  "TypesPanel_fileMimeTypesChart_audio_title=Audio",
64  "TypesPanel_fileMimeTypesChart_documents_title=Documents",
65  "TypesPanel_fileMimeTypesChart_executables_title=Executables",
66  "TypesPanel_fileMimeTypesChart_images_title=Images",
67  "TypesPanel_fileMimeTypesChart_videos_title=Videos",
68  "TypesPanel_fileMimeTypesChart_other_title=Other",
69  "TypesPanel_fileMimeTypesChart_unknown_title=Unknown",
70  "TypesPanel_fileMimeTypesChart_notAnalyzed_title=Not Analyzed",
71  "TypesPanel_usageLabel_title=Usage",
72  "TypesPanel_osLabel_title=OS",
73  "TypesPanel_sizeLabel_title=Size"})
74 class TypesPanel extends BaseDataSourceSummaryPanel {
75 
79  private static class TypesPieChartData {
80 
81  private final List<PieChartItem> pieSlices;
82  private final boolean usefulContent;
83 
91  public TypesPieChartData(List<PieChartItem> pieSlices, boolean usefulContent) {
92  this.pieSlices = pieSlices;
93  this.usefulContent = usefulContent;
94  }
95 
99  public List<PieChartItem> getPieSlices() {
100  return pieSlices;
101  }
102 
106  public boolean isUsefulContent() {
107  return usefulContent;
108  }
109  }
110 
114  private static class TypesPieCategory {
115 
116  private final String label;
117  private final Set<String> mimeTypes;
118  private final Color color;
119 
127  TypesPieCategory(String label, Set<String> mimeTypes, Color color) {
128  this.label = label;
129  this.mimeTypes = mimeTypes;
130  this.color = color;
131  }
132 
140  TypesPieCategory(String label, FileTypeCategory fileCategory, Color color) {
141  this(label, fileCategory.getMediaTypes(), color);
142  }
143 
147  String getLabel() {
148  return label;
149  }
150 
154  Set<String> getMimeTypes() {
155  return mimeTypes;
156  }
157 
161  Color getColor() {
162  return color;
163  }
164  }
165 
166  private static final long serialVersionUID = 1L;
167  private static final DecimalFormat INTEGER_SIZE_FORMAT = new DecimalFormat("#");
168  private static final DecimalFormat COMMA_FORMATTER = new DecimalFormat("#,###");
169  private static final String FILE_TYPE_FACTORY = FileTypeIdModuleFactory.class.getCanonicalName();
170  private static final String FILE_TYPE_MODULE_NAME = FileTypeIdModuleFactory.getModuleName();
171  private static final Logger logger = Logger.getLogger(TypesPanel.class.getName());
172 
173  private static final Color IMAGES_COLOR = new Color(156, 39, 176);
174  private static final Color VIDEOS_COLOR = Color.YELLOW;
175  private static final Color AUDIO_COLOR = Color.BLUE;
176  private static final Color DOCUMENTS_COLOR = Color.GREEN;
177  private static final Color EXECUTABLES_COLOR = new Color(0, 188, 212);
178  private static final Color UNKNOWN_COLOR = Color.ORANGE;
179  private static final Color OTHER_COLOR = new Color(78, 52, 46);
180  private static final Color NOT_ANALYZED_COLOR = Color.WHITE;
181 
182  // All file type categories.
183  private static final List<TypesPieCategory> FILE_MIME_TYPE_CATEGORIES = Arrays.asList(
184  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_images_title(), FileTypeCategory.IMAGE.getMediaTypes(), IMAGES_COLOR),
185  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_videos_title(), FileTypeCategory.VIDEO.getMediaTypes(), VIDEOS_COLOR),
186  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_audio_title(), FileTypeCategory.AUDIO.getMediaTypes(), AUDIO_COLOR),
187  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_documents_title(), FileTypeCategory.DOCUMENTS.getMediaTypes(), DOCUMENTS_COLOR),
188  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_executables_title(), FileTypeCategory.EXECUTABLE.getMediaTypes(), EXECUTABLES_COLOR),
189  new TypesPieCategory(Bundle.TypesPanel_fileMimeTypesChart_unknown_title(), new HashSet<>(Arrays.asList("application/octet-stream")), UNKNOWN_COLOR)
190  );
191 
192  private final LoadableLabel usageLabel = new LoadableLabel(Bundle.TypesPanel_usageLabel_title());
193  private final LoadableLabel osLabel = new LoadableLabel(Bundle.TypesPanel_osLabel_title());
194  private final LoadableLabel sizeLabel = new LoadableLabel(Bundle.TypesPanel_sizeLabel_title());
195 
196  private final PieChartPanel fileMimeTypesChart = new PieChartPanel(Bundle.TypesPanel_fileMimeTypesChart_title());
197 
198  private final LoadableLabel allocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_allocatedRow_title());
199  private final LoadableLabel unallocatedLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_unallocatedRow_title());
200  private final LoadableLabel slackLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_slackRow_title());
201  private final LoadableLabel directoriesLabel = new LoadableLabel(Bundle.TypesPanel_filesByCategoryTable_directoryRow_title());
202 
203  // all loadable components
204  private final List<LoadableComponent<?>> loadables = Arrays.asList(
205  usageLabel,
206  osLabel,
207  sizeLabel,
208  fileMimeTypesChart,
209  allocatedLabel,
210  unallocatedLabel,
211  slackLabel,
212  directoriesLabel
213  );
214 
215  private final IngestRunningLabel ingestRunningLabel = new IngestRunningLabel();
216 
217  // all of the means for obtaining data for the gui components.
218  private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
219 
223  public TypesPanel() {
224  this(new MimeTypeSummary(), new TypesSummary(), new ContainerSummary());
225  }
226 
227  @Override
228  public void close() {
229  ingestRunningLabel.unregister();
230  super.close();
231  }
232 
240  public TypesPanel(
241  MimeTypeSummary mimeTypeData,
242  TypesSummary typeData,
243  ContainerSummary containerData) {
244 
245  super(mimeTypeData, typeData, containerData);
246 
247  this.dataFetchComponents = Arrays.asList(
248  // usage label worker
249  new DataFetchWorker.DataFetchComponents<>(
250  containerData::getDataSourceType,
251  (result) -> usageLabel.showDataFetchResult(result)),
252  // os label worker
253  new DataFetchWorker.DataFetchComponents<>(
254  containerData::getOperatingSystems,
255  (result) -> osLabel.showDataFetchResult(result)),
256  // size label worker
257  new DataFetchWorker.DataFetchComponents<>(
258  (dataSource) -> {
259  Long size = dataSource == null ? null : dataSource.getSize();
260  return SizeRepresentationUtil.getSizeString(size, INTEGER_SIZE_FORMAT, false);
261  },
262  sizeLabel::showDataFetchResult),
263  // file types worker
264  new DataFetchWorker.DataFetchComponents<>(
265  (dataSource) -> getMimeTypeCategoriesModel(mimeTypeData, dataSource),
266  this::showMimeTypeCategories),
267  // allocated files worker
268  new DataFetchWorker.DataFetchComponents<>(
269  (dataSource) -> getStringOrZero(typeData.getCountOfAllocatedFiles(dataSource)),
270  allocatedLabel::showDataFetchResult),
271  // unallocated files worker
272  new DataFetchWorker.DataFetchComponents<>(
273  (dataSource) -> getStringOrZero(typeData.getCountOfUnallocatedFiles(dataSource)),
274  unallocatedLabel::showDataFetchResult),
275  // slack files worker
276  new DataFetchWorker.DataFetchComponents<>(
277  (dataSource) -> getStringOrZero(typeData.getCountOfSlackFiles(dataSource)),
278  slackLabel::showDataFetchResult),
279  // directories worker
280  new DataFetchWorker.DataFetchComponents<>(
281  (dataSource) -> getStringOrZero(typeData.getCountOfDirectories(dataSource)),
282  directoriesLabel::showDataFetchResult)
283  );
284 
285  initComponents();
286  }
287 
288  @Override
289  protected void fetchInformation(DataSource dataSource) {
290  fetchInformation(dataFetchComponents, dataSource);
291  }
292 
293  @Override
294  protected void onNewDataSource(DataSource dataSource) {
295  onNewDataSource(dataFetchComponents, loadables, dataSource);
296  }
297 
306  private TypesPieChartData getMimeTypeCategoriesModel(MimeTypeSummary mimeTypeData, DataSource dataSource)
307  throws SQLException, SleuthkitCaseProviderException, TskCoreException {
308 
309  if (dataSource == null) {
310  return null;
311  }
312 
313  // for each category of file types, get the counts of files
314  List<PieChartItem> fileCategoryItems = new ArrayList<>();
315  long categoryTotalCount = 0;
316 
317  for (TypesPieCategory cat : FILE_MIME_TYPE_CATEGORIES) {
318  long thisValue = getLongOrZero(mimeTypeData.getCountOfFilesForMimeTypes(dataSource, cat.getMimeTypes()));
319  categoryTotalCount += thisValue;
320 
321  fileCategoryItems.add(new PieChartItem(
322  cat.getLabel(),
323  thisValue,
324  cat.getColor()));
325  }
326 
327  // get a count of all files with no mime type
328  long noMimeTypeCount = getLongOrZero(mimeTypeData.getCountOfFilesWithNoMimeType(dataSource));
329 
330  // get a count of all regular files
331  long allRegularFiles = getLongOrZero(mimeTypeData.getCountOfAllRegularFiles(dataSource));
332 
333  // create entry for mime types in other category
334  long otherCount = allRegularFiles - (categoryTotalCount + noMimeTypeCount);
335  PieChartItem otherPieItem = new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_other_title(),
336  otherCount, OTHER_COLOR);
337 
338  // check at this point to see if these are all 0; if so, we don't have useful content.
339  boolean usefulContent = categoryTotalCount > 0 || otherCount > 0;
340 
341  // create entry for not analyzed mime types category
342  PieChartItem notAnalyzedItem = new PieChartItem(Bundle.TypesPanel_fileMimeTypesChart_notAnalyzed_title(),
343  noMimeTypeCount, NOT_ANALYZED_COLOR);
344 
345  // combine categories with 'other' and 'not analyzed'
346  List<PieChartItem> items = Stream.concat(
347  fileCategoryItems.stream(),
348  Stream.of(otherPieItem, notAnalyzedItem))
349  // remove items that have no value
350  .filter(slice -> slice.getValue() > 0)
351  .collect(Collectors.toList());
352 
353  return new TypesPieChartData(items, usefulContent);
354  }
355 
364  private void showMimeTypeCategories(DataFetchResult<TypesPieChartData> result) {
365  if (result == null) {
366  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
367  return;
368  }
369 
370  // if error, show error
371  if (result.getResultType() == ResultType.ERROR) {
372  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getErrorResult(result.getException()));
373  return;
374  }
375 
376  TypesPieChartData data = result.getData();
377  if (data == null) {
378  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(null));
379  } else {
380  fileMimeTypesChart.showDataFetchResult(DataFetchResult.getSuccessResult(data.getPieSlices()));
381  }
382  }
383 
391  private static long getLongOrZero(Long longVal) {
392  return longVal == null ? 0 : longVal;
393  }
394 
403  private static String getStringOrZero(Long longVal) {
404  return longVal == null ? "0" : COMMA_FORMATTER.format(longVal);
405  }
406 
412  @SuppressWarnings("unchecked")
413  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
414  private void initComponents() {
415 
416  javax.swing.JScrollPane scrollParent = new javax.swing.JScrollPane();
417  javax.swing.JPanel contentParent = new javax.swing.JPanel();
418  javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
419  javax.swing.JPanel usagePanel = usageLabel;
420  javax.swing.JPanel osPanel = osLabel;
421  javax.swing.JPanel sizePanel = sizeLabel;
422  javax.swing.JPanel fileMimeTypesPanel = fileMimeTypesChart;
423  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));
424  javax.swing.JPanel allocatedPanel = allocatedLabel;
425  javax.swing.JPanel unallocatedPanel = unallocatedLabel;
426  javax.swing.JPanel slackPanel = slackLabel;
427  javax.swing.JPanel directoriesPanel = directoriesLabel;
428  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));
429 
430  setLayout(new java.awt.BorderLayout());
431 
432  contentParent.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
433  contentParent.setMaximumSize(new java.awt.Dimension(32787, 32787));
434  contentParent.setMinimumSize(new java.awt.Dimension(400, 490));
435  contentParent.setLayout(new javax.swing.BoxLayout(contentParent, javax.swing.BoxLayout.PAGE_AXIS));
436 
437  ingestRunningPanel.setAlignmentX(0.0F);
438  ingestRunningPanel.setMaximumSize(new java.awt.Dimension(32767, 25));
439  ingestRunningPanel.setMinimumSize(new java.awt.Dimension(10, 25));
440  ingestRunningPanel.setPreferredSize(new java.awt.Dimension(10, 25));
441  contentParent.add(ingestRunningPanel);
442 
443  usagePanel.setAlignmentX(0.0F);
444  usagePanel.setMaximumSize(new java.awt.Dimension(32767, 20));
445  usagePanel.setMinimumSize(new java.awt.Dimension(10, 20));
446  usagePanel.setName(""); // NOI18N
447  usagePanel.setPreferredSize(new java.awt.Dimension(800, 20));
448  contentParent.add(usagePanel);
449 
450  osPanel.setAlignmentX(0.0F);
451  osPanel.setMaximumSize(new java.awt.Dimension(32767, 20));
452  osPanel.setMinimumSize(new java.awt.Dimension(10, 20));
453  osPanel.setPreferredSize(new java.awt.Dimension(800, 20));
454  contentParent.add(osPanel);
455 
456  sizePanel.setAlignmentX(0.0F);
457  sizePanel.setMaximumSize(new java.awt.Dimension(32767, 20));
458  sizePanel.setMinimumSize(new java.awt.Dimension(10, 20));
459  sizePanel.setPreferredSize(new java.awt.Dimension(800, 20));
460  contentParent.add(sizePanel);
461 
462  fileMimeTypesPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
463  fileMimeTypesPanel.setAlignmentX(0.0F);
464  fileMimeTypesPanel.setMaximumSize(new java.awt.Dimension(400, 300));
465  fileMimeTypesPanel.setMinimumSize(new java.awt.Dimension(400, 300));
466  fileMimeTypesPanel.setPreferredSize(new java.awt.Dimension(400, 300));
467  contentParent.add(fileMimeTypesPanel);
468  contentParent.add(filler2);
469 
470  allocatedPanel.setAlignmentX(0.0F);
471  allocatedPanel.setMaximumSize(new java.awt.Dimension(32767, 16));
472  allocatedPanel.setMinimumSize(new java.awt.Dimension(10, 16));
473  allocatedPanel.setPreferredSize(new java.awt.Dimension(800, 16));
474  contentParent.add(allocatedPanel);
475 
476  unallocatedPanel.setAlignmentX(0.0F);
477  unallocatedPanel.setMaximumSize(new java.awt.Dimension(32767, 16));
478  unallocatedPanel.setMinimumSize(new java.awt.Dimension(10, 16));
479  unallocatedPanel.setPreferredSize(new java.awt.Dimension(800, 16));
480  contentParent.add(unallocatedPanel);
481 
482  slackPanel.setAlignmentX(0.0F);
483  slackPanel.setMaximumSize(new java.awt.Dimension(32767, 16));
484  slackPanel.setMinimumSize(new java.awt.Dimension(10, 16));
485  slackPanel.setPreferredSize(new java.awt.Dimension(800, 16));
486  contentParent.add(slackPanel);
487 
488  directoriesPanel.setAlignmentX(0.0F);
489  directoriesPanel.setMaximumSize(new java.awt.Dimension(32767, 16));
490  directoriesPanel.setMinimumSize(new java.awt.Dimension(10, 16));
491  directoriesPanel.setPreferredSize(new java.awt.Dimension(800, 16));
492  contentParent.add(directoriesPanel);
493  contentParent.add(filler3);
494 
495  scrollParent.setViewportView(contentParent);
496 
497  add(scrollParent, java.awt.BorderLayout.CENTER);
498  }// </editor-fold>//GEN-END:initComponents
499 
500 
501  // Variables declaration - do not modify//GEN-BEGIN:variables
502  // End of variables declaration//GEN-END:variables
503 }
TypesPieChartData(List< PieChartItem > pieSlices, boolean usefulContent)
Definition: TypesPanel.java:91

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.