diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/FileTypeUtils.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/FileTypeUtils.java index 4498021484..90c60bb190 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/FileTypeUtils.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/FileTypeUtils.java @@ -178,6 +178,25 @@ public enum FileTypeUtils { return ImageUtils.isGIF(file); } + public static Optional getMimeType(AbstractFile file) throws TskCoreException { + final FileTypeDetector fileTypeDetector = getFileTypeDetector(); + if (nonNull(fileTypeDetector)) { + return Optional.ofNullable(fileTypeDetector.getFileType(file)); + } + return Optional.empty(); + } + + static boolean isDrawableMimeType(String mimeType) { + if (isNull(mimeType)) { + return false; + } else { + String mimeTypeLower = mimeType.toLowerCase(); + return mimeTypeLower.startsWith("image/") + || mimeTypeLower.startsWith("video/") + || supportedMimeTypes.contains(mimeTypeLower); + } + } + /** * does the given file have drawable/supported mime type * @@ -188,21 +207,7 @@ public enum FileTypeUtils { * mimetype could not be detected. */ static Optional hasDrawableMimeType(AbstractFile file) throws TskCoreException { - - final FileTypeDetector fileTypeDetector = getFileTypeDetector(); - if (nonNull(fileTypeDetector)) { - String mimeType = fileTypeDetector.getFileType(file); - if (isNull(mimeType)) { - return Optional.empty(); - } else { - mimeType = mimeType.toLowerCase(); - return Optional.of(mimeType.startsWith("image/") - || mimeType.startsWith("video/") - || supportedMimeTypes.contains(mimeType)); - } - } - - return Optional.empty(); + return getMimeType(file).map(FileTypeUtils::isDrawableMimeType); } /** @@ -216,17 +221,14 @@ public enum FileTypeUtils { */ public static boolean isVideoFile(AbstractFile file) { try { - final FileTypeDetector fileTypeDetector = getFileTypeDetector(); - if (nonNull(fileTypeDetector)) { - String mimeType = fileTypeDetector.getFileType(file); - if (nonNull(mimeType)) { - mimeType = mimeType.toLowerCase(); - return mimeType.startsWith("video/") || videoMimeTypes.contains(mimeType); - } - } + return getMimeType(file) + .map(String::toLowerCase) + .map(mimeType -> + mimeType.startsWith("video/") + || videoMimeTypes.contains(mimeType)) + .orElseGet(() -> FileTypeUtils.videoExtensions.contains(file.getNameExtension())); } catch (TskCoreException ex) { - LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex); + return FileTypeUtils.videoExtensions.contains(file.getNameExtension()); } - return FileTypeUtils.videoExtensions.contains(file.getNameExtension()); } } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java index b749c9cdde..30c308b089 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java @@ -757,14 +757,16 @@ public final class ImageGalleryController implements Executor { if (known) { taskDB.removeFile(f.getId(), tr); //remove known files } else { - final Optional hasMimeType = FileTypeUtils.hasDrawableMimeType(f); - if (hasMimeType.isPresent()) { - if (hasMimeType.get()) { //supported mimetype => analyzed + Optional mimeType = FileTypeUtils.getMimeType(f); + if (mimeType.isPresent()) { + //mime type + if (FileTypeUtils.isDrawableMimeType(mimeType.get())) { //supported mimetype => analyzed taskDB.updateFile(DrawableFile.create(f, true, false), tr); } else { //unsupported mimtype => analyzed but shouldn't include taskDB.removeFile(f.getId(), tr); } } else { + //no mime tyoe if (FileTypeUtils.isDrawable(f)) { //no mime type but supported => add as not analyzed taskDB.insertFile(DrawableFile.create(f, false, false), tr); diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java index 61ef672bc2..265f5ebaa3 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java @@ -42,6 +42,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.stream.Collectors; +import javax.annotation.Nonnull; import javax.annotation.concurrent.GuardedBy; import javax.swing.SortOrder; import org.apache.commons.lang3.StringUtils; @@ -588,18 +589,27 @@ public final class DrawableDB { insertOrUpdateFile(f, tr, updateFileStmt); } - private void insertOrUpdateFile(DrawableFile f, DrawableTransaction tr, PreparedStatement stmt) { + /** + * Update (or insert) a file in(to) the drawable db. Weather this is an + * insert or an update depends on the given prepared statement. This method + * also inserts hash set hits and groups into their respective tables for + * the given file. + * + * //TODO: this is a kinda weird design, is their a better way? //TODO: + * implement batch version -jm + * + * @param f The file to insert. + * @param tr a transaction to use, must not be null + * @param stmt the statement that does the actull inserting + */ + private void insertOrUpdateFile(DrawableFile f, @Nonnull DrawableTransaction tr, @Nonnull PreparedStatement stmt) { - //TODO: implement batch version -jm if (tr.isClosed()) { throw new IllegalArgumentException("can't update database with closed transaction"); } dbWriteLock(); try { - // Update the list of file IDs in memory - addImageFileToList(f.getId()); - // "INSERT OR IGNORE/ INTO drawable_files (path, name, created_time, modified_time, make, model, analyzed)" stmt.setLong(1, f.getId()); stmt.setString(2, f.getDrawablePath()); @@ -610,6 +620,8 @@ public final class DrawableDB { stmt.setString(7, f.getModel()); stmt.setBoolean(8, f.isAnalyzed()); stmt.executeUpdate(); + // Update the list of file IDs in memory + addImageFileToList(f.getId()); try { for (String name : f.getHashSetNames()) { @@ -633,24 +645,29 @@ public final class DrawableDB { } } } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "failed to insert/update hash hits for file" + f.getName(), ex); + LOGGER.log(Level.SEVERE, "failed to insert/update hash hits for file" + f.getContentPathSafe(), ex); } //and update all groups this file is in for (DrawableAttribute attr : DrawableAttribute.getGroupableAttrs()) { Collection> vals = attr.getValue(f); - for (Object val : vals) { - insertGroup(val.toString(), attr); + for (Comparable val : vals) { + //use empty string for null values (mime_type), this shouldn't happen! + if (null != val) { + insertGroup(val.toString(), attr); + } } } tr.addUpdatedFile(f.getId()); } catch (SQLException | NullPointerException ex) { - // This is one of the places where we get an error if the case is closed during processing, - // which doesn't need to be reported here. + /* + * This is one of the places where we get an error if the case is + * closed during processing, which doesn't need to be reported here. + */ if (Case.isCaseOpen()) { - LOGGER.log(Level.SEVERE, "failed to insert/update file" + f.getName(), ex); + LOGGER.log(Level.SEVERE, "failed to insert/update file" + f.getContentPathSafe(), ex); } } finally {