Autopsy  4.9.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
CommonAttributeCaseSearchResults.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2018 Basis Technology Corp.
6  * Contact: carrier <at> sleuthkit <dot> org
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 package org.sleuthkit.autopsy.commonfilesearch;
21 
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.Set;
28 import java.util.logging.Level;
36 import org.sleuthkit.datamodel.AbstractFile;
37 
43 
44  private static final Logger LOGGER = Logger.getLogger(CommonAttributeCaseSearchResults.class.getName());
45 
46  // maps instance count to list of attribute values.
47  private final Map<String, Map<String, CommonAttributeValueList>> caseNameToDataSources;
48 
61  CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType, Set<String> mimeTypesToFilterOn) {
62  this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, resultType.getId(), mimeTypesToFilterOn);
63  }
64 
73  CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold) {
74  this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, CorrelationAttributeInstance.FILES_TYPE_ID, new HashSet<>());
75  }
76 
87  Map<String, CommonAttributeValueList> getAttributeValuesForCaseName(String caseName) {
88  return this.caseNameToDataSources.get(caseName);
89  }
90 
97  public Map<String, Map<String, CommonAttributeValueList>> getMetadata() {
98  return Collections.unmodifiableMap(this.caseNameToDataSources);
99  }
100 
117  private Map<String, Map<String, CommonAttributeValueList>> filterMetadata(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, int resultTypeId, Set<String> mimeTypesToFilterOn) {
118  try {
119  final String currentCaseName;
120  try {
121  currentCaseName = Case.getCurrentCaseThrows().getDisplayName();
122  } catch (NoCurrentCaseException ex) {
123  throw new EamDbException("Unable to get current case while performing filtering", ex);
124  }
125  Map<String, CommonAttributeValueList> currentCaseDataSourceMap = metadata.get(currentCaseName);
126  if (currentCaseDataSourceMap == null) {
127  throw new EamDbException("No data for current case found in results, indicating there are no results and nothing will be filtered");
128  }
131  .stream()
132  .filter(filterType -> filterType.getId() == resultTypeId)
133  .findFirst().get();
134  //Call countUniqueDataSources once to reduce the number of DB queries needed to get the frequencyPercentage
135  Double uniqueCaseDataSourceTuples = EamDb.getInstance().getCountUniqueDataSources().doubleValue();
136  Map<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>();
137  Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, percentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn);
138  for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(metadata).entrySet()) {
139  if (!mapOfDataSources.getKey().equals(currentCaseName)) {
140  //rebuild the metadata structure with items from the current case substituted for their matches in other cases results we want to filter out removed
141  Map<String, CommonAttributeValueList> newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue());
142  filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase);
143  }
144  }
145  return filteredCaseNameToDataSourcesTree;
146  } catch (EamDbException ex) {
147  LOGGER.log(Level.INFO, "Unable to perform filtering returning unfiltered result set", ex);
148  return metadata;
149  }
150 
151  }
152 
172  private Map<String, CommonAttributeValue> getValuesToKeepFromCurrentCase(Map<String, CommonAttributeValueList> dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set<String> mimeTypesToFilterOn) throws EamDbException {
173  Map<String, CommonAttributeValue> valuesToKeep = new HashMap<>();
174  Set<String> valuesToRemove = new HashSet<>();
175  for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) {
176  for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataList()) {
177  if (valuesToRemove.contains(value.getValue())) {
178  //do nothing this value will not be added
179  } else if (filterValue(attributeType, value, maximumPercentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn)) {
180  valuesToRemove.add(value.getValue());
181  } else {
182  valuesToKeep.put(value.getValue(), value);
183  }
184  }
185  }
186  return valuesToKeep;
187  }
188 
202  private Map<String, CommonAttributeValueList> createTreeForCase(Map<String, CommonAttributeValue> valuesToKeepCurrentCase, Map<String, CommonAttributeValueList> dataSourceToValueList) throws EamDbException {
203  Map<String, CommonAttributeValueList> treeForCase = new HashMap<>();
204  for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) {
205  for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataList()) {
206  if (valuesToKeepCurrentCase.containsKey(value.getValue())) {
207  if (!treeForCase.containsKey(mapOfValueLists.getKey())) {
208  treeForCase.put(mapOfValueLists.getKey(), new CommonAttributeValueList());
209  }
210  treeForCase.get(mapOfValueLists.getKey()).addMetadataToList(valuesToKeepCurrentCase.get(value.getValue()));
211  }
212  }
213  }
214  return treeForCase;
215  }
216 
237  private boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set<String> mimeTypesToInclude) throws EamDbException {
238  //Intracase common attribute searches will have been created with an empty mimeTypesToInclude list
239  //because when performing intra case search this filtering will have been done during the query of the case database
240  if (!mimeTypesToInclude.isEmpty()) { //only do the mime type filtering when mime types aren't empty
241  for (AbstractCommonAttributeInstance commonAttr : value.getInstances()) {
242  AbstractFile abstractFile = commonAttr.getAbstractFile();
243  if (abstractFile != null) {
244  String mimeType = abstractFile.getMIMEType();
245  if (mimeType != null && !mimeTypesToInclude.contains(mimeType)) {
246  return true;
247  }
248  }
249  }
250  }
251  if (maximumPercentageThreshold != 0) { //only do the frequency filtering when a max % was set
252  try {
254  attributeType, value.getValue()).doubleValue();
255  Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
256  int frequencyPercentage = commonalityPercentage.intValue();
257  if (frequencyPercentage > maximumPercentageThreshold) {
258  return true;
259  }
261  LOGGER.log(Level.WARNING, "Unable to determine frequency percentage attribute - frequency filter may not be accurate for these results.", ex);
262  }
263  }
264  return false;
265  }
266 }
Map< String, CommonAttributeValueList > createTreeForCase(Map< String, CommonAttributeValue > valuesToKeepCurrentCase, Map< String, CommonAttributeValueList > dataSourceToValueList)
Map< String, Map< String, CommonAttributeValueList > > filterMetadata(Map< String, Map< String, CommonAttributeValueList >> metadata, int percentageThreshold, int resultTypeId, Set< String > mimeTypesToFilterOn)
boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set< String > mimeTypesToInclude)
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
final Map< String, Map< String, CommonAttributeValueList > > caseNameToDataSources
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
Map< String, CommonAttributeValue > getValuesToKeepFromCurrentCase(Map< String, CommonAttributeValueList > dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set< String > mimeTypesToFilterOn)

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.