From b02243dac780f363e2a1190ff896d44ab044e64c Mon Sep 17 00:00:00 2001
From: Greg DiCristofaro <gregd@basistech.com>
Date: Fri, 7 Jul 2023 09:10:48 -0400
Subject: [PATCH] updates

---
 .../org/sleuthkit/datamodel/AbstractFile.java | 62 +++++++++----------
 ...Stream.java => ContentProviderStream.java} | 22 +------
 .../sleuthkit/datamodel/SleuthkitCase.java    | 17 +++--
 3 files changed, 41 insertions(+), 60 deletions(-)
 rename bindings/java/src/org/sleuthkit/datamodel/{ContentStream.java => ContentProviderStream.java} (71%)

diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
index db07ed5d4..a7166b65e 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
@@ -119,9 +119,9 @@ public abstract class AbstractFile extends AbstractContent {
 	private volatile String uniquePath;
 	private volatile FileSystem parentFileSystem;
 	
-	private boolean tryContentStream;
-	private Object contentStreamLock = new Object();
-	private SoftReference<ContentStream> contentStreamRef = null;
+	private boolean tryContentProviderStream;
+	private Object contentProviderStreamLock = new Object();
+	private SoftReference<ContentProviderStream> contentProviderStreamRef = null;
 
 	/**
 	 * Initializes common fields used by AbstactFile implementations (objects in
@@ -234,8 +234,8 @@ public abstract class AbstractFile extends AbstractContent {
 		this.osAccountObjId = osAccountObjectId;
 		this.collected = collected;
 		// any item that is marked as YES_REPO and there is a custom content provider for the db will attempt to use the content provider to provide data
-		// this will be flipped to false if there is no content stream from the content provider for this file
-		this.tryContentStream = collected == CollectedStatus.YES_REPO && db.getContentProvider() != null;
+		// this will be flipped to false if there is no content provider stream from the content provider for this file
+		this.tryContentProviderStream = collected == CollectedStatus.YES_REPO && db.getContentProvider() != null;
 		if (Objects.nonNull(fileAttributes) && !fileAttributes.isEmpty()) {
 			this.fileAttributesCache.addAll(fileAttributes);
 			loadedAttributesCacheFromDb = true;
@@ -1074,52 +1074,52 @@ short getMetaFlagsAsInt() {
 	
 
 	
-	private boolean hasContentStream() {
-		ContentStream contentStream = null;
+	private boolean hasContentProviderStream() {
+		ContentProviderStream contentProviderStream = null;
 		try {
-			contentStream = getContentStream();	
+			contentProviderStream = getContentProviderStream();	
 		} catch (TskCoreException ex) {
-			LOGGER.log(Level.WARNING, "An error occurred while loading content stream for file with id: " + getId(), ex);
+			LOGGER.log(Level.WARNING, "An error occurred while loading content provider stream for file with id: " + getId(), ex);
 		}
-		return contentStream != null;
+		return contentProviderStream != null;
 	}
 	
 	/**
-	 * Attempts to load the content stream for this file.  If none exists, returns null.
+	 * Attempts to load the content provider stream for this file.  If none exists, returns null.
 	 * @return  The content stream for this file or null if none exists.
 	 * @throws TskCoreException 
 	 */
-	private ContentStream getContentStream() throws TskCoreException {
-		ContentStream contentStream = null;
-		if (tryContentStream) {
+	private ContentProviderStream getContentProviderStream() throws TskCoreException {
+		ContentProviderStream contentProviderStream = null;
+		if (tryContentProviderStream) {
 			try {
-				synchronized (contentStreamLock) {
-					// try to get soft reference content stream
-					contentStream = contentStreamRef == null ? null : contentStreamRef.get();
+				synchronized (contentProviderStreamLock) {
+					// try to get soft reference content provider stream
+					contentProviderStream = contentProviderStreamRef == null ? null : contentProviderStreamRef.get();
 					// load if not cached and then cache if present
-					if (contentStream == null) {
-						contentStream = getSleuthkitCase().getContentProvider().getContentStream(this).orElse(null);
-						if (contentStream != null) {
-							this.contentStreamRef = new SoftReference<>(contentStream);
+					if (contentProviderStream == null) {
+						contentProviderStream = getSleuthkitCase().getContentProvider().getContentStream(this).orElse(null);
+						if (contentProviderStream != null) {
+							this.contentProviderStreamRef = new SoftReference<>(contentProviderStream);
 						}
 					}
 				}
 			} finally {
-				if (contentStream == null) {
-					// don't try to load the content stream again if it fails to load (either through exception or not existing)
-					tryContentStream = false;
+				if (contentProviderStream == null) {
+					// don't try to load the content provider stream again if it fails to load (either through exception or not existing)
+					tryContentProviderStream = false;
 				}				
 			}
 		}
-		return contentStream;
+		return contentProviderStream;
 	}
 	
 	@Override
 	public final int read(byte[] buf, long offset, long len) throws TskCoreException {
-		// try to use content stream if present
-		ContentStream contentStream = getContentStream();
-		if (contentStream != null) {
-			return contentStream.read(buf, offset, len);
+		// try to use content provider stream if present
+		ContentProviderStream contentProviderStream = getContentProviderStream();
+		if (contentProviderStream != null) {
+			return contentProviderStream.read(buf, offset, len);
 		}
 		
 		//if localPath is set, use local, otherwise, use readCustom() supplied by derived class
@@ -1295,7 +1295,7 @@ final void setEncodingType(TskData.EncodingType encodingType) {
 	 * @return true if the file exists, false otherwise
 	 */
 	public boolean exists() {
-		if (hasContentStream()) {
+		if (hasContentProviderStream()) {
 			return true;
 		}
 		
@@ -1320,7 +1320,7 @@ public boolean exists() {
 	 * @return true if the file is readable
 	 */
 	public boolean canRead() {
-		if (hasContentStream()) {
+		if (hasContentProviderStream()) {
 			return true;
 		}
 		
diff --git a/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java b/bindings/java/src/org/sleuthkit/datamodel/ContentProviderStream.java
similarity index 71%
rename from bindings/java/src/org/sleuthkit/datamodel/ContentStream.java
rename to bindings/java/src/org/sleuthkit/datamodel/ContentProviderStream.java
index 00055d0a7..561736203 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/ContentProviderStream.java
@@ -18,12 +18,11 @@
  */
 package org.sleuthkit.datamodel;
 
-import java.util.Optional;
-
 /**
  * Custom provider for content bytes.
  */
-public interface ContentStream extends AutoCloseable {
+@SuppressWarnings("try")
+public interface ContentProviderStream extends AutoCloseable {
 
 	/**
 	 * Reads data that this content object is associated with (file contents,
@@ -39,21 +38,4 @@ public interface ContentStream extends AutoCloseable {
 	 *                          tsk core
 	 */
 	public int read(byte[] buf, long offset, long len) throws TskCoreException;
-
-	/**
-	 * Custom provider for bytes of an abstract file.
-	 */
-	public interface ContentProvider {
-
-		/**
-		 * Provides a content stream for a content object or empty if this
-		 * provider has none to provide.
-		 *
-		 * @param content The content.
-		 *
-		 * @return The content stream or empty if no stream can be provided
-		 *         for this content.
-		 */
-		Optional<ContentStream> getContentStream(Content content) throws TskCoreException;
-	}
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 16df4a34f..03f665165 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -94,7 +94,6 @@
 import org.sqlite.SQLiteConfig;
 import org.sqlite.SQLiteDataSource;
 import org.sqlite.SQLiteJDBCLoader;
-import org.sleuthkit.datamodel.ContentStream.ContentProvider;
 
 /**
  * Represents the case database with methods that provide abstractions for
@@ -205,7 +204,7 @@ public class SleuthkitCase {
 	private final Cache<Long, Boolean> isRootDirectoryCache
 			= CacheBuilder.newBuilder().maximumSize(200000).expireAfterAccess(5, TimeUnit.MINUTES).build();
 	// custom provider for file bytes (can be null)
-	private final ContentProvider contentProvider;
+	private final ContentStreamProvider contentProvider;
 	
 	/*
 	 * First parameter is used to specify the SparseBitSet to use, as object IDs
@@ -339,7 +338,7 @@ public static void tryConnect(CaseDbConnectionInfo info) throws TskCoreException
 	 *
 	 * @throws Exception
 	 */
-	private SleuthkitCase(String dbPath, SleuthkitJNI.CaseDbHandle caseHandle, DbType dbType, ContentProvider contentProvider) throws Exception {
+	private SleuthkitCase(String dbPath, SleuthkitJNI.CaseDbHandle caseHandle, DbType dbType, ContentStreamProvider contentProvider) throws Exception {
 		Class.forName("org.sqlite.JDBC");
 		this.dbPath = dbPath;
 		this.dbType = dbType;
@@ -372,7 +371,7 @@ private SleuthkitCase(String dbPath, SleuthkitJNI.CaseDbHandle caseHandle, DbTyp
 	 *
 	 * @throws Exception
 	 */
-	private SleuthkitCase(String host, int port, String dbName, String userName, String password, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, DbType dbType, ContentProvider contentProvider) throws Exception {
+	private SleuthkitCase(String host, int port, String dbName, String userName, String password, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, DbType dbType, ContentStreamProvider contentProvider) throws Exception {
 		this.dbPath = "";
 		this.databaseName = dbName;
 		this.dbType = dbType;
@@ -421,7 +420,7 @@ private void init() throws Exception {
 	 * @return The custom content provider for this case if one exists.
 	 *         Otherwise, returns null.
 	 */
-	ContentProvider getContentProvider() {
+	ContentStreamProvider getContentProvider() {
 		return this.contentProvider;
 	}
 
@@ -3002,7 +3001,7 @@ public static SleuthkitCase openCase(String dbPath) throws TskCoreException {
 	 * @throws org.sleuthkit.datamodel.TskCoreException
 	 */
 	@Beta
-	public static SleuthkitCase openCase(String dbPath, ContentProvider provider) throws TskCoreException {
+	public static SleuthkitCase openCase(String dbPath, ContentStreamProvider provider) throws TskCoreException {
 		try {
 			final SleuthkitJNI.CaseDbHandle caseHandle = SleuthkitJNI.openCaseDb(dbPath);
 			return new SleuthkitCase(dbPath, caseHandle, DbType.SQLITE, provider);
@@ -3042,7 +3041,7 @@ public static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo i
 	 * @throws TskCoreException If there is a problem opening the database.
 	 */
 	@Beta
-	public static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo info, String caseDir, ContentProvider contentProvider) throws TskCoreException {
+	public static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo info, String caseDir, ContentStreamProvider contentProvider) throws TskCoreException {
 		try {
 			/*
 			 * The flow of this method involves trying to open case and if
@@ -3094,7 +3093,7 @@ public static SleuthkitCase newCase(String dbPath) throws TskCoreException {
 	 * @throws org.sleuthkit.datamodel.TskCoreException
 	 */
 	@Beta
-	public static SleuthkitCase newCase(String dbPath, ContentProvider contentProvider) throws TskCoreException {
+	public static SleuthkitCase newCase(String dbPath, ContentStreamProvider contentProvider) throws TskCoreException {
 		try {
 			CaseDatabaseFactory factory = new CaseDatabaseFactory(dbPath);
 			factory.createCaseDatabase();
@@ -3143,7 +3142,7 @@ public static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info,
 	 * @throws org.sleuthkit.datamodel.TskCoreException
 	 */
 	@Beta
-	public static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info, String caseDirPath, ContentProvider contentProvider) throws TskCoreException {
+	public static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info, String caseDirPath, ContentStreamProvider contentProvider) throws TskCoreException {
 		String databaseName = createCaseDataBaseName(caseName);
 		try {
 			/**
-- 
GitLab