Autopsy  4.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
FilteredEventsModel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2014-15 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.datamodel;
20 
21 import com.google.common.eventbus.EventBus;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27 import java.util.Set;
28 import java.util.logging.Level;
29 import javafx.beans.Observable;
30 import javafx.beans.property.ReadOnlyObjectProperty;
31 import javafx.beans.property.ReadOnlyObjectWrapper;
32 import javafx.collections.ListChangeListener;
33 import javafx.collections.MapChangeListener;
34 import javax.annotation.concurrent.GuardedBy;
35 import org.joda.time.Interval;
63 import org.sleuthkit.datamodel.BlackboardArtifact;
64 import org.sleuthkit.datamodel.BlackboardArtifactTag;
65 import org.sleuthkit.datamodel.Content;
66 import org.sleuthkit.datamodel.ContentTag;
67 import org.sleuthkit.datamodel.TagName;
68 import org.sleuthkit.datamodel.TskCoreException;
69 
92 public final class FilteredEventsModel {
93 
94  private static final Logger LOGGER = Logger.getLogger(FilteredEventsModel.class.getName());
95 
99  @GuardedBy("this")
100  private final ReadOnlyObjectWrapper<Interval> requestedTimeRange = new ReadOnlyObjectWrapper<>();
101 
102  @GuardedBy("this")
103  private final ReadOnlyObjectWrapper<RootFilter> requestedFilter = new ReadOnlyObjectWrapper<>();
104 
105  @GuardedBy("this")
106  private final ReadOnlyObjectWrapper< EventTypeZoomLevel> requestedTypeZoom = new ReadOnlyObjectWrapper<>(EventTypeZoomLevel.BASE_TYPE);
107 
108  @GuardedBy("this")
109  private final ReadOnlyObjectWrapper< DescriptionLoD> requestedLOD = new ReadOnlyObjectWrapper<>(DescriptionLoD.SHORT);
110 
111  @GuardedBy("this")
112  private final ReadOnlyObjectWrapper<ZoomParams> requestedZoomParamters = new ReadOnlyObjectWrapper<>();
113 
114  private final EventBus eventbus = new EventBus("Event_Repository_EventBus"); //NON-NLS
115 
121  @GuardedBy("this")
122  private final EventsRepository repo;
123  private final Case autoCase;
124 
125  public FilteredEventsModel(EventsRepository repo, ReadOnlyObjectProperty<ZoomParams> currentStateProperty) {
126  this.repo = repo;
127  this.autoCase = repo.getAutoCase();
128  repo.getDatasourcesMap().addListener((MapChangeListener.Change<? extends Long, ? extends String> change) -> {
129  DataSourceFilter dataSourceFilter = new DataSourceFilter(change.getValueAdded(), change.getKey());
130  RootFilter rootFilter = filterProperty().get();
131  rootFilter.getDataSourcesFilter().addSubFilter(dataSourceFilter);
132  requestedFilter.set(rootFilter.copyOf());
133  });
134  repo.getHashSetMap().addListener((MapChangeListener.Change<? extends Long, ? extends String> change) -> {
135  HashSetFilter hashSetFilter = new HashSetFilter(change.getValueAdded(), change.getKey());
136  RootFilter rootFilter = filterProperty().get();
137  rootFilter.getHashHitsFilter().addSubFilter(hashSetFilter);
138  requestedFilter.set(rootFilter.copyOf());
139  });
140  repo.getTagNames().addListener((ListChangeListener.Change<? extends TagName> c) -> {
141  RootFilter rootFilter = filterProperty().get();
142  TagsFilter tagsFilter = rootFilter.getTagsFilter();
143  repo.syncTagsFilter(tagsFilter);
144  requestedFilter.set(rootFilter.copyOf());
145  });
147 
148  //TODO: use bindings to keep these in sync? -jm
149  requestedZoomParamters.addListener((Observable observable) -> {
150  final ZoomParams zoomParams = requestedZoomParamters.get();
151 
152  if (zoomParams != null) {
153  if (zoomParams.getTypeZoomLevel().equals(requestedTypeZoom.get()) == false
154  || zoomParams.getDescriptionLOD().equals(requestedLOD.get()) == false
155  || zoomParams.getFilter().equals(requestedFilter.get()) == false
156  || Objects.equals(zoomParams.getTimeRange(), requestedTimeRange.get()) == false) {
157 
158  requestedTypeZoom.set(zoomParams.getTypeZoomLevel());
159  requestedFilter.set(zoomParams.getFilter());
160  requestedTimeRange.set(zoomParams.getTimeRange());
161  requestedLOD.set(zoomParams.getDescriptionLOD());
162  }
163  }
164  });
165 
166  requestedZoomParamters.bind(currentStateProperty);
167  }
168 
169  synchronized public ReadOnlyObjectProperty<ZoomParams> zoomParametersProperty() {
170  return requestedZoomParamters.getReadOnlyProperty();
171  }
172 
177  synchronized public ReadOnlyObjectProperty<Interval> timeRangeProperty() {
178  if (requestedTimeRange.get() == null) {
180  }
181  return requestedTimeRange.getReadOnlyProperty();
182  }
183 
184  synchronized public ReadOnlyObjectProperty<DescriptionLoD> descriptionLODProperty() {
185  return requestedLOD.getReadOnlyProperty();
186  }
187 
188  synchronized public ReadOnlyObjectProperty<RootFilter> filterProperty() {
189  return requestedFilter.getReadOnlyProperty();
190  }
191 
192  synchronized public ReadOnlyObjectProperty<EventTypeZoomLevel> eventTypeZoomProperty() {
193  return requestedTypeZoom.getReadOnlyProperty();
194  }
195 
196  synchronized public DescriptionLoD getDescriptionLOD() {
197  return requestedLOD.get();
198  }
199 
200  synchronized public RootFilter getFilter() {
201  return requestedFilter.get();
202  }
203 
204  synchronized public EventTypeZoomLevel getEventTypeZoom() {
205  return requestedTypeZoom.get();
206  }
207 
212  DataSourcesFilter dataSourcesFilter = new DataSourcesFilter();
213 
214  repo.getDatasourcesMap().entrySet().stream().forEach((Map.Entry<Long, String> t) -> {
215  DataSourceFilter dataSourceFilter = new DataSourceFilter(t.getValue(), t.getKey());
216  dataSourceFilter.setSelected(Boolean.TRUE);
217  dataSourcesFilter.addSubFilter(dataSourceFilter);
218  });
219 
220  HashHitsFilter hashHitsFilter = new HashHitsFilter();
221  repo.getHashSetMap().entrySet().stream().forEach((Map.Entry<Long, String> t) -> {
222  HashSetFilter hashSetFilter = new HashSetFilter(t.getValue(), t.getKey());
223  hashSetFilter.setSelected(Boolean.TRUE);
224  hashHitsFilter.addSubFilter(hashSetFilter);
225  });
226 
227  TagsFilter tagsFilter = new TagsFilter();
228  repo.getTagNames().stream().forEach(t -> {
229  TagNameFilter tagNameFilter = new TagNameFilter(t, autoCase);
230  tagNameFilter.setSelected(Boolean.TRUE);
231  tagsFilter.addSubFilter(tagNameFilter);
232  });
233  return new RootFilter(new HideKnownFilter(), tagsFilter, hashHitsFilter, new TextFilter(), new TypeFilter(RootEventType.getInstance()), dataSourcesFilter, Collections.emptySet());
234  }
235 
236  public Interval getBoundingEventsInterval() {
238  }
239 
240  public TimeLineEvent getEventById(Long eventID) {
241  return repo.getEventById(eventID);
242  }
243 
244  public Set<TimeLineEvent> getEventsById(Collection<Long> eventIDs) {
245  return repo.getEventsById(eventIDs);
246  }
247 
256  public Map<String, Long> getTagCountsByTagName(Set<Long> eventIDsWithTags) {
257  return repo.getTagCountsByTagName(eventIDsWithTags);
258  }
259 
260  public Set<Long> getEventIDs(Interval timeRange, Filter filter) {
261  final Interval overlap;
262  final RootFilter intersect;
263  synchronized (this) {
264  overlap = getSpanningInterval().overlap(timeRange);
265  intersect = requestedFilter.get().copyOf();
266  }
267  intersect.getSubFilters().add(filter);
268  return repo.getEventIDs(overlap, intersect);
269  }
270 
281  public Map<EventType, Long> getEventCounts(Interval timeRange) {
282 
283  final RootFilter filter;
284  final EventTypeZoomLevel typeZoom;
285  synchronized (this) {
286  filter = requestedFilter.get();
287  typeZoom = requestedTypeZoom.get();
288  }
289  return repo.countEvents(new ZoomParams(timeRange, typeZoom, filter, null));
290  }
291 
296  public Interval getSpanningInterval() {
297  return new Interval(getMinTime() * 1000, 1000 + getMaxTime() * 1000);
298  }
299 
303  public Interval getSpanningInterval(Collection<Long> eventIDs) {
304  return repo.getSpanningInterval(eventIDs);
305  }
306 
312  public Long getMinTime() {
313  return repo.getMinTime();
314  }
315 
321  public Long getMaxTime() {
322  return repo.getMaxTime();
323  }
324 
330  public List<EventStripe> getEventStripes() {
331  final Interval range;
332  final RootFilter filter;
333  final EventTypeZoomLevel zoom;
334  final DescriptionLoD lod;
335  synchronized (this) {
336  range = requestedTimeRange.get();
337  filter = requestedFilter.get();
338  zoom = requestedTypeZoom.get();
339  lod = requestedLOD.get();
340  }
341  return repo.getEventStripes(new ZoomParams(range, zoom, filter, lod));
342  }
343 
351  public List<EventStripe> getEventStripes(ZoomParams params) {
352  return repo.getEventStripes(params);
353  }
354 
355  synchronized public boolean handleContentTagAdded(ContentTagAddedEvent evt) {
356  ContentTag contentTag = evt.getAddedTag();
357  Content content = contentTag.getContent();
358  Set<Long> updatedEventIDs = repo.addTag(content.getId(), null, contentTag, null);
359  return postTagsUpdated(updatedEventIDs);
360  }
361 
362  synchronized public boolean handleArtifactTagAdded(BlackBoardArtifactTagAddedEvent evt) {
363  BlackboardArtifactTag artifactTag = evt.getAddedTag();
364  BlackboardArtifact artifact = artifactTag.getArtifact();
365  Set<Long> updatedEventIDs = repo.addTag(artifact.getObjectID(), artifact.getArtifactID(), artifactTag, null);
366  return postTagsUpdated(updatedEventIDs);
367  }
368 
369  synchronized public boolean handleContentTagDeleted(ContentTagDeletedEvent evt) {
370  DeletedContentTagInfo deletedTagInfo = evt.getDeletedTagInfo();
371  try {
372  Content content = autoCase.getSleuthkitCase().getContentById(deletedTagInfo.getContentID());
373  boolean tagged = autoCase.getServices().getTagsManager().getContentTagsByContent(content).isEmpty() == false;
374  Set<Long> updatedEventIDs = repo.deleteTag(content.getId(), null, deletedTagInfo.getTagID(), tagged);
375  return postTagsUpdated(updatedEventIDs);
376  } catch (TskCoreException ex) {
377  LOGGER.log(Level.SEVERE, "unable to determine tagged status of content.", ex); //NON-NLS
378  }
379  return false;
380  }
381 
384  try {
385  BlackboardArtifact artifact = autoCase.getSleuthkitCase().getBlackboardArtifact(deletedTagInfo.getArtifactID());
386  boolean tagged = autoCase.getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact).isEmpty() == false;
387  Set<Long> updatedEventIDs = repo.deleteTag(artifact.getObjectID(), artifact.getArtifactID(), deletedTagInfo.getTagID(), tagged);
388  return postTagsUpdated(updatedEventIDs);
389  } catch (TskCoreException ex) {
390  LOGGER.log(Level.SEVERE, "unable to determine tagged status of artifact.", ex); //NON-NLS
391  }
392  return false;
393  }
394 
395  private boolean postTagsUpdated(Set<Long> updatedEventIDs) {
396  boolean tagsUpdated = !updatedEventIDs.isEmpty();
397  if (tagsUpdated) {
398  eventbus.post(new TagsUpdatedEvent(updatedEventIDs));
399  }
400  return tagsUpdated;
401  }
402 
403  synchronized public void registerForEvents(Object o) {
404  eventbus.register(o);
405  }
406 
407  synchronized public void unRegisterForEvents(Object o) {
408  eventbus.unregister(0);
409  }
410 
411  public void refresh() {
412  eventbus.post(new RefreshRequestedEvent());
413  }
414 
415 }
final ReadOnlyObjectWrapper< ZoomParams > requestedZoomParamters
Map< String, Long > getTagCountsByTagName(Set< Long > eventIDsWithTags)
synchronized ObservableMap< Long, String > getHashSetMap()
synchronized Map< EventType, Long > countEvents(ZoomParams params)
synchronized List< EventStripe > getEventStripes(ZoomParams params)
synchronized ObservableMap< Long, String > getDatasourcesMap()
Interval getSpanningInterval(Collection< Long > eventIDs)
synchronized ReadOnlyObjectProperty< EventTypeZoomLevel > eventTypeZoomProperty()
synchronized boolean handleArtifactTagAdded(BlackBoardArtifactTagAddedEvent evt)
Map< EventType, Long > getEventCounts(Interval timeRange)
synchronized Set< Long > deleteTag(long objID, Long artifactID, long tagID, boolean tagged)
synchronized boolean handleContentTagDeleted(ContentTagDeletedEvent evt)
synchronized ReadOnlyObjectProperty< ZoomParams > zoomParametersProperty()
synchronized Set< Long > addTag(long objID, Long artifactID, Tag tag, EventDB.EventTransaction trans)
synchronized List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)
synchronized ReadOnlyObjectProperty< RootFilter > filterProperty()
synchronized boolean handleContentTagAdded(ContentTagAddedEvent evt)
Set< Long > getEventIDs(Interval timeRange, RootFilter filter)
void addSubFilter(TagNameFilter tagFilter)
Definition: TagsFilter.java:76
final ReadOnlyObjectWrapper< EventTypeZoomLevel > requestedTypeZoom
synchronized boolean handleArtifactTagDeleted(BlackBoardArtifactTagDeletedEvent evt)
Map< String, Long > getTagCountsByTagName(Set< Long > eventIDsWithTags)
synchronized static Logger getLogger(String name)
Definition: Logger.java:166
Interval getBoundingEventsInterval(Interval timeRange, RootFilter filter)
Set< Long > getEventIDs(Interval timeRange, Filter filter)
synchronized Set< TimeLineEvent > getEventsById(Collection< Long > eventIDs)
synchronized ReadOnlyObjectProperty< DescriptionLoD > descriptionLODProperty()
synchronized ReadOnlyObjectProperty< Interval > timeRangeProperty()
synchronized List< ContentTag > getContentTagsByContent(Content content)
Set< TimeLineEvent > getEventsById(Collection< Long > eventIDs)
final ReadOnlyObjectWrapper< DescriptionLoD > requestedLOD

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.