19 package org.sleuthkit.autopsy.datamodel;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.EnumSet;
26 import java.util.List;
27 import java.util.Observable;
28 import java.util.Observer;
30 import java.util.logging.Level;
31 import org.openide.nodes.AbstractNode;
32 import org.openide.nodes.ChildFactory;
33 import org.openide.nodes.Children;
34 import org.openide.nodes.Node;
35 import org.openide.nodes.Sheet;
36 import org.openide.util.NbBundle;
37 import org.openide.util.lookup.Lookups;
62 @NbBundle.Messages({
"DeletedContent.fsDelFilter.text=File System",
63 "DeletedContent.allDelFilter.text=All"})
66 FS_DELETED_FILTER(0,
"FS_DELETED_FILTER",
67 Bundle.DeletedContent_fsDelFilter_text()),
68 ALL_DELETED_FILTER(1,
"ALL_DELETED_FILTER",
69 Bundle.DeletedContent_allDelFilter_text());
78 this.displayName = displayName;
91 return this.displayName;
96 return visitor.
visit(
this);
106 this.filteringDSObjId = dsObjId;
109 long filteringDataSourceObjId() {
114 public <T> T accept(AutopsyItemVisitor<T> visitor) {
115 return visitor.visit(
this);
124 @NbBundle.Messages(
"DeletedContent.deletedContentsNode.name=Deleted Files")
125 private static final String
NAME = Bundle.DeletedContent_deletedContentsNode_name();
130 super.setDisplayName(NAME);
131 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon-deleted.png");
141 return visitor.
visit(
this);
146 "DeletedContent.createSheet.name.displayName=Name",
147 "DeletedContent.createSheet.name.desc=no description"})
149 Sheet sheet = super.createSheet();
150 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
151 if (sheetSet == null) {
152 sheetSet = Sheet.createPropertiesSet();
157 Bundle.DeletedContent_createSheet_name_displayName(),
158 Bundle.DeletedContent_createSheet_name_desc(),
165 return getClass().getName();
179 this.datasourceObjId = dsObjId;
207 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
208 String eventType = evt.getPropertyName();
246 if (evt.getNewValue() == null) {
249 maxFilesDialogShown =
false;
261 protected boolean createKeys(List<DeletedContent.DeletedContentFilter> list) {
279 super(Children.create(
new DeletedContentChildren(
filter, skCase, null, dsObjId),
true), Lookups.singleton(
filter.getDisplayName()));
281 this.datasourceObjId = dsObjId;
286 super(Children.create(
new DeletedContentChildren(
filter, skCase, o, dsObjId),
true), Lookups.singleton(
filter.getDisplayName()));
288 this.datasourceObjId = dsObjId;
290 o.addObserver(
new DeletedContentNodeObserver());
294 super.setName(
filter.getName());
296 String tooltip =
filter.getDisplayName();
297 this.setShortDescription(tooltip);
298 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon-deleted.png");
306 public void update(Observable o, Object arg) {
313 final long count = DeletedContentChildren.calculateItems(skCase,
filter, datasourceObjId);
315 super.setDisplayName(
filter.getDisplayName() +
" (" + count +
")");
320 return visitor.
visit(
this);
325 "DeletedContent.createSheet.filterType.displayName=Type",
326 "DeletedContent.createSheet.filterType.desc=no description"})
328 Sheet sheet = super.createSheet();
329 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
330 if (sheetSet == null) {
331 sheetSet = Sheet.createPropertiesSet();
336 Bundle.DeletedContent_createSheet_filterType_displayName(),
337 Bundle.DeletedContent_createSheet_filterType_desc(),
338 filter.getDisplayName()));
358 static class DeletedContentChildren
extends BaseChildFactory<AbstractFile> {
360 private final SleuthkitCase
skCase;
368 super(filter.getName(),
new ViewsKnownAndSlackFilter<>());
370 this.filter = filter;
375 private final Observer observer =
new DeletedContentChildrenObserver();
378 protected List<AbstractFile> makeKeys() {
386 public void update(Observable o, Object arg) {
392 protected void onAdd() {
393 if (notifier != null) {
394 notifier.addObserver(observer);
399 protected void onRemove() {
400 if (notifier != null) {
401 notifier.deleteObserver(observer);
405 static private String makeQuery(
DeletedContent.DeletedContentFilter filter,
long filteringDSObjId) {
408 case FS_DELETED_FILTER:
409 query =
"dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
410 +
" AND meta_flags != " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
411 +
" AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType();
414 case ALL_DELETED_FILTER:
417 +
"(dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
419 +
"meta_flags = " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
421 +
" AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType()
423 +
" OR type = " + TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()
424 +
" OR (dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
425 +
" AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.LAYOUT_FILE.getFileType() +
" )"
436 logger.log(Level.SEVERE,
"Unsupported filter type to get deleted content: {0}", filter);
440 if (filteringDSObjId > 0) {
446 private List<AbstractFile> runFsQuery() {
447 List<AbstractFile> ret =
new ArrayList<>();
449 String query = makeQuery(filter, datasourceObjId);
451 ret = skCase.findAllFilesWhere(query);
452 }
catch (TskCoreException e) {
453 logger.log(Level.SEVERE,
"Error getting files for the deleted content view using: " + query, e);
468 static long calculateItems(SleuthkitCase sleuthkitCase,
DeletedContent.DeletedContentFilter filter,
long datasourceObjId) {
470 return sleuthkitCase.countFilesWhere(makeQuery(filter, datasourceObjId));
471 }
catch (TskCoreException ex) {
472 logger.log(Level.SEVERE,
"Error getting deleted files search view count", ex);
479 return key.accept(
new ContentVisitor.Default<AbstractNode>() {
480 public FileNode visit(AbstractFile f) {
481 return new FileNode(f, false);
484 public FileNode visit(FsContent f) {
485 return new FileNode(f,
false);
489 public FileNode visit(LayoutFile f) {
490 return new FileNode(f,
false);
494 public FileNode visit(File f) {
495 return new FileNode(f,
false);
499 public FileNode visit(Directory f) {
500 return new FileNode(f,
false);
504 public FileNode visit(VirtualDirectory f) {
505 return new FileNode(f,
false);
509 protected AbstractNode defaultVisit(Content di) {
510 throw new UnsupportedOperationException(
"Not supported for this type of Displayable Item: " + di.toString());
final long filteringDSObjId
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
public< T > T accept(AutopsyItemVisitor< T > visitor)
void update(Observable o, Object arg)
static volatile boolean maxFilesDialogShown
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
T visit(DataSourcesNode in)
final DeletedContent.DeletedContentFilter filter
void removeIngestJobEventListener(final PropertyChangeListener listener)
DeletedContentFilter(int id, String name, String displayName)
boolean createKeys(List< DeletedContent.DeletedContentFilter > list)
SleuthkitCase getSleuthkitCase()
void addIngestJobEventListener(final PropertyChangeListener listener)
final PropertyChangeListener pcl
final long datasourceObjId
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Node createNodeForKey(DeletedContent.DeletedContentFilter key)
DeletedContent(SleuthkitCase skCase)
DeletedContentsChildren(SleuthkitCase skCase, long dsObjId)
final long datasourceObjId
void update(Observable o, Object arg)
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
DeletedContent(SleuthkitCase skCase, long dsObjId)