Bug 14: Added comments to the storage classes and interfaces

This commit is contained in:
Robert Vokac 2024-09-13 20:41:11 +02:00
parent de7c9a665e
commit 552bbc6274
No known key found for this signature in database
GPG Key ID: C459E1E4B4A986BB
13 changed files with 637 additions and 99 deletions

View File

@ -23,15 +23,35 @@ import com.pixelgamelibrary.api.Platform;
import java.util.List;
/**
*
* This interface provides the methods to interact with the underlying storage system.
* It supports basic file system operations such as navigating directories, creating files
* and directories, and reading/writing data.
*
* @author robertvokac
*/
public interface Storage {
/**
* Returns the platform associated with this storage.
*
* @return the platform object.
*/
Platform getPlatform();
/**
* Changes the current working directory to the specified path.
*
* @param path the path to change to.
* @return a result message or an empty string if successful.
*/
public String cd(String path);
/**
* Changes the directory to the default "home/user" directory, creating the necessary
* directories if they do not exist.
*
* @return a result message or an empty string if successful.
*/
default String cd() {
cd("/");
mkdir("home");
@ -41,71 +61,207 @@ public interface Storage {
return "";
}
/**
* Creates a directory with the specified name.
*
* @param argument the name of the directory to create.
* @return a result message or an empty string if successful.
*/
public String mkdir(String argument);
/**
* Creates multiple directories specified by the arguments.
*
* @param argument the names of the directories to create.
* @return a result message or an empty string if successful.
*/
default String mkdirmore(String... argument) {
// System.out.println("argumentCount=" + argument.length);
// for(String z: argument){System.out.println(z);}
if(argument.length == 0) {
if (argument.length == 0) {
return "Missing argument";
}
for(String n:argument) {
for (String n : argument) {
String result = mkdir(n);
if(!result.isEmpty()) {
if (!result.isEmpty()) {
return result;
}
}
return "";
}
/**
* Returns the current working directory.
*
* @return the path of the current working directory.
*/
public String pwd();
/**
* Lists the contents of the specified directory.
*
* @param workingDirectory the directory to list.
* @return a list of file and directory names in the specified directory.
*/
public List<String> ls(String workingDirectory);
/**
* Lists the contents of the current working directory.
*
* @return a list of file and directory names in the current working directory.
*/
default List<String> ls() {
return ls(pwd());
}
/**
* Returns the depth of the specified directory path in the directory tree.
*
* @param path the path to calculate depth for.
* @return the depth of the path.
*/
public int depth(String path);
/**
* Returns the depth of the current working directory in the directory tree.
*
* @return the depth of the current working directory.
*/
default int depth() {
return depth(pwd());
}
/**
* Creates an empty file with the specified name.
*
* @param name the name of the file to create.
* @return a result message or an empty string if successful.
*/
public String touch(String name);
/**
* Removes the file with the specified name.
*
* @param name the name of the file to remove.
* @return true if the file was successfully removed, false otherwise.
*/
public boolean rm(String name);
/**
* Removes the directory with the specified name.
*
* @param dirname the name of the directory to remove.
* @return true if the directory was successfully removed, false otherwise.
*/
public boolean rmdir(String dirname);
/**
* Copies a file from the source path to the target path.
*
* @param source the source file path.
* @param target the target file path.
* @return a result message or an empty string if successful.
*/
public String cp(String source, String target);
/**
* Moves a file from the source path to the target path.
*
* @param source the source file path.
* @param target the target file path.
* @return a result message or an empty string if successful.
*/
public String mv(String source, String target);
/**
* Reads the contents of a text file with the specified name.
*
* @param name the name of the file to read.
* @return the text content of the file.
*/
public String readtext(String name);
/**
* Reads the contents of a binary file with the specified name.
*
* @param name the name of the file to read.
* @return the binary content of the file.
*/
public byte[] readbin(String name);
/**
* Saves the specified text content to a file with the given name.
*
* @param name the name of the file to save.
* @param text the text content to save.
* @return a result message or an empty string if successful.
*/
public String savetext(String name, String text);
/**
* Saves the specified binary data to a file with the given name.
*
* @param name the name of the file to save.
* @param data the binary data to save.
* @return a result message or an empty string if successful.
*/
public String savebin(String name, byte[] data);
/**
* Checks whether a file or directory with the specified name exists.
*
* @param name the name to check for existence.
* @return true if the file or directory exists, false otherwise.
*/
public boolean exists(String name);
/**
* Checks whether the specified name refers to a file.
*
* @param name the name to check.
* @return true if the name refers to a file, false otherwise.
*/
public boolean isfile(String name);
/**
* Checks whether the specified name refers to a directory.
*
* @param name the name to check.
* @return true if the name refers to a directory, false otherwise.
*/
public boolean isdir(String name);
/**
* Returns a debug string with information about the current state of the storage.
*
* @return a debug string.
*/
public String debug();
public void flush();
default String uname() {return USER;}
static final String USER = "user";
/**
* If the size of this storage is limited, then the count of bytes is returned, otherwise 0 is returned.
*/
default int sizelimitedto() {
return 0;
}
/**
* Flushes any pending writes to the storage.
*/
public void flush();
/**
* Returns the username associated with this storage.
*
* @return the username.
*/
default String uname() {
return USER;
}
/**
* If the size of this storage is limited, returns the number of bytes it is limited to.
* Otherwise, returns 0.
*
* @return the size limit in bytes, or 0 if there is no limit.
*/
default long sizelimitedto() {
return 0;
}
/**
* The default username for the storage.
*/
static final String USER = "user";
}

View File

@ -22,11 +22,18 @@ package com.pixelgamelibrary.api.storage;
import com.pixelgamelibrary.api.PixelException;
/**
*
* StorageException is a custom exception class that extends {@link PixelException}.
* It represents exceptions that occur within the storage system of the Pixel Game Library.
*
* @author robertvokac
*/
public class StorageException extends PixelException {
/**
* Constructs a new StorageException with the specified detail message.
*
* @param string the detail message for this exception.
*/
public StorageException(String string) {
super(string);
}

View File

@ -22,39 +22,80 @@ package com.pixelgamelibrary.api.storage.command;
import java.util.function.Function;
/**
*
* The {@code BaseStorageCommand} class provides a basic implementation of the {@link StorageCommand} interface.
* It defines a command that can be executed within a storage command-line context using a function
* that processes the command and its arguments.
*
* @author robertvokac
*/
public class BaseCommand implements StorageCommand {
public class BaseStorageCommand implements StorageCommand {
/**
* The command-line interface this command is associated with.
*/
private StorageCommandLine storageCommandLine = null;
/**
* The name of the command.
*/
private String name;
/**
* The function that will be applied to execute the command with its arguments.
*/
private final Function<String, StorageCommandResult> function;
public BaseCommand(
/**
* Constructs a new {@code BaseStorageCommand} with the specified command-line interface, name, and execution function.
*
* @param storageCommandLineIn the command-line interface associated with this command.
* @param nameIn the name of the command.
* @param functionIn the function that defines the command's behavior when executed.
*/
public BaseStorageCommand(
StorageCommandLine storageCommandLineIn, String nameIn, Function<String, StorageCommandResult> functionIn
) {
setStorageCommandLine(storageCommandLineIn);
this.name = nameIn;
this.function = functionIn;
}
/**
* Sets the {@link StorageCommandLine} for this command.
*
* @param storageCommandLineIn the command-line interface to set.
*/
@Override
public final void setStorageCommandLine(StorageCommandLine storageCommandLineIn) {
storageCommandLine = storageCommandLineIn;
}
/**
* Returns the {@link StorageCommandLine} associated with this command.
*
* @return the command-line interface.
*/
@Override
public final StorageCommandLine getStorageCommandLine() {
return storageCommandLine;
}
/**
* Returns the name of this command.
*
* @return the command name.
*/
@Override
public String getName() {
return name;
}
/**
* Executes the command with the provided arguments.
*
* @param commandWithArguments the command string including its arguments.
* @return the result of executing the command.
*/
@Override
public StorageCommandResult execute(String commandWithArguments) {
return function.apply(commandWithArguments);

View File

@ -20,10 +20,18 @@
package com.pixelgamelibrary.api.storage.command;
/**
*
* The {@code CommandLineScanner} interface defines a contract for scanning input from a command line.
* It provides methods to read input lines from the command line.
*
* @author robertvokac
*/
public interface CommandLineScanner {
/**
* Reads the next line of input from the command line.
*
* @return the next line of input as a {@code String}.
*/
String nextLine();
}

View File

@ -20,19 +20,49 @@
package com.pixelgamelibrary.api.storage.command;
/**
*
* The {@code StorageCommand} interface defines the contract for commands that can be executed within
* a storage command-line environment. It provides methods for getting the command's name, executing
* the command with arguments, and managing the command-line context.
*
* @author robertvokac
*/
public interface StorageCommand {
/**
* Returns the name of the command.
*
* @return the name of the command as a {@code String}.
*/
public String getName();
/**
* Executes the command with the specified arguments and returns the result.
*
* @param arguments the arguments to be passed to the command.
* @return the result of executing the command as a {@link StorageCommandResult}.
*/
StorageCommandResult execute(String arguments);
/**
* Returns the {@link StorageCommandLine} associated with this command.
*
* @return the command-line interface associated with this command.
*/
StorageCommandLine getStorageCommandLine();
/**
* Sets the {@link StorageCommandLine} for this command.
*
* @param storageCommandLine the command-line interface to set.
*/
void setStorageCommandLine(StorageCommandLine storageCommandLine);
/**
* Creates and returns a new, empty {@link StorageCommandResult}.
*
* @return a new {@link StorageCommandResult} instance.
*/
static StorageCommandResult emptyNewResult() {
return new StorageCommandResult();
}
}

View File

@ -17,6 +17,7 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.command;
import com.pixelgamelibrary.api.storage.Storage;
@ -30,46 +31,66 @@ import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* The StorageCommandLine class represents a command-line interface for interacting with storage.
* It provides methods to execute various commands that manipulate or retrieve information from the storage.
*
* @author robertvokac
*/
public class StorageCommandLine {
private String user;
private String hostname;
private Storage storage;
//
private boolean exited = false;
//
private long startNanoTime = System.nanoTime();
private String user; // User for the command line
private String hostname; // Hostname for the command line
private Storage storage; // Storage object for interacting with files
private boolean exited = false; // Indicates if the command line session has been exited
private long startNanoTime = System.nanoTime(); // Start time of the session in nanoseconds
/**
* Returns the command line prompt string.
*
* @return the command line prompt string
*/
public String getCommandLineStart() {
return user + "@" + hostname + ":" + storage.pwd() + "$ ";
}
/**
* Extracts an argument from the command line arguments based on its index.
*
* @param arguments the command line arguments
* @param argumentIndex the index of the argument to extract
* @return the extracted argument
*/
private String extractArgument(String arguments, int argumentIndex) {
if(arguments.isEmpty()) {
return arguments;
}
String[] array = arguments.split(" ");
if (argumentIndex > (array.length)) {
if (argumentIndex >= array.length) {
return "";
}
return array[argumentIndex + 1];
}
/**
* Constructs a StorageCommandLine instance with the specified user, hostname, and storage.
* Initializes commands for the command line interface.
*
* @param userIn the user for the command line
* @param hostnameIn the hostname for the command line
* @param storageIn the storage object for interacting with files
*/
public StorageCommandLine(String userIn, String hostnameIn, Storage storageIn) {
this.user = userIn;
this.hostname = hostnameIn;
this.storage = storageIn;
// Initialize commands
addCommand("date", arguments -> provideOutput(result -> result.setOutput(new Date().toString())));
addCommand("whoami", arguments -> provideOutput(result -> result.setOutput(user)));
addCommand("uptime", arguments -> provideOutput(result
-> result.setOutput(
new Date().toString().substring(11, 19) + " up "
+ (System.nanoTime() - startNanoTime) / 1000000000l / 60l
+ (System.nanoTime() - startNanoTime) / 1000000000L / 60L
+ " minutes"
+ ", 1 user"
)));
@ -90,8 +111,8 @@ public class StorageCommandLine {
.map(l -> {
String[] a = l.split("/");
return a[a.length - 1];
}
).collect(Collectors.joining("\n")))));
})
.collect(Collectors.joining("\n")))));
addCommand("pwd", arguments -> provideOutput(result -> result.setOutput(storage.pwd())));
addCommand("depth", arguments -> provideOutput(result -> result.setOutput(storage.depth())));
@ -101,32 +122,47 @@ public class StorageCommandLine {
String string = storage.mkdirmore(extractArguments(arguments));
if (string.isEmpty()) {
result.setOutput("New directory was successfully created");
} else {
result.setErrorOutput("Creating new directory failed: " + string);
}
}
));
}));
// Set the StorageCommandLine instance for each command
commands.keySet().stream().map(k -> commands.get(k)).forEach(c -> c.setStorageCommandLine(this));
}
/**
* Extracts arguments from the command line arguments string.
*
* @param arguments the command line arguments
* @return an array of extracted arguments
*/
private String[] extractArguments(String arguments) {
return Arrays.asList(arguments.split(" ")).stream()
.filter(a->!a.isEmpty())
.toArray(String[]::new);
}
/**
* Provides output based on a consumer function that modifies the result.
*
* @param consumer the function to modify the result
* @return the modified result
*/
private StorageCommandResult provideOutput(Consumer<StorageCommandResult> consumer) {
StorageCommandResult result = StorageCommand.emptyNewResult();
consumer.accept(result);
return result;
}
/**
* Adds a command to the command line interface.
*
* @param nameIn the name of the command
* @param functionIn the function to execute for the command
*/
private void addCommand(String nameIn, Function<String, StorageCommandResult> functionIn) {
StorageCommand storageCommand = new BaseCommand(this, nameIn, functionIn);
StorageCommand storageCommand = new BaseStorageCommand(this, nameIn, functionIn);
commands.put(storageCommand.getName(), storageCommand);
}
@ -148,8 +184,13 @@ public class StorageCommandLine {
return exited;
}
/**
* Executes a command with the specified arguments.
*
* @param commandWithArguments the command and its arguments
* @return the result of the command execution
*/
public StorageCommandResult execute(String commandWithArguments) {
String[] arguments = commandWithArguments.split(" ");
String command = arguments.length == 0 ? "" : arguments[0];
@ -159,43 +200,34 @@ public class StorageCommandLine {
}
int argumentCount = arguments.length - 1;
//System.out.println("argumentCount=" + argumentCount);
Optional<String> argument1 = Optional.ofNullable(argumentCount >= 1 ? arguments[1] : null);
Optional<String> argument2 = Optional.ofNullable(argumentCount >= 2 ? arguments[2] : null);
StorageCommandResult finalResult = new StorageCommandResult();
switch (command) {
case "touch":
String r = storage.touch(argument1.get());
if (r.isEmpty()) {
finalResult.setOutput("New file was successfully created");
} else {
finalResult.setErrorOutput("Creating new directory failed: " + r);
}
break;
case "readtext":
String rr = storage.readtext(argument1.get());
if (rr != null) {
finalResult.setOutput("Text file was successfully loaded" + "\n\n" + rr);
} else {
finalResult.setErrorOutput("Loading text file failed:");
}
break;
case "savetext":
String result = storage.savetext(argument1.get(), argument2.get());
if (result.isEmpty()) {
finalResult.setOutput("Text file was successfully saved");
} else {
finalResult.setErrorOutput("Saving text file failed: " + result);
}
break;
case "cd":
String rrr = argument1.isEmpty() ? storage.cd() : storage.cd(argument1.get());
@ -204,22 +236,17 @@ public class StorageCommandLine {
} else {
finalResult.setErrorOutput("Changing working directory failed: " + rrr);
}
break;
case "debug":
finalResult.setOutput(storage.debug());
break;
case "exit":
exited = true;
finalResult.setOutput("Exited");
break;
default: {
default:
finalResult.setErrorOutput("Unsupported command: " + command);
}
}
return finalResult;
}
}

View File

@ -17,37 +17,62 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.command;
/**
*
* The StorageCommandLineScanner class provides a command-line interface for interacting with
* the StorageCommandLine instance. It reads user input and executes commands in a loop until
* the exit command is issued.
*
* @author robertvokac
*/
public class StorageCommandLineScanner {
/**
* Constructs a StorageCommandLineScanner instance that continuously reads input from the
* user and executes commands until the exit command is issued.
*
* @param storageCommandLine the StorageCommandLine instance to interact with
* @param scanner the Scanner object for reading user input
*/
public StorageCommandLineScanner(StorageCommandLine storageCommandLine, CommandLineScanner scanner) {
while (true) {
// Print the command line prompt
System.out.print(storageCommandLine.getCommandLineStart());
// Read user input
String argument = scanner.nextLine();
// Execute the command and get the result
StorageCommandResult result = storageCommandLine.execute(argument);
// Print error or output based on the result
if (result.isError()) {
printError(result.getOutput());
} else {
print(result.getOutput());
}
// Exit if the command line session is marked as exited
if (storageCommandLine.isExited()) {
break;
}
}
}
/**
* Prints a message to the standard output.
*
* @param msg the message to print
*/
private static void print(String msg) {
System.out.println(msg);
}
/**
* Prints an error message to the standard error output.
*
* @param msg the error message to print
*/
private static void printError(String msg) {
System.err.println(msg);
}

View File

@ -17,52 +17,99 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.command;
/**
*
* The StorageCommandResult class encapsulates the result of executing a storage command.
* It holds the output of the command and a flag indicating whether an error occurred.
*
* @author robertvokac
*/
public class StorageCommandResult {
/**
* Default constructor that initializes an empty result.
*/
public StorageCommandResult() {
this("");
}
/**
* Constructor that initializes the result with the specified output.
*
* @param output the output of the command
*/
public StorageCommandResult(String output) {
this(output, false);
}
/**
* Constructor that initializes the result with the specified output and error flag.
*
* @param output the output of the command
* @param error true if an error occurred, false otherwise
*/
public StorageCommandResult(String output, boolean error) {
this.output = output;
this.error = error;
}
/**
* Gets the output of the command.
*
* @return the output as a string
*/
public String getOutput() {
return output;
}
/**
* Checks if the command result indicates an error.
*
* @return true if an error occurred, false otherwise
*/
public boolean isError() {
return error;
}
/**
* Sets the output of the command, given an integer value.
*
* @param output the integer output to set
*/
public void setOutput(int output) {
setOutput(String.valueOf(output));
}
/**
* Sets the error output and marks the result as an error.
*
* @param output the error message to set
*/
public void setErrorOutput(String output) {
this.output = output;
setError(true);
}
/**
* Sets the output of the command.
*
* @param output the output to set as a string
*/
public void setOutput(String output) {
this.output = output;
}
/**
* Sets the error flag.
*
* @param error true to indicate an error, false otherwise
*/
public void setError(boolean error) {
this.error = error;
}
private String output;
private boolean error;
private String output; // Holds the output of the command
private boolean error; // Indicates whether an error occurred
}

View File

@ -17,31 +17,44 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.map;
import com.pixelgamelibrary.api.storage.StorageException;
/**
*
* Enum representing the types of files or directories in the map.
* It can either be a FILE or a DIRECTORY.
*
* @author robertvokac
*/
public enum MapFileType {
FILE, DIRECTORY;
/**
* Determines the MapFileType based on the value associated with the specified key in the map.
* Throws a StorageException if the key is not found or if the value does not match any known type.
*
* @param key the key whose associated value determines the file type
* @param map the map from which to retrieve the value
* @return the MapFileType corresponding to the value in the map
* @throws StorageException if the key is not present in the map or if the value does not match FILE or DIRECTORY
*/
public static MapFileType ofKey(String key, SimpleMap map) {
// Check if the map contains the specified key
if (!map.contains(key)) {
throw new StorageException("Map does not contain key: " + key);
}
// Retrieve the value associated with the key
String value = map.getString(key);
// Determine the MapFileType based on the value
if (value.startsWith(FILE.name())) {
return FILE;
}
if (value.startsWith(DIRECTORY.name())) {
return DIRECTORY;
}
// Throw an exception if the value does not match known types
throw new StorageException("Unsupported MapFileType for key in the map: " + key);
}
}

View File

@ -17,6 +17,7 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.map;
import com.badlogic.gdx.Gdx;
@ -28,44 +29,66 @@ import java.util.List;
import java.util.stream.Collectors;
/**
*
* Implementation of the Storage interface for managing a map-based file system.
* Provides methods to interact with files and directories stored in a map.
*
* @author robertvokac
*/
public class MapStorage implements Storage {
private final SimpleMap map;
private final MapStorageCompression mapStorageCompression;
/**
* Constructs a MapStorage instance with the specified map and default compression.
*
* @param mapIn the map to be used for storage
*/
public MapStorage(SimpleMap mapIn) {
this(mapIn, MapStorageCompression.NONE);
}
/**
* Constructs a MapStorage instance with the specified map and compression.
*
* @param mapIn the map to be used for storage
* @param mapStorageCompressionIn the compression method to be used
*/
public MapStorage(SimpleMap mapIn, MapStorageCompression mapStorageCompressionIn) {
this.map = mapIn;
this.mapStorageCompression = mapStorageCompressionIn;
mkdir("/");
mkdir("/"); // Initialize the root directory
}
private String workingDirectory = "/";
@Override
public Platform getPlatform() {
// Returns null as this implementation does not specify a platform
return null;
}
/**
* Converts a path to an absolute path if it is not already absolute.
*
* @param path the path to convert
* @return the absolute path
*/
private String convertToAbsolutePathIfNeeded(String path) {
if (path.startsWith(SLASH)) {
return path;
}
return workingDirectory + (workingDirectory.equals("/") ? "" : SLASH) + path;
}
private static final String TWO_DOTS = "..";
private static final String SLASH = "/";
private static final String EIGHT_COLONS = "::::::::";
private static final String BINARYFILE = "BINARYFILE";
@Override
public String cd(String path) {
// System.out.println("path="+path);
// Change directory to the specified path
String absolutePath = path.equals(TWO_DOTS) ? getParentPath(workingDirectory) : convertToAbsolutePathIfNeeded(path);
if (!exists(absolutePath)) {
@ -82,10 +105,10 @@ public class MapStorage implements Storage {
workingDirectory = absolutePath;
return "";
}
private static final String SLASH = "/";
@Override
public String mkdir(String path) {
// Create a new directory at the specified path
if(path.isEmpty()) {
String msg = "Missing argument";
logError(msg);
@ -109,14 +132,17 @@ public class MapStorage implements Storage {
return msg;
}
map.putString(absolutePath, MapFileType.DIRECTORY + EIGHT_COLONS);
return "";
}
private static final String EIGHT_COLONS = "::::::::";
/**
* Retrieves the parent path of the given path.
*
* @param path the path to get the parent of
* @return the parent path
* @throws StorageException if the path is null or empty
*/
private static String getParentPath(String path) {
// System.out.println("getParentPath()");
if (path == null) {
throw new StorageException("Path is null");
}
@ -136,21 +162,24 @@ public class MapStorage implements Storage {
@Override
public String pwd() {
// Return the current working directory
return workingDirectory;
}
@Override
public int depth(String path) {
// Return the depth of the given path
String absolutePath = convertToAbsolutePathIfNeeded(path);
if (absolutePath.equals(SLASH)) {
return 0;
}
String[] array = absolutePath.split(SLASH);
return array.length -1;
return array.length - 1;
}
@Override
public List<String> ls(String path) {
// List all files and directories at the specified path
int currentDepth = depth(path);
return map
.keyList()
@ -166,6 +195,7 @@ public class MapStorage implements Storage {
}
public String touch(String path, String content) {
// Create a new file at the specified path with optional content
String absolutePath = convertToAbsolutePathIfNeeded(path);
final String parentPath = getParentPath(absolutePath);
if (!exists(parentPath)) {
@ -184,12 +214,12 @@ public class MapStorage implements Storage {
return msg;
}
map.putString(absolutePath, MapFileType.FILE + EIGHT_COLONS + content);
return "";
}
@Override
public boolean rm(String path) {
// Remove the file or directory at the specified path
String absolutePath = convertToAbsolutePathIfNeeded(path);
if (!map.contains(absolutePath)) {
@ -210,6 +240,15 @@ public class MapStorage implements Storage {
return moveOrCp(source, target, true, false);
}
/**
* Moves or copies a file from the source path to the target path.
*
* @param source the source path
* @param target the target path
* @param move whether to move the file (true) or copy it (false)
* @param cp whether to copy the file (true) or move it (false)
* @return an empty string if successful or an error message
*/
private String moveOrCp(String source, String target, boolean move, boolean cp) {
if (move && cp) {
throw new StorageException("move == true && cp == true");
@ -258,6 +297,7 @@ public class MapStorage implements Storage {
@Override
public String readtext(String path) {
// Read the text content of a file at the specified path
String absolutePath = convertToAbsolutePathIfNeeded(path);
if (!exists(absolutePath)) {
logError("absolutePathSource does not exist: " + absolutePath);
@ -273,17 +313,16 @@ public class MapStorage implements Storage {
@Override
public byte[] readbin(String path) {
// Read binary data from a file at the specified path
String absolutePath = convertToAbsolutePathIfNeeded(path);
String text = readtext(absolutePath);
if (!text.startsWith(BINARYFILE)) {
logError("File is not binary:" + absolutePath);
logError("File is not binary: " + absolutePath);
return null;
}
text = text.substring(BINARYFILE.length());
return Pixel.utils().decodeBase64AsByteArray(text);
}
private static final String BINARYFILE = "BINARYFILE";
@Override
public String savetext(String name, String text) {
@ -297,25 +336,30 @@ public class MapStorage implements Storage {
@Override
public boolean exists(String name) {
// Check if the path exists in the map
return map.contains(convertToAbsolutePathIfNeeded(name));
}
@Override
public boolean isfile(String name) {
// Check if the path is a file
return filetype(name) == MapFileType.FILE;
}
@Override
public boolean isdir(String name) {
// Check if the path is a directory
return filetype(name) == MapFileType.DIRECTORY;
}
public MapFileType filetype(String name) {
// Get the file type for the given path
return MapFileType.ofKey(convertToAbsolutePathIfNeeded(name), map);
}
@Override
public String debug() {
// Return a debug string of all keys and their values
StringBuilder sb = new StringBuilder();
for(String key: map.keyList()) {
sb
@ -329,16 +373,22 @@ public class MapStorage implements Storage {
@Override
public void flush() {
// Flush the map to persist changes
map.flush();
}
@Override
public boolean rmdir(String dirname) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
// Remove directory is not supported
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Logs an error message using the Pixel application logging mechanism.
*
* @param msg the error message to log
*/
private void logError(String msg) {
Pixel.app().error(msg);
}
}

View File

@ -17,23 +17,33 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.map;
import com.pixelgamelibrary.api.Platform;
/**
*
* Implementation of Storage that uses an in-memory map for storing data.
* Extends the MapStorage class to utilize a SimpleJavaMap for internal storage.
*
* This class is used when you need a temporary storage solution that
* does not persist data beyond the runtime of the application.
*
* @author robertvokac
*/
public class MemoryStorage extends MapStorage {
@Override
public Platform getPlatform() {
return null;
}
/**
* Constructs a MemoryStorage instance using a SimpleJavaMap.
* Initializes the parent MapStorage with an in-memory map implementation.
*/
public MemoryStorage() {
super(new SimpleJavaMap());
}
@Override
public Platform getPlatform() {
// Returns null as this implementation does not specify a platform
return null;
}
}

View File

@ -17,6 +17,7 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.map;
import java.util.Collections;
@ -26,25 +27,49 @@ import java.util.Map;
import java.util.stream.Collectors;
/**
*
* An implementation of SimpleMap using a HashMap for internal storage.
* This class provides basic operations for storing and retrieving key-value pairs.
* It implements the SimpleMap interface.
*
* @author robertvokac
*/
public class SimpleJavaMap implements SimpleMap {
// Internal map for storing key-value pairs
private final Map<String, String> map;
/**
* Constructs a SimpleJavaMap instance with an empty HashMap.
*/
public SimpleJavaMap() {
this(new HashMap<>());
}
/**
* Constructs a SimpleJavaMap instance with a provided map.
*
* @param mapIn Initial map to use for storage
*/
public SimpleJavaMap(Map<String, String> mapIn) {
this.map = mapIn;
}
/**
* Puts a key-value pair into the map.
*
* @param key Key to store
* @param val Value to store
*/
@Override
public void putString(String key, String val) {
map.put(key, val);
}
/**
* Puts multiple key-value pairs into the map.
*
* @param map Key-value pairs to store
*/
@Override
public void put(Map<String, String> map) {
for (String key : map.keySet()) {
@ -52,40 +77,81 @@ public class SimpleJavaMap implements SimpleMap {
}
}
/**
* Retrieves the value associated with the given key.
*
* @param key Key to retrieve value for
* @return Value associated with the key, or null if not found
*/
@Override
public String getString(String key) {
return map.get(key);
}
/**
* Retrieves the value associated with the given key, or returns a default value if not found.
*
* @param key Key to retrieve value for
* @param defaultValue Default value to return if key is not found
* @return Value associated with the key, or default value if key is not found
*/
@Override
public String getString(String key, String defaultValue) {
return contains(key) ? getString(key) : defaultValue;
}
/**
* Retrieves an unmodifiable view of the map.
*
* @return Unmodifiable map
*/
@Override
public Map<String, String> getReadOnlyMap() {
return Collections.unmodifiableMap(map);
}
/**
* Checks if the map contains the given key.
*
* @param key Key to check
* @return True if the key is present, false otherwise
*/
@Override
public boolean contains(String key) {
return map.containsKey(key);
}
/**
* Clears all key-value pairs from the map.
*/
@Override
public void clear() {
map.clear();
}
/**
* Removes the key-value pair associated with the given key.
*
* @param key Key to remove
*/
@Override
public void remove(String key) {
map.remove(key);
}
/**
* No-op method for flushing the map. This implementation does nothing.
*/
@Override
public void flush() {
//nothing to do
}
/**
* Retrieves a list of all keys in the map.
*
* @return List of keys
*/
@Override
public List<String> keyList() {
return map.keySet().stream().collect(Collectors.toList());

View File

@ -17,34 +17,92 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.storage.map;
import java.util.List;
import java.util.Map;
/**
*
* Interface for a simple key-value map storage.
* Provides methods for basic operations on a key-value map.
*
* Implementations of this interface should define how key-value pairs
* are stored and managed.
*
* @author robertvokac
*/
public interface SimpleMap {
/**
* Stores a key-value pair in the map.
*
* @param key Key to be stored
* @param val Value to be associated with the key
*/
public void putString(String key, String val);
/**
* Stores multiple key-value pairs in the map.
*
* @param map Key-value pairs to be stored
*/
public void put(Map<String, String> map);
/**
* Retrieves the value associated with the given key.
*
* @param key Key whose associated value is to be returned
* @return Value associated with the key, or null if the key is not found
*/
public String getString(String key);
/**
* Retrieves the value associated with the given key, or returns a default value if the key is not found.
*
* @param key Key whose associated value is to be returned
* @param defaultValue Default value to return if the key is not found
* @return Value associated with the key, or default value if the key is not found
*/
public String getString(String key, String defaultValue);
/**
* Retrieves an unmodifiable view of the map.
*
* @return Unmodifiable map
*/
public Map<String, String> getReadOnlyMap();
/**
* Checks if the map contains the given key.
*
* @param key Key to be checked
* @return True if the key is present in the map, false otherwise
*/
public boolean contains(String key);
/**
* Clears all key-value pairs from the map.
*/
public void clear();
/**
* Removes the key-value pair associated with the given key.
*
* @param key Key to be removed
*/
public void remove(String key);
/**
* No-operation method for flushing the map. Implementations may use this method if needed.
* This default implementation does nothing.
*/
public void flush();
/**
* Retrieves a list of all keys present in the map.
*
* @return List of keys in the map
*/
public List<String> keyList();
}