19 package org.sleuthkit.datamodel;
21 import com.google.common.annotations.VisibleForTesting;
22 import com.google.common.collect.Lists;
23 import com.google.common.net.MediaType;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import static java.util.Arrays.asList;
27 import java.util.Collection;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Objects;
32 import java.util.stream.Collectors;
33 import static java.util.stream.Collectors.joining;
34 import java.util.stream.Stream;
35 import static org.apache.commons.lang3.ObjectUtils.notEqual;
36 import org.apache.commons.lang3.StringUtils;
71 @SuppressWarnings(
"unchecked")
72 static <S extends TimelineFilter, T extends CompoundFilter<S>> T copySubFilters(T from, T to) {
73 from.getSubFilters().forEach(subFilter -> to.addSubFilter((S) subFilter.copyOf()));
98 @SuppressWarnings(
"unchecked")
99 List<SubFilterType> subfilters = Lists.transform(
getSubFilters(), f -> (SubFilterType) f.copyOf());
107 .collect(joining(
","));
108 return BundleProvider.getBundle().getString(
"IntersectionFilter.displayName.text") +
"[" + subFilterDisplayNames +
"]";
113 String trueLiteral = manager.getSQLWhere(null);
115 .filter(Objects::nonNull)
116 .map(filter -> filter.getSQLWhere(manager))
117 .filter(sqlString -> notEqual(sqlString, trueLiteral))
118 .collect(Collectors.joining(
" AND "));
119 return join.isEmpty() ? trueLiteral :
"(" + join +
")";
148 super(
new ArrayList<>());
149 this.rootEventType = rootEventType;
169 this(rootEventType,
true);
179 return rootEventType;
191 return copySubFilters(
this,
new EventTypeFilter(rootEventType,
false));
197 hash = 17 * hash + Objects.hashCode(this.rootEventType);
209 if (getClass() != obj.getClass()) {
216 return Objects.
equals(this.getSubFilters(), other.getSubFilters());
221 return "(tsk_events.event_type_id IN (" + getSubTypeIDs().collect(Collectors.joining(
",")) +
"))";
224 private Stream<String> getSubTypeIDs() {
225 if (this.getSubFilters().isEmpty()) {
228 return this.getSubFilters().stream().flatMap(EventTypeFilter::getSubTypeIDs);
234 return "EventTypeFilter{" +
"rootEventType=" + rootEventType +
", subfilters=" + getSubFilters() +
'}';
245 private boolean eventSourcesAreTagged;
265 this.eventSourcesAreTagged = eventSourcesAreTagged;
277 this.eventSourcesAreTagged = eventSourcesAreTagged;
287 return eventSourcesAreTagged;
292 return BundleProvider.getBundle().getString(
"tagsFilter.displayName.text");
302 if (obj == null || !(obj instanceof
TagsFilter)) {
312 hash = 67 * hash + Objects.hashCode(this.eventSourcesAreTagged);
319 if (eventSourcesAreTagged) {
320 whereStr =
"tagged = 1";
322 whereStr =
"tagged = 0";
343 super(
new ArrayList<SubFilterType>());
348 super.addSubFilter(subfilter);
354 .map(subFilter -> subFilter.getSQLWhere(manager))
355 .collect(Collectors.joining(
" OR "));
356 return join.isEmpty() ? manager.getSQLWhere(null) :
"(" + join +
")";
367 private String descriptionSubstring;
388 this.descriptionSubstring = descriptionSubstring.trim();
398 this.descriptionSubstring = descriptionSubstring.trim();
403 return BundleProvider.getBundle().getString(
"TextFilter.displayName.text");
413 return descriptionSubstring;
426 if (getClass() != obj.getClass()) {
436 hash = 29 * hash + Objects.hashCode(this.descriptionSubstring);
442 if (StringUtils.isNotBlank(
this.getDescriptionSubstring())) {
447 return manager.getSQLWhere(null);
453 return "TextFilter{" +
"textProperty=" + descriptionSubstring +
'}';
467 private final TextFilter descriptionSubstringFilter;
471 private final Set<TimelineFilter> additionalFilters =
new HashSet<>();
479 return dataSourcesFilter;
497 return hashSetHitsFilter;
506 return eventTypesFilter;
515 return knownFilesFilter;
524 return descriptionSubstringFilter;
533 return fileTypesFilter;
569 Collection<TimelineFilter> additionalFilters) {
571 super(Arrays.asList(descriptionSubstringFilter, knownFilesFilter, tagsFilter, dataSourcesFilter, hashSetHitsFilter, fileTypesFilter, eventTypesFilter));
572 getSubFilters().removeIf(Objects::isNull);
573 this.knownFilesFilter = knownFilesFilter;
574 this.tagsFilter = tagsFilter;
575 this.hashSetHitsFilter = hashSetHitsFilter;
576 this.descriptionSubstringFilter = descriptionSubstringFilter;
577 this.eventTypesFilter = eventTypesFilter;
578 this.dataSourcesFilter = dataSourcesFilter;
579 this.fileTypesFilter = fileTypesFilter;
580 this.additionalFilters.addAll(asList(descriptionSubstringFilter, knownFilesFilter, tagsFilter, dataSourcesFilter, hashSetHitsFilter, fileTypesFilter, eventTypesFilter));
581 this.additionalFilters.removeIf(Objects::isNull);
582 additionalFilters.stream().
583 filter(Objects::nonNull).
584 filter(this::hasAdditionalFilter).
586 forEach(anonymousFilter -> getSubFilters().add(anonymousFilter));
591 Set<TimelineFilter> subFilters = getSubFilters().stream()
592 .filter(this::hasAdditionalFilter)
594 .collect(Collectors.toSet());
596 hashSetHitsFilter.
copyOf(), descriptionSubstringFilter.
copyOf(), eventTypesFilter.
copyOf(),
597 dataSourcesFilter.
copyOf(), fileTypesFilter.
copyOf(), subFilters);
602 return !(additionalFilters.contains(subFilter));
607 return "RootFilter{" +
"knownFilter=" + knownFilesFilter +
", tagsFilter=" + tagsFilter +
", hashFilter=" + hashSetHitsFilter +
", textFilter=" + descriptionSubstringFilter +
", typeFilter=" + eventTypesFilter +
", dataSourcesFilter=" + dataSourcesFilter +
", fileTypesFilter=" + fileTypesFilter +
", namedSubFilters=" + additionalFilters +
'}';
613 hash = 17 * hash + Objects.hashCode(this.knownFilesFilter);
614 hash = 17 * hash + Objects.hashCode(this.tagsFilter);
615 hash = 17 * hash + Objects.hashCode(this.hashSetHitsFilter);
616 hash = 17 * hash + Objects.hashCode(this.descriptionSubstringFilter);
617 hash = 17 * hash + Objects.hashCode(this.eventTypesFilter);
618 hash = 17 * hash + Objects.hashCode(this.dataSourcesFilter);
619 hash = 17 * hash + Objects.hashCode(this.fileTypesFilter);
620 hash = 17 * hash + Objects.hashCode(this.additionalFilters);
632 if (getClass() != obj.getClass()) {
645 if (notEqual(this.descriptionSubstringFilter, other.
getTextFilter())) {
658 return Objects.
equals(this.additionalFilters, other.getSubFilters());
671 return BundleProvider.getBundle().getString(
"hideKnownFilter.displayName.text");
689 return getClass() == obj.getClass();
699 return "HideKnownFilter{" +
'}';
719 private final List<SubFilterType> subFilters =
new ArrayList<>();
747 this.subFilters.addAll(subFilters);
756 hash = 23 * hash + Objects.hashCode(this.subFilters);
768 if (getClass() != obj.getClass()) {
777 return this.getClass().getSimpleName() +
"{" +
"subFilters=" + subFilters +
'}';
788 private final String dataSourceName;
789 private final long dataSourceID;
806 return dataSourceName;
818 this.dataSourceName = dataSourceName;
819 this.dataSourceID = dataSourceID;
835 hash = 47 * hash + Objects.hashCode(this.dataSourceName);
836 hash = 47 * hash + (int) (this.dataSourceID ^ (this.dataSourceID >>> 32));
848 if (getClass() != obj.getClass()) {
852 if (this.dataSourceID != other.dataSourceID) {
855 return Objects.
equals(this.dataSourceName, other.dataSourceName);
873 private boolean eventSourcesHaveHashSetHits;
893 this.eventSourcesHaveHashSetHits = eventSourcesHaveHashSetHits;
903 this.eventSourcesHaveHashSetHits = eventSourcesHaveHashSetHits;
913 return eventSourcesHaveHashSetHits;
918 return BundleProvider.getBundle().getString(
"hashHitsFilter.displayName.text");
938 hash = 67 * hash + Objects.hashCode(this.eventSourcesHaveHashSetHits);
944 String whereStr =
"";
945 if (eventSourcesHaveHashSetHits) {
946 whereStr =
"hash_hit = 1";
948 whereStr =
"hash_hit = 0";
970 return BundleProvider.getBundle().getString(
"DataSourcesFilter.displayName.text");
989 return BundleProvider.getBundle().getString(
"FileTypesFilter.displayName.text");
1001 super(displayName, mediaTypes);
1011 return " NOT " + super.getSQLWhere(manager);
1021 private final String displayName;
1022 private final String sqlWhere;
1023 Collection<String> mediaTypes =
new HashSet<>();
1026 this.displayName = displayName;
1027 this.sqlWhere = sql;
1042 .map(MediaType::parse)
1043 .map(FileTypeFilter::mediaTypeToSQL)
1044 .collect(Collectors.joining(
" OR ",
"(",
")")));
1045 this.mediaTypes = mediaTypes;
1048 private static String mediaTypeToSQL(MediaType mediaType) {
1049 return mediaType.hasWildcard()
1050 ?
" (tsk_events.mime_type LIKE '" + escapeSingleQuotes(mediaType.type()) +
"/_%' ) "
1051 :
" (tsk_events.mime_type = '" + escapeSingleQuotes(mediaType.toString()) +
"' ) ";
1067 hash = 17 * hash + Objects.hashCode(this.displayName);
1068 hash = 17 * hash + Objects.hashCode(this.sqlWhere);
1080 if (getClass() != obj.getClass()) {
1084 if (notEqual(this.displayName, other.displayName)) {
1087 return Objects.
equals(this.sqlWhere, other.sqlWhere);
1097 return "FileTypeFilter{" +
"displayName=" + displayName +
", sqlWhere=" + sqlWhere +
'}';
DataSourcesFilter copyOf()
boolean equals(Object obj)
HideKnownFilter getKnownFilter()
boolean equals(Object obj)
TextFilter getTextFilter()
InverseFileTypeFilter(String displayName, Collection< String > mediaTypes)
boolean equals(Object obj)
HashHitsFilter(boolean eventSourcesHaveHashSetHits)
boolean equals(Object obj)
SortedSet<?extends TimelineEventType > getChildren()
CompoundFilter(List< SubFilterType > subFilters)
final List< SubFilterType > getSubFilters()
TimelineEventType getRootEventType()
abstract String getDisplayName()
FileTypeFilter(String displayName, Collection< String > mediaTypes)
synchronized DataSourceFilter copyOf()
boolean equals(Object obj)
DataSourcesFilter getDataSourcesFilter()
synchronized TextFilter copyOf()
EventTypeFilter getEventTypeFilter()
FileTypesFilter getFileTypesFilter()
void addSubFilter(SubFilterType subfilter)
EventTypeFilter(TimelineEventType rootEventType)
TextFilter(String descriptionSubstring)
IntersectionFilter(List< SubFilterType > subFilters)
synchronized boolean getEventSourcesHaveHashSetHits()
InverseFileTypeFilter copyOf()
static String escapeSingleQuotes(String text)
synchronized void setEventSourcesHaveHashSetHits(boolean eventSourcesHaveHashSetHits)
boolean equals(Object obj)
TagsFilter getTagsFilter()
IntersectionFilter< SubFilterType > copyOf()
String getDataSourceName()
abstract CompoundFilter< SubFilterType > copyOf()
boolean equals(Object obj)
synchronized void setDescriptionSubstring(String descriptionSubstring)
abstract TimelineFilter copyOf()
RootFilter(HideKnownFilter knownFilesFilter, TagsFilter tagsFilter, HashHitsFilter hashSetHitsFilter, TextFilter descriptionSubstringFilter, EventTypeFilter eventTypesFilter, DataSourcesFilter dataSourcesFilter, FileTypesFilter fileTypesFilter, Collection< TimelineFilter > additionalFilters)
boolean equals(Object obj)
TimelineEventType ROOT_EVENT_TYPE
KNOWN
File marked as a known by hash db.
void addSubFilter(SubFilterType subfilter)
synchronized String getDescriptionSubstring()
DataSourceFilter(String dataSourceName, long dataSourceID)
HashHitsFilter getHashHitsFilter()