Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FileSize.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-2014 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  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Observable;
27 import java.util.Observer;
28 import java.util.logging.Level;
29 import org.openide.nodes.AbstractNode;
30 import org.openide.nodes.ChildFactory;
31 import org.openide.nodes.Children;
32 import org.openide.nodes.Node;
33 import org.openide.nodes.Sheet;
34 import org.openide.util.NbBundle;
35 import org.openide.util.lookup.Lookups;
52 
56 public class FileSize implements AutopsyVisitableItem {
57 
59 
60  public enum FileSizeFilter implements AutopsyVisitableItem {
61 
62  SIZE_50_200(0, "SIZE_50_200", "50 - 200MB"), //NON-NLS
63  SIZE_200_1000(1, "SIZE_200_1GB", "200MB - 1GB"), //NON-NLS
64  SIZE_1000_(2, "SIZE_1000+", "1GB+"); //NON-NLS
65  private int id;
66  private String name;
67  private String displayName;
68 
69  private FileSizeFilter(int id, String name, String displayName) {
70  this.id = id;
71  this.name = name;
72  this.displayName = displayName;
73 
74  }
75 
76  public String getName() {
77  return this.name;
78  }
79 
80  public int getId() {
81  return this.id;
82  }
83 
84  public String getDisplayName() {
85  return this.displayName;
86  }
87 
88  @Override
89  public <T> T accept(AutopsyItemVisitor<T> v) {
90  return v.visit(this);
91  }
92  }
93 
94  public FileSize(SleuthkitCase skCase) {
95  this.skCase = skCase;
96  }
97 
98  @Override
99  public <T> T accept(AutopsyItemVisitor<T> v) {
100  return v.visit(this);
101  }
102 
104  return this.skCase;
105  }
106 
107  /* Root node. Children are nodes for specific sizes. */
108  public static class FileSizeRootNode extends DisplayableItemNode {
109 
110  private static final String NAME = NbBundle.getMessage(FileSize.class, "FileSize.fileSizeRootNode.name");
111 
113  super(Children.create(new FileSizeRootChildren(skCase), true), Lookups.singleton(NAME));
114  super.setName(NAME);
115  super.setDisplayName(NAME);
116  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png"); //NON-NLS
117  }
118 
119  @Override
120  public boolean isLeafTypeNode() {
121  return false;
122  }
123 
124  @Override
125  public <T> T accept(DisplayableItemNodeVisitor<T> v) {
126  return v.visit(this);
127  }
128 
129  @Override
130  protected Sheet createSheet() {
131  Sheet s = super.createSheet();
132  Sheet.Set ss = s.get(Sheet.PROPERTIES);
133  if (ss == null) {
134  ss = Sheet.createPropertiesSet();
135  s.put(ss);
136  }
137 
138  ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileSize.createSheet.name.name"),
139  NbBundle.getMessage(this.getClass(), "FileSize.createSheet.name.displayName"),
140  NbBundle.getMessage(this.getClass(), "FileSize.createSheet.name.desc"),
141  NAME));
142  return s;
143  }
144  }
145 
146  /* Makes the children for specific sizes */
147  public static class FileSizeRootChildren extends ChildFactory<org.sleuthkit.autopsy.datamodel.FileSize.FileSizeFilter> {
148 
150  private Observable notifier;
151 
153  this.skCase = skCase;
154  notifier = new FileSizeRootChildrenObservable();
155  }
156 
161  private final class FileSizeRootChildrenObservable extends Observable {
162 
167  }
168 
169  private void removeListeners() {
170  deleteObservers();
174  }
175 
176  private final PropertyChangeListener pcl = new PropertyChangeListener() {
177  @Override
178  public void propertyChange(PropertyChangeEvent evt) {
179  String eventType = evt.getPropertyName();
180 
181  // new file was added
182  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
183  // @@@ could check the size here and only fire off updates if we know the file meets the min size criteria
184  update();
185  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
186  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
187  update();
188  } else if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
189  update();
190  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
191  // case was closed. Remove listeners so that we don't get called with a stale case handle
192  if (evt.getNewValue() == null) {
193  removeListeners();
194  }
195  }
196  }
197  };
198 
199  private void update() {
200  setChanged();
201  notifyObservers();
202  }
203  }
204 
205 
206  @Override
207  protected boolean createKeys(List<FileSizeFilter> list) {
208  list.addAll(Arrays.asList(FileSizeFilter.values()));
209  return true;
210  }
211 
212  @Override
213  protected Node createNodeForKey(FileSizeFilter key) {
214  return new FileSizeNode(skCase, key, notifier);
215  }
216 
217  /* Node for a specific size range. Children are files. */
218  public class FileSizeNode extends DisplayableItemNode {
220 
221  // use version with observer instead so that it updates
222  @Deprecated
223  FileSizeNode(SleuthkitCase skCase, FileSizeFilter filter) {
224  super(Children.create(new FileSizeChildren(filter, skCase, null), true), Lookups.singleton(filter.getDisplayName()));
225  this.filter = filter;
226  init();
227  }
228 
235  FileSizeNode(SleuthkitCase skCase, FileSizeFilter filter, Observable o) {
236  super(Children.create(new FileSizeChildren(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName()));
237  this.filter = filter;
238  init();
239  o.addObserver(new FileSizeNodeObserver());
240  }
241 
242  private void init() {
243  super.setName(filter.getName());
244 
245  String tooltip = filter.getDisplayName();
246  this.setShortDescription(tooltip);
247  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png"); //NON-NLS
248 
250  }
251 
252  // update the display name when new events are fired
253  private class FileSizeNodeObserver implements Observer {
254 
255  @Override
256  public void update(Observable o, Object arg) {
258  }
259  }
260 
261  private void updateDisplayName() {
262  final long count = FileSizeChildren.calculateItems(skCase, filter);
263  super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
264  }
265 
266  @Override
267  public <T> T accept(DisplayableItemNodeVisitor<T> v) {
268  return v.visit(this);
269  }
270 
271  @Override
272  protected Sheet createSheet() {
273  Sheet s = super.createSheet();
274  Sheet.Set ss = s.get(Sheet.PROPERTIES);
275  if (ss == null) {
276  ss = Sheet.createPropertiesSet();
277  s.put(ss);
278  }
279 
280  ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileSize.createSheet.filterType.name"),
281  NbBundle.getMessage(this.getClass(), "FileSize.createSheet.filterType.displayName"),
282  NbBundle.getMessage(this.getClass(), "FileSize.createSheet.filterType.desc"),
283  filter.getDisplayName()));
284 
285  return s;
286  }
287 
288  @Override
289  public boolean isLeafTypeNode() {
290  return true;
291  }
292  }
293 
294  /* Makes children, which are nodes for files of a given range */
295  static class FileSizeChildren extends ChildFactory.Detachable<AbstractFile> {
296 
297  private final SleuthkitCase skCase;
298  private final FileSizeFilter filter;
299  private final Observable notifier;
300  private static final Logger logger = Logger.getLogger(FileSizeChildren.class.getName());
301 
308  FileSizeChildren(FileSizeFilter filter, SleuthkitCase skCase, Observable o) {
309  this.skCase = skCase;
310  this.filter = filter;
311  this.notifier = o;
312  }
313 
314  @Override
315  protected void addNotify() {
316  if (notifier != null) {
317  notifier.addObserver(observer);
318  }
319  }
320 
321  @Override
322  protected void removeNotify() {
323  if (notifier != null) {
324  notifier.deleteObserver(observer);
325  }
326  }
327 
328  private final Observer observer = new FileSizeChildrenObserver();
329 
330  // Cause refresh of children if there are changes
331  private class FileSizeChildrenObserver implements Observer {
332 
333  @Override
334  public void update(Observable o, Object arg) {
335  refresh(true);
336  }
337  }
338 
339  @Override
340  protected boolean createKeys(List<AbstractFile> list) {
341  List<AbstractFile> l = runFsQuery();
342  if (l == null) {
343  return false;
344  }
345  list.addAll(l);
346  return true;
347  }
348 
349  private static String makeQuery(FileSizeFilter filter) {
350  String query;
351  switch (filter) {
352  case SIZE_50_200:
353  query = "(size >= 50000000 AND size < 200000000)"; //NON-NLS
354  break;
355  case SIZE_200_1000:
356  query = "(size >= 200000000 AND size < 1000000000)"; //NON-NLS
357  break;
358 
359  case SIZE_1000_:
360  query = "(size >= 1000000000)"; //NON-NLS
361  break;
362 
363  default:
364  logger.log(Level.SEVERE, "Unsupported filter type to get files by size: {0}", filter); //NON-NLS
365  return null;
366  }
367  // ignore unalloc block files
368  query = query + " AND (type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType() + ")"; //NON-NLS
369 
370  return query;
371  }
372 
373  private List<AbstractFile> runFsQuery() {
374  List<AbstractFile> ret = new ArrayList<>();
375 
376  String query = makeQuery(filter);
377  if (query == null) {
378  return null;
379  }
380 
381  try {
382  ret = skCase.findAllFilesWhere(query);
383  } catch (TskCoreException e) {
384  logger.log(Level.SEVERE, "Error getting files for the file size view using: " + query, e); //NON-NLS
385  }
386 
387  return ret;
388 
389  }
390 
396  static long calculateItems(SleuthkitCase sleuthkitCase, FileSizeFilter filter) {
397  try {
398  return sleuthkitCase.countFilesWhere(makeQuery(filter));
399  } catch (TskCoreException ex) {
400  logger.log(Level.SEVERE, "Error getting files by size search view count", ex); //NON-NLS
401  return 0;
402  }
403  }
404 
405  @Override
406  protected Node createNodeForKey(AbstractFile key) {
407  return key.accept(new ContentVisitor.Default<AbstractNode>() {
408  public FileNode visit(AbstractFile f) {
409  return new FileNode(f, false);
410  }
411 
412  public FileNode visit(FsContent f) {
413  return new FileNode(f, false);
414  }
415 
416  @Override
417  public FileNode visit(LayoutFile f) {
418  return new FileNode(f, false);
419  }
420 
421  @Override
422  public FileNode visit(File f) {
423  return new FileNode(f, false);
424  }
425 
426  @Override
427  public FileNode visit(Directory f) {
428  return new FileNode(f, false);
429  }
430 
431  @Override
432  public FileNode visit(LocalFile f) {
433  return new FileNode(f, false);
434  }
435 
436  @Override
437  public FileNode visit(DerivedFile f) {
438  return new FileNode(f, false);
439  }
440 
441  @Override
442  public FileNode visit(VirtualDirectory f) {
443  return new FileNode(f, false);
444  }
445 
446  @Override
447  protected AbstractNode defaultVisit(Content di) {
448  throw new UnsupportedOperationException(
449  NbBundle.getMessage(this.getClass(),
450  "FileSize.exception.notSupported.msg",
451  di.toString()));
452  }
453  });
454  }
455  }
456  }
457 }
public< T > T accept(AutopsyItemVisitor< T > v)
Definition: FileSize.java:89
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
static synchronized void removePropertyChangeListener(PropertyChangeListener listener)
Definition: Case.java:837
FileSizeFilter(int id, String name, String displayName)
Definition: FileSize.java:69
void addIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized void addPropertyChangeListener(PropertyChangeListener listener)
Definition: Case.java:833
List< AbstractFile > findAllFilesWhere(String sqlWhereClause)
static Logger getLogger(String name)
Definition: Logger.java:131

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.