19 package org.sleuthkit.datamodel;
21 import com.google.common.net.InternetDomainName;
23 import java.net.URISyntaxException;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
26 import org.apache.commons.lang3.StringUtils;
35 class TimelineEventTypes {
37 private TimelineEventTypes() {
45 final static class EmptyExtractor
implements TimelineEventArtifactTypeImpl.TSKCoreCheckedFunction<BlackboardArtifact, String> {
48 public String apply(BlackboardArtifact ignored)
throws TskCoreException {
53 static class URLArtifactEventType
extends TimelineEventArtifactTypeSingleDescription {
55 URLArtifactEventType(
int typeID, String displayName, TimelineEventType superType, BlackboardArtifact.Type artifactType, BlackboardAttribute.Type timeAttribute, BlackboardAttribute.Type descriptionAttribute) {
56 super(typeID, displayName, superType, artifactType, timeAttribute, descriptionAttribute);
60 TimelineEventDescription parseDescription(String fullDescriptionRaw, String medDescriptionRaw, String shortDescriptionRaw) {
68 String fullDescription = fullDescriptionRaw;
70 URI uri =
new URI(fullDescription);
71 String host = uri.getHost();
73 host = StringUtils.strip(fullDescription,
"./");
76 String shortDescription;
77 if (InternetDomainName.isValid(host)) {
78 InternetDomainName domain = InternetDomainName.from(host);
79 shortDescription = (domain.isUnderPublicSuffix())
80 ? domain.topPrivateDomain().toString()
83 shortDescription = host;
86 String mediumDescription =
new URI(uri.getScheme(), uri.getUserInfo(), host, uri.getPort(), uri.getPath(), null, null).toString();
88 return new TimelineEventDescription(fullDescription, mediumDescription, shortDescription);
89 }
catch (URISyntaxException ex) {
91 return new TimelineEventDescription(fullDescription);
96 static class FilePathEventType
extends TimelineEventTypeImpl {
98 FilePathEventType(
long typeID, String displayName, TimelineEventType.HierarchyLevel eventTypeZoomLevel, TimelineEventType superType) {
99 super(typeID, displayName, eventTypeZoomLevel, superType);
103 TimelineEventDescription parseDescription(String fullDescription, String medDescription, String shortDescription) {
104 return parseFilePathDescription(fullDescription);
109 static class FilePathArtifactEventType
extends TimelineEventArtifactTypeSingleDescription {
111 FilePathArtifactEventType(
int typeID, String displayName, TimelineEventType superType, BlackboardArtifact.Type artifactType, BlackboardAttribute.Type timeAttribute, BlackboardAttribute.Type descriptionAttribute) {
112 super(typeID, displayName, superType, artifactType, timeAttribute, descriptionAttribute);
116 TimelineEventDescription parseDescription(String fullDescriptionRaw, String medDescriptionRaw, String shortDescriptionRaw) {
117 return parseFilePathDescription(fullDescriptionRaw);
126 static class GPSTrackArtifactEventType
extends TimelineEventArtifactTypeSingleDescription {
128 private final TskGeoTrackpointsUtil trackpointUtil =
new TskGeoTrackpointsUtil();
130 GPSTrackArtifactEventType(
int typeID, String displayName, TimelineEventType superType, BlackboardArtifact.Type artifactType, BlackboardAttribute.Type descriptionAttribute) {
132 super(typeID, displayName, superType, artifactType,
new BlackboardAttribute.Type(TSK_GEO_TRACKPOINTS), descriptionAttribute);
136 public TimelineEventDescriptionWithTime makeEventDescription(BlackboardArtifact artifact)
throws TskCoreException {
139 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(TSK_GEO_TRACKPOINTS));
140 if (attribute == null) {
145 GeoTrackPointList pointsList = trackpointUtil.fromAttribute(attribute);
146 Long startTime = pointsList.getStartTime();
149 if (startTime == null) {
153 return new TimelineEventDescriptionWithTime(startTime, null, null, extractFullDescription(artifact));
165 static TimelineEventDescription parseFilePathDescription(String fullDescription) {
167 String[] split = fullDescription.split(
"/");
168 String mediumDescription = Stream.of(split)
169 .filter(StringUtils::isNotBlank)
170 .limit(Math.max(1, split.length - 2))
171 .collect(Collectors.joining(
"/",
"/",
""))
172 .replaceAll(
"//",
"/");
174 String shortDescription = Stream.of(split)
175 .filter(StringUtils::isNotBlank)
177 .collect(Collectors.joining(
"/",
"/",
""))
178 .replaceAll(
"//",
"/");
179 return new TimelineEventDescription(fullDescription, mediumDescription, shortDescription);