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.Observable;
32 import java.util.Observer;
34 import java.util.logging.Level;
35 import java.util.stream.Collectors;
36 import org.apache.commons.lang3.StringUtils;
37 import org.openide.nodes.ChildFactory;
38 import org.openide.nodes.Children;
39 import org.openide.nodes.Node;
40 import org.openide.nodes.Sheet;
41 import org.openide.util.NbBundle;
42 import org.openide.util.lookup.Lookups;
83 private final PropertyChangeListener
pcl;
102 return "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() +
")"
104 + TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal() +
","
105 + TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal() +
","
106 + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal() +
","
107 + TskData.TSK_DB_FILES_TYPE_ENUM.LAYOUT_FILE.ordinal() +
","
108 + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()
109 + (hideSlackFilesInViewsTree() ?
"" : (
"," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()))
111 + ((filteringDataSourceObjId() > 0) ?
" AND data_source_obj_id = " + this.filteringDataSourceObjId() :
" ")
112 + (hideKnownFilesInViewsTree() ? (
" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() +
")") :
"");
127 String query =
"SELECT mime_type, count(*) AS count FROM tsk_files "
128 +
" WHERE mime_type IS NOT null "
130 +
" GROUP BY mime_type";
132 existingMimeTypeCounts.clear();
135 ResultSet resultSet = dbQuery.getResultSet();
136 while (resultSet.next()) {
137 final String mime_type = resultSet.getString(
"mime_type");
138 if (!mime_type.isEmpty()) {
140 final String mediaType = StringUtils.substringBefore(mime_type,
"/");
141 final String subType = StringUtils.removeStart(mime_type, mediaType +
"/");
142 if (!mediaType.isEmpty() && !subType.isEmpty()) {
143 final long count = resultSet.getLong(
"count");
144 existingMimeTypeCounts.computeIfAbsent(mediaType, t ->
new HashMap<>())
145 .put(subType, count);
150 logger.log(Level.SEVERE,
"Unable to populate File Types by MIME Type tree view from DB: ", ex);
160 this.pcl = (PropertyChangeEvent evt) -> {
161 String eventType = evt.getPropertyName();
167 }
else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
168 if (evt.getNewValue() == null) {
173 refreshThrottler =
new RefreshThrottler(
new FileTypesByMimeTypeRefresher());
181 public <T> T accept(AutopsyItemVisitor<T> visitor) {
182 return visitor.visit(
this);
185 long filteringDataSourceObjId() {
186 return typesRoot.filteringDataSourceObjId();
199 boolean isEmptyMimeNode =
false;
201 isEmptyMimeNode =
true;
203 return isEmptyMimeNode;
215 typesRoot.updateShowCounts();
250 @NbBundle.Messages({
"FileTypesByMimeType.name.text=By MIME Type"})
252 final String NAME = Bundle.FileTypesByMimeType_name_text();
255 super(Children.create(
new ByMimeTypeNodeChildren(),
true), Lookups.singleton(Bundle.FileTypesByMimeType_name_text()));
257 super.setDisplayName(NAME);
258 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
262 public boolean isLeafTypeNode() {
267 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
268 return visitor.visit(
this);
272 public String getItemType() {
273 return getClass().getName();
278 return existingMimeTypeCounts.isEmpty();
296 final List<String> keylist;
298 keylist =
new ArrayList<>(existingMimeTypeCounts.keySet());
300 Collections.sort(keylist);
301 mediaTypeNodes.addAll(keylist);
308 return new MediaTypeNode(key);
312 public void update(Observable o, Object arg) {
323 @NbBundle.Messages({
"FileTypesByMimeTypeNode.createSheet.mediaType.name=Type",
324 "FileTypesByMimeTypeNode.createSheet.mediaType.displayName=Type",
325 "FileTypesByMimeTypeNode.createSheet.mediaType.desc=no description"})
327 MediaTypeNode(String name) {
328 super(Children.create(
new MediaTypeNodeChildren(name),
true), Lookups.singleton(name));
330 setDisplayName(name);
331 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
335 public boolean isLeafTypeNode() {
340 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
341 return visitor.visit(
this);
345 protected Sheet createSheet() {
346 Sheet sheet = super.createSheet();
347 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
348 if (sheetSet == null) {
349 sheetSet = Sheet.createPropertiesSet();
352 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()));
357 public String getItemType() {
358 return getClass().getName();
374 this.mediaType = name;
379 mediaTypeNodes.addAll(existingMimeTypeCounts.get(mediaType).keySet());
385 String mimeType = mediaType +
"/" + subtype;
386 return new MediaSubTypeNode(mimeType);
390 public void update(Observable o, Object arg) {
400 final class MediaSubTypeNode
extends FileTypes.BGCountUpdatingNode {
402 @NbBundle.Messages({
"FileTypesByMimeTypeNode.createSheet.mediaSubtype.name=Subtype",
403 "FileTypesByMimeTypeNode.createSheet.mediaSubtype.displayName=Subtype",
404 "FileTypesByMimeTypeNode.createSheet.mediaSubtype.desc=no description"})
405 private final String mimeType;
406 private final String subType;
408 private MediaSubTypeNode(String mimeType) {
409 super(typesRoot, Children.create(
new MediaSubTypeNodeChildren(mimeType),
true), Lookups.singleton(mimeType));
410 this.mimeType = mimeType;
411 this.subType = StringUtils.substringAfter(mimeType,
"/");
412 super.setName(mimeType);
413 super.setDisplayName(subType);
415 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-filter-icon.png");
426 public boolean isLeafTypeNode() {
431 public <T> T accept(DisplayableItemNodeVisitor< T> visitor) {
432 return visitor.visit(
this);
436 protected Sheet createSheet() {
437 Sheet sheet = super.createSheet();
438 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
439 if (sheetSet == null) {
440 sheetSet = Sheet.createPropertiesSet();
443 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()));
448 public String getItemType() {
449 return getClass().getName();
453 public void update(Observable o, Object arg) {
458 String getDisplayNameBase() {
463 long calculateChildCount() {
464 return existingMimeTypeCounts.get(StringUtils.substringBefore(mimeType,
"/")).
get(subType);
478 super(mimeType,
new ViewsKnownAndSlackFilter<>());
484 public void update(Observable o, Object arg) {
498 .stream().map(f ->
new FileTypesKey(f)).collect(Collectors.toList());
500 logger.log(Level.SEVERE,
"Couldn't get search results", ex);
502 return Collections.emptyList();
void registerForIngestModuleEvents()
String createBaseWhereExpr()
static synchronized IngestManager getInstance()
boolean createKeys(List< String > mediaTypeNodes)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
void unregisterEventListener()
void update(Observable o, Object arg)
static boolean hideKnownFilesInViewsTree()
void removeIngestJobEventListener(final PropertyChangeListener listener)
final RefreshThrottler refreshThrottler
final PropertyChangeListener pcl
static boolean hideSlackFilesInViewsTree()
SleuthkitCase getSleuthkitCase()
boolean isRefreshRequired(PropertyChangeEvent evt)
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 final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
final FileTypes typesRoot
static final Logger logger