19 package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel;
 
   21 import com.google.common.cache.CacheBuilder;
 
   22 import com.google.common.cache.LoadingCache;
 
   23 import com.google.common.collect.HashMultimap;
 
   24 import com.google.common.collect.SetMultimap;
 
   25 import com.google.common.eventbus.Subscribe;
 
   26 import java.sql.ResultSet;
 
   27 import java.sql.SQLException;
 
   28 import java.util.ArrayList;
 
   29 import java.util.Collection;
 
   30 import java.util.Comparator;
 
   31 import java.util.HashMap;
 
   32 import java.util.Iterator;
 
   33 import java.util.List;
 
   36 import java.util.SortedSet;
 
   37 import java.util.TreeSet;
 
   38 import java.util.concurrent.ExecutionException;
 
   39 import java.util.concurrent.TimeUnit;
 
   40 import java.util.function.Consumer;
 
   41 import java.util.logging.Level;
 
   42 import java.util.stream.Collectors;
 
   43 import org.apache.commons.lang3.tuple.ImmutablePair;
 
   44 import org.joda.time.DateTimeZone;
 
   45 import org.joda.time.Interval;
 
   46 import org.joda.time.Period;
 
   72     private final LoadingCache<EventsModelParams, List<TimelineEvent>> 
eventCache;
 
   80         eventCache = CacheBuilder.newBuilder()
 
   82                 .expireAfterAccess(10, TimeUnit.MINUTES)
 
   90         eventCache.invalidateAll();
 
  119         Interval timeRange = zoom.getTimeRange();
 
  120         TimelineLevelOfDetail descriptionLOD = zoom.getTimelineLOD();
 
  123         Map<TimelineEventType, SetMultimap< String, EventCluster>> eventClusters = 
new HashMap<>();
 
  125             eventCache.get(zoom).stream()
 
  127                     .forEach(
new Consumer<TimelineEvent>() {
 
  129                 public void accept(TimelineEvent event) {
 
  130                     TimelineEventType clusterType = 
event.getEventType().getCategory();
 
  131                     eventClusters.computeIfAbsent(clusterType, eventType -> HashMultimap.create())
 
  132                             .put(event.getDescription(descriptionLOD), 
new EventCluster(event, clusterType, descriptionLOD));
 
  139         } 
catch (ExecutionException ex) {
 
  140             throw new TskCoreException(
"Failed to load Event Stripes from cache for " + zoom.toString(), ex); 
 
  161         Interval timeRange = zoom.getTimeRange();
 
  162         TimelineFilter.RootFilter activeFilter = zoom.getEventFilterState().getActiveFilter();
 
  163         return eventManager.getEvents(timeRange, activeFilter);
 
  179     static private List<EventStripe> 
mergeClustersToStripes(Period timeUnitLength, Map<TimelineEventType, SetMultimap< String, EventCluster>> eventClusters) {
 
  182         ArrayList<EventCluster> mergedClusters = 
new ArrayList<>();
 
  185         for (Map.Entry<TimelineEventType, SetMultimap<String, EventCluster>> typeMapEntry : eventClusters.entrySet()) {
 
  186             TimelineEventType type = typeMapEntry.getKey();
 
  187             SetMultimap<String, EventCluster> descrMap = typeMapEntry.getValue();
 
  189             for (String descr : descrMap.keySet()) {
 
  190                 Set<EventCluster> events = descrMap.get(descr);
 
  192                 Iterator<EventCluster> iterator = events.stream()
 
  198                 while (iterator.hasNext()) {
 
  204                     if (gap == null || gap.toDuration().getMillis() <= timeUnitLength.toDurationFrom(gap.getStart()).getMillis() / 4) {
 
  209                         mergedClusters.add(current);
 
  213                 mergedClusters.add(current);
 
  218         Map<ImmutablePair<TimelineEventType, String>, 
EventStripe> stripeDescMap = 
new HashMap<>();
 
  221             stripeDescMap.
merge(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription()),
 
  225         return stripeDescMap.values().stream()
 
  227                 .collect(Collectors.toList());
 
  239     static <X> SortedSet<X> copyAsSortedSet(Collection<X> setA, Comparator<X> comparator) {
 
  240         TreeSet<X> treeSet = 
new TreeSet<>(comparator);
 
  241         treeSet.addAll(setA);
 
DetailsViewModel(EventsModel eventsModel)
 
final TimelineManager eventManager
 
static UIFilter getAllPassFilter()
 
static final Logger logger
 
TimelineManager getEventManager()
 
SleuthkitCase getSleuthkitCase()
 
final SleuthkitCase sleuthkitCase
 
List< EventStripe > getEventStripes(EventsModelParams zoom)
 
static EventStripe merge(EventStripe stripeA, EventStripe stripeB)
 
static EventCluster merge(EventCluster cluster1, EventCluster cluster2)
 
final LoadingCache< EventsModelParams, List< TimelineEvent > > eventCache
 
final EventsModel eventsModel
 
List< EventStripe > getEventStripes(UIFilter uiFilter, EventsModelParams zoom)
 
static DateTimeZone getJodaTimeZone()
 
synchronized void registerForEvents(Object subscriber)
 
static List< EventStripe > mergeClustersToStripes(Period timeUnitLength, Map< TimelineEventType, SetMultimap< String, EventCluster >> eventClusters)
 
List< TimelineEvent > getEvents(EventsModelParams zoom, DateTimeZone timeZone)
 
TimeUnits getPeriodSize()
 
synchronized static Logger getLogger(String name)
 
static RangeDivision getRangeDivision(Interval timeRange, DateTimeZone timeZone)