19 package org.sleuthkit.autopsy.datamodel;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.EnumSet;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.Objects;
32 import java.util.Observable;
33 import java.util.Observer;
35 import java.util.logging.Level;
36 import java.util.stream.Collectors;
37 import org.apache.commons.lang3.StringUtils;
38 import org.openide.nodes.ChildFactory;
39 import org.openide.nodes.Children;
40 import org.openide.nodes.Node;
41 import org.openide.nodes.Sheet;
42 import org.openide.util.NbBundle;
43 import org.openide.util.lookup.Lookups;
85 private final PropertyChangeListener
pcl;
98 return "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() +
")"
100 + TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal() +
","
101 + TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal() +
","
102 + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal() +
","
103 + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()
104 + (hideSlackFilesInViewsTree() ?
"" : (
"," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()))
107 + (hideKnownFilesInViewsTree() ? (
" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() +
")") :
"");
121 String query =
"SELECT mime_type, count(*) AS count FROM tsk_files "
122 +
" WHERE mime_type IS NOT null "
124 +
" GROUP BY mime_type";
126 existingMimeTypeCounts.clear();
128 if (skCase == null) {
131 try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(query)) {
132 ResultSet resultSet = dbQuery.getResultSet();
133 while (resultSet.next()) {
134 final String mime_type = resultSet.getString(
"mime_type");
135 if (!mime_type.isEmpty()) {
137 final String mediaType = StringUtils.substringBefore(mime_type,
"/");
138 final String subType = StringUtils.removeStart(mime_type, mediaType +
"/");
139 if (!mediaType.isEmpty() && !subType.isEmpty()) {
140 final long count = resultSet.getLong(
"count");
141 existingMimeTypeCounts.computeIfAbsent(mediaType, t ->
new HashMap<>())
142 .put(subType, count);
146 }
catch (TskCoreException | SQLException ex) {
147 logger.log(Level.SEVERE,
"Unable to populate File Types by MIME Type tree view from DB: ", ex);
156 this.skCase = typesRoot.getSleuthkitCase();
158 this.pcl = (PropertyChangeEvent evt) -> {
159 String eventType = evt.getPropertyName();
172 typesRoot.updateShowCounts();
174 }
catch (NoCurrentCaseException notUsed) {
179 }
else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
180 if (evt.getNewValue() == null) {
185 IngestManager.getInstance().addIngestJobEventListener(pcl);
191 public <T> T accept(AutopsyItemVisitor<T> visitor) {
192 return visitor.visit(
this);
195 long filteringDataSourceObjId() {
196 return typesRoot.filteringDataSourceObjId();
209 boolean isEmptyMimeNode =
false;
211 isEmptyMimeNode =
true;
213 return isEmptyMimeNode;
225 @NbBundle.Messages({
"FileTypesByMimeType.name.text=By MIME Type"})
227 final String NAME = Bundle.FileTypesByMimeType_name_text();
230 super(Children.create(
new ByMimeTypeNodeChildren(),
true), Lookups.singleton(Bundle.FileTypesByMimeType_name_text()));
232 super.setDisplayName(NAME);
233 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
237 public boolean isLeafTypeNode() {
242 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
243 return visitor.visit(
this);
247 public String getItemType() {
248 return getClass().getName();
253 return existingMimeTypeCounts.isEmpty();
271 final List<String> keylist;
273 keylist =
new ArrayList<>(existingMimeTypeCounts.keySet());
275 Collections.sort(keylist);
276 mediaTypeNodes.addAll(keylist);
283 return new MediaTypeNode(key);
287 public void update(Observable o, Object arg) {
298 @NbBundle.Messages({
"FileTypesByMimeTypeNode.createSheet.mediaType.name=Type",
299 "FileTypesByMimeTypeNode.createSheet.mediaType.displayName=Type",
300 "FileTypesByMimeTypeNode.createSheet.mediaType.desc=no description"})
302 MediaTypeNode(String name) {
303 super(Children.create(
new MediaTypeNodeChildren(name),
true), Lookups.singleton(name));
305 setDisplayName(name);
306 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
310 public boolean isLeafTypeNode() {
315 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
316 return visitor.visit(
this);
320 protected Sheet createSheet() {
321 Sheet sheet = super.createSheet();
322 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
323 if (sheetSet == null) {
324 sheetSet = Sheet.createPropertiesSet();
327 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaType.name"), NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaType.displayName"), NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaType.desc"), getDisplayName()));
332 public String getItemType() {
333 return getClass().getName();
349 this.mediaType = name;
354 mediaTypeNodes.addAll(existingMimeTypeCounts.get(mediaType).keySet());
360 String mimeType = mediaType +
"/" + subtype;
361 return new MediaSubTypeNode(mimeType);
365 public void update(Observable o, Object arg) {
375 class MediaSubTypeNode
extends FileTypes.BGCountUpdatingNode {
377 @NbBundle.Messages({
"FileTypesByMimeTypeNode.createSheet.mediaSubtype.name=Subtype",
378 "FileTypesByMimeTypeNode.createSheet.mediaSubtype.displayName=Subtype",
379 "FileTypesByMimeTypeNode.createSheet.mediaSubtype.desc=no description"})
380 private final String mimeType;
381 private final String subType;
383 private MediaSubTypeNode(String mimeType) {
384 super(typesRoot, Children.create(
new MediaSubTypeNodeChildren(mimeType),
true), Lookups.singleton(mimeType));
385 this.mimeType = mimeType;
386 this.subType = StringUtils.substringAfter(mimeType,
"/");
387 super.setName(mimeType);
388 super.setDisplayName(subType);
390 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-filter-icon.png");
401 public boolean isLeafTypeNode() {
406 public <T> T accept(DisplayableItemNodeVisitor< T> visitor) {
407 return visitor.visit(
this);
411 protected Sheet createSheet() {
412 Sheet sheet = super.createSheet();
413 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
414 if (sheetSet == null) {
415 sheetSet = Sheet.createPropertiesSet();
418 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaSubtype.name"), NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaSubtype.displayName"), NbBundle.getMessage(
this.getClass(),
"FileTypesByMimeTypeNode.createSheet.mediaSubtype.desc"), getDisplayName()));
423 public String getItemType() {
424 return getClass().getName();
428 public void update(Observable o, Object arg) {
433 String getDisplayNameBase() {
438 long calculateChildCount() {
439 return existingMimeTypeCounts.get(StringUtils.substringBefore(mimeType,
"/")).
get(subType);
461 list.addAll(skCase.findAllFilesWhere(
createBaseWhereExpr() +
" AND mime_type = '" + mimeType +
"'")
462 .stream().map(f ->
new FileTypesKey(f)).collect(Collectors.toList()));
463 }
catch (TskCoreException ex) {
464 logger.log(Level.SEVERE,
"Couldn't get search results", ex);
470 public void update(Observable o, Object arg) {
String createBaseWhereExpr()
final SleuthkitCase skCase
static synchronized IngestManager getInstance()
boolean createKeys(List< String > mediaTypeNodes)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
void update(Observable o, Object arg)
static boolean hideKnownFilesInViewsTree()
void removeIngestJobEventListener(final PropertyChangeListener listener)
final PropertyChangeListener pcl
static boolean hideSlackFilesInViewsTree()
static Boolean getGroupItemsInTreeByDataSource()
final HashMap< String, Map< String, Long > > existingMimeTypeCounts
Node createNodeForKey(String key)
static boolean isEmptyMimeTypeNode(Node node)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
final FileTypes typesRoot
static final Logger logger