com.lapissea.datamanager.IDataManager Maven / Gradle / Ivy
Show all versions of jlapisdata Show documentation
package com.lapissea.datamanager;
import com.lapissea.datamanager.managers.DataManagerMulti;
import com.lapissea.util.NotNull;
import com.lapissea.util.Nullable;
import com.lapissea.util.UtilL;
import com.lapissea.util.function.UnsafeFunction;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.ObjIntConsumer;
import java.util.stream.Stream;
import static com.lapissea.util.UtilL.*;
/**
* Concepts
* domain
*
* A path and all its contents handled by an implementation of {@link Domain}.
* Can be interchangeable with a folder or compressed file, depending on context.
*
* local path
*
* Path that represents the end portion of any domain.
* EG:
* registered domain = resources/gamedata.zip
* localPath = textures/sky.hdr
*
* AKA: ./resources/gamedata.zip/textures/sky.hdr
in an example format
* Opens gamedata zip and in it searches for textures/sky.hdr
*
*/
public interface IDataManager{
/**
* A manager for the directory where it was ran
*/
IDataManager APP_RUN_DIR=new DataManagerMulti(".");
/**
* A manager for appdata
*/
IDataManager APPDATA_DIR=new DataManagerMulti(UtilL.getAppData());
/**
* Function used to get a raw {@link InputStream} of some resource provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link BufferedInputStream} that is a wrapper of specific {@link Domain} implementation.
*
* - System file: {@link java.io.FileInputStream}
* - File inside compressed folder: {@link java.util.jar.JarInputStream} (without caching)
* - ...
*
*/
@Nullable
BufferedInputStream getInStream(@NotNull String localPath);
/**
* Runs {@link #getInStream(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param onRead Callback to process {@link BufferedInputStream} and return a "parsed" result
* @param resulting output type defined by {@code onRead}
* @return {@link CompletableFuture} that will return object provided by {@code onRead}
* @see #getInStream(String)
*/
@NotNull
default CompletableFuture readBytesAsync(@NotNull String localPath, @NotNull UnsafeFunction onRead){
return async(()->{
try(BufferedInputStream s=getInStream(localPath)){
return onRead.apply(Objects.requireNonNull(s));
}catch(Exception e){
throw uncheckedThrow(e);
}
});
}
/**
* Function used to get a raw {@link Reader} of some resource provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link java.io.BufferedReader} that is a wrapper of specific {@link Domain} implementation.
*
* - System file: {@link java.io.FileReader}
* - File inside compressed folder: {@link java.io.InputStreamReader}
* - ...
*
*/
@Nullable
BufferedReader getReader(@NotNull String localPath);
/**
* Runs {@link #getReader(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param onRead Callback to process {@link BufferedReader} and return a "parsed" result
* @param resulting output type defined by {@code onRead}
* @return {@link CompletableFuture} that will return object provided by {@code onRead}
* @see #getReader(String)
*/
@NotNull
default CompletableFuture readCharsAsync(@NotNull String localPath, @NotNull Function onRead){
return async(()->{
try(BufferedReader s=getReader(localPath)){
return onRead.apply(Objects.requireNonNull(s));
}catch(IOException e){
throw uncheckedThrow(e);
}
});
}
/**
* Function used to get all bytes of some resource provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@code byte[]} with contents of the resource
*/
@Nullable
byte[] readAllBytes(@NotNull String localPath);
/**
* Runs {@link #readAllBytes(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link CompletableFuture} that will return {@code byte[]} with contents of the resource
* @see #readAllBytes(String)
*/
@NotNull
default CompletableFuture readAllBytesAsync(@NotNull String localPath){
return async(()->Objects.requireNonNull(readAllBytes(localPath)));
}
/**
* Function used to get all characters of some resource provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@code char[]} with contents of the resource
*/
@Nullable
char[] readAllChars(@NotNull String localPath);
/**
* Runs {@link #readAllChars(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link CompletableFuture} that will return {@code char[]} with contents of the resource
* @see #readAllChars(String)
*/
@NotNull
default CompletableFuture readAllCharsAsync(@NotNull String localPath){
return async(()->Objects.requireNonNull(readAllChars(localPath)));
}
/**
* Function used to get all contents of some resource in a string provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link String} with contents of the resource
*/
@Nullable
String readAll(@NotNull String localPath);
/**
* Runs {@link #readAll(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link CompletableFuture} that will return {@link String} with contents of the resource
* @see #readAll(String)
*/
@NotNull
default CompletableFuture readAllAsync(@NotNull String localPath){
return async(()->Objects.requireNonNull(readAll(localPath)));
}
/**
* Function used to get all lines of a text based resource provided by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link List} with all lines of the resource
*/
@Nullable
List getLines(@NotNull String localPath);
/**
* Runs {@link #getLines(String)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link CompletableFuture} that will return {@link List} with all lines of the resource
* @see #readAll(String)
*/
@NotNull
default CompletableFuture> getLinesAsync(@NotNull String localPath){
return async(()->Objects.requireNonNull(getLines(localPath)));
}
/**
* Function used to get all lines of a text based resource provided in a callback fashion by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param lineConsumer {@link Consumer} that will be given individual line by line of a resource provided by registered {@link Domain}.
* @return this object (for chaining)
*/
@NotNull
IDataManager getLines(@NotNull String localPath, @NotNull Consumer lineConsumer);
/**
* Function used to get all lines of a text with its index (line number) based resource provided in a callback fashion by registered {@link Domain}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param lineConsumer {@link Consumer} that will be given individual line by line of a resource provided by registered {@link Domain}.
* @return this object (for chaining)
*/
@NotNull
IDataManager getLines(@NotNull String localPath, @NotNull ObjIntConsumer lineConsumer);
/**
* Function used to get all names of files/directories in a directory defined by {@code localPath}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@code String[]} containing all names
*/
@Nullable
String[] getDirNames(@NotNull String localPath);
/**
* Function used to get all names of files/directories in a directory defined by {@code localPath}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link Stream} of all names
*/
@Nullable
Stream getDirNamesS(@NotNull String localPath);
/**
* Function used to check if a resource exists at {@code localPath}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return flag representing if resource was found
*/
boolean exists(@NotNull String localPath);
/**
* Function that creates a view of current {@link IDataManager} with localPath
* EG:
* Domain contains:
*
* textures/sky.hdr
* textures/...
* ...
*
*
* So a to localize textures something like this would be done:
*
* {@link IDataManager} assets=...;
* {@link IDataManager} tx=assets.subData("textures");
*
* And to get something from it would be done like:
* {@link InputStream} skyStream=tx.getInStream("sky.hdr");
*
*
* @param localPath The string that will limit the view (aka: localize local paths called from created manager)
* @return A new instance of {@link com.lapissea.datamanager.managers.SubDataManager SubDataManager} with calling object as the parent
*/
@NotNull
IDataManager subData(@NotNull String localPath);
/**
* Function used to get size of a readable resource in bytes. If it is not readable (directory/missing) then this will return -1.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return size of resource in bytes
*/
long getSize(@NotNull String localPath);
/**
*
* Function used to get all bytes of some resource provided by registered {@link Domain} and put them in to a {@link ByteBuffer}.
* Instead of passing in the {@link ByteBuffer} this function requests a ByteBuffer with a speified size- (resource byte size)
*
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param newByteBuffer Function to create/supply a {@link ByteBuffer} where to write bytes
* @return {@link ByteBuffer} that was given in {@code byteBuffer}.
*/
@Nullable
default ByteBuffer readAllBytes(@NotNull String localPath, @NotNull IntFunction newByteBuffer){
long size=getSize(localPath);
if(size<=0) return null;
if(size>Integer.MAX_VALUE) throw new OutOfMemoryError("Trying to load extremely large file in to memory");
return readAllBytes(localPath, newByteBuffer.apply((int)size));
}
/**
* Runs {@link #readAllBytes(String, IntFunction)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param newByteBuffer Function to create/supply a {@link ByteBuffer}
* @return {@link CompletableFuture} that will return object provided by {@code onRead}
* @see #getInStream(String)
*/
@NotNull
default CompletableFuture readAllBytesAsync(@NotNull String localPath, @NotNull IntFunction newByteBuffer){
return async(()->Objects.requireNonNull(readAllBytes(localPath, newByteBuffer)));
}
/**
* Function used to get all bytes of some resource provided by registered {@link Domain} and put them in to a {@link ByteBuffer}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param byteBuffer destination where to write bytes
* @return {@link ByteBuffer} that was given in {@code byteBuffer}.
*/
@NotNull
default ByteBuffer readAllBytes(@NotNull String localPath, @NotNull ByteBuffer byteBuffer){
try(BufferedInputStream in=getInStream(localPath)){
int b;
while((b=in.read())!=-1) byteBuffer.put((byte)b);
byteBuffer.flip();
return byteBuffer;
}catch(IOException e){
throw new RuntimeException(e);
}
}
/**
* Runs {@link #readAllBytes(String, ByteBuffer)} in a {@link CompletableFuture} where if result fails (aka is null),
* throws exception so it cen be handled properly with functions like {@link CompletableFuture#exceptionally}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param byteBuffer destination og where to store bytes in
* @return {@link CompletableFuture} that will return object provided by {@code onRead}
* @see #getInStream(String)
*/
@NotNull
default CompletableFuture readAllBytesAsync(@NotNull String localPath, @NotNull ByteBuffer byteBuffer){
return async(()->Objects.requireNonNull(readAllBytes(localPath, byteBuffer)));
}
/**
* Function used to get all text of some resource provided by registered {@link Domain} and put it in a {@link StringBuilder}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param dest String builder where to put all the contents in to.
* @return returns {@link StringBuilder} that was given in {@code dest}.
*/
@NotNull
default StringBuilder readAllTo(@NotNull String localPath, @NotNull StringBuilder dest){
int size=(int)getSize(localPath);
dest.ensureCapacity(dest.length()+size);
try(BufferedReader in=getReader(localPath)){
int b;
while((b=in.read())!=-1) dest.append((char)b);
}catch(IOException e){}
return dest;
}
/**
* Function used to get all paths of files/directories in a directory defined by {@code localPath}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@code String[]} containing all paths
*/
@Nullable
String[] getDirPaths(@NotNull String localPath);
/**
* Function used to get all paths of files/directories in a directory and all its child directories defined by {@code localPath}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@code String[]} containing all paths
*/
@Nullable
String[] getDirPathsDeep(@NotNull String localPath);
/**
* Function used to get all paths of files/directories in a directory defined by {@code localPath} and returned in a stream.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link Stream} containing all paths
*/
@Nullable
Stream getDirPathsS(@NotNull String localPath);
/**
* Function used to get all paths of files/directories in a directory and all its child directories defined by {@code localPath} and returned in a stream.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link Stream} containing all paths
*/
@Nullable
Stream getDirPathsDeepS(@NotNull String localPath);
/**
* Function used to check if any {@link Domain} is editable and can create new files/folders. (usually a domain that handles a compressed file will not be editable)
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return Flag that represents if it is possible to edit/create resources
*/
boolean canEditCreate(@NotNull String localPath);
/**
* Function used to create/modify a resource. If a resource is missing, it will be automatically created. When resource is created its contents will be set to {@code data}
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @param data content that will be written to resource
*/
void makeFile(@NotNull String localPath, byte[] data);
/**
* Function used to create/modify a resource. If a resource is missing, it will be automatically created.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return {@link BufferedOutputStream} that is a wrapper of specific {@link Domain} implementation.
*/
@NotNull
BufferedOutputStream makeFile(@NotNull String localPath);
/**
* Function used to create a {@link DataSignature}.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return new instance of {@link DataSignature}
*/
@NotNull
DataSignature createSignature(@NotNull String localPath);
/**
* Function used to get the time in ms when a resource was last changed. Useful when working with editable domains. If it is not possible to get time, -1 will be returned.
*
* @param localPath see {@link IDataManager} -> Concepts -> local path
* @return date of last modification or creation if it was never modified in ms or -1 in a case of failure
*/
long getLastChange(@NotNull String localPath);
}