Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ScoreContent.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2023 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.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.sql.SQLException;
24 import java.text.MessageFormat;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Comparator;
28 import java.util.EnumSet;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.Set;
34 import java.util.concurrent.atomic.AtomicLong;
35 import java.util.concurrent.atomic.AtomicReference;
36 import java.util.logging.Level;
37 import java.util.stream.Collectors;
38 import java.util.stream.IntStream;
39 import org.apache.commons.lang3.StringUtils;
40 import org.apache.commons.lang3.tuple.Pair;
41 import org.openide.nodes.AbstractNode;
42 import org.openide.nodes.ChildFactory;
43 import org.openide.nodes.Children;
44 import org.openide.nodes.Node;
45 import org.openide.nodes.Sheet;
46 import org.openide.util.NbBundle;
47 import org.openide.util.NbBundle.Messages;
48 import org.openide.util.WeakListeners;
49 import org.openide.util.lookup.Lookups;
59 import org.sleuthkit.datamodel.AbstractFile;
60 import org.sleuthkit.datamodel.BlackboardArtifact;
61 import org.sleuthkit.datamodel.BlackboardArtifact.Category;
62 import org.sleuthkit.datamodel.BlackboardAttribute;
63 import org.sleuthkit.datamodel.Content;
64 import org.sleuthkit.datamodel.ContentVisitor;
65 import org.sleuthkit.datamodel.DerivedFile;
66 import org.sleuthkit.datamodel.Directory;
67 import org.sleuthkit.datamodel.File;
68 import org.sleuthkit.datamodel.FsContent;
69 import org.sleuthkit.datamodel.LayoutFile;
70 import org.sleuthkit.datamodel.LocalFile;
71 import org.sleuthkit.datamodel.Score.Priority;
72 import org.sleuthkit.datamodel.Score.Significance;
73 import org.sleuthkit.datamodel.SlackFile;
74 import org.sleuthkit.datamodel.SleuthkitCase;
75 import org.sleuthkit.datamodel.TskCoreException;
76 import org.sleuthkit.datamodel.VirtualDirectory;
77 
81 public class ScoreContent implements AutopsyVisitableItem {
82 
83  private SleuthkitCase skCase;
84  private final long filteringDSObjId; // 0 if not filtering/grouping by data source
85 
86  @NbBundle.Messages({"ScoreContent_badFilter_text=Bad Items",
87  "ScoreContent_susFilter_text=Suspicious Items"})
88  public enum ScoreContentFilter implements AutopsyVisitableItem {
89 
90  BAD_ITEM_FILTER(0, "BAD_ITEM_FILTER",
91  Bundle.ScoreContent_badFilter_text()),
92  SUS_ITEM_FILTER(1, "SUS_ITEM_FILTER",
93  Bundle.ScoreContent_susFilter_text());
94 
95  private int id;
96  private String name;
97  private String displayName;
98 
99  private ScoreContentFilter(int id, String name, String displayName) {
100  this.id = id;
101  this.name = name;
102  this.displayName = displayName;
103 
104  }
105 
106  public String getName() {
107  return this.name;
108  }
109 
110  public int getId() {
111  return this.id;
112  }
113 
114  public String getDisplayName() {
115  return this.displayName;
116  }
117 
118  @Override
119  public <T> T accept(AutopsyItemVisitor<T> visitor) {
120  return visitor.visit(this);
121  }
122  }
123 
129  public ScoreContent(SleuthkitCase skCase) {
130  this(skCase, 0);
131  }
132 
139  public ScoreContent(SleuthkitCase skCase, long dsObjId) {
140  this.skCase = skCase;
141  this.filteringDSObjId = dsObjId;
142  }
143 
147  long filteringDataSourceObjId() {
148  return this.filteringDSObjId;
149  }
150 
151  @Override
152  public <T> T accept(AutopsyItemVisitor<T> visitor) {
153  return visitor.visit(this);
154  }
155 
159  public SleuthkitCase getSleuthkitCase() {
160  return this.skCase;
161  }
162 
163  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
170  );
171  private static final Set<String> CASE_EVENTS_OF_INTEREST_STRS = CASE_EVENTS_OF_INTEREST.stream()
172  .map(evt -> evt.name())
173  .collect(Collectors.toSet());
174 
177 
186  private static PropertyChangeListener getPcl(final Runnable onRefresh, final Runnable onRemove) {
187  return (PropertyChangeEvent evt) -> {
188  String eventType = evt.getPropertyName();
189  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
190  // only refresh if there is a current case.
191  try {
193  if (onRefresh != null) {
194  onRefresh.run();
195  }
196  } catch (NoCurrentCaseException notUsed) {
200  }
201  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
202  // case was closed. Remove listeners so that we don't get called with a stale case handle
203  if (evt.getNewValue() == null && onRemove != null) {
204  onRemove.run();
205  }
206  } else if (CASE_EVENTS_OF_INTEREST_STRS.contains(eventType)) {
207  // only refresh if there is a current case.
208  try {
210  if (onRefresh != null) {
211  onRefresh.run();
212  }
213  } catch (NoCurrentCaseException notUsed) {
217  }
218  }
219  };
220  }
221 
233  private static String getFilter(ScoreContent.ScoreContentFilter filter, String objIdAlias, String dsIdAlias, long filteringDSObjId) throws IllegalArgumentException {
234  String aggregateScoreFilter = getScoreFilter(filter);
235  String query = " " + objIdAlias + " IN (SELECT tsk_aggregate_score.obj_id FROM tsk_aggregate_score WHERE " + aggregateScoreFilter + ") ";
236 
237  if (filteringDSObjId > 0) {
238  query += " AND " + dsIdAlias + " = " + filteringDSObjId;
239  }
240  return query;
241  }
242 
243  private static String getScoreFilter(ScoreContentFilter filter) throws IllegalArgumentException {
244  switch (filter) {
245  case SUS_ITEM_FILTER:
246  return " tsk_aggregate_score.significance = " + Significance.LIKELY_NOTABLE.getId()
247  + " AND (tsk_aggregate_score.priority = " + Priority.NORMAL.getId() + " OR tsk_aggregate_score.priority = " + Priority.OVERRIDE.getId() + " )";
248  case BAD_ITEM_FILTER:
249  return " tsk_aggregate_score.significance = " + Significance.NOTABLE.getId()
250  + " AND (tsk_aggregate_score.priority = " + Priority.NORMAL.getId() + " OR tsk_aggregate_score.priority = " + Priority.OVERRIDE.getId() + " )";
251  default:
252  throw new IllegalArgumentException(MessageFormat.format("Unsupported filter type to get suspect content: {0}", filter));
253  }
254  }
255 
264  private static String getFileFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId) throws IllegalArgumentException {
265  return getFilter(filter, "obj_id", "data_source_obj_id", filteringDsObjId);
266  }
267 
276  private static String getDataArtifactFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId) throws IllegalArgumentException {
277  return getFilter(filter, "artifacts.artifact_obj_id", "artifacts.data_source_obj_id", filteringDsObjId);
278  }
279 
287  private static boolean isRefreshRequired(PropertyChangeEvent evt) {
288  String eventType = evt.getPropertyName();
289  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
290  // check if current case is active before updating
291  try {
293  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
294  if (null != event && Category.ANALYSIS_RESULT.equals(event.getBlackboardArtifactType().getCategory())) {
295  return true;
296  }
297  } catch (NoCurrentCaseException notUsed) {
301  }
302  }
303  return false;
304  }
305 
309  public static class ScoreContentsNode extends DisplayableItemNode {
310 
311  @NbBundle.Messages("ScoreContent_ScoreContentNode_name=Score")
312  private static final String NAME = Bundle.ScoreContent_ScoreContentNode_name();
313 
314  ScoreContentsNode(SleuthkitCase skCase, long datasourceObjId) {
315  super(Children.create(new ScoreContentsChildren(skCase, datasourceObjId), true), Lookups.singleton(NAME));
316  super.setName(NAME);
317  super.setDisplayName(NAME);
318  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/red-circle-exclamation.png"); //NON-NLS
319  }
320 
321  @Override
322  public boolean isLeafTypeNode() {
323  return false;
324  }
325 
326  @Override
327  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
328  return visitor.visit(this);
329  }
330 
331  @Override
332  @NbBundle.Messages({
333  "ScoreContent_createSheet_name_displayName=Name",
334  "ScoreContent_createSheet_name_desc=no description"})
335  protected Sheet createSheet() {
336  Sheet sheet = super.createSheet();
337  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
338  if (sheetSet == null) {
339  sheetSet = Sheet.createPropertiesSet();
340  sheet.put(sheetSet);
341  }
342 
343  sheetSet.put(new NodeProperty<>("Name", //NON-NLS
344  Bundle.ScoreContent_createSheet_name_displayName(),
345  Bundle.ScoreContent_createSheet_name_desc(),
346  NAME));
347  return sheet;
348  }
349 
350  @Override
351  public String getItemType() {
352  return getClass().getName();
353  }
354  }
355 
359  public static class ScoreContentsChildren extends ChildFactory.Detachable<ScoreContent.ScoreContentFilter> implements RefreshThrottler.Refresher {
360 
361  private SleuthkitCase skCase;
362  private final long datasourceObjId;
363 
365 
366  private final PropertyChangeListener pcl = getPcl(
367  () -> ScoreContentsChildren.this.refresh(false),
368  () -> ScoreContentsChildren.this.removeNotify());
369 
370  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
371 
373 
374  public ScoreContentsChildren(SleuthkitCase skCase, long dsObjId) {
375  this.skCase = skCase;
376  this.datasourceObjId = dsObjId;
377  }
378 
379  @Override
380  protected void addNotify() {
381  super.addNotify();
382  refreshThrottler.registerForIngestModuleEvents();
386  }
387 
388  @Override
389  protected void removeNotify() {
390  refreshThrottler.unregisterEventListener();
394  typeNodeMap.clear();
395  }
396 
397  @Override
398  public void refresh() {
399  refresh(false);
400  }
401 
402  @Override
403  public boolean isRefreshRequired(PropertyChangeEvent evt) {
404  return ScoreContent.isRefreshRequired(evt);
405  }
406 
407  @Override
408  protected boolean createKeys(List<ScoreContent.ScoreContentFilter> list) {
409  list.addAll(Arrays.asList(ScoreContent.ScoreContentFilter.values()));
410  typeNodeMap.values().forEach(nd -> nd.updateDisplayName());
411  return true;
412  }
413 
414  @Override
416  ScoreContentsChildren.ScoreContentNode nd = new ScoreContentsChildren.ScoreContentNode(skCase, key, datasourceObjId);
417  typeNodeMap.put(key, nd);
418  return nd;
419  }
420 
424  public class ScoreContentNode extends DisplayableItemNode {
425 
426  private static final Logger logger = Logger.getLogger(ScoreContentNode.class.getName());
428  private final long datasourceObjId;
429 
430  ScoreContentNode(SleuthkitCase skCase, ScoreContent.ScoreContentFilter filter, long dsObjId) {
431  super(Children.create(new ScoreContentChildren(filter, skCase, dsObjId), true), Lookups.singleton(filter.getDisplayName()));
432  this.filter = filter;
433  this.datasourceObjId = dsObjId;
434  init();
435  }
436 
437  private void init() {
438  super.setName(filter.getName());
439 
440  String tooltip = filter.getDisplayName();
441  this.setShortDescription(tooltip);
442  switch (this.filter) {
443  case SUS_ITEM_FILTER:
444  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/yellow-circle-yield.png"); //NON-NLS
445  break;
446  default:
447  case BAD_ITEM_FILTER:
448  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/red-circle-exclamation.png"); //NON-NLS
449  break;
450  }
451 
452  updateDisplayName();
453  }
454 
455  void updateDisplayName() {
456  //get count of children without preloading all child nodes
457  long count = 0;
458  try {
459  count = calculateItems(skCase, filter, datasourceObjId);
460  } catch (TskCoreException ex) {
461  logger.log(Level.WARNING, "An error occurred while fetching file counts", ex);
462  }
463  super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
464  }
465 
474  private static long calculateItems(SleuthkitCase sleuthkitCase, ScoreContent.ScoreContentFilter filter, long datasourceObjId) throws TskCoreException {
475  AtomicLong retVal = new AtomicLong(0L);
476  AtomicReference<SQLException> exRef = new AtomicReference(null);
477 
478  String query = " COUNT(tsk_aggregate_score.obj_id) AS count FROM tsk_aggregate_score WHERE\n"
479  + getScoreFilter(filter) + "\n"
480  + ((datasourceObjId > 0) ? "AND tsk_aggregate_score.data_source_obj_id = \n" + datasourceObjId : "")
481  + " AND tsk_aggregate_score.obj_id IN\n"
482  + " (SELECT tsk_files.obj_id AS obj_id FROM tsk_files UNION\n"
483  + " SELECT blackboard_artifacts.artifact_obj_id AS obj_id FROM blackboard_artifacts WHERE blackboard_artifacts.artifact_type_id IN\n"
484  + " (SELECT artifact_type_id FROM blackboard_artifact_types WHERE category_type = " + Category.DATA_ARTIFACT.getID() + ")) ";
485  sleuthkitCase.getCaseDbAccessManager().select(query, (rs) -> {
486  try {
487  if (rs.next()) {
488  retVal.set(rs.getLong("count"));
489  }
490  } catch (SQLException ex) {
491  exRef.set(ex);
492  }
493  });
494 
495  SQLException sqlEx = exRef.get();
496  if (sqlEx != null) {
497  throw new TskCoreException(
498  MessageFormat.format("A sql exception occurred fetching results with query: SELECT {0}", query),
499  sqlEx);
500  } else {
501  return retVal.get();
502  }
503  }
504 
505  @Override
506  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
507  return visitor.visit(this);
508  }
509 
510  @Override
511  @NbBundle.Messages({
512  "ScoreContent_createSheet_filterType_displayName=Type",
513  "ScoreContent_createSheet_filterType_desc=no description"})
514  protected Sheet createSheet() {
515  Sheet sheet = super.createSheet();
516  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
517  if (sheetSet == null) {
518  sheetSet = Sheet.createPropertiesSet();
519  sheet.put(sheetSet);
520  }
521 
522  sheetSet.put(new NodeProperty<>("Type", //NON_NLS
523  Bundle.ScoreContent_createSheet_filterType_displayName(),
524  Bundle.ScoreContent_createSheet_filterType_desc(),
525  filter.getDisplayName()));
526 
527  return sheet;
528  }
529 
530  @Override
531  public boolean isLeafTypeNode() {
532  return true;
533  }
534 
535  @Override
536  public String getItemType() {
537  return DisplayableItemNode.FILE_PARENT_NODE_KEY;
538  }
539  }
540 
544  static class ScoreContentChildren extends BaseChildFactory<Content> implements RefreshThrottler.Refresher {
545 
546  private final RefreshThrottler refreshThrottler = new RefreshThrottler(this);
547 
548  private final PropertyChangeListener pcl = getPcl(
549  () -> ScoreContentChildren.this.refresh(false),
550  () -> ScoreContentChildren.this.removeNotify());
551 
552  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
553 
554  private final SleuthkitCase skCase;
555  private final ScoreContent.ScoreContentFilter filter;
556  private static final Logger logger = Logger.getLogger(ScoreContentChildren.class.getName());
557 
558  private final long datasourceObjId;
559 
560  ScoreContentChildren(ScoreContent.ScoreContentFilter filter, SleuthkitCase skCase, long datasourceObjId) {
561  super(filter.getName(), new ViewsKnownAndSlackFilter<>());
562  this.skCase = skCase;
563  this.filter = filter;
564  this.datasourceObjId = datasourceObjId;
565  }
566 
567  @Override
568  protected void onAdd() {
569  refreshThrottler.registerForIngestModuleEvents();
573  }
574 
575  @Override
576  protected void onRemove() {
577  refreshThrottler.unregisterEventListener();
578  IngestManager.getInstance().removeIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, weakPcl);
579  IngestManager.getInstance().removeIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl);
580  Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl);
581  }
582 
583  @Override
584  public void refresh() {
585  refresh(false);
586  }
587 
588  @Override
589  public boolean isRefreshRequired(PropertyChangeEvent evt) {
590  return ScoreContent.isRefreshRequired(evt);
591  }
592 
593  private List<Content> runFsQuery() {
594  List<Content> ret = new ArrayList<>();
595 
596  String fileFilter = null;
597  String dataArtifactFilter = null;
598  try {
599  fileFilter = getFileFilter(filter, datasourceObjId);
600  dataArtifactFilter = getDataArtifactFilter(filter, datasourceObjId);
601  ret.addAll(skCase.findAllFilesWhere(fileFilter));
602  ret.addAll(skCase.getBlackboard().getDataArtifactsWhere(dataArtifactFilter));
603  } catch (TskCoreException | IllegalArgumentException e) {
604  logger.log(Level.SEVERE, MessageFormat.format(
605  "Error getting files for the deleted content view using file filter: {0} data artifact filter: {1}",
606  StringUtils.defaultString(fileFilter, "<null>"),
607  StringUtils.defaultString(dataArtifactFilter, "<null>")), e); //NON-NLS
608  }
609 
610  return ret;
611 
612  }
613 
614  @Override
615  protected List<Content> makeKeys() {
616  return runFsQuery();
617  }
618 
619  @Override
620  protected Node createNodeForKey(Content key) {
621  return key.accept(new ContentVisitor.Default<AbstractNode>() {
622  public FileNode visit(AbstractFile f) {
623  return new ScoreFileNode(f, false);
624  }
625 
626  public FileNode visit(FsContent f) {
627  return new ScoreFileNode(f, false);
628  }
629 
630  @Override
631  public FileNode visit(LayoutFile f) {
632  return new ScoreFileNode(f, false);
633  }
634 
635  @Override
636  public FileNode visit(File f) {
637  return new ScoreFileNode(f, false);
638  }
639 
640  @Override
641  public FileNode visit(Directory f) {
642  return new ScoreFileNode(f, false);
643  }
644 
645  @Override
646  public FileNode visit(VirtualDirectory f) {
647  return new ScoreFileNode(f, false);
648  }
649 
650  @Override
651  public AbstractNode visit(SlackFile sf) {
652  return new ScoreFileNode(sf, false);
653  }
654 
655  @Override
656  public AbstractNode visit(LocalFile lf) {
657  return new ScoreFileNode(lf, false);
658  }
659 
660  @Override
661  public AbstractNode visit(DerivedFile df) {
662  return new ScoreFileNode(df, false);
663  }
664 
665  @Override
666  public AbstractNode visit(BlackboardArtifact ba) {
667  return new ScoreArtifactNode(ba);
668  }
669 
670  @Override
671  protected AbstractNode defaultVisit(Content di) {
672  if (di instanceof AbstractFile) {
673  return visit((AbstractFile) di);
674  } else {
675  throw new UnsupportedOperationException("Not supported for this type of Displayable Item: " + di.toString());
676  }
677  }
678  });
679  }
680  }
681  }
682 
683  private static final String SOURCE_PROP = "Source";
684  private static final String TYPE_PROP = "Type";
685  private static final String PATH_PROP = "Path";
686  private static final String DATE_PROP = "Created Date";
687 
688  private static Sheet createScoreSheet(String type, String path, Long time) {
689  Sheet sheet = new Sheet();
690  Sheet.Set sheetSet = Sheet.createPropertiesSet();
691  sheet.put(sheetSet);
692 
693  List<NodeProperty<?>> properties = new ArrayList<>();
694  properties.add(new NodeProperty<>(
695  SOURCE_PROP,
696  SOURCE_PROP,
697  NO_DESCR,
698  StringUtils.defaultString(path)));
699 
700  properties.add(new NodeProperty<>(
701  TYPE_PROP,
702  TYPE_PROP,
703  NO_DESCR,
704  type));
705 
706  if (StringUtils.isNotBlank(path)) {
707  properties.add(new NodeProperty<>(
708  PATH_PROP,
709  PATH_PROP,
710  NO_DESCR,
711  path));
712  }
713 
714  if (time != null && time > 0) {
715  properties.add(new NodeProperty<>(
716  DATE_PROP,
717  DATE_PROP,
718  NO_DESCR,
720  }
721 
722  properties.forEach((property) -> {
723  sheetSet.put(property);
724  });
725 
726  return sheet;
727  }
728 
729  public static class ScoreArtifactNode extends BlackboardArtifactNode {
730 
731  private static final Logger logger = Logger.getLogger(ScoreArtifactNode.class.getName());
732 
733  private static final List<BlackboardAttribute.Type> TIME_ATTRS = Arrays.asList(
734  BlackboardAttribute.Type.TSK_DATETIME,
735  BlackboardAttribute.Type.TSK_DATETIME_ACCESSED,
736  BlackboardAttribute.Type.TSK_DATETIME_RCVD,
737  BlackboardAttribute.Type.TSK_DATETIME_SENT,
738  BlackboardAttribute.Type.TSK_DATETIME_CREATED,
739  BlackboardAttribute.Type.TSK_DATETIME_MODIFIED,
740  BlackboardAttribute.Type.TSK_DATETIME_START,
741  BlackboardAttribute.Type.TSK_DATETIME_END,
742  BlackboardAttribute.Type.TSK_DATETIME_DELETED,
743  BlackboardAttribute.Type.TSK_DATETIME_PASSWORD_RESET,
744  BlackboardAttribute.Type.TSK_DATETIME_PASSWORD_FAIL
745  );
746 
747  private static final Map<Integer, Integer> TIME_ATTR_IMPORTANCE = IntStream.range(0, TIME_ATTRS.size())
748  .mapToObj(idx -> Pair.of(TIME_ATTRS.get(idx).getTypeID(), idx))
749  .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1));
750 
751  public ScoreArtifactNode(BlackboardArtifact artifact) {
752  super(artifact);
753  }
754 
755  private Long getTime(BlackboardArtifact artifact) {
756  try {
757  BlackboardAttribute timeAttr = artifact.getAttributes().stream()
758  .filter((attr) -> TIME_ATTR_IMPORTANCE.keySet().contains(attr.getAttributeType().getTypeID()))
759  .sorted(Comparator.comparing(attr -> TIME_ATTR_IMPORTANCE.get(attr.getAttributeType().getTypeID())))
760  .findFirst()
761  .orElse(null);
762 
763  if (timeAttr != null) {
764  return timeAttr.getValueLong();
765  } else {
766  return (artifact.getParent() instanceof AbstractFile) ? ((AbstractFile) artifact.getParent()).getCtime() : null;
767  }
768  } catch (TskCoreException ex) {
769  logger.log(Level.WARNING, "An exception occurred while fetching time for artifact", ex);
770  return null;
771  }
772  }
773 
774  @Override
775  protected synchronized Sheet createSheet() {
776  try {
777  return createScoreSheet(
778  this.content.getType().getDisplayName(),
779  this.content.getUniquePath(),
780  getTime(this.content)
781  );
782  } catch (TskCoreException ex) {
783  logger.log(Level.WARNING, "An error occurred while fetching sheet data for score artifact.", ex);
784  return new Sheet();
785  }
786  }
787  }
788 
789  @Messages("ScoreContent_ScoreFileNode_type=File")
790  public static class ScoreFileNode extends FileNode {
791 
792  private static final Logger logger = Logger.getLogger(ScoreFileNode.class.getName());
793 
794  public ScoreFileNode(AbstractFile af, boolean directoryBrowseMode) {
795  super(af, directoryBrowseMode);
796  }
797 
798  @Override
799  protected synchronized Sheet createSheet() {
800  try {
801  return createScoreSheet(
802  Bundle.ScoreContent_ScoreFileNode_type(),
803  this.content.getUniquePath(),
804  this.content.getCtime()
805  );
806  } catch (TskCoreException ex) {
807  logger.log(Level.WARNING, "An error occurred while fetching sheet data for score file.", ex);
808  return new Sheet();
809  }
810  }
811  }
812 }
boolean createKeys(List< ScoreContent.ScoreContentFilter > list)
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static boolean isRefreshRequired(PropertyChangeEvent evt)
static synchronized IngestManager getInstance()
public< T > T accept(AutopsyItemVisitor< T > visitor)
static String getFileFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId)
static final Set< String > CASE_EVENTS_OF_INTEREST_STRS
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
static Sheet createScoreSheet(String type, String path, Long time)
ScoreContent(SleuthkitCase skCase, long dsObjId)
static String getFormattedTime(long epochTime)
final Map< ScoreContentFilter, ScoreContentsChildren.ScoreContentNode > typeNodeMap
static String getFilter(ScoreContent.ScoreContentFilter filter, String objIdAlias, String dsIdAlias, long filteringDSObjId)
void removeIngestJobEventListener(final PropertyChangeListener listener)
Node createNodeForKey(ScoreContent.ScoreContentFilter key)
static long calculateItems(SleuthkitCase sleuthkitCase, ScoreContent.ScoreContentFilter filter, long datasourceObjId)
void addIngestJobEventListener(final PropertyChangeListener listener)
static String getDataArtifactFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId)
ScoreContentFilter(int id, String name, String displayName)
void addIngestModuleEventListener(final PropertyChangeListener listener)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:704
ScoreFileNode(AbstractFile af, boolean directoryBrowseMode)
static String getScoreFilter(ScoreContentFilter filter)
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:749
static PropertyChangeListener getPcl(final Runnable onRefresh, final Runnable onRemove)

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