diff --git a/boot/platform/src/main/java/com/plate/boot/commons/converters/CollectionConverters.java b/boot/platform/src/main/java/com/plate/boot/commons/converters/CollectionConverters.java index 0e1cf8ad..bc5b0c20 100644 --- a/boot/platform/src/main/java/com/plate/boot/commons/converters/CollectionConverters.java +++ b/boot/platform/src/main/java/com/plate/boot/commons/converters/CollectionConverters.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.plate.boot.commons.exception.JsonException; import com.plate.boot.commons.utils.ContextUtils; import io.r2dbc.postgresql.codec.Json; @@ -17,21 +18,78 @@ import java.util.Collection; /** - * @author Alex bob + * CollectionConverters is a Spring Configuration class responsible for initializing converters + * that facilitate the transformation between JSON and Java Collection types. It provides + * ReadingConverter and WritingConverter components to support these conversions seamlessly + * within a Spring application context, particularly useful in scenarios involving data binding + * with JSON data sources like databases or web requests. + * + *
This class implements InitializingBean, ensuring that the converters are properly initialized + * upon the application's startup sequence. + * + *
Both converters utilize {@link ContextUtils#OBJECT_MAPPER}, an ObjectMapper instance configured + * elsewhere in the application context, to perform the actual JSON serialization and deserialization. + * + * @see InitializingBean Spring's InitializingBean interface for callback on bean initialization. + * @see ReadingConverter Marker interface for converters reading from a MongoDB representation. + * @see WritingConverter Marker interface for converters writing to a MongoDB representation. + * @since Typically used in applications requiring data binding with JSON. */ @Log4j2 @Configuration(proxyBeanMethods = false) public class CollectionConverters implements InitializingBean { + /** + * Initializes the converters managed by this class. This method is part of the + * Spring Framework's {@link InitializingBean} contract, ensuring that the converters + * are properly set up when the Spring container initializes this bean. + *
+ * Logs a message indicating the start of the initialization process for the + * [CollectionConverters], which is crucial for preparing the application to handle + * JSON to Collection and vice versa transformations seamlessly. + * + * @see InitializingBean for more details on the callback contract for bean initialization. + */ @Override public void afterPropertiesSet() { log.info("Initializing converter [CollectionConverters]..."); } + /** + * CollectionReadConverter is a Spring component and a ReadingConverter that is designed to + * deserialize JSON data into a Collection of objects. It is part of the CollectionConverters + * configuration, ensuring seamless integration within a Spring context where conversion between + * JSON and Java Collections is required, such as when interacting with MongoDB or processing web requests. + *
This converter leverages the OBJECT_MAPPER from ContextUtils to perform JSON deserialization. + * It defines the conversion logic for transforming a Json representation into a Collection of generic type. + *
In the event of a JsonProcessingException during deserialization, this converter throws a
+ * JsonException, encapsulating the error details for further handling.
+ *
+ * @see ContextUtils For the setup of the OBJECT_MAPPER utilized in deserialization.
+ * @see JsonException For the exception type thrown upon JSON processing errors.
+ * @see CollectionConverters The parent configuration class managing this converter.
+ */
@Component
@ReadingConverter
public static class CollectionReadConverter implements Converter
+ * This method utilizes the OBJECT_MAPPER from ContextUtils to deserialize the JSON string
+ * represented by the Json source into a Collection of a generic type determined at runtime.
+ * In case of a JsonProcessingException during deserialization, a JsonException is thrown
+ * with a descriptive error message including the original exception's message.
+ *
+ * @param source The Json source to be converted into a Collection. Must not be null.
+ * @return A Collection of objects resulting from the JSON deserialization.
+ * @throws JsonException If an error occurs during the JSON processing or deserialization.
+ */
@Override
public Collection> convert(@NonNull Json source) {
try {
@@ -44,10 +102,34 @@ public Collection> convert(@NonNull Json source) {
}
}
+ /**
+ * A converter class designed to serialize collections into their corresponding JSON representations.
+ * This class is annotated as a Spring Component and a WritingConverter, indicating its role within
+ * the Spring ConversionService for writing data to JSON format.
+ *
+ * The primary method, {@link #convert(Collection)}, accepts a collection of any type and
+ * utilizes Jackson's `ObjectMapper` to serialize the collection into a byte array, which is then
+ * encapsulated within a {@link Json} object for further processing or transmission. Note: The method throws a {@link JsonException} if the serialization process encounters an
+ * issue, providing a descriptive error message that includes the original exception's details.
+ * In this implementation, it logs the initialization status of the [JsonNodeConverters],
+ * indicating that the converter setup process is being initiated.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing converter [JsonNodeConverters]...");
}
+ /**
+ * Converts a Jackson {@link JsonNode} to a custom {@link Json} object for write operations.
+ * This converter is designed to be used within a Spring context and is annotated as a component
+ * and a writing converter.
+ *
+ * The conversion process involves converting the JsonNode to its string representation
+ * and then wrapping it into a Json object using the {@link Json#of(String)} method.
+ */
@Component
@WritingConverter
public static class JsonToNodeWriteConverter implements Converter
+ * The conversion process involves parsing the Json object into a JSON array and then
+ * using Jackson's ObjectMapper to read this array into a JsonNode structure.
+ * If an {@link IOException} occurs during the conversion, it is rethrown as a {@link JsonException}
+ * to propagate the error appropriately.
+ */
@Component
@ReadingConverter
public static class JsonToNodeReadConverter implements Converter
+ * This method is part of the read conversion process, used to transform auditor codes
+ * stored as strings (for example, in a database) back into rich {@link UserAuditor} objects.
+ * It delegates the conversion to the {@link UserAuditor#withCode(String)} factory method,
+ * which reconstructs the auditor with the provided code while setting default null values for
+ * the username and name fields.
+ *
+ * @param source The non-null String containing the user auditor code to convert.
+ * @return A {@link UserAuditor} instance created using the provided code.
+ * @throws NullPointerException if the source is null.
+ */
@Override
public UserAuditor convert(@NonNull String source) {
return UserAuditor.withCode(source);
diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/BeanUtils.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/BeanUtils.java
index 7a923f71..f322fd16 100644
--- a/boot/platform/src/main/java/com/plate/boot/commons/utils/BeanUtils.java
+++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/BeanUtils.java
@@ -271,6 +271,13 @@ public void setMaxInMemorySize(DataSize dataSize) {
MAX_IN_MEMORY_SIZE = dataSize;
}
+ /**
+ * Initializes the utils bean by performing necessary setup steps.
+ * This method is called after all properties of this bean have been set.
+ * It is part of the Spring Framework's InitializingBean interface contract.
+ *
+ * Logs a message indicating the start of the initialization process for BeanUtils.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing utils [BeanUtils]...");
diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/ContextUtils.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/ContextUtils.java
index fbd5658a..3e241898 100644
--- a/boot/platform/src/main/java/com/plate/boot/commons/utils/ContextUtils.java
+++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/ContextUtils.java
@@ -23,20 +23,49 @@
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
/**
- * @author Alex bob(Alex Bob)
+ * Utility class providing context-related operations and services for the application.
+ * This class is designed as a Spring Component and implements InitializingBean to ensure
+ * proper setup during application initialization.
+ *
+ * It offers functionalities such as encoding strings to MD5, retrieving client IP addresses,
+ * handling security details within reactive context, serializing UserAuditor objects,
+ * generating unique IDs, and initializing utility setup with logging.
*/
@Log4j2
@Component
public final class ContextUtils implements InitializingBean {
+ /**
+ * Constant defining the role identifier for administrators within the system.
+ * This role grants access to administrative functionalities and permissions.
+ */
public final static String RULE_ADMINISTRATORS = "ROLE_ADMINISTRATORS";
+ /**
+ * Constants for the context key used to store CSRF token information.
+ * This string represents the identifier used to retrieve or store CSRF tokens in a context such as a thread local,
+ * request attribute, or any other data structure where keys are strings.
+ */
public final static String CSRF_TOKEN_CONTEXT = "CSRF_TOKEN_CONTEXT";
+ /**
+ * A constant holding a pre-initialized instance of {@link MessageDigest}.
+ * This digest can be used for cryptographic hashing operations.
+ */
+ public final static MessageDigest MD;
+ /**
+ * An array of strings representing the possible header names that could contain
+ * the client's IP address in HTTP requests. This is typically used when working
+ * behind proxies or load balancers where the original client IP is not directly
+ * available in the standard {@code REMOTE_ADDR} header.
+ *
+ * The list includes common headers like {@code X-Forwarded-For}, {@code X-Real-IP},
+ * and others that are often set by proxies to facilitate correct identification
+ * of the originating IP address of the client.
+ */
private final static String[] IP_HEADER_CANDIDATES = {
"X-Forwarded-For",
"X-Real-IP",
@@ -52,8 +81,6 @@ public final class ContextUtils implements InitializingBean {
"REMOTE_ADDR"
};
- public final static MessageDigest MD;
-
static {
try {
MD = MessageDigest.getInstance("MD5");
@@ -61,20 +88,61 @@ public final class ContextUtils implements InitializingBean {
throw RestServerException.withMsg("MD5 algorithm not found", e);
}
}
-
+ /**
+ * A shared static instance of Jackson's {@link ObjectMapper}, which is utilized for
+ * serializing and deserializing Java objects to and from JSON format. This singleton pattern
+ * helps in ensuring consistent JSON processing across the application and reduces the
+ * overhead of creating multiple ObjectMapper instances.
+ *
+ * Usage of this mapper should be considered for general-purpose JSON operations within the application,
+ * unless specific configurations are required for certain use cases, in which case a separate
+ * ObjectMapper instance with tailored configurations should be created.
+ *
+ * It is important to note that since this is a static shared resource, any configuration changes
+ * made to this instance will affect all parts of the application using it. Therefore, caution must
+ * be exercised when modifying its settings.
+ */
public static ObjectMapper OBJECT_MAPPER;
+ /**
+ * Static reference to the UsersService instance.
+ * This service provides functionalities related to user management such as
+ * user retrieval, creation, update, and deletion.
+ */
public static UsersService USERS_SERVICE;
+ /**
+ * Initializes the ContextUtils class with necessary dependencies.
+ *
+ * @param objectMapper The ObjectMapper instance used for JSON serialization and deserialization.
+ * @param usersService The UsersService instance to provide access to user-related operations.
+ */
ContextUtils(ObjectMapper objectMapper, UsersService usersService) {
ContextUtils.OBJECT_MAPPER = objectMapper;
ContextUtils.USERS_SERVICE = usersService;
}
+ /**
+ * Encodes the given input string into its MD5 hash representation, which is then
+ * base64 encoded for a more compact and URL-friendly format.
+ *
+ * @param input The string to be encoded into MD5 hash.
+ * @return A base64 encoded string representing the MD5 hash of the input string.
+ */
public static String encodeToMD5(String input) {
byte[] bytes = MD.digest(input.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(bytes);
}
+ /**
+ * Retrieves the client's IP address from the given server HTTP request.
+ * This method iterates over a set of common headers used to carry the client's IP address
+ * and returns the first non-empty value found. If none of these headers yield an IP,
+ * it falls back to extracting the IP from the remote address of the request.
+ *
+ * @param httpRequest The server HTTP request from which to extract the client's IP address.
+ * @return The client's IP address as a string, or the remote address's host address if no
+ * explicit IP is found in the headers.
+ */
public static String getClientIpAddress(ServerHttpRequest httpRequest) {
HttpHeaders headers = httpRequest.getHeaders();
for (String header : IP_HEADER_CANDIDATES) {
@@ -86,22 +154,56 @@ public static String getClientIpAddress(ServerHttpRequest httpRequest) {
return Objects.requireNonNull(httpRequest.getRemoteAddress()).getAddress().getHostAddress();
}
+ /**
+ * Retrieves the security details of the currently authenticated user.
+ *
+ * This method accesses the security context asynchronously and extracts the principal,
+ * which is then cast to a {@link SecurityDetails} object. It is designed to be used
+ * within a reactive environment where security information is required for further processing.
+ *
+ * This method utilizes the {@link UlidCreator#getMonotonicUlid()} to produce ULIDs which are:
+ * - Globally unique across space and time.
+ * - Lexicographically sortable.
+ * - Monotonic in time.
+ *
+ * Logs a message indicating the initialization of the [ContextUtils] component.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing utils [ContextUtils]...");
diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java
index 5612045d..4e03e953 100644
--- a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java
+++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java
@@ -50,10 +50,27 @@ public Map
+ * This method is useful for accessing the SQL fragment that represents
+ * a part of a query, such as a WHERE clause, which can be further
+ * incorporated into a complete SQL statement.
+ *
+ * @return The {@link StringJoiner} object holding the concatenated SQL segments.
+ */
public StringJoiner sql() {
return this.sql;
}
+ /**
+ * Generates the WHERE clause part of a SQL query based on the stored conditions.
+ * If conditions have been accumulated, it prefixes the conditions with the 'WHERE' keyword;
+ * otherwise, it returns an empty string to indicate no conditions.
+ *
+ * @return A String forming the WHERE clause of the SQL query, or an empty string if no conditions are present.
+ */
public String whereSql() {
if (this.sql.length() > 0) {
return " where " + this.sql;