Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FileSearch.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2019-2021 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 */
19package org.sleuthkit.autopsy.discovery.search;
20
21import com.google.common.cache.Cache;
22import com.google.common.cache.CacheBuilder;
23import java.io.IOException;
24import java.util.ArrayList;
25import java.util.LinkedHashMap;
26import java.util.List;
27import java.util.Map;
28import java.util.logging.Level;
29import org.apache.commons.lang.StringUtils;
30import org.openide.util.NbBundle;
31import org.sleuthkit.autopsy.coreutils.Logger;
32import org.sleuthkit.datamodel.AbstractFile;
33import org.sleuthkit.datamodel.SleuthkitCase;
34import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
35import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.AttributeType;
36import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
37import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.SearchKey;
38import org.sleuthkit.autopsy.textsummarizer.TextSummarizer;
39import org.sleuthkit.autopsy.textsummarizer.TextSummary;
40
44public class FileSearch {
45
46 private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
47 private static final int MAXIMUM_CACHE_SIZE = 10;
48 private static final Cache<SearchKey, Map<GroupKey, List<Result>>> searchCache = CacheBuilder.newBuilder()
49 .maximumSize(MAXIMUM_CACHE_SIZE)
50 .build();
51
74 static SearchResults runFileSearchDebug(String userName,
75 List<AbstractFilter> filters,
76 AttributeType groupAttributeType,
77 Group.GroupSortingAlgorithm groupSortingType,
78 ResultsSorter.SortingMethod fileSortingMethod,
79 SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context) throws DiscoveryException, SearchCancellationException {
80 // Make a list of attributes that we want to add values for. This ensures the
81 // ResultFile objects will have all needed fields set when it's time to group
82 // and sort them. For example, if we're grouping by central repo frequency, we need
83 // to make sure we've loaded those values before grouping.
84 List<AttributeType> attributesNeededForGroupingOrSorting = new ArrayList<>();
85 attributesNeededForGroupingOrSorting.add(groupAttributeType);
86 attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
87
88 // Run the queries for each filter
89 List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb, context);
90
91 // Add the data to resultFiles for any attributes needed for sorting and grouping
92 addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb, context);
93
94 // Collect everything in the search results
95 SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
96 searchResults.add(results);
97
98 // Sort and group the results
99 searchResults.sortGroupsAndFiles();
100 Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
101 SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
102 synchronized (searchCache) {
103 searchCache.put(searchKey, resultHashMap);
104 }
105 return searchResults;
106 }
107
130 public static Map<GroupKey, Integer> getGroupSizes(String userName,
131 List<AbstractFilter> filters,
132 AttributeType groupAttributeType,
133 Group.GroupSortingAlgorithm groupSortingType,
134 ResultsSorter.SortingMethod fileSortingMethod,
135 SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context) throws DiscoveryException, SearchCancellationException {
136 Map<GroupKey, List<Result>> searchResults = runFileSearch(userName, filters,
137 groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb, context);
138 LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
139 for (GroupKey groupKey : searchResults.keySet()) {
140 if (context.searchIsCancelled()) {
141 throw new SearchCancellationException("The search was cancelled before group sizes were finished being calculated");
142 }
143 groupSizes.put(groupKey, searchResults.get(groupKey).size());
144 }
145 return groupSizes;
146 }
147
174 public static List<Result> getFilesInGroup(String userName,
175 List<AbstractFilter> filters,
176 AttributeType groupAttributeType,
177 Group.GroupSortingAlgorithm groupSortingType,
178 ResultsSorter.SortingMethod fileSortingMethod,
179 GroupKey groupKey,
180 int startingEntry,
181 int numberOfEntries,
182 SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context) throws DiscoveryException, SearchCancellationException {
183 //the group should be in the cache at this point
184 List<Result> filesInGroup = null;
185 SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
186 Map<GroupKey, List<Result>> resultsMap;
187 synchronized (searchCache) {
188 resultsMap = searchCache.getIfPresent(searchKey);
189 }
190 if (resultsMap != null) {
191 filesInGroup = resultsMap.get(groupKey);
192 }
193 List<Result> page = new ArrayList<>();
194 if (filesInGroup == null) {
195 logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
196 runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb, context);
197 synchronized (searchCache) {
198 resultsMap = searchCache.getIfPresent(searchKey.getKeyString());
199 }
200 if (resultsMap != null) {
201 filesInGroup = resultsMap.get(groupKey);
202 }
203 if (filesInGroup == null) {
204 logger.log(Level.WARNING, "Group {0} did not exist in cache or new search results", groupKey);
205 return page; //group does not exist
206 }
207 }
208 // Check that there is data after the starting point
209 if (filesInGroup.size() < startingEntry) {
210 logger.log(Level.WARNING, "Group only contains {0} files, starting entry of {1} is too large.", new Object[]{filesInGroup.size(), startingEntry});
211 return page;
212 }
213 // Add files to the page
214 for (int i = startingEntry; (i < startingEntry + numberOfEntries)
215 && (i < filesInGroup.size()); i++) {
216 page.add(filesInGroup.get(i));
217 }
218 return page;
219 }
220
229 @NbBundle.Messages({"FileSearch.documentSummary.noPreview=No preview available.",
230 "FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview."})
231 public static TextSummary summarize(AbstractFile file) {
232 TextSummary summary = null;
233 TextSummarizer localSummarizer;
234 synchronized (searchCache) {
235 localSummarizer = SummaryHelpers.getLocalSummarizer();
236 }
237 if (localSummarizer != null) {
238 try {
239 //a summary of length 40 seems to fit without vertical scroll bars
240 summary = localSummarizer.summarize(file, 40);
241 } catch (IOException ex) {
242 return new TextSummary(Bundle.FileSearch_documentSummary_noPreview(), null, 0);
243 }
244 }
245 if (summary == null || StringUtils.isBlank(summary.getSummaryText())) {
246 //summary text was empty grab the beginning of the file
247 summary = SummaryHelpers.getDefaultSummary(file);
248 }
249 return summary;
250 }
251
273 public static Map<GroupKey, List<Result>> runFileSearch(String userName,
274 List<AbstractFilter> filters,
275 AttributeType groupAttributeType,
276 Group.GroupSortingAlgorithm groupSortingType,
277 ResultsSorter.SortingMethod fileSortingMethod,
278 SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context) throws DiscoveryException, SearchCancellationException {
279
280 // Make a list of attributes that we want to add values for. This ensures the
281 // ResultFile objects will have all needed fields set when it's time to group
282 // and sort them. For example, if we're grouping by central repo frequency, we need
283 // to make sure we've loaded those values before grouping.
284 List<AttributeType> attributesNeededForGroupingOrSorting = new ArrayList<>();
285 attributesNeededForGroupingOrSorting.add(groupAttributeType);
286 attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
287
288 // Run the queries for each filter
289 List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb, context);
290
291 // Add the data to resultFiles for any attributes needed for sorting and grouping
292 addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb, context);
293
294 // Collect everything in the search results
295 SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
296 searchResults.add(results);
297 Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
298 SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
299 synchronized (searchCache) {
300 searchCache.put(searchKey, resultHashMap);
301 }
302 // Return a version of the results in general Java objects
303 return resultHashMap;
304 }
305
323 private static void addAttributes(List<AttributeType> attrs, List<Result> results, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
325 for (AttributeType attr : attrs) {
326 attr.addAttributeToResults(results, caseDb, centralRepoDb, context);
327 }
328 }
329
330 private FileSearch() {
331 // Class should not be instantiated
332 }
333
334}
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static void addAttributes(List< AttributeType > attrs, List< Result > results, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
static List< Result > getFilesInGroup(String userName, List< AbstractFilter > filters, AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, ResultsSorter.SortingMethod fileSortingMethod, GroupKey groupKey, int startingEntry, int numberOfEntries, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
static Map< GroupKey, List< Result > > runFileSearch(String userName, List< AbstractFilter > filters, AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, ResultsSorter.SortingMethod fileSortingMethod, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
static final Cache< SearchKey, Map< GroupKey, List< Result > > > searchCache
static TextSummary summarize(AbstractFile file)
static Map< GroupKey, Integer > getGroupSizes(String userName, List< AbstractFilter > filters, AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, ResultsSorter.SortingMethod fileSortingMethod, SleuthkitCase caseDb, CentralRepository centralRepoDb, SearchContext context)
TextSummary summarize(AbstractFile file, int summarySize)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.