19 package org.sleuthkit.datamodel.blackboardutils.attributes;
21 import com.google.common.collect.ImmutableList;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
71 private final String url;
116 private final String path;
117 private final long objectID;
127 transient private static final List<String> KNOWN_MOUNTPOINTS
130 "/storage/emulated/");
149 this.path = normalizePath(pathName);
151 String fileName = path.substring(path.lastIndexOf(
'/') + 1);
152 if (fileName.isEmpty()) {
153 throw new TskCoreException(String.format(
"No file name specified for attachment file: %s, on data source = %d", path, dataSource.getId()));
156 String parentPathSubString = (path.lastIndexOf(
'/') < 0) ?
"" : path.substring(0, path.lastIndexOf(
'/'));
159 objectID = findAttachmentFile(caseDb, fileName, parentPathSubString, dataSource);
175 objectID = derivedFile.getId();
176 path = derivedFile.getUniquePath();
185 objectID = abstractFile.
getId();
216 private String normalizePath(String path) {
218 String adjustedPath = path.replace(
"\\",
"/").replace(
"%20",
" ");
221 for (String mountPoint : KNOWN_MOUNTPOINTS) {
222 if (adjustedPath.toLowerCase().startsWith(mountPoint)) {
223 adjustedPath = (
"/").concat(adjustedPath.substring(mountPoint.length()));
249 String whereClause = String.format(
"LOWER(name) = LOWER('%s') AND LOWER(parent_path) LIKE LOWER('%%%s%%')", fileName, parentPathSubstring);
250 List<AbstractFile> matchedFiles = caseDb.findAllFilesWhere(whereClause);
254 List<Long> allocFileMatchesOnSameDatasource =
new ArrayList<>();
255 List<Long> allocFileMatchesOnOtherDatasources =
new ArrayList<>();
256 List<Long> unallocFileMatches =
new ArrayList<>();
260 if (dataSource.getId() == file.getDataSource().getId()) {
261 allocFileMatchesOnSameDatasource.add(file.getId());
263 allocFileMatchesOnOtherDatasources.add(file.getId());
266 unallocFileMatches.add(file.getId());
271 return pickBestMatchFile(allocFileMatchesOnSameDatasource, allocFileMatchesOnOtherDatasources, unallocFileMatches);
302 private long pickBestMatchFile(List<Long> allocFileMatchesOnSameDatasource,
303 List<Long> allocFileMatchesOnOtherDatasources,
304 List<Long> unallocFileMatches) {
307 if (!allocFileMatchesOnSameDatasource.isEmpty() && allocFileMatchesOnSameDatasource.size() == 1) {
308 return allocFileMatchesOnSameDatasource.get(0);
311 if (!allocFileMatchesOnOtherDatasources.isEmpty()
312 && allocFileMatchesOnOtherDatasources.size() == 1) {
313 return allocFileMatchesOnOtherDatasources.get(0);
316 if (!unallocFileMatches.isEmpty()
317 && unallocFileMatches.size() == 1) {
318 return unallocFileMatches.get(0);
332 return this.objectID;
336 private final Collection<FileAttachment> fileAttachments;
337 private final Collection<URLAttachment> urlAttachments;
346 public MessageAttachments(Collection<FileAttachment> fileAttachments, Collection<URLAttachment> urlAttachments) {
347 this.fileAttachments = fileAttachments;
348 this.urlAttachments = urlAttachments;
357 return Collections.unmodifiableCollection(fileAttachments);
366 return Collections.unmodifiableCollection(urlAttachments);
375 return (fileAttachments.size() + urlAttachments.size());
FileAttachment(SleuthkitCase caseDb, Content dataSource, String pathName)
Collection< URLAttachment > getUrlAttachments()
ALLOC
Metadata structure is currently in an allocated state.
URLAttachment(String url)
MessageAttachments(Collection< FileAttachment > fileAttachments, Collection< URLAttachment > urlAttachments)
FileAttachment(DerivedFile derivedFile)
Collection< FileAttachment > getFileAttachments()
FileAttachment(AbstractFile abstractFile)
int getAttachmentsCount()