Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.datamodel;
20
21import java.beans.PropertyChangeEvent;
22import java.beans.PropertyChangeListener;
23import java.sql.SQLException;
24import java.text.MessageFormat;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Comparator;
28import java.util.EnumSet;
29import java.util.HashMap;
30import java.util.List;
31import java.util.Map;
32import java.util.Map.Entry;
33import java.util.Set;
34import java.util.concurrent.atomic.AtomicLong;
35import java.util.concurrent.atomic.AtomicReference;
36import java.util.logging.Level;
37import java.util.stream.Collectors;
38import java.util.stream.IntStream;
39import org.apache.commons.lang3.StringUtils;
40import org.apache.commons.lang3.tuple.Pair;
41import org.openide.nodes.AbstractNode;
42import org.openide.nodes.ChildFactory;
43import org.openide.nodes.Children;
44import org.openide.nodes.Node;
45import org.openide.nodes.Sheet;
46import org.openide.util.NbBundle;
47import org.openide.util.NbBundle.Messages;
48import org.openide.util.WeakListeners;
49import org.openide.util.lookup.Lookups;
50import org.sleuthkit.autopsy.casemodule.Case;
51import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
52import org.sleuthkit.autopsy.coreutils.Logger;
53import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
54import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
55import org.sleuthkit.autopsy.guiutils.RefreshThrottler;
56import org.sleuthkit.autopsy.ingest.IngestManager;
57import org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent;
58import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
59import org.sleuthkit.datamodel.AbstractFile;
60import org.sleuthkit.datamodel.BlackboardArtifact;
61import org.sleuthkit.datamodel.BlackboardArtifact.Category;
62import org.sleuthkit.datamodel.BlackboardAttribute;
63import org.sleuthkit.datamodel.Content;
64import org.sleuthkit.datamodel.ContentVisitor;
65import org.sleuthkit.datamodel.DerivedFile;
66import org.sleuthkit.datamodel.Directory;
67import org.sleuthkit.datamodel.File;
68import org.sleuthkit.datamodel.FsContent;
69import org.sleuthkit.datamodel.LayoutFile;
70import org.sleuthkit.datamodel.LocalFile;
71import org.sleuthkit.datamodel.Score.Priority;
72import org.sleuthkit.datamodel.Score.Significance;
73import org.sleuthkit.datamodel.SlackFile;
74import org.sleuthkit.datamodel.SleuthkitCase;
75import org.sleuthkit.datamodel.TskCoreException;
76import org.sleuthkit.datamodel.VirtualDirectory;
77
81public 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"})
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
372 private final Map<ScoreContentFilter, ScoreContentsChildren.ScoreContentNode> typeNodeMap = new HashMap<>();
373
374 public ScoreContentsChildren(SleuthkitCase skCase, long dsObjId) {
375 this.skCase = skCase;
376 this.datasourceObjId = dsObjId;
377 }
378
379 @Override
387
388 @Override
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
415 protected Node createNodeForKey(ScoreContent.ScoreContentFilter key) {
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 {
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;
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() {
573 }
574
575 @Override
576 protected void onRemove() {
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<>(
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}
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition Case.java:757
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition Case.java:712
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static String getFormattedTime(long epochTime)
BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath)
static final List< BlackboardAttribute.Type > TIME_ATTRS
static long calculateItems(SleuthkitCase sleuthkitCase, ScoreContent.ScoreContentFilter filter, long datasourceObjId)
final Map< ScoreContentFilter, ScoreContentsChildren.ScoreContentNode > typeNodeMap
boolean createKeys(List< ScoreContent.ScoreContentFilter > list)
ScoreFileNode(AbstractFile af, boolean directoryBrowseMode)
static boolean isRefreshRequired(PropertyChangeEvent evt)
static String getFilter(ScoreContent.ScoreContentFilter filter, String objIdAlias, String dsIdAlias, long filteringDSObjId)
static String getFileFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId)
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static String getDataArtifactFilter(ScoreContent.ScoreContentFilter filter, long filteringDsObjId)
static final Set< String > CASE_EVENTS_OF_INTEREST_STRS
ScoreContent(SleuthkitCase skCase, long dsObjId)
static PropertyChangeListener getPcl(final Runnable onRefresh, final Runnable onRemove)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
static Sheet createScoreSheet(String type, String path, Long time)
static String getScoreFilter(ScoreContentFilter filter)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
static synchronized IngestManager getInstance()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
ScoreContentFilter(int id, String name, String displayName)
public< T > T accept(AutopsyItemVisitor< T > visitor)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.