19 package org.sleuthkit.autopsy.timeline.events.db;
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.cache.RemovalNotification;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.List;
31 import java.util.concurrent.CancellationException;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.TimeUnit;
34 import java.util.logging.Level;
35 import javafx.beans.property.ReadOnlyObjectProperty;
36 import javax.annotation.concurrent.GuardedBy;
37 import javax.swing.JOptionPane;
38 import javax.swing.SwingWorker;
39 import org.apache.commons.lang3.StringUtils;
40 import org.joda.time.Interval;
41 import org.openide.util.NbBundle;
84 private final LoadingCache<Object, Long>
maxCache;
86 private final LoadingCache<Object, Long>
minCache;
97 return eventDB.getBoundingEventsInterval(timeRange, filter);
112 idToEventCache = CacheBuilder.newBuilder().maximumSize(5000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<Long, TimeLineEvent> rn) -> {
114 }).build(CacheLoader.from(eventDB::getEventById));
115 eventCountsCache = CacheBuilder.newBuilder().maximumSize(1000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<
ZoomParams, Map<EventType, Long>> rn) -> {
117 }).build(CacheLoader.from(eventDB::countEvents));
118 aggregateEventsCache = CacheBuilder.newBuilder().maximumSize(1000L).expireAfterAccess(10, TimeUnit.MINUTES).removalListener((RemovalNotification<
ZoomParams, List<AggregateEvent>> rn) -> {
120 }).build(CacheLoader.from(eventDB::getAggregatedEvents));
121 maxCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMaxTime));
122 minCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMinTime));
130 return maxCache.getUnchecked(
"max");
136 return minCache.getUnchecked(
"min");
141 eventDB.recordLastArtifactID(lastArtfID);
145 eventDB.recordWasIngestRunning(wasIngestRunning);
149 eventDB.recordLastObjID(lastObjID);
153 return eventDB.getWasIngestRunning();
157 return eventDB.getLastObjID();
160 return eventDB.getLastArtfactID();
184 return eventDB.getEventIDs(timeRange, filter);
212 private final Runnable
r;
216 progressDialog.setVisible(
true);
223 "EventsRepository.progressWindow.msg.reinit_db"),
"")));
227 eventDB.initializeDB();
233 final int numFiles = files.size();
235 "EventsRepository.progressWindow.msg.populateMacEventsFiles"),
"")));
240 for (
final Long fID : files) {
252 String datasourceName = StringUtils.substringBefore(StringUtils.stripStart(uniquePath,
"/"), parentPath);
253 String rootFolder = StringUtils.substringBetween(parentPath,
"/",
"/");
254 String shortDesc = datasourceName +
"/" + StringUtils.defaultIfBlank(rootFolder,
"");
255 String medD = datasourceName + parentPath;
272 NbBundle.getMessage(
this.getClass(),
273 "EventsRepository.progressWindow.msg.populateMacEventsFiles2"), f.
getName())));
275 LOGGER.log(Level.WARNING,
"failed to look up data for file : " + fID);
278 LOGGER.log(Level.WARNING,
"failed to insert mac event for file : " + fID, tskCoreException);
297 "EventsRepository.progressWindow.msg.commitingDb"),
"")));
299 eventDB.rollBackTransaction(trans);
301 eventDB.commitTransaction(trans,
true);
315 protected void process(List<ProgressWindow.ProgressUpdate> chunks) {
316 super.process(chunks);
318 progressDialog.
update(chunk);
325 progressDialog.
close();
328 }
catch (CancellationException ex) {
329 LOGGER.log(Level.INFO,
"Database population was cancelled by the user. Not all events may be present or accurate. See the log for details.", ex);
330 }
catch (InterruptedException | ExecutionException ex) {
331 LOGGER.log(Level.WARNING,
"Exception while populating database.", ex);
332 JOptionPane.showMessageDialog(null, NbBundle.getMessage(
this.getClass(),
333 "EventsRepository.msgdlg.problem.text"));
334 }
catch (Exception ex) {
335 LOGGER.log(Level.WARNING,
"Unexpected exception while populating database.", ex);
336 JOptionPane.showMessageDialog(null, NbBundle.getMessage(
this.getClass(),
337 "EventsRepository.msgdlg.problem.text"));
353 final int numArtifacts = blackboardArtifacts.size();
356 NbBundle.getMessage(
this.getClass(),
357 "EventsRepository.progressWindow.populatingXevents",
358 type.toString()),
"")));
365 if (eventDescription != null && eventDescription.getTime() > 0L) {
366 eventDB.insertEvent(eventDescription.getTime(), type, bbart.getObjectID(), bbart.getArtifactID(), eventDescription.getFullDescription(), eventDescription.getMedDescription(), eventDescription.getShortDescription(), null, trans);
371 NbBundle.getMessage(
this.getClass(),
372 "EventsRepository.progressWindow.populatingXevents",
373 type.toString()),
"")));
376 LOGGER.log(Level.SEVERE,
"There was a problem getting events with sub type = " + type.toString() +
".", ex);
static EventDB getEventDB(String dbPath)
void update(ProgressUpdate chunk)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(int artifactTypeID)
synchronized void rebuildRepository(Runnable r)
static final Logger LOGGER
static final String FILES_AND_DIRS_WHERE_CLAUSE
Interval getSpanningInterval(Collection< Long > eventIDs)
String getCaseDirectory()
final ProgressWindow progressDialog
FilteredEventsModel getEventsModel()
synchronized String getUniquePath()
Set< Long > getEventIDs(Interval timeRange, Filter filter)
Map< EventType, Long > countEvents(ZoomParams params)
final LoadingCache< Object, Long > minCache
List< Long > findAllFileIdsWhere(String sqlWhereClause)
void process(List< ProgressWindow.ProgressUpdate > chunks)
AbstractFile getAbstractFileById(long id)
SwingWorker< Void, ProgressWindow.ProgressUpdate > dbPopulationWorker
TskData.FileKnown getKnown()
void recordLastObjID(Long lastObjID)
DBPopulationWorker(Runnable r)
void recordWasIngestRunning(Boolean wasIngestRunning)
boolean getWasIngestRunning()
final LoadingCache< Object, Long > maxCache
EventsRepository(ReadOnlyObjectProperty< ZoomParams > currentStateProperty)
void populateEventType(final ArtifactEventType type, EventDB.EventTransaction trans, SleuthkitCase skCase)
final FilteredEventsModel modelInstance
void recordLastArtifactID(long lastArtfID)
SleuthkitCase getSleuthkitCase()
final LoadingCache< Long, TimeLineEvent > idToEventCache
BlackboardArtifact.ARTIFACT_TYPE getArtifactType()
TimeLineEvent getEventById(Long eventID)
Interval getSpanningInterval(Collection< Long > eventIDs)
final LoadingCache< ZoomParams, Map< EventType, Long > > eventCountsCache
static Case getCurrentCase()
final LoadingCache< ZoomParams, List< AggregateEvent > > aggregateEventsCache
List< AggregateEvent > getAggregatedEvents(ZoomParams params)
static AttributeEventDescription buildEventDescription(ArtifactEventType type, BlackboardArtifact artf)
static Logger getLogger(String name)
Interval getBoundingEventsInterval(Interval timeRange, Filter filter)
static final List<?extends EventType > allTypes