org.junit.jupiter
diff --git a/src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesGenerationException.java b/src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesGenerationException.java
deleted file mode 100644
index a3688c0..0000000
--- a/src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesGenerationException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package pt.codeforge.toolertools.internal.exceptions;
-
-public class PropertiesGenerationException extends Exception {
-
- public PropertiesGenerationException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public PropertiesGenerationException(String message) {
- super(message);
- }
-
- public PropertiesGenerationException(Throwable cause) {
- super(cause);
- }
-
- public PropertiesGenerationException() {
- }
-}
diff --git a/src/main/java/pt/codeforge/toolertools/props/PropertiesLoader.java b/src/main/java/pt/codeforge/toolertools/props/PropertiesLoader.java
index 97f59e2..fd3fd6c 100644
--- a/src/main/java/pt/codeforge/toolertools/props/PropertiesLoader.java
+++ b/src/main/java/pt/codeforge/toolertools/props/PropertiesLoader.java
@@ -1,47 +1,111 @@
package pt.codeforge.toolertools.props;
+import java.io.File;
+import java.nio.file.Path;
import java.util.Iterator;
import java.util.Optional;
import java.util.Properties;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.ex.ConfigurationException;
-import pt.codeforge.toolertools.internal.exceptions.PropertiesGenerationException;
-import pt.codeforge.toolertools.internal.exceptions.PropertiesLoadingException;
import pt.codeforge.toolertools.pathfinder.EnvPathParser;
+/**
+ * Utility class for loading properties from various sources, such as files and system properties, with support for
+ * environment variable expansion in file paths.
+ *
+ * Instances of this class provide methods to load properties based on different inputs, including
+ * property names, paths, {@code java.nio.file.Path}, and {@code java.io.File}.
+ *
+ *
Environment variable placeholders in file paths are automatically expanded using the {@link EnvPathParser}.
+ *
+ * @see EnvPathParser
+ * @see PropertiesLoader#loadFromPropertyName(String)
+ * @see PropertiesLoader#loadFromPath(String)
+ * @see PropertiesLoader#loadFromPath(Path)
+ * @see PropertiesLoader#loadFromFile(File)
+ */
public class PropertiesLoader {
- public static PropertiesLoader createPropertiesLoader() {
- return new PropertiesLoader();
+ private PropertiesLoader() {
+ throw new AssertionError("PropertiesLoader should not be instantiated.");
}
- public Properties loadProperties(String propName) throws PropertiesGenerationException {
+ /**
+ * Loads properties from the specified property name, expanding environment variable placeholders in the associated
+ * file path.
+ *
+ * @param propName The name of the property. Must not be null.
+ * @return The loaded properties.
+ * @throws PropertiesLoadingException If an error occurs during loading.
+ * @see EnvPathParser#getEnvPath(String)
+ */
+ public static Properties loadFromPropertyName(String propName) {
- String filePath = this.getOptionalFilePath(propName).orElseThrow(
+ String propertiesFilePath = getOptionalPropertiesFilePath(propName).orElseThrow(
() -> new PropertiesLoadingException(getPropertiesLoadingErrorMsg(propName)));
- String propsPath = EnvPathParser.getEnvPath(filePath);
+ String propsPath = EnvPathParser.getEnvPath(propertiesFilePath);
- return this.getOptionalProperties(propsPath).orElseThrow(
- () -> new PropertiesGenerationException(getInvalidPathToPropErrorMsg(propName, propsPath)));
+ return getOptionalProperties(propsPath).orElseThrow(
+ () -> new PropertiesLoadingException(getInvalidPathToPropErrorMsg(propName, propsPath)));
}
- private String getInvalidPathToPropErrorMsg(String propName, String propsPath) {
- return String.format("Invalid path to %s.properties. Path provided -> %s", propName, propsPath);
+ /**
+ * Loads properties from the specified path, expanding environment variable placeholders.
+ *
+ * @param path The path to the properties file. Must not be null.
+ * @return The loaded properties.
+ * @throws PropertiesLoadingException If an error occurs during loading.
+ * @see EnvPathParser#getEnvPath(String)
+ */
+ public static Properties loadFromPath(String path) {
+
+ String propsPath = EnvPathParser.getEnvPath(path);
+
+ return getOptionalProperties(propsPath).orElseThrow(
+ () -> new PropertiesLoadingException(getInvalidPathToPropErrorMsg(propsPath)));
}
- private String getPropertiesLoadingErrorMsg(String propName) {
- return String.format("Error loading %s.properties.", propName);
+ /**
+ * Loads properties from the specified {@code java.nio.file.Path}, expanding environment variable placeholders.
+ *
+ * @param path The {@code java.nio.file.Path} to the properties file. Must not be null.
+ * @return The loaded properties.
+ * @throws PropertiesLoadingException If an error occurs during loading.
+ * @see EnvPathParser#getEnvPath(String)
+ */
+ public static Properties loadFromPath(Path path) {
+
+ String propsPath = EnvPathParser.getEnvPath(path.toString());
+
+ return getOptionalProperties(propsPath).orElseThrow(
+ () -> new PropertiesLoadingException(getInvalidPathToPropErrorMsg(propsPath)));
+ }
+
+ /**
+ * Loads properties from the specified {@code java.io.File}, expanding environment variable placeholders.
+ *
+ * @param file The {@code java.io.File} representing the properties file. Must not be null.
+ * @return The loaded properties.
+ * @throws PropertiesLoadingException If an error occurs during loading.
+ * @see EnvPathParser#getEnvPath(String)
+ */
+ public static Properties loadFromFile(File file) {
+
+ String propsPath = EnvPathParser.getEnvPath(file.getAbsolutePath());
+
+ return getOptionalProperties(propsPath).orElseThrow(
+ () -> new PropertiesLoadingException(getInvalidPathToPropErrorMsg(propsPath)));
}
- private Optional getOptionalProperties(String filePath) {
+ private static Optional getOptionalProperties(String filePath) {
try {
Configurations configs = new Configurations();
Configuration config = configs.properties(filePath);
Properties properties = new Properties();
Iterator keys = config.getKeys();
- keys.forEachRemaining((key) -> {
+ keys.forEachRemaining(key -> {
String value = config.getString(key);
properties.setProperty(key, value);
});
@@ -51,8 +115,32 @@ private Optional getOptionalProperties(String filePath) {
}
}
- private Optional getOptionalFilePath(String propName) {
- return Optional.ofNullable(System.getProperty(propName));
+ private static Optional getOptionalPropertiesFilePath(String propName) {
+ try {
+ return Optional.ofNullable(System.getProperty(propName));
+ } catch (NullPointerException | IllegalArgumentException e) {
+ return Optional.empty();
+ }
+ }
+
+ private static String getInvalidPathToPropErrorMsg(String propName, String path) {
+ return String.format("Invalid path to %s.properties. Path provided -> %s", propName, path);
+ }
+
+ private static String getInvalidPathToPropErrorMsg(String path) {
+ return String.format("Invalid path provided. Path provided -> %s", path);
+ }
+
+ private static String getPropertiesLoadingErrorMsg(String propName) {
+ if (propName == null) {
+ return "Error loading properties. Key can't be null.";
+ }
+
+ if (propName.isEmpty()) {
+ return "Error loading properties. Key can't be empty.";
+ }
+
+ return String.format("Error loading %s.properties.", propName);
}
}
diff --git a/src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesLoadingException.java b/src/main/java/pt/codeforge/toolertools/props/PropertiesLoadingException.java
similarity index 73%
rename from src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesLoadingException.java
rename to src/main/java/pt/codeforge/toolertools/props/PropertiesLoadingException.java
index 16cc883..17eb6cc 100644
--- a/src/main/java/pt/codeforge/toolertools/internal/exceptions/PropertiesLoadingException.java
+++ b/src/main/java/pt/codeforge/toolertools/props/PropertiesLoadingException.java
@@ -1,6 +1,6 @@
-package pt.codeforge.toolertools.internal.exceptions;
+package pt.codeforge.toolertools.props;
-public class PropertiesLoadingException extends RuntimeException {
+class PropertiesLoadingException extends RuntimeException {
public PropertiesLoadingException(String message, Throwable cause) {
super(message, cause);
diff --git a/src/test/java/pt/codeforge/toolertools/props/PropertiesLoaderTest.java b/src/test/java/pt/codeforge/toolertools/props/PropertiesLoaderTest.java
new file mode 100644
index 0000000..32c2c7d
--- /dev/null
+++ b/src/test/java/pt/codeforge/toolertools/props/PropertiesLoaderTest.java
@@ -0,0 +1,30 @@
+package pt.codeforge.toolertools.props;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+class PropertiesLoaderTest {
+
+ @BeforeAll
+ static void setup() {
+ System.setProperty("test", "src/test/resources/test.properties"
+ );
+ }
+
+ @Test
+ void givenWrongInput_testLoadFromPropertyName_shouldThrowPropertiesLoadingException() {
+ assertThrows(PropertiesLoadingException.class, () -> PropertiesLoader.loadFromPropertyName("wrong"));
+ }
+
+ @Test
+ void givenEmptyInput_testLoadFromPropertyName_shouldThrowPropertiesLoadingException() {
+ assertThrows(PropertiesLoadingException.class, () -> PropertiesLoader.loadFromPropertyName(""));
+ }
+
+ @Test
+ void givenNullInput_testLoadFromPropertyName_shouldThrowPropertiesLoadingException() {
+ assertThrows(PropertiesLoadingException.class, () -> PropertiesLoader.loadFromPropertyName(null));
+ }
+}
diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties
index 1935ecc..09ea3a1 100644
--- a/src/test/resources/test.properties
+++ b/src/test/resources/test.properties
@@ -1,4 +1,5 @@
-HOME=$HOME
+HOME=${env:HOME}
+HOMEUSR=${env:HOMEDRIVE}${env:HOMEPATH}
testVariable=testVariable_test
fromVariable=${testVariable}
comboVariable=${HOME}/${fromVariable}