From 552bbc62745cd2ce0de2315803b1c9bc4ab1d757 Mon Sep 17 00:00:00 2001 From: Robert Vokac Date: Fri, 13 Sep 2024 20:41:11 +0200 Subject: [PATCH] Bug 14: Added comments to the storage classes and interfaces --- .../pixelgamelibrary/api/storage/Storage.java | 192 ++++++++++++++++-- .../api/storage/StorageException.java | 9 +- ...seCommand.java => BaseStorageCommand.java} | 49 ++++- .../storage/command/CommandLineScanner.java | 10 +- .../api/storage/command/StorageCommand.java | 34 +++- .../storage/command/StorageCommandLine.java | 97 +++++---- .../command/StorageCommandLineScanner.java | 29 ++- .../storage/command/StorageCommandResult.java | 53 ++++- .../api/storage/map/MapFileType.java | 21 +- .../api/storage/map/MapStorage.java | 88 ++++++-- .../api/storage/map/MemoryStorage.java | 24 ++- .../api/storage/map/SimpleJavaMap.java | 68 ++++++- .../api/storage/map/SimpleMap.java | 62 +++++- 13 files changed, 637 insertions(+), 99 deletions(-) rename src/main/java/com/pixelgamelibrary/api/storage/command/{BaseCommand.java => BaseStorageCommand.java} (56%) diff --git a/src/main/java/com/pixelgamelibrary/api/storage/Storage.java b/src/main/java/com/pixelgamelibrary/api/storage/Storage.java index 5ebff80..d64c2f2 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/Storage.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/Storage.java @@ -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 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 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"; } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/StorageException.java b/src/main/java/com/pixelgamelibrary/api/storage/StorageException.java index dae7c71..eed99e1 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/StorageException.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/StorageException.java @@ -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); } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/BaseCommand.java b/src/main/java/com/pixelgamelibrary/api/storage/command/BaseStorageCommand.java similarity index 56% rename from src/main/java/com/pixelgamelibrary/api/storage/command/BaseCommand.java rename to src/main/java/com/pixelgamelibrary/api/storage/command/BaseStorageCommand.java index 2714d51..de92114 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/BaseCommand.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/BaseStorageCommand.java @@ -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 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 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); diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/CommandLineScanner.java b/src/main/java/com/pixelgamelibrary/api/storage/command/CommandLineScanner.java index 4110807..5e6454d 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/CommandLineScanner.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/CommandLineScanner.java @@ -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(); } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommand.java b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommand.java index 396c6fa..b373699 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommand.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommand.java @@ -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(); } - } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLine.java b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLine.java index d6fa1dd..8bf7d0b 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLine.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLine.java @@ -17,6 +17,7 @@ // 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 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 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 argument1 = Optional.ofNullable(argumentCount >= 1 ? arguments[1] : null); Optional 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; } - } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLineScanner.java b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLineScanner.java index 29373f7..184be0f 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLineScanner.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandLineScanner.java @@ -17,37 +17,62 @@ // 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); } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandResult.java b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandResult.java index 665a9b9..bf82d6f 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandResult.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/command/StorageCommandResult.java @@ -17,52 +17,99 @@ // 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 } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/map/MapFileType.java b/src/main/java/com/pixelgamelibrary/api/storage/map/MapFileType.java index 937524c..6d35d48 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/map/MapFileType.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/map/MapFileType.java @@ -17,31 +17,44 @@ // 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); - } - } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/map/MapStorage.java b/src/main/java/com/pixelgamelibrary/api/storage/map/MapStorage.java index bc3fa1c..1a92bcf 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/map/MapStorage.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/map/MapStorage.java @@ -17,6 +17,7 @@ // 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 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); } - } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/map/MemoryStorage.java b/src/main/java/com/pixelgamelibrary/api/storage/map/MemoryStorage.java index e907898..59b6bb9 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/map/MemoryStorage.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/map/MemoryStorage.java @@ -17,23 +17,33 @@ // 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; + } } diff --git a/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleJavaMap.java b/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleJavaMap.java index a5ab3a9..5ccebab 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleJavaMap.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleJavaMap.java @@ -17,6 +17,7 @@ // 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 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 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 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 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 keyList() { return map.keySet().stream().collect(Collectors.toList()); diff --git a/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleMap.java b/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleMap.java index a9ebfec..31dfdcc 100644 --- a/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleMap.java +++ b/src/main/java/com/pixelgamelibrary/api/storage/map/SimpleMap.java @@ -17,34 +17,92 @@ // 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 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 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 keyList(); }