Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
EventsModel.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2014-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 */
19package org.sleuthkit.autopsy.timeline;
20
21import com.google.common.cache.CacheBuilder;
22import com.google.common.cache.LoadingCache;
23import com.google.common.collect.ImmutableList;
24import com.google.common.eventbus.EventBus;
25import java.util.Collection;
26import java.util.Collections;
27import java.util.HashSet;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
31import java.util.concurrent.ExecutionException;
32import java.util.concurrent.TimeUnit;
33import java.util.logging.Level;
34import javafx.beans.InvalidationListener;
35import javafx.beans.property.ReadOnlyObjectProperty;
36import javafx.beans.property.ReadOnlyObjectWrapper;
37import javafx.collections.FXCollections;
38import javafx.collections.ObservableMap;
39import static org.apache.commons.collections4.CollectionUtils.emptyIfNull;
40import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
41import org.joda.time.DateTimeZone;
42import org.joda.time.Interval;
43import org.openide.util.NbBundle;
44import org.sleuthkit.autopsy.casemodule.Case;
45import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
46import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent;
47import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent.DeletedBlackboardArtifactTagInfo;
48import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
49import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
50import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent.DeletedContentTagInfo;
51import org.sleuthkit.autopsy.coreutils.Logger;
52import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
53import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent;
54import org.sleuthkit.autopsy.timeline.events.TagsAddedEvent;
55import org.sleuthkit.autopsy.timeline.events.TagsDeletedEvent;
56import org.sleuthkit.autopsy.timeline.ui.filtering.datamodel.FilterState;
57import org.sleuthkit.autopsy.timeline.ui.filtering.datamodel.RootFilterState;
58import org.sleuthkit.autopsy.timeline.ui.filtering.datamodel.SqlFilterState;
59import org.sleuthkit.autopsy.timeline.utils.CacheLoaderImpl;
60import org.sleuthkit.autopsy.timeline.utils.FilterUtils;
61import org.sleuthkit.autopsy.timeline.zooming.EventsModelParams;
62import org.sleuthkit.datamodel.AbstractFile;
63import org.sleuthkit.datamodel.BlackboardArtifact;
64import org.sleuthkit.datamodel.BlackboardArtifactTag;
65import org.sleuthkit.datamodel.Content;
66import org.sleuthkit.datamodel.ContentTag;
67import org.sleuthkit.datamodel.DataSource;
68import org.sleuthkit.datamodel.SleuthkitCase;
69import org.sleuthkit.datamodel.TimelineManager;
70import org.sleuthkit.datamodel.TskCoreException;
71import org.sleuthkit.datamodel.TimelineEvent;
72import org.sleuthkit.datamodel.TimelineEventType;
73import org.sleuthkit.datamodel.TimelineFilter;
74import org.sleuthkit.datamodel.TimelineFilter.DataSourceFilter;
75import org.sleuthkit.datamodel.TimelineFilter.DataSourcesFilter;
76import org.sleuthkit.datamodel.TimelineFilter.EventTypeFilter;
77import org.sleuthkit.datamodel.TimelineFilter.FileTypesFilter;
78import org.sleuthkit.datamodel.TimelineFilter.HashHitsFilter;
79import org.sleuthkit.datamodel.TimelineFilter.HideKnownFilter;
80import org.sleuthkit.datamodel.TimelineFilter.RootFilter;
81import org.sleuthkit.datamodel.TimelineFilter.TagsFilter;
82import org.sleuthkit.datamodel.TimelineFilter.TextFilter;
83import org.sleuthkit.datamodel.TimelineLevelOfDetail;
84
96public final class EventsModel {
97
98 private static final Logger logger = Logger.getLogger(EventsModel.class.getName());
99 private final EventBus eventbus = new EventBus("EventsModel_EventBus"); //NON-NLS
100 private final Case currentCase;
101 private final TimelineManager caseDbEventManager;
102
103 /*
104 * User-specified parameters for the model exposed as JFX properties. These
105 * parameters apply across all of the views of the model and are set using
106 * GUI elements such the event filters panel.
107 *
108 * IMPORTANT: Note that the parameters are exposed both as a set and
109 * individually.
110 */
111 private final ReadOnlyObjectWrapper<EventsModelParams> modelParamsProperty = new ReadOnlyObjectWrapper<>();
112 private final ReadOnlyObjectWrapper<RootFilterState> filterStateProperty = new ReadOnlyObjectWrapper<>();
113 private final ReadOnlyObjectWrapper<Interval> timeRangeProperty = new ReadOnlyObjectWrapper<>();
114 private final ReadOnlyObjectWrapper<TimelineEventType.HierarchyLevel> eventTypesHierarchyLevelProperty = new ReadOnlyObjectWrapper<>(TimelineEventType.HierarchyLevel.CATEGORY);
115 private final ReadOnlyObjectWrapper<TimelineLevelOfDetail> timelineLODProperty = new ReadOnlyObjectWrapper<>(TimelineLevelOfDetail.LOW);
116
117 /*
118 * Caches of model data from the case database.
119 */
120 private final ObservableMap<Long, String> datasourceIDsToNamesMap = FXCollections.observableHashMap();
121 private final LoadingCache<Object, Long> maxEventTimeCache;
122 private final LoadingCache<Object, Long> minEventTimeCache;
123 private final LoadingCache<Long, TimelineEvent> idsToEventsCache;
124 private final LoadingCache<EventsModelParams, Map<TimelineEventType, Long>> eventCountsCache;
125
134 private static DataSourceFilter newDataSourceFilter(Map.Entry<Long, String> dataSourceEntry) {
135 return new DataSourceFilter(dataSourceEntry.getValue(), dataSourceEntry.getKey());
136 }
137
147 public EventsModel(Case currentCase, ReadOnlyObjectProperty<EventsModelParams> modelParams) throws TskCoreException {
148 this.currentCase = currentCase;
149 this.caseDbEventManager = currentCase.getSleuthkitCase().getTimelineManager();
150
151 /*
152 * Set up the caches of model data from the case database. Note that the
153 * build() method calls specify the methods used to create default cache
154 * entries when a call to get() would otherwise return a cache miss.
155 */
157 idsToEventsCache = CacheBuilder.newBuilder()
158 .maximumSize(5000L)
159 .expireAfterAccess(10, TimeUnit.MINUTES)
160 .build(new CacheLoaderImpl<>(caseDbEventManager::getEventById));
161 eventCountsCache = CacheBuilder.newBuilder()
162 .maximumSize(1000L)
163 .expireAfterAccess(10, TimeUnit.MINUTES)
164 .build(new CacheLoaderImpl<>(this::countEventsByType));
165 maxEventTimeCache = CacheBuilder.newBuilder()
166 .build(new CacheLoaderImpl<>(ignored -> caseDbEventManager.getMaxEventTime()));
167 minEventTimeCache = CacheBuilder.newBuilder()
168 .build(new CacheLoaderImpl<>(ignored -> caseDbEventManager.getMinEventTime()));
169
170 /*
171 * Add a listener to the data sources cache that adds a data source
172 * filter to the event filter state model parameter when a data source
173 * is added to the cache.
174 */
175 InvalidationListener dataSourcesMapListener = observable -> {
176 RootFilterState rootFilter = filterStateProperty.getReadOnlyProperty().get();
177 addDataSourceFilters(rootFilter);
178 filterStateProperty.set(rootFilter.copyOf());
179 };
180 datasourceIDsToNamesMap.addListener(dataSourcesMapListener);
181
182 /*
183 * Initialize the events filter state model parameter with the default
184 * events filter.
185 */
187
188 /*
189 * Add a listener to the model parameters property that updates the
190 * properties that expose the individual model parameters when they are
191 * changed through the model parameters property.
192 */
193 modelParamsProperty.addListener(observable -> {
194 final EventsModelParams params = modelParamsProperty.get();
195 if (params != null) {
196 synchronized (EventsModel.this) {
199 timeRangeProperty.set(params.getTimeRange());
201 }
202 }
203 });
204
205 modelParamsProperty.bind(modelParams);
206 }
207
212 synchronized private void populateDataSourcesCache() throws TskCoreException {
213 SleuthkitCase skCase = currentCase.getSleuthkitCase();
214 for (DataSource ds : skCase.getDataSources()) {
215 datasourceIDsToNamesMap.putIfAbsent(ds.getId(), ds.getName());
216 }
217 }
218
225 synchronized void addDataSourceFilters(RootFilterState rootFilterState) {
226 datasourceIDsToNamesMap.entrySet().forEach(entry -> rootFilterState.getDataSourcesFilterState().addSubFilterState(new SqlFilterState<>(newDataSourceFilter(entry))));
227 }
228
242 private Map<TimelineEventType, Long> countEventsByType(EventsModelParams modelParams) throws TskCoreException {
243 if (modelParams.getTimeRange() == null) {
244 return Collections.emptyMap();
245 } else {
246 return caseDbEventManager.countEventsByType(modelParams.getTimeRange().getStartMillis() / 1000,
247 modelParams.getTimeRange().getEndMillis() / 1000,
248 modelParams.getEventFilterState().getActiveFilter(),
249 modelParams.getEventTypesHierarchyLevel());
250 }
251 }
252
258 public TimelineManager getEventManager() {
259 return caseDbEventManager;
260 }
261
267 public SleuthkitCase getSleuthkitCase() {
268 return currentCase.getSleuthkitCase();
269 }
270
277 synchronized public ReadOnlyObjectProperty<EventsModelParams> modelParamsProperty() {
278 return modelParamsProperty.getReadOnlyProperty();
279 }
280
286 @NbBundle.Messages({
287 "FilteredEventsModel.timeRangeProperty.errorTitle=Timeline",
288 "FilteredEventsModel.timeRangeProperty.errorMessage=Error getting spanning interval."})
289 synchronized public ReadOnlyObjectProperty<Interval> timeRangeProperty() {
290 if (timeRangeProperty.get() == null) {
291 try {
292 timeRangeProperty.set(EventsModel.this.getSpanningInterval());
293 } catch (TskCoreException timelineCacheException) {
294 MessageNotifyUtil.Notify.error(Bundle.FilteredEventsModel_timeRangeProperty_errorTitle(),
295 Bundle.FilteredEventsModel_timeRangeProperty_errorMessage());
296 logger.log(Level.SEVERE, "Error getting spanning interval.", timelineCacheException);
297 }
298 }
299 return timeRangeProperty.getReadOnlyProperty();
300 }
301
308 synchronized public ReadOnlyObjectProperty<TimelineLevelOfDetail> descriptionLODProperty() {
309 return timelineLODProperty.getReadOnlyProperty();
310 }
311
318 synchronized public ReadOnlyObjectProperty<RootFilterState> eventFilterProperty() {
319 return filterStateProperty.getReadOnlyProperty();
320 }
321
328 synchronized public ReadOnlyObjectProperty<TimelineEventType.HierarchyLevel> eventTypesHierarchyLevelProperty() {
329 return eventTypesHierarchyLevelProperty.getReadOnlyProperty();
330 }
331
337 synchronized public EventsModelParams getModelParams() {
338 return modelParamsProperty.get();
339 }
340
346 synchronized public Interval getTimeRange() {
347 return getModelParams().getTimeRange();
348 }
349
355 synchronized public TimelineLevelOfDetail getDescriptionLOD() {
357 }
358
364 synchronized public RootFilterState getEventFilterState() {
366 }
367
373 synchronized public TimelineEventType.HierarchyLevel getEventTypeZoom() {
375 }
376
385 /*
386 * Construct data source filters for all of the data sources in the data
387 * sources cache.
388 */
389 DataSourcesFilter dataSourcesFilter = new DataSourcesFilter();
390 datasourceIDsToNamesMap.entrySet().forEach(dataSourceEntry
391 -> dataSourcesFilter.addSubFilter(newDataSourceFilter(dataSourceEntry)));
392
393 /*
394 * Make the rest of the event filters and wrap all of the filters with
395 * filter state objects for the GUI.
396 */
397 RootFilterState rootFilterState = new RootFilterState(new RootFilter(
398 new HideKnownFilter(),
399 new TagsFilter(),
400 new HashHitsFilter(),
401 new TextFilter(),
402 new EventTypeFilter(TimelineEventType.ROOT_EVENT_TYPE),
403 dataSourcesFilter,
405 Collections.emptySet()));
406
407 return rootFilterState;
408 }
409
420 public TimelineEvent getEventById(Long eventID) throws TskCoreException {
421 try {
422 return idsToEventsCache.get(eventID);
423 } catch (ExecutionException ex) {
424 throw new TskCoreException("Error getting cached event from ID", ex);
425 }
426 }
427
438 public Set<TimelineEvent> getEventsById(Collection<Long> eventIDs) throws TskCoreException {
439 Set<TimelineEvent> events = new HashSet<>();
440 for (Long id : eventIDs) {
441 events.add(getEventById(id));
442 }
443 return events;
444 }
445
458 public List<Long> getEventIDs(Interval timeRange, FilterState<? extends TimelineFilter> filterState) throws TskCoreException {
459 final Interval overlap;
460 RootFilter intersection;
461 synchronized (this) {
462 overlap = EventsModel.this.getSpanningInterval().overlap(timeRange);
463 intersection = getEventFilterState().intersect(filterState).getActiveFilter();
464 }
465 return caseDbEventManager.getEventIDs(overlap, intersection);
466 }
467
481 public Set<Long> getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts) throws TskCoreException {
482 return caseDbEventManager.getEventIDsForContent(file, includeDerivedArtifacts);
483 }
484
495 public List<Long> getEventIDsForArtifact(BlackboardArtifact artifact) throws TskCoreException {
496 return caseDbEventManager.getEventIDsForArtifact(artifact);
497 }
498
509 public Map<TimelineEventType, Long> getEventCounts(Interval timeRange) throws TskCoreException {
510 final RootFilterState filter;
511 final TimelineEventType.HierarchyLevel typeZoom;
512 synchronized (this) {
513 filter = getEventFilterState();
514 typeZoom = getEventTypeZoom();
515 }
516 try {
517 return eventCountsCache.get(new EventsModelParams(timeRange, typeZoom, filter, null));
518 } catch (ExecutionException executionException) {
519 throw new TskCoreException("Error getting cached event counts.`1", executionException);
520 }
521 }
522
534 public Interval getSpanningInterval(DateTimeZone timeZone) throws TskCoreException {
535 return caseDbEventManager.getSpanningInterval(modelParamsProperty().get().getTimeRange(), getEventFilterState().getActiveFilter(), timeZone);
536 }
537
546 public Interval getSpanningInterval() throws TskCoreException {
547 return new Interval(getMinEventTime() * 1000, 1000 + getMaxEventTime() * 1000);
548 }
549
560 public Interval getSpanningInterval(Collection<Long> eventIDs) throws TskCoreException {
561 return caseDbEventManager.getSpanningInterval(eventIDs);
562 }
563
573 public Long getMinEventTime() throws TskCoreException {
574 try {
575 return minEventTimeCache.get("min"); // NON-NLS
576 } catch (ExecutionException ex) {
577 throw new TskCoreException("Error getting cached min time.", ex);
578 }
579 }
580
590 public Long getMaxEventTime() throws TskCoreException {
591 try {
592 return maxEventTimeCache.get("max"); // NON-NLS
593 } catch (ExecutionException ex) {
594 throw new TskCoreException("Error getting cached max time.", ex);
595 }
596 }
597
609 synchronized public boolean handleContentTagAdded(ContentTagAddedEvent evt) throws TskCoreException {
610 ContentTag contentTag = evt.getAddedTag();
611 Content content = contentTag.getContent();
612 Set<Long> updatedEventIDs = caseDbEventManager.updateEventsForContentTagAdded(content);
613 if (isNotEmpty(updatedEventIDs)) {
614 invalidateCaches(updatedEventIDs);
615 }
616 return postTagsAdded(updatedEventIDs);
617 }
618
630 synchronized public boolean handleArtifactTagAdded(BlackBoardArtifactTagAddedEvent evt) throws TskCoreException {
631 BlackboardArtifactTag artifactTag = evt.getAddedTag();
632 BlackboardArtifact artifact = artifactTag.getArtifact();
633 Set<Long> updatedEventIDs = caseDbEventManager.updateEventsForArtifactTagAdded(artifact);
634 if (isNotEmpty(updatedEventIDs)) {
635 invalidateCaches(updatedEventIDs);
636 }
637 return postTagsAdded(updatedEventIDs);
638 }
639
651 synchronized public boolean handleContentTagDeleted(ContentTagDeletedEvent evt) throws TskCoreException {
652 DeletedContentTagInfo deletedTagInfo = evt.getDeletedTagInfo();
653 Content content = currentCase.getSleuthkitCase().getContentById(deletedTagInfo.getContentID());
654 Set<Long> updatedEventIDs = caseDbEventManager.updateEventsForContentTagDeleted(content);
655 if (isNotEmpty(updatedEventIDs)) {
656 invalidateCaches(updatedEventIDs);
657 }
658 return postTagsDeleted(updatedEventIDs);
659 }
660
667 synchronized void handleDataSourceAdded() throws TskCoreException {
669 invalidateCaches(null);
670 }
671
683 synchronized public boolean handleArtifactTagDeleted(BlackBoardArtifactTagDeletedEvent evt) throws TskCoreException {
684 DeletedBlackboardArtifactTagInfo deletedTagInfo = evt.getDeletedTagInfo();
685 BlackboardArtifact artifact = currentCase.getSleuthkitCase().getBlackboardArtifact(deletedTagInfo.getArtifactID());
686 Set<Long> updatedEventIDs = caseDbEventManager.updateEventsForArtifactTagDeleted(artifact);
687 if (isNotEmpty(updatedEventIDs)) {
688 invalidateCaches(updatedEventIDs);
689 }
690 return postTagsDeleted(updatedEventIDs);
691 }
692
702 private boolean postTagsAdded(Set<Long> updatedEventIDs) {
703 boolean tagsUpdated = !updatedEventIDs.isEmpty();
704 if (tagsUpdated) {
705 eventbus.post(new TagsAddedEvent(updatedEventIDs));
706 }
707 return tagsUpdated;
708 }
709
719 private boolean postTagsDeleted(Set<Long> updatedEventIDs) {
720 boolean tagsUpdated = !updatedEventIDs.isEmpty();
721 if (tagsUpdated) {
722 eventbus.post(new TagsDeletedEvent(updatedEventIDs));
723 }
724 return tagsUpdated;
725 }
726
733 synchronized public void registerForEvents(Object subscriber) {
734 eventbus.register(subscriber);
735 }
736
742 synchronized public void unRegisterForEvents(Object subscriber) {
743 eventbus.unregister(subscriber);
744 }
745
749 public void postRefreshRequest() {
751 }
752
758 public ImmutableList<TimelineEventType> getEventTypes() {
759 return caseDbEventManager.getEventTypes();
760 }
761
773 synchronized public Set<Long> updateEventsForHashSetHits(Collection<BlackboardArtifact> hashSetHitArtifacts) throws TskCoreException {
774 Set<Long> updatedEventIDs = new HashSet<>();
775 for (BlackboardArtifact artifact : hashSetHitArtifacts) {
776 Content content = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID());
777 updatedEventIDs.addAll(caseDbEventManager.updateEventsForHashSetHit(content));
778 }
779 if (isNotEmpty(updatedEventIDs)) {
780 invalidateCaches(updatedEventIDs);
781 }
782 return updatedEventIDs;
783 }
784
795 public synchronized void invalidateCaches(Collection<Long> updatedEventIDs) throws TskCoreException {
796 minEventTimeCache.invalidateAll();
797 maxEventTimeCache.invalidateAll();
798 idsToEventsCache.invalidateAll(emptyIfNull(updatedEventIDs));
799 eventCountsCache.invalidateAll();
801 }
802
807 public static class CacheInvalidatedEvent {
808
810 }
811 }
812
813}
synchronized static Logger getLogger(String name)
Definition Logger.java:124
synchronized void registerForEvents(Object subscriber)
Interval getSpanningInterval(DateTimeZone timeZone)
ImmutableList< TimelineEventType > getEventTypes()
synchronized ReadOnlyObjectProperty< RootFilterState > eventFilterProperty()
synchronized TimelineEventType.HierarchyLevel getEventTypeZoom()
Interval getSpanningInterval(Collection< Long > eventIDs)
boolean postTagsDeleted(Set< Long > updatedEventIDs)
final ReadOnlyObjectWrapper< TimelineEventType.HierarchyLevel > eventTypesHierarchyLevelProperty
synchronized boolean handleArtifactTagDeleted(BlackBoardArtifactTagDeletedEvent evt)
synchronized boolean handleContentTagAdded(ContentTagAddedEvent evt)
Map< TimelineEventType, Long > getEventCounts(Interval timeRange)
synchronized ReadOnlyObjectProperty< TimelineEventType.HierarchyLevel > eventTypesHierarchyLevelProperty()
boolean postTagsAdded(Set< Long > updatedEventIDs)
final ReadOnlyObjectWrapper< Interval > timeRangeProperty
final ReadOnlyObjectWrapper< TimelineLevelOfDetail > timelineLODProperty
EventsModel(Case currentCase, ReadOnlyObjectProperty< EventsModelParams > modelParams)
synchronized ReadOnlyObjectProperty< TimelineLevelOfDetail > descriptionLODProperty()
synchronized RootFilterState getDefaultEventFilterState()
synchronized TimelineLevelOfDetail getDescriptionLOD()
TimelineEvent getEventById(Long eventID)
synchronized void invalidateCaches(Collection< Long > updatedEventIDs)
static DataSourceFilter newDataSourceFilter(Map.Entry< Long, String > dataSourceEntry)
synchronized EventsModelParams getModelParams()
synchronized boolean handleContentTagDeleted(ContentTagDeletedEvent evt)
final LoadingCache< EventsModelParams, Map< TimelineEventType, Long > > eventCountsCache
final ObservableMap< Long, String > datasourceIDsToNamesMap
synchronized boolean handleArtifactTagAdded(BlackBoardArtifactTagAddedEvent evt)
synchronized ReadOnlyObjectProperty< Interval > timeRangeProperty()
final LoadingCache< Object, Long > maxEventTimeCache
synchronized void unRegisterForEvents(Object subscriber)
synchronized RootFilterState getEventFilterState()
Map< TimelineEventType, Long > countEventsByType(EventsModelParams modelParams)
final ReadOnlyObjectWrapper< RootFilterState > filterStateProperty
synchronized Set< Long > updateEventsForHashSetHits(Collection< BlackboardArtifact > hashSetHitArtifacts)
final LoadingCache< Object, Long > minEventTimeCache
Set< Long > getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts)
synchronized ReadOnlyObjectProperty< EventsModelParams > modelParamsProperty()
final LoadingCache< Long, TimelineEvent > idsToEventsCache
Set< TimelineEvent > getEventsById(Collection< Long > eventIDs)
List< Long > getEventIDs(Interval timeRange, FilterState<? extends TimelineFilter > filterState)
List< Long > getEventIDsForArtifact(BlackboardArtifact artifact)
final ReadOnlyObjectWrapper< EventsModelParams > modelParamsProperty
void addSubFilterState(FilterState< ? extends SubFilterType > newSubFilterState)
CompoundFilterState< DataSourceFilter, DataSourcesFilter > getDataSourcesFilterState()
RootFilterState intersect(FilterState< ? extends TimelineFilter > other)
static FileTypesFilter createDefaultFileTypesFilter()
TimelineEventType.HierarchyLevel getEventTypesHierarchyLevel()

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