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.HashMap;
28 import java.util.List;
29 import java.util.Observable;
30 import java.util.Observer;
31 import java.util.logging.Level;
32 import org.apache.commons.lang3.ArrayUtils;
33 import org.apache.commons.lang3.StringUtils;
34 import org.openide.nodes.AbstractNode;
35 import org.openide.nodes.ChildFactory;
36 import org.openide.nodes.Children;
37 import org.openide.nodes.Node;
38 import org.openide.util.NbBundle;
84 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
85 String eventType = evt.getPropertyName();
98 }
catch (IllegalStateException notUsed) {
104 if (evt.getNewValue() == null) {
118 List<String> mediaTypes =
new ArrayList<>(existingMimeTypes.keySet());
119 Collections.sort(mediaTypes);
129 StringBuilder allDistinctMimeTypesQuery =
new StringBuilder();
130 allDistinctMimeTypesQuery.append(
"SELECT DISTINCT mime_type from tsk_files where mime_type IS NOT null");
140 existingMimeTypes.clear();
142 if (skCase == null) {
147 ResultSet resultSet = dbQuery.getResultSet();
148 while (resultSet.next()) {
149 final String mime_type = resultSet.getString(
"mime_type");
150 if (!mime_type.isEmpty()) {
151 String mimeType[] = mime_type.split(
"/");
153 final String mimeMediaSubType = StringUtils.join(ArrayUtils.subarray(mimeType, 1, mimeType.length),
"/");
154 if (mimeType.length > 1 && !mimeType[0].isEmpty() && !mimeMediaSubType.isEmpty()) {
155 if (!existingMimeTypes.containsKey(mimeType[0])) {
156 existingMimeTypes.put(mimeType[0],
new ArrayList<>());
158 existingMimeTypes.get(mimeType[0]).add(mimeMediaSubType);
163 LOGGER.log(Level.SEVERE,
"Unable to populate File Types by MIME Type tree view from DB: ", ex);
180 public <T> T accept(AutopsyItemVisitor<T> v) {
181 return v.visit(
this);
194 boolean isEmptyMimeNode =
false;
196 isEmptyMimeNode =
true;
198 return isEmptyMimeNode;
210 @NbBundle.Messages(
"FileTypesByMimeType.name.text=By MIME Type")
211 final String NAME = Bundle.FileTypesByMimeType_name_text();
214 super(Children.create(
new ByMimeTypeNodeChildren(),
true));
216 super.setDisplayName(NAME);
217 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
221 public boolean isLeafTypeNode() {
226 public <T> T accept(DisplayableItemNodeVisitor<T> v) {
227 return v.visit(
this);
231 public String getItemType() {
232 return getClass().getName();
236 return existingMimeTypes.isEmpty();
254 if (!existingMimeTypes.isEmpty()) {
262 return new MediaTypeNode(key);
266 public void update(Observable o, Object arg) {
278 MediaTypeNode(String name) {
279 super(Children.create(
new MediaTypeNodeChildren(name),
true));
281 setDisplayName(name);
282 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file_types.png");
286 public boolean isLeafTypeNode() {
291 public <T> T accept(DisplayableItemNodeVisitor<T> v) {
292 return v.visit(
this);
296 public String getItemType() {
297 return getClass().getName();
313 this.mediaType = name;
318 mediaTypeNodes.addAll(existingMimeTypes.get(mediaType));
324 String mimeType = mediaType +
"/" + subtype;
325 return new MediaSubTypeNode(mimeType);
329 public void update(Observable o, Object arg) {
341 private MediaSubTypeNode(String mimeType) {
342 super(Children.create(
new MediaSubTypeNodeChildren(mimeType),
true));
347 private void init(String mimeType) {
348 super.setName(mimeType);
349 updateDisplayName(mimeType);
350 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-filter-icon.png");
360 private void updateDisplayName(String mimeType) {
361 final long count =
new MediaSubTypeNodeChildren(mimeType).calculateItems(skCase, mimeType);
362 String[] mimeTypeParts = mimeType.split(
"/");
364 super.setDisplayName(StringUtils.join(ArrayUtils.subarray(mimeTypeParts, 1, mimeTypeParts.length),
"/") +
" (" + count +
")");
374 public boolean isLeafTypeNode() {
379 public <T> T accept(DisplayableItemNodeVisitor<T> v) {
380 return v.visit(
this);
384 public String getItemType() {
385 return getClass().getName();
389 public void update(Observable o, Object arg) {
390 updateDisplayName(getName());
419 LOGGER.log(Level.SEVERE,
"Error getting file search view count", ex);
440 LOGGER.log(Level.SEVERE,
"Couldn't get search results", ex);
457 StringBuilder query =
new StringBuilder();
467 query.append(
" AND (known IS NULL OR known != ").append(
TskData.
FileKnown.
KNOWN.getFileKnownValue()).append(
")");
469 query.append(
" AND mime_type = '").append(mime_type).append(
"'");
470 return query.toString();
474 public void update(Observable o, Object arg) {
490 public FileNode visit(File f) {
491 return new FileNode(f, false);
520 protected AbstractNode defaultVisit(
Content di) {
521 throw new UnsupportedOperationException(NbBundle.getMessage(
this.getClass(),
"FileTypeChildren.exception.notSupported.msg", di.toString()));
final SleuthkitCase skCase
static synchronized IngestManager getInstance()
boolean createKeys(List< String > mediaTypeNodes)
static void removePropertyChangeListener(PropertyChangeListener listener)
void update(Observable o, Object arg)
static boolean hideKnownFilesInViewsTree()
void removeIngestJobEventListener(final PropertyChangeListener listener)
long countFilesWhere(String sqlWhereClause)
void addIngestJobEventListener(final PropertyChangeListener listener)
final PropertyChangeListener pcl
static final Logger LOGGER
final HashMap< String, List< String > > existingMimeTypes
static boolean hideSlackFilesInViewsTree()
static void addPropertyChangeListener(PropertyChangeListener listener)
Node createNodeForKey(String key)
List< AbstractFile > findAllFilesWhere(String sqlWhereClause)
static boolean isEmptyMimeTypeNode(Node node)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
public< T > T accept(ContentVisitor< T > v)
List< String > getMediaTypeList()
CaseDbQuery executeQuery(String query)