Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
EventsRepository.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 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.timeline.db;
20 
21 import com.google.common.cache.CacheBuilder;
22 import com.google.common.cache.CacheLoader;
23 import com.google.common.cache.LoadingCache;
24 import com.google.common.util.concurrent.ThreadFactoryBuilder;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.EnumMap;
29 import java.util.List;
30 import java.util.Map;
31 import static java.util.Objects.isNull;
32 import java.util.Set;
33 import java.util.concurrent.CancellationException;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.Executor;
36 import java.util.concurrent.Executors;
37 import java.util.concurrent.TimeUnit;
38 import java.util.function.Consumer;
39 import java.util.logging.Level;
40 import java.util.stream.Collectors;
41 import javafx.application.Platform;
42 import javafx.beans.property.ReadOnlyBooleanProperty;
43 import javafx.beans.property.ReadOnlyBooleanWrapper;
44 import javafx.beans.property.ReadOnlyObjectProperty;
45 import javafx.collections.FXCollections;
46 import javafx.collections.ObservableList;
47 import javafx.collections.ObservableMap;
48 import javafx.concurrent.Worker;
49 import javax.swing.JOptionPane;
50 import org.apache.commons.lang3.StringUtils;
51 import org.joda.time.Interval;
52 import org.netbeans.api.progress.ProgressHandle;
53 import org.openide.util.NbBundle;
71 import org.sleuthkit.datamodel.AbstractFile;
72 import org.sleuthkit.datamodel.BlackboardArtifact;
73 import org.sleuthkit.datamodel.BlackboardArtifactTag;
74 import org.sleuthkit.datamodel.ContentTag;
75 import org.sleuthkit.datamodel.SleuthkitCase;
76 import org.sleuthkit.datamodel.Tag;
77 import org.sleuthkit.datamodel.TagName;
78 import org.sleuthkit.datamodel.TskCoreException;
79 import org.sleuthkit.datamodel.TskData;
80 
96 public class EventsRepository {
97 
98  private final static Logger LOGGER = Logger.getLogger(EventsRepository.class.getName());
99 
100  private final Executor workerExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("eventrepository-worker-%d").build()); //NON-NLS
102  private final EventDB eventDB;
103  private final Case autoCase;
105 
106  private final LoadingCache<Object, Long> maxCache;
107  private final LoadingCache<Object, Long> minCache;
108  private final LoadingCache<Long, SingleEvent> idToEventCache;
109  private final LoadingCache<ZoomParams, Map<EventType, Long>> eventCountsCache;
110  private final LoadingCache<ZoomParams, List<EventStripe>> eventStripeCache;
111 
112  private final ObservableMap<Long, String> datasourcesMap = FXCollections.observableHashMap();
113  private final ObservableMap<Long, String> hashSetMap = FXCollections.observableHashMap();
114  private final ObservableList<TagName> tagNames = FXCollections.observableArrayList();
115 
116  public Case getAutoCase() {
117  return autoCase;
118  }
119 
120  public ObservableList<TagName> getTagNames() {
121  return tagNames;
122  }
123 
124  synchronized public ObservableMap<Long, String> getDatasourcesMap() {
125  return datasourcesMap;
126  }
127 
128  synchronized public ObservableMap<Long, String> getHashSetMap() {
129  return hashSetMap;
130  }
131 
132  public Interval getBoundingEventsInterval(Interval timeRange, RootFilter filter) {
133  return eventDB.getBoundingEventsInterval(timeRange, filter);
134  }
135 
141  return modelInstance;
142  }
143 
144  public EventsRepository(Case autoCase, ReadOnlyObjectProperty<ZoomParams> currentStateProperty) {
145  this.autoCase = autoCase;
146  //TODO: we should check that case is open, or get passed a case object/directory -jm
147  this.eventDB = EventDB.getEventDB(autoCase);
149  idToEventCache = CacheBuilder.newBuilder()
150  .maximumSize(5000L)
151  .expireAfterAccess(10, TimeUnit.MINUTES)
152  .build(CacheLoader.from(eventDB::getEventById));
153  eventCountsCache = CacheBuilder.newBuilder()
154  .maximumSize(1000L)
155  .expireAfterAccess(10, TimeUnit.MINUTES)
156  .build(CacheLoader.from(eventDB::countEventsByType));
157  eventStripeCache = CacheBuilder.newBuilder()
158  .maximumSize(1000L)
159  .expireAfterAccess(10, TimeUnit.MINUTES
160  ).build(CacheLoader.from(eventDB::getEventStripes));
161  maxCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMaxTime));
162  minCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMinTime));
163  this.modelInstance = new FilteredEventsModel(this, currentStateProperty);
164  }
165 
169  public Long getMaxTime() {
170  return maxCache.getUnchecked("max"); // NON-NLS
171 
172  }
173 
177  public Long getMinTime() {
178  return minCache.getUnchecked("min"); // NON-NLS
179 
180  }
181 
182  public SingleEvent getEventById(Long eventID) {
183  return idToEventCache.getUnchecked(eventID);
184  }
185 
186  synchronized public Set<SingleEvent> getEventsById(Collection<Long> eventIDs) {
187  return eventIDs.stream()
188  .map(idToEventCache::getUnchecked)
189  .collect(Collectors.toSet());
190 
191  }
192 
193  synchronized public List<EventStripe> getEventStripes(ZoomParams params) {
194  try {
195  return eventStripeCache.get(params);
196  } catch (ExecutionException ex) {
197  LOGGER.log(Level.SEVERE, "Failed to load Event Stripes from cache for " + params.toString(), ex); //NON-NLS
198  return Collections.emptyList();
199  }
200  }
201 
202  synchronized public Map<EventType, Long> countEvents(ZoomParams params) {
203  return eventCountsCache.getUnchecked(params);
204  }
205 
206  synchronized public int countAllEvents() {
207  return eventDB.countAllEvents();
208  }
209 
225  public List<Long> getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts) {
226  return eventDB.getEventIDsForFile(file, includeDerivedArtifacts);
227  }
228 
238  public List<Long> getEventIDsForArtifact(BlackboardArtifact artifact) {
239  return eventDB.getEventIDsForArtifact(artifact);
240  }
241 
242  private void invalidateCaches() {
243  minCache.invalidateAll();
244  maxCache.invalidateAll();
245  eventCountsCache.invalidateAll();
246  eventStripeCache.invalidateAll();
247  idToEventCache.invalidateAll();
248  }
249 
250  public List<Long> getEventIDs(Interval timeRange, RootFilter filter) {
251  return eventDB.getEventIDs(timeRange, filter);
252  }
253 
265  public List<CombinedEvent> getCombinedEvents(Interval timeRange, RootFilter filter) {
266  return eventDB.getCombinedEvents(timeRange, filter);
267  }
268 
269  public Interval getSpanningInterval(Collection<Long> eventIDs) {
270  return eventDB.getSpanningInterval(eventIDs);
271  }
272 
273  public boolean hasNewColumns() {
274  return eventDB.hasNewColumns();
275  }
276 
285  public Map<String, Long> getTagCountsByTagName(Set<Long> eventIDsWithTags) {
286  return eventDB.getTagCountsByTagName(eventIDsWithTags);
287  }
288 
295  synchronized private void populateFilterData(SleuthkitCase skCase) {
296 
297  for (Map.Entry<Long, String> hashSet : eventDB.getHashSetNames().entrySet()) {
298  hashSetMap.putIfAbsent(hashSet.getKey(), hashSet.getValue());
299  }
300  //because there is no way to remove a datasource we only add to this map.
301  for (Long id : eventDB.getDataSourceIDs()) {
302  try {
303  datasourcesMap.putIfAbsent(id, skCase.getContentById(id).getDataSource().getName());
304  } catch (TskCoreException ex) {
305  LOGGER.log(Level.SEVERE, "Failed to get datasource by ID.", ex); //NON-NLS
306  }
307  }
308 
309  try {
310  //should this only be tags applied to files or event bearing artifacts?
311  tagNames.setAll(skCase.getTagNamesInUse());
312  } catch (TskCoreException ex) {
313  LOGGER.log(Level.SEVERE, "Failed to get tag names in use.", ex); //NON-NLS
314  }
315  }
316 
317  synchronized public Set<Long> addTag(long objID, Long artifactID, Tag tag, EventDB.EventTransaction trans) {
318  Set<Long> updatedEventIDs = eventDB.addTag(objID, artifactID, tag, trans);
319  if (!updatedEventIDs.isEmpty()) {
320  invalidateCaches(updatedEventIDs);
321  }
322  return updatedEventIDs;
323  }
324 
325  synchronized public Set<Long> deleteTag(long objID, Long artifactID, long tagID, boolean tagged) {
326  Set<Long> updatedEventIDs = eventDB.deleteTag(objID, artifactID, tagID, tagged);
327  if (!updatedEventIDs.isEmpty()) {
328  invalidateCaches(updatedEventIDs);
329  }
330  return updatedEventIDs;
331  }
332 
333  synchronized private void invalidateCaches(Set<Long> updatedEventIDs) {
334  eventCountsCache.invalidateAll();
335  eventStripeCache.invalidateAll();
336  idToEventCache.invalidateAll(updatedEventIDs);
337  try {
338  tagNames.setAll(autoCase.getSleuthkitCase().getTagNamesInUse());
339  } catch (TskCoreException ex) {
340  LOGGER.log(Level.SEVERE, "Failed to get tag names in use.", ex); //NON-NLS
341  }
342  }
343 
352  public void syncTagsFilter(TagsFilter tagsFilter) {
353  for (TagName t : tagNames) {
354  tagsFilter.addSubFilter(new TagNameFilter(t, autoCase));
355  }
356  for (TagNameFilter t : tagsFilter.getSubFilters()) {
357  t.setDisabled(tagNames.contains(t.getTagName()) == false);
358  }
359  }
360 
361  public boolean areFiltersEquivalent(RootFilter f1, RootFilter f2) {
362  return SQLHelper.getSQLWhere(f1).equals(SQLHelper.getSQLWhere(f2));
363  }
364 
377  public CancellationProgressTask<Void> rebuildRepository(Consumer<Worker.State> onStateChange) {
378  return rebuildRepository(DBPopulationMode.FULL, onStateChange);
379  }
380 
393  public CancellationProgressTask<Void> rebuildTags(Consumer<Worker.State> onStateChange) {
394  return rebuildRepository(DBPopulationMode.TAGS_ONLY, onStateChange);
395  }
396 
409  private CancellationProgressTask<Void> rebuildRepository(final DBPopulationMode mode, Consumer<Worker.State> onStateChange) {
410  LOGGER.log(Level.INFO, "(re)starting {0} db population task", mode); //NON-NLS
411  if (dbWorker != null) {
412  dbWorker.cancel();
413  }
414  dbWorker = new DBPopulationWorker(mode, onStateChange);
415  workerExecutor.execute(dbWorker);
416  return dbWorker;
417  }
418 
419  private enum DBPopulationMode {
420 
423  }
424 
429  private class DBPopulationWorker extends CancellationProgressTask<Void> {
430 
431  private final ReadOnlyBooleanWrapper cancellable = new ReadOnlyBooleanWrapper(true);
432 
434  private final SleuthkitCase skCase;
435  private final TagsManager tagsManager;
436 
437  private ProgressHandle progressHandle;
438 
439  @Override
440  public ReadOnlyBooleanProperty cancellableProperty() {
441  return cancellable.getReadOnlyProperty();
442  }
443 
444  @Override
445  public boolean requestCancel() {
446  Platform.runLater(() -> cancellable.set(false));
447  return super.requestCancel();
448  }
449 
450  @Override
451  protected void updateTitle(String title) {
452  super.updateTitle(title);
453  progressHandle.setDisplayName(title);
454  }
455 
456  @Override
457  protected void updateMessage(String message) {
458  super.updateMessage(message);
459  progressHandle.progress(message);
460  }
461 
462  @Override
463  protected void updateProgress(double workDone, double max) {
464  super.updateProgress(workDone, max);
465  if (workDone >= 0) {
466  progressHandle.progress((int) workDone);
467  }
468  }
469 
470  @Override
471  protected void updateProgress(long workDone, long max) {
472  super.updateProgress(workDone, max);
473  super.updateProgress(workDone, max);
474  if (workDone >= 0) {
475  progressHandle.progress((int) workDone);
476  }
477  }
478 
479  DBPopulationWorker(DBPopulationMode mode, Consumer<Worker.State> onStateChange) {
480  skCase = autoCase.getSleuthkitCase();
481  tagsManager = autoCase.getServices().getTagsManager();
482  this.dbPopulationMode = mode;
483  this.stateProperty().addListener(stateObservable -> onStateChange.accept(getState()));
484  }
485 
486  void restartProgressHandle(String title, String message, Double workDone, double total, Boolean cancellable) {
487  if (progressHandle != null) {
488  progressHandle.finish();
489  }
490  progressHandle = cancellable
491  ? ProgressHandle.createHandle(title, this::requestCancel)
492  : ProgressHandle.createHandle(title);
493 
494  if (workDone < 0) {
495  progressHandle.start();
496  } else {
497  progressHandle.start((int) total);
498  }
499  updateTitle(title);
500  updateMessage(message);
501  updateProgress(workDone, total);
502  }
503 
504  @SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
505  @Override
506  @NbBundle.Messages({"progressWindow.msg.refreshingFileTags=Refreshing file tags",
507  "progressWindow.msg.refreshingResultTags=Refreshing result tags",
508  "progressWindow.msg.gatheringData=Gathering event data",
509  "progressWindow.msg.commitingDb=Committing events database"})
510  protected Void call() throws Exception {
511  EventDB.EventTransaction trans = null;
512 
513  if (dbPopulationMode == DBPopulationMode.FULL) {
514  //drop old db, and add back MAC and artifact events
515  LOGGER.log(Level.INFO, "Beginning population of timeline db."); // NON-NLS
516  restartProgressHandle(Bundle.progressWindow_msg_gatheringData(), "", -1D, 1, true);
517  //reset database //TODO: can we do more incremental updates? -jm
518  eventDB.reInitializeDB();
519  //grab ids of all files
520  List<Long> fileIDs = skCase.findAllFileIdsWhere("name != '.' AND name != '..'"); //NON-NLS
521  final int numFiles = fileIDs.size();
522 
523  trans = eventDB.beginTransaction();
524  insertMACTimeEvents(numFiles, fileIDs, trans);
526  }
527 
528  //tags
529  if (dbPopulationMode == DBPopulationMode.TAGS_ONLY) {
530  trans = eventDB.beginTransaction();
531  LOGGER.log(Level.INFO, "dropping old tags"); // NON-NLS
532  eventDB.reInitializeTags();
533  }
534 
535  LOGGER.log(Level.INFO, "updating content tags"); // NON-NLS
536  List<ContentTag> contentTags = tagsManager.getAllContentTags();
537  int currentWorkTotal = contentTags.size();
538  restartProgressHandle(Bundle.progressWindow_msg_refreshingFileTags(), "", 0D, currentWorkTotal, true);
539  insertContentTags(currentWorkTotal, contentTags, trans);
540 
541  LOGGER.log(Level.INFO, "updating artifact tags"); // NON-NLS
542  List<BlackboardArtifactTag> artifactTags = tagsManager.getAllBlackboardArtifactTags();
543  currentWorkTotal = artifactTags.size();
544  restartProgressHandle(Bundle.progressWindow_msg_refreshingResultTags(), "", 0D, currentWorkTotal, true);
545  insertArtifactTags(currentWorkTotal, artifactTags, trans);
546 
547  LOGGER.log(Level.INFO, "committing db"); // NON-NLS
548  Platform.runLater(() -> cancellable.set(false));
549  restartProgressHandle(Bundle.progressWindow_msg_commitingDb(), "", -1D, 1, false);
550  eventDB.commitTransaction(trans);
551 
552  eventDB.analyze();
553  populateFilterData(skCase);
555 
556  progressHandle.finish();
557  if (isCancelRequested()) {
558  cancel();
559  }
560  return null;
561  }
562 
563  private void insertArtifactTags(int currentWorkTotal, List<BlackboardArtifactTag> artifactTags, EventDB.EventTransaction trans) {
564  for (int i = 0; i < currentWorkTotal; i++) {
565  if (isCancelRequested()) {
566  break;
567  }
568  updateProgress(i, currentWorkTotal);
569  BlackboardArtifactTag artifactTag = artifactTags.get(i);
570  eventDB.addTag(artifactTag.getContent().getId(), artifactTag.getArtifact().getArtifactID(), artifactTag, trans);
571  }
572  }
573 
574  private void insertContentTags(int currentWorkTotal, List<ContentTag> contentTags, EventDB.EventTransaction trans) {
575  for (int i = 0; i < currentWorkTotal; i++) {
576  if (isCancelRequested()) {
577  break;
578  }
579  updateProgress(i, currentWorkTotal);
580  ContentTag contentTag = contentTags.get(i);
581  eventDB.addTag(contentTag.getContent().getId(), null, contentTag, trans);
582  }
583  }
584 
586  //insert artifact based events
587  //TODO: use (not-yet existing api) to grab all artifacts with timestamps, rather than the hardcoded lists in EventType -jm
588  for (EventType type : RootEventType.allTypes) {
589  if (isCancelRequested()) {
590  break;
591  }
592  //skip file_system events, they are already handled above.
593  if (type instanceof ArtifactEventType) {
594  populateEventType((ArtifactEventType) type, trans);
595  }
596  }
597  }
598 
599  @NbBundle.Messages("progressWindow.msg.populateMacEventsFiles=Populating MAC time events for files")
600  private void insertMACTimeEvents(final int numFiles, List<Long> fileIDs, EventDB.EventTransaction trans) {
601  restartProgressHandle(Bundle.progressWindow_msg_populateMacEventsFiles(), "", 0D, numFiles, true);
602  for (int i = 0; i < numFiles; i++) {
603  if (isCancelRequested()) {
604  break;
605  }
606  long fID = fileIDs.get(i);
607  try {
608  AbstractFile f = skCase.getAbstractFileById(fID);
609 
610  if (isNull(f)) {
611  LOGGER.log(Level.WARNING, "Failed to get data for file : {0}", fID); // NON-NLS
612  } else {
613  insertEventsForFile(f, trans);
614  updateProgress(i, numFiles);
615  updateMessage(f.getName());
616  }
617  } catch (TskCoreException tskCoreException) {
618  LOGGER.log(Level.SEVERE, "Failed to insert MAC time events for file : " + fID, tskCoreException); // NON-NLS
619  }
620  }
621  }
622 
623  private void insertEventsForFile(AbstractFile f, EventDB.EventTransaction trans) throws TskCoreException {
624  //gather time stamps into map
625  EnumMap<FileSystemTypes, Long> timeMap = new EnumMap<>(FileSystemTypes.class);
626  timeMap.put(FileSystemTypes.FILE_CREATED, f.getCrtime());
627  timeMap.put(FileSystemTypes.FILE_ACCESSED, f.getAtime());
628  timeMap.put(FileSystemTypes.FILE_CHANGED, f.getCtime());
629  timeMap.put(FileSystemTypes.FILE_MODIFIED, f.getMtime());
630 
631  /*
632  * if there are no legitimate ( greater than zero ) time stamps (
633  * eg, logical/local files) skip the rest of the event generation:
634  * this should result in dropping logical files, since they do not
635  * have legitimate time stamps.
636  */
637  if (Collections.max(timeMap.values()) > 0) {
638  final String uniquePath = f.getUniquePath();
639  final String parentPath = f.getParentPath();
640  long datasourceID = f.getDataSource().getId();
641  String datasourceName = StringUtils.substringBeforeLast(uniquePath, parentPath);
642 
643  String rootFolder = StringUtils.substringBefore(StringUtils.substringAfter(parentPath, "/"), "/");
644  String shortDesc = datasourceName + "/" + StringUtils.defaultString(rootFolder);
645  shortDesc = shortDesc.endsWith("/") ? shortDesc : shortDesc + "/";
646  String medDesc = datasourceName + parentPath;
647 
648  final TskData.FileKnown known = f.getKnown();
649  Set<String> hashSets = f.getHashSetNames();
650  List<ContentTag> tags = tagsManager.getContentTagsByContent(f);
651 
652  for (Map.Entry<FileSystemTypes, Long> timeEntry : timeMap.entrySet()) {
653  if (timeEntry.getValue() > 0) {
654  // if the time is legitimate ( greater than zero ) insert it
655  eventDB.insertEvent(timeEntry.getValue(), timeEntry.getKey(),
656  datasourceID, f.getId(), null, uniquePath, medDesc,
657  shortDesc, known, hashSets, tags, trans);
658  }
659  }
660  }
661  }
662 
663  @Override
664  @NbBundle.Messages("msgdlg.problem.text=There was a problem populating the timeline."
665  + " Not all events may be present or accurate.")
666  protected void done() {
667  super.done();
668  try {
669  get();
670  } catch (CancellationException ex) {
671  LOGGER.log(Level.WARNING, "Timeline database population was cancelled by the user. " //NON-NLS
672  + " Not all events may be present or accurate."); // NON-NLS
673  } catch (Exception ex) {
674  LOGGER.log(Level.WARNING, "Unexpected exception while populating database.", ex); // NON-NLS
675  JOptionPane.showMessageDialog(null, Bundle.msgdlg_problem_text());
676  }
677  }
678 
685  @NbBundle.Messages({"# {0} - event type ", "progressWindow.populatingXevents=Populating {0} events"})
687  try {
688  //get all the blackboard artifacts corresponding to the given event sub_type
689  final ArrayList<BlackboardArtifact> blackboardArtifacts = skCase.getBlackboardArtifacts(type.getArtifactTypeID());
690  final int numArtifacts = blackboardArtifacts.size();
691  restartProgressHandle(Bundle.progressWindow_populatingXevents(type.getDisplayName()), "", 0D, numArtifacts, true);
692  for (int i = 0; i < numArtifacts; i++) {
693  try {
694  //for each artifact, extract the relevant information for the descriptions
695  insertEventForArtifact(type, blackboardArtifacts.get(i), trans);
696  updateProgress(i, numArtifacts);
697  } catch (TskCoreException ex) {
698  LOGGER.log(Level.SEVERE, "There was a problem inserting event for artifact: " + blackboardArtifacts.get(i).getArtifactID(), ex); // NON-NLS
699  }
700  }
701  } catch (TskCoreException ex) {
702  LOGGER.log(Level.SEVERE, "There was a problem getting events with sub type " + type.toString() + ".", ex); // NON-NLS
703  }
704  }
705 
706  private void insertEventForArtifact(final ArtifactEventType type, BlackboardArtifact bbart, EventDB.EventTransaction trans) throws TskCoreException {
708 
709  // if the time is legitimate ( greater than zero ) insert it into the db
710  if (eventDescription != null && eventDescription.getTime() > 0) {
711  long objectID = bbart.getObjectID();
712  AbstractFile f = skCase.getAbstractFileById(objectID);
713  long datasourceID = f.getDataSource().getId();
714  long artifactID = bbart.getArtifactID();
715  Set<String> hashSets = f.getHashSetNames();
716  List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbart);
717  String fullDescription = eventDescription.getFullDescription();
718  String medDescription = eventDescription.getMedDescription();
719  String shortDescription = eventDescription.getShortDescription();
720  eventDB.insertEvent(eventDescription.getTime(), type, datasourceID, objectID, artifactID, fullDescription, medDescription, shortDescription, null, hashSets, tags, trans);
721  }
722  }
723  }
724 }
static EventDB getEventDB(Case autoCase)
Definition: EventDB.java:110
List< Long > getEventIDsForArtifact(BlackboardArtifact artifact)
List< Long > getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts)
boolean areFiltersEquivalent(RootFilter f1, RootFilter f2)
Interval getSpanningInterval(Collection< Long > eventIDs)
Definition: EventDB.java:177
void insertMACTimeEvents(final int numFiles, List< Long > fileIDs, EventDB.EventTransaction trans)
Map< String, Long > getTagCountsByTagName(Set< Long > eventIDsWithTags)
synchronized ObservableMap< Long, String > getHashSetMap()
synchronized Map< EventType, Long > countEvents(ZoomParams params)
synchronized void populateFilterData(SleuthkitCase skCase)
synchronized List< EventStripe > getEventStripes(ZoomParams params)
synchronized ObservableMap< Long, String > getDatasourcesMap()
Interval getSpanningInterval(Collection< Long > eventIDs)
void insertEventForArtifact(final ArtifactEventType type, BlackboardArtifact bbart, EventDB.EventTransaction trans)
synchronized Set< Long > deleteTag(long objID, Long artifactID, long tagID, boolean tagged)
synchronized List< BlackboardArtifactTag > getAllBlackboardArtifactTags()
synchronized Set< Long > addTag(long objID, Long artifactID, Tag tag, EventDB.EventTransaction trans)
synchronized List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)
CancellationProgressTask< Void > rebuildRepository(Consumer< Worker.State > onStateChange)
static final List<?extends EventType > allTypes
Definition: EventType.java:35
final ObservableMap< Long, String > hashSetMap
EventsRepository(Case autoCase, ReadOnlyObjectProperty< ZoomParams > currentStateProperty)
void insertArtifactTags(int currentWorkTotal, List< BlackboardArtifactTag > artifactTags, EventDB.EventTransaction trans)
synchronized Set< SingleEvent > getEventsById(Collection< Long > eventIDs)
List< CombinedEvent > getCombinedEvents(Interval timeRange, RootFilter filter)
final LoadingCache< ZoomParams, Map< EventType, Long > > eventCountsCache
void populateEventType(final ArtifactEventType type, EventDB.EventTransaction trans)
final LoadingCache< Long, SingleEvent > idToEventCache
void insertEventsForFile(AbstractFile f, EventDB.EventTransaction trans)
synchronized void invalidateCaches(Set< Long > updatedEventIDs)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
final ObservableMap< Long, String > datasourcesMap
CancellationProgressTask< Void > rebuildTags(Consumer< Worker.State > onStateChange)
Interval getBoundingEventsInterval(Interval timeRange, RootFilter filter)
final LoadingCache< ZoomParams, List< EventStripe > > eventStripeCache
static AttributeEventDescription buildEventDescription(ArtifactEventType type, BlackboardArtifact artf)
void insertContentTags(int currentWorkTotal, List< ContentTag > contentTags, EventDB.EventTransaction trans)
synchronized List< ContentTag > getContentTagsByContent(Content content)
List< Long > getEventIDs(Interval timeRange, RootFilter filter)
synchronized List< ContentTag > getAllContentTags()

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