diff --git a/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractDatabase.java b/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractDatabase.java index 12671885..2ef13135 100644 --- a/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractDatabase.java +++ b/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractDatabase.java @@ -7,33 +7,114 @@ import org.springframework.jdbc.core.simple.JdbcClient; /** - * @author Alex bob + * AbstractDatabase serves as an abstract base class for database-related services within the application. + * It centralizes common database connection and setup logic by providing initialized instances + * of JDBC clients and templates, along with a ConversionService, ready for extension by concrete service implementations. + * This class extends AbstractService which ensures additional initialization steps are performed after bean properties are set. + * + *
This abstract class autowires the following dependencies:
+ *Subclasses should implement specific database interaction logic tailored to their needs, + * leveraging the provided database access tools.
+ * + *Usage Note:
+ *+ * {@code + * public class MyDatabaseService extends AbstractDatabase { + * // Implement your service methods here + * // Access JDBC tools using `this.jdbcTemplate`, `this.namedParameterJdbcTemplate`, etc. + * } + * }*/ public abstract class AbstractDatabase extends AbstractService { + /** + * The JDBC client instance used for executing SQL statements and managing + * database connections within the service. This field is populated by Spring's + * dependency injection through the {@link #setJdbcClient(JdbcClient)} method. + * It serves as the primary interface for interacting with the underlying database. + */ protected JdbcClient jdbcClient; + /** + * JDBC template instance utilized for executing SQL commands and queries against the database. + * This field is automatically wired by the Spring framework through the {@link #setJdbcTemplate(JdbcTemplate)} method, + * which injects a configured {@link JdbcTemplate} capable of efficient data access operations. + */ protected JdbcTemplate jdbcTemplate; + /** + * Instance of NamedParameterJdbcTemplate used for executing SQL queries with named parameters. + * This field is automatically wired by the Spring framework, facilitating safer and more convenient + * parameter binding in SQL statements compared to traditional positional parameters. + */ protected NamedParameterJdbcTemplate namedParameterJdbcTemplate; + /** + * Conversion service used for type conversion operations within the application. + * This service facilitates binding of parameters and reading of results from the database, + * ensuring seamless communication between different data types. + */ protected ConversionService conversionService; + /** + * Sets the JDBC client instance for the service. + * This method is automatically called by the Spring framework to inject the JDBC client dependency. + * + * @param jdbcClient The JDBC client used for executing SQL statements and managing database connections. + */ @Autowired public void setJdbcClient(JdbcClient jdbcClient) { this.jdbcClient = jdbcClient; } + /** + * Sets the ConversionService instance to be used by the service. + * This method is automatically invoked by the Spring framework during bean initialization to inject the ConversionService dependency. + * + * @param conversionService The ConversionService responsible for type conversion operations within the application, + * facilitating binding of parameters and reading of results from the database. + */ @Autowired public void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } + + /** + * Sets the JdbcTemplate instance for the service. + * This method is automatically invoked by the Spring framework's dependency injection to provide the JdbcTemplate bean, + * enabling the service to execute SQL commands and queries efficiently. + * + * @param jdbcTemplate The JdbcTemplate that simplifies JDBC operations and provides high-level data access functions. + */ @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } + + /** + * Sets the NamedParameterJdbcTemplate instance for the service. + * This method is automatically called by the Spring framework to inject the NamedParameterJdbcTemplate dependency, + * which allows for executing SQL queries with named parameters. + * + * @param namedParameterJdbcTemplate The NamedParameterJdbcTemplate used for executing parameterized SQL statements + * with named parameters, providing a more convenient and safer way to bind query variables. + */ @Autowired public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; } + /** + * Callback method that is invoked by the Spring container once all properties + * of this Bean have been set. This method is part of the lifecycle interface + * for beans that need to react once all their properties have been initialized. + * It calls the superclass's {@code afterPropertiesSet} method to ensure + * any additional setup defined there is also executed. + */ @Override public void afterPropertiesSet() { super.afterPropertiesSet(); diff --git a/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractService.java b/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractService.java index d13b57d8..b6aa354d 100644 --- a/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractService.java +++ b/boot/oauth2/src/main/java/com/plate/auth/commons/base/AbstractService.java @@ -4,22 +4,66 @@ import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** - * @author Alex bob + * AbstractService serves as a foundation for implementing service layers within an application, + * encapsulating common functionality and providing a structure for dependency injection and initialization. + * It integrates with Spring Framework features, ensuring that services are properly set up and ready to use. + * + *
This abstract class offers the following core functionalities:
+ *Subclasses should extend this class and may override {@link #afterPropertiesSet()} + * to include custom initialization steps, ensuring they call `super.afterPropertiesSet()` to maintain base behavior.
+ * + *Dependencies like {@link JdbcTemplate}, {@link NamedParameterJdbcTemplate}, and {@link ConversionService} + * can be injected via respective setter methods (not shown directly here), following Spring's dependency injection principles.
*/ @Log4j2 public abstract class AbstractService implements InitializingBean { + /** + * Provides an instance of {@link ObjectMapper} configured for JSON serialization and deserialization. + * This object is essential for converting Java objects to and from JSON format. + * It is automatically configured and injected into subclasses of {@link AbstractService}, + * ensuring that service layers have the capability to handle JSON data processing consistently. + *+ * Subclasses can utilize this {@code objectMapper} directly to perform JSON operations without needing + * to manage the configuration themselves. + */ protected ObjectMapper objectMapper; + /** + * Sets the {@link ObjectMapper} instance to be used for JSON serialization and deserialization. + * This method is typically called by the Spring framework to inject a pre-configured ObjectMapper bean. + * + * @param objectMapper The ObjectMapper instance to be set, which should be configured for the application's needs. + */ @Autowired public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } + /** + * Invoked by the Spring IoC container after all properties + * of this bean have been set. This method is an implementation + * of the {@link InitializingBean} interface, allowing for custom + * initialization logic to be executed at the appropriate time + * in the bean lifecycle. It logs a debug message indicating + * the name of the initializing provider class. + *
+ * Subclasses may override this method but should call + * `super.afterPropertiesSet()` to maintain the base + * class's initialization behavior. + */ @Override public void afterPropertiesSet() { - log.debug("Initializing provider names: {}",this.getClass().getName()); + log.debug("Initializing provider names: {}", this.getClass().getName()); } } \ No newline at end of file diff --git a/boot/oauth2/src/main/java/com/plate/auth/commons/base/BaseEntity.java b/boot/oauth2/src/main/java/com/plate/auth/commons/base/BaseEntity.java index 8ab42cea..aca538c9 100644 --- a/boot/oauth2/src/main/java/com/plate/auth/commons/base/BaseEntity.java +++ b/boot/oauth2/src/main/java/com/plate/auth/commons/base/BaseEntity.java @@ -8,29 +8,41 @@ import java.io.Serializable; /** - * @author Alex bob + * Represents the base entity definition with common functionality shared across all entities. + * This interface extends {@link Serializable} and {@link Persistable}, ensuring entities can be serialized + * and have basic persistence-related operations defined. + * + *
{@code BaseEntity} introduces a default method to set a code value and overrides the `isNew` method + * to determine if an entity instance is new (typically based on the absence of an identifier). + * It also suggests a flexible way to handle entity identifiers through the `setCode` method. + * + *
- * 此方法提供了一个接口来为相关对象设置一个代码值。具体的实现可能会根据实际需求来决定如何处理这个代码值。 - * 由于这是一个默认方法,它为接口的实现提供了一种灵活的方式来处理代码值,而不需要强制实现这个方法。 + * Assigns a code to the entity. * - * @param code 要设置的代码值。这个参数允许调用者指定一个代码值,该值可以是任何字符串,具体的含义和使用方式取决于实现。 + * This method is intended to set a unique code identifier for an entity. The implementation should define + * how the `code` parameter is utilized, as the current implementation is a placeholder. + * + * @param code The code value to be assigned to the entity. The nature of this code is dependent on the + * business logic or system requirements where this interface is implemented. */ default void setCode(String code) { - //todo 方法体为空,具体的实现可能需要根据实际需求来决定如何处理code参数。 + //todo } /** - * 判断当前对象是否为新对象,即是否具有ID。 - * 如果对象尚未分配ID,则将其视为新对象,并生成一个新的ID。 - * 此方法用于标识对象是否已存在于持久化存储中,如果没有ID,则认为是新对象需要进行持久化操作。 - * - * @return 如果对象是新对象(没有ID),则返回true;否则返回false。 - */ + * Determines whether the entity instance represents a new record that has not yet been persisted. + * This method checks if the entity's identifier ({@code getId}) is empty to assess its novelty. + * If the entity is deemed new, it assigns a new unique code*/ @Override @JsonIgnore default boolean isNew() { diff --git a/boot/oauth2/src/main/java/com/plate/auth/commons/converters/CollectionConverters.java b/boot/oauth2/src/main/java/com/plate/auth/commons/converters/CollectionConverters.java index 8d3d19fd..77a45905 100644 --- a/boot/oauth2/src/main/java/com/plate/auth/commons/converters/CollectionConverters.java +++ b/boot/oauth2/src/main/java/com/plate/auth/commons/converters/CollectionConverters.java @@ -17,21 +17,59 @@ import java.util.Collection; /** - * @author Alex bob + * CollectionConverters is a Spring configuration class that provides converters to facilitate + * the serialization and deserialization of {@link Collection} objects into and from JSON strings, + * primarily for database storage and retrieval operations. This class registers these converters + * to be automatically applied within the Spring context where applicable. + * + *
The converters encapsulated within this class are:
+ *These converters leverage {@link ContextUtils#OBJECT_MAPPER} for JSON processing.
+ * + *Note: This class implements {@link InitializingBean} to log an initialization message.
*/ @Log4j2 @Configuration(proxyBeanMethods = false) public class CollectionConverters implements InitializingBean { + /** + * Invoked by the containing {@code BeanFactory} after it has set all bean properties + * and satisfied all dependencies for this bean. This method allows the bean instance + * to perform initialization only possible when all bean properties have been set + * and to throw an exception in the event of misconfiguration. + *
+ * This implementation logs a message indicating the initialization of
+ * {@code CollectionConverters}, which provides converters for handling
+ * {@link Collection} serialization and deserialization within a Spring context.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing converter [CollectionConverters]...");
}
+ /**
+ * A converter class designed to facilitate the persistence of {@link Collection} objects into a database and their retrieval back into Java objects.
+ * This converter serializes collections to JSON strings when persisting into a database column and deserializes them back into collections when loading from the database.
+ * It is annotated to be automatically applied by JPA for any {@link Collection} fields marked with the appropriate JPA annotations.
+ */
@Component
@jakarta.persistence.Converter(autoApply = true)
public static class CollectionAttributeConverter implements AttributeConverter Usage Note:
+ * The converter expects the input string to be formatted as a valid JSON array.
+ * If the source string fails to deserialize due to invalid JSON format,
+ * a {@link JsonException} is thrown, providing a descriptive error message. Upon invocation of the {@link #convert(Collection)} method, the source collection is serialized
+ * into a JSON string. If any exception occurs during the serialization, a custom {@link JsonException}
+ * is thrown, encapsulating the original error message to provide a clearer indication of the issue. Contains inner classes that act as converters:
+ * Note: Relies on {@link ContextUtils#OBJECT_MAPPER} for JSON serialization/deserialization operations.
*/
@Log4j2
@Configuration(proxyBeanMethods = false)
public class JsonNodeConverters implements InitializingBean {
+ /**
+ * Invoked by a BeanFactory on beans that carry a {@code InitializingBean} interface,
+ * after it has set all bean properties supplied in its bean definition.
+ * This method allows the bean instance to perform initialization only possible
+ * when all bean properties have been set and to throw an exception in the event of misconfiguration.
+ *
+ * Within this implementation, it logs the initialization status of the [JsonNodeConverters] component,
+ * indicating that the converter setup process is being initiated.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing converter [JsonNodeConverters]...");
}
+ /**
+ * Converts a collection represented as an {@link ObjectNode} to a string for database storage
+ * and vice versa. This class is designed to be used within an ORM framework that supports JPA's
+ * {@link AttributeConverter} interface, automatically applying the conversion for entities using
+ * {@link ObjectNode} fields.
+ *
+ * The conversion process handles null and empty collections gracefully, ensuring database
+ * integrity and efficient storage by avoiding unnecessary entries for empty collections.
+ *
+ * During the conversion to a database column, the method {@link #convertToDatabaseColumn(ObjectNode)}
+ * utilizes JSON serialization to transform the {@link ObjectNode} into a string representation.
+ * Conversely, {@link #convertToEntityAttribute(String)} deserializes the string back into an
+ * {@link ObjectNode} when loading from the database.
+ *
+ * @see AttributeConverter
+ * @see jakarta.persistence.Converter
+ */
@Component
@jakarta.persistence.Converter(autoApply = true)
public static class CollectionAttributeConverter implements AttributeConverter The conversion process involves parsing the input JSON string using Jackson's
+ * {@link ObjectMapper#readTree(String)} method to create a tree representation of the JSON,
+ * followed by a deep copy operation to ensure the converted {@link ObjectNode} is independent
+ * of the original source string, thus preventing unintended side effects from subsequent modifications.
+ *
+ * In the event of a parsing failure, such as when the source string is not a valid JSON,
+ * the method throws a {@link JsonException}, encapsulating the original {@link IOException},
+ * to propagate the error in a controlled manner.
+ *
+ * @see ReadingConverter
+ * @see Converter
+ * @see ObjectNode
+ */
@Component
@ReadingConverter
public static class JsonToNodeReadConverter implements Converter
+ * The converters provided are:
+ *
+ * This converter is automatically applied to all {@link UserAuditor} fields marked with JPA annotations,
+ * ensuring seamless conversion between the entity attribute and the database column.
+ *
+ * ConvertToEntityAttribute: The class provides static factory methods for convenience in creating instances with common
+ * configurations, allowing for快速 instantiation based on typical error scenarios.
+ * Key Features:
+ * - Utilizes R2dbcEntityTemplate for entity-based operations.
+ * - Leverages DatabaseClient for SQL execution.
+ * - Implements caching mechanisms to enhance query performance.
+ * - Supports reactive programming model using Flux and Mono.
+ *
+ * Usage Note:
+ * Subclasses should implement specific database interaction logic while leveraging
+ * the provided caching wrappers around query and count operations.
+ *
+ * Dependencies:
+ * Requires an R2dbcEntityTemplate, DatabaseClient, and Cache instance to be functional,
+ * typically wired through dependency injection.
*/
public abstract class AbstractDatabase extends AbstractService {
+ /**
+ * The R2dbcEntityTemplate instance used for executing reactive database operations.
+ * This template facilitates interaction with the database, including query execution,
+ * entity conversion, and transaction management specifically tailored for R2DBC (Reactive Relational Database Connectivity).
+ */
protected R2dbcEntityTemplate entityTemplate;
+ /**
+ * Represents a client for interacting with the database, facilitating operations such as
+ * querying, updating, and managing data within the database. This field is initialized
+ * and configured typically during the setup or initialization phase of the hosting class,
+ * enabling seamless database access throughout the application.
+ */
protected DatabaseClient databaseClient;
+ /**
+ * The R2DBC Converter instance used for converting between R2DBC Data types and domain-specific objects.
+ * This converter plays a crucial role in mapping query results to entity classes and vice versa,
+ * facilitating seamless interaction with the R2DBC database through the R2dbcEntityTemplate.
+ */
protected R2dbcConverter r2dbcConverter;
+ /**
+ * Executes a database query with caching functionality.
+ * It takes a cache key, a query object, and an entity class type to perform the operation.
+ * The results are cached for future queries with the same key.
+ *
+ * @param In this implementation, the method sets up the {@code databaseClient} and
+ * {@code r2dbcConverter} by extracting them from the injected {@code entityTemplate}.
+ * It calls the superclass's {@code afterPropertiesSet} first to ensure any
+ * necessary setup in the parent class is also executed.
+ */
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
diff --git a/boot/platform/src/main/java/com/plate/boot/commons/base/AbstractService.java b/boot/platform/src/main/java/com/plate/boot/commons/base/AbstractService.java
index 29dfa03a..cdb288c8 100644
--- a/boot/platform/src/main/java/com/plate/boot/commons/base/AbstractService.java
+++ b/boot/platform/src/main/java/com/plate/boot/commons/base/AbstractService.java
@@ -11,27 +11,85 @@
import java.util.Optional;
/**
- * @author Alex bob
+ * AbstractService serves as a foundation for implementing service layers with common functionalities,
+ * such as caching and initialization routines. It integrates with Spring's cache management and
+ * initialization callbacks, providing a structured approach to service layer development.
+ *
+ * This abstract class requires implementations to define business logic while benefiting from
+ * built-in support for an {@link ObjectMapper} for JSON serialization/deserialization and a
+ * {@link CacheManager} for managing caching operations. It enforces the setup of a dedicated cache
+ * per extending service class, enhancing performance through result caching.
+ * Notable features include:
+ * Usage of this {@link ObjectMapper} should adhere to best practices regarding JSON processing within the application,
+ * including proper handling of date formats, polymorphism, and any custom serializers/deserializers defined
+ * for application-specific data structures.
+ */
protected ObjectMapper objectMapper;
+ /**
+ * Sets the ObjectMapper instance to be used by this component.
+ *
+ * @param objectMapper The ObjectMapper object which provides functionality for JSON serialization and deserialization.
+ */
@Autowired
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
+ /**
+ * Sets the CacheManager instance to be used by this component.
+ *
+ * @param cacheManager The CacheManager instance to manage caches.
+ */
@Autowired
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
+ /**
+ * Initializes the cache with the specified name.
+ * If the cache manager is set, it attempts to retrieve the cache from the manager;
+ * otherwise, it creates a new ConcurrentMapCache with the given name.
+ * After initialization, the cache is cleared and a debug log message is generated indicating
+ * the cache's class name and name.
+ *
+ * @param cacheName The name of the cache to initialize.
+ */
protected void initializingCache(String cacheName) {
this.cache = Optional.ofNullable(this.cacheManager).map(manager -> manager.getCache(cacheName))
.orElse(new ConcurrentMapCache(cacheName));
@@ -40,6 +98,15 @@ protected void initializingCache(String cacheName) {
this.cache.getNativeCache().getClass().getSimpleName(), this.cache.getName());
}
+ /**
+ * Invoked by the containing {@code BeanFactory} after it has set all bean properties
+ * and satisfied all dependencies for this bean. This method allows the bean instance
+ * to perform initialization only possible when all bean properties have been set
+ * and to throw an exception in the event of misconfiguration.
+ *
+ * This implementation initializes the cache associated with this component,
+ * using the bean's class name concatenated with ".cache" as the cache identifier.
+ */
@Override
public void afterPropertiesSet() {
initializingCache(this.getClass().getName().concat(".cache"));
diff --git a/boot/platform/src/main/java/com/plate/boot/commons/base/BaseEntity.java b/boot/platform/src/main/java/com/plate/boot/commons/base/BaseEntity.java
index 36174770..788dc228 100644
--- a/boot/platform/src/main/java/com/plate/boot/commons/base/BaseEntity.java
+++ b/boot/platform/src/main/java/com/plate/boot/commons/base/BaseEntity.java
@@ -2,7 +2,7 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.plate.boot.commons.utils.ContextUtils;
-import com.plate.boot.commons.utils.query.CriteriaUtils;
+import com.plate.boot.commons.utils.query.QueryHelper;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.util.ObjectUtils;
@@ -11,28 +11,31 @@
import java.util.Collection;
/**
- * @author Alex bob
+ * Represents the base entity contract for entities that require common functionality
+ * such as having a unique code, being serializable, and persistable with a generic type identifier.
+ * Implementing classes should provide concrete behavior for these base operations.
*/
public interface BaseEntity
- * 此方法提供了一个接口来为相关对象设置一个代码值。具体的实现可能会根据实际需求来决定如何处理这个代码值。
- * 由于这是一个默认方法,它为接口的实现提供了一种灵活的方式来处理代码值,而不需要强制实现这个方法。
+ * Sets the unique code for an entity.
+ * This method is intended to assign or update the code attribute of an entity,
+ * which serves as a unique identifier in accordance with the BaseEntity interface.
+ * The implementation should handle the logic of how the code is generated or validated,
+ * based on specific business rules, which may involve prefixing, formatting, or checking for uniqueness.
*
- * @param code 要设置的代码值。这个参数允许调用者指定一个代码值,该值可以是任何字符串,具体的含义和使用方式取决于实现。
+ * @param code The code to be set for the entity. It could be a plain string or follow a predefined format.
*/
default void setCode(String code) {
- //todo 方法体为空,具体的实现可能需要根据实际需求来决定如何处理code参数。
}
/**
- * 判断当前对象是否为新对象,即是否具有ID。
- * 如果对象尚未分配ID,则将其视为新对象,并生成一个新的ID。
- * 此方法用于标识对象是否已存在于持久化存储中,如果没有ID,则认为是新对象需要进行持久化操作。
+ * Determines whether the entity instance is considered new.
+ * This is typically used to decide if the entity needs to be inserted or updated when persisted.
+ * The method checks if the identifier ({@code getId()}) is empty to assess newness.
+ * If the entity is determined to be new, it generates and assigns a new unique code ({@code setCode(ContextUtils.nextId());}).
*
- * @return 如果对象是新对象(没有ID),则返回true;否则返回false。
+ * @return {@code true} if the entity is considered new (i.e., its identifier is empty), otherwise {@code false}.
*/
@Override
@JsonIgnore
@@ -47,14 +50,16 @@ default boolean isNew() {
}
/**
- * 创建一个Criteria对象,用于构建查询条件。
- * 此方法允许指定一组应被忽略的属性键,这些键不会被包含在查询条件中。
+ * Constructs a {@link Criteria} instance based on the current entity,
+ * allowing for the specification of properties to be excluded from criteria creation.
*
- * @param skipKeys 一个字符串集合,包含应被忽略的属性键。
- * @return 返回一个Criteria对象,用于进一步构建查询条件。
+ * @param skipKeys A {@link Collection} of {@link String} property keys to be skipped when building the criteria.
+ * These properties will not be included in the generated criteria.
+ * @return A {@link Criteria} object tailored according to the current entity,
+ * excluding the properties specified in the {@code skipKeys} collection.
*/
default Criteria criteria(Collection
+ * The class registers two converters:
+ *
+ * The conversion process involves extracting the 'code' attribute from the provided
+ * {@link UserAuditor} instance and returning it as a plain String.
+ *
+ * Part of the {@link UserAuditorConverters} configuration which manages the bidirectional
+ * transformations between {@link UserAuditor} and String for read/write operations.
+ */
@Component
@WritingConverter
public static class UserAuditorWriteConverter implements Converter
+ * The conversion logic employs the {@link UserAuditor#withCode(String)} factory method,
+ * passing the source string, which typically corresponds to the 'code' attribute of a {@link UserAuditor},
+ * to reconstruct the auditor object with default values for username and name.
+ *
+ * This class is part of the {@link UserAuditorConverters} configuration, complementing the write-side
+ * conversion provided by {@link UserAuditorWriteConverter}.
+ *
+ * @see UserAuditorConverters
+ * @see UserAuditorWriteConverter
+ * @see UserAuditor#withCode(String)
+ */
@Component
@ReadingConverter
public static class UserAuditorReadConverter implements Converter
+ * This class provides constructors to initialize the exception with a descriptive message and an underlying
+ * {@link IOException} that led to the JSON pointer error, allowing for detailed diagnostics of the issue.
+ * Additionally, it includes a static factory method for conveniently creating instances with an error message
+ * and the associated {@linkplain IOException}.
+ *
+ * It provides factory methods to conveniently create instances with predefined or custom error messages and codes,
+ * facilitating standardization of error responses in a RESTful API context.
+ *
+ *
+ * This method takes a JsonNode, a JSON Path string, and a target class type, then navigates to the
+ * JSON node located at the specified path within the input JSON. If the node exists, it is converted
+ * into an instance of the target class. If the path does not exist or conversion fails, exceptions are thrown.
+ *
+ * @param
+ * This record is primarily used within SQL construction logic to dynamically
+ * build WHERE clauses based on provided criteria, supporting various comparison
+ * and set-based operations through its components.
+ *
+ * @param operation A Map.Entry consisting of a keyword indicating the type of operation (e.g., equality, range)
+ * and a placeholder or specific SQL syntax related to the operation.
+ * @param sql The SQL fragment representing the condition without actual values,
+ * with placeholders for parameters.
+ * @param params A map mapping parameter placeholders used in the SQL fragment to their intended values.
+ */
+public record QueryCondition(
+ String sql,
+ Map
+ *
+ *
+ *
+ *
+ * All converters use the {@code code} attribute of the {@link UserAuditor} as the basis for conversion, ensuring
+ * a consistent serialization/deserialization mechanism across different layers of the application.
*/
@Log4j2
@Configuration(proxyBeanMethods = false)
public class UserAuditorConverters implements InitializingBean {
+ /**
+ * Callback method that indicates bean initialization is complete and all properties have been set.
+ * This method is implemented from the {@link InitializingBean} interface.
+ * It logs an informational message indicating the initialization of the converters within the {@link UserAuditorConverters} class.
+ */
@Override
public void afterPropertiesSet() {
log.info("Initializing converter [UserAuditorConverters]...");
}
+ /**
+ * Converts a {@link UserAuditor} object to its string representation and vice versa for database storage and retrieval.
+ *
+ * Transforms a {@link UserAuditor} instance into its string code equivalent, suitable for storing in the database.
+ *
+ * Restores a {@link UserAuditor} instance from the string value retrieved from the database column.
+ *
+ * @see UserAuditor
+ * @see AttributeConverter
+ */
@Component
@jakarta.persistence.Converter(autoApply = true)
- public static class UserAuditorAttributeConverter implements AttributeConverter
+ *
+ * Extending classes should override or implement specific business logic methods as needed,
+ * leveraging the provided utilities and infrastructure setup.
+ *
+ * @see InitializingBean Interface to be implemented by beans that need to react once all their properties
+ * have been set by a BeanFactory.
*/
@Log4j2
public abstract class AbstractService implements InitializingBean {
+ /**
+ * Cache instance used to store and retrieve data within the service.
+ * Initialized through the {@link #initializingCache(String)} method with a cache name defaulting to the class name concatenated with ".cache".
+ * This cache is cleared upon initialization and is essential for providing temporary storage that accelerates data access.
+ */
protected Cache cache;
+ /**
+ * Manages the caching infrastructure for the service.
+ * This field holds an instance of a CacheManager which is responsible for creating,
+ * retrieving, and managing caches used throughout the application to improve performance by storing frequently accessed data.
+ * It is initialized via dependency injection and utilized in the {@link #initializingCache(String)} method to obtain or create specific caches.
+ */
protected CacheManager cacheManager;
+ /**
+ * Provides an instance of Jackson's {@link ObjectMapper}, which is a powerful JSON processor
+ * capable of converting Java objects into their JSON representation and vice versa.
+ * This field is automatically wired by Spring's dependency injection, ensuring that it is properly configured
+ * and ready to handle complex object mappings and custom serialization/deserialization scenarios within the service layer.
+ *
+ *
+ *
+ * These converters are annotated with Spring's {@link Component}, {@link WritingConverter}, and {@link ReadingConverter}
+ * to integrate seamlessly with Spring Data's conversion service.
*/
@Log4j2
@Configuration(proxyBeanMethods = false)
@@ -22,6 +32,18 @@ public void afterPropertiesSet() {
log.info("Initializing converter [UserAuditorConverters]...");
}
+ /**
+ * Converts a {@link UserAuditor} object to its code represented as a String.
+ * This converter is intended for write operations, facilitating the storage of auditor details
+ * in a textual format, typically used within data persistence frameworks where type conversion
+ * services are leveraged.
+ * Features:
+ *
+ *
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class RestServerException extends RuntimeException implements Serializable {
+ /**
+ * Encapsulates additional metadata or details about the error condition.
+ * This field can hold any type of object, enabling the transmission of structured
+ * information alongside the exception, such as maps, lists, or custom objects that
+ * provide context for the error scenario.
+ */
protected Object msg;
+ /**
+ * The error code associated with this {@link RestServerException}.
+ * This field represents a custom error code that provides more granular information
+ * about the specific error scenario beyond standard HTTP status codes.
+ * It is intended for use in identifying and differentiating between various error conditions.
+ */
protected int code;
+ /**
+ * Constructs a new instance of {@code RestServerException} with the specified error message and cause.
+ * This exception is typically used to convey that a RESTful service encountered an issue on the server side,
+ * where the provided message describes the error and the throwable denotes the underlying cause.
+ *
+ * @param message The detailed message explaining the reason for the exception.
+ * @param throwable The cause of the exception, usually an instance of {@link Throwable}
+ * that triggered this exception.
+ */
+ public RestServerException(String message, Throwable throwable) {
+ super(message, throwable);
+ this.code = 500;
+ this.msg = throwable.fillInStackTrace().getMessage();
+ }
+
+ /**
+ * Constructs a new instance of {@code RestServerException} with specified error code, message, and additional details.
+ * This exception is intended for conveying REST server-side error conditions, providing a more granular error code
+ * alongside a standard exception message and an optional object that can carry detailed contextual information.
+ *
+ * @param code The custom error code associated with the exception. This can be used to differentiate between
+ * various error scenarios beyond the standard HTTP status codes.
+ * @param message The human-readable error message explaining the exception circumstances. Should be concise and informative.
+ * @param msg An optional object containing additional metadata or details about the error. Can be any type,
+ * facilitating the passing of structured error information (e.g., maps, lists, or domain-specific objects).
+ */
public RestServerException(int code, String message, Object msg) {
super(message);
this.msg = msg;
this.code = code;
}
+ /**
+ * Creates a new instance of {@code RestServerException} with a predefined HTTP status code of 500 (Internal Server Error),
+ * a custom message, and additional details encapsulated in the {@code msg} parameter.
+ * This method serves as a convenience factory for generating exceptions that indicate a generic server error
+ * along with specific contextual information.
+ *
+ * @param message A descriptive message explaining the reason for the exception.
+ * @param msg An arbitrary object containing additional details about the error. This can be used to provide more
+ * extensive error context or metadata.
+ * @return A new instance of {@code RestServerException} initialized with the provided message, a status code of 500,
+ * and the additional details object.
+ */
public static RestServerException withMsg(String message, Object msg) {
return withMsg(500, message, msg);
}
+ /**
+ * Creates a new instance of {@code RestServerException} with a specified error code, message, and additional details.
+ * This static factory method allows for customization of the error response by providing a unique error code and
+ * a message along with an arbitrary object that can contain further information about the error condition.
+ *
+ * @param code The custom error code to identify the specific error scenario. This code supplements the HTTP status code.
+ * @param message The error message describing the exception's nature. Should be informative for debugging purposes.
+ * @param msg An optional object holding additional metadata or details related to the error. Can be any type.
+ * @return A new instance of {@code RestServerException} initialized with the provided code, message, and additional details.
+ */
public static RestServerException withMsg(int code, String message, Object msg) {
return new RestServerException(code, message, msg);
}
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 defb53da..7a923f71 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
@@ -9,6 +9,7 @@
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.google.common.collect.Maps;
import com.plate.boot.commons.exception.JsonException;
+import com.plate.boot.commons.exception.JsonPointerException;
import com.plate.boot.commons.exception.RestServerException;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.InitializingBean;
@@ -23,11 +24,13 @@
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Map;
-import java.util.Objects;
import java.util.StringJoiner;
+import java.util.stream.Collectors;
/**
- * @author Alex bob
+ * Converts a JavaBean object into a Map representation.
+ * Each property of the bean is represented as a key-value pair in the map,
+ * with the property name as the key and its corresponding value as the value.
*/
@Log4j2
@Component
@@ -46,6 +49,21 @@ public final class BeanUtils implements InitializingBean {
}
}
+ /**
+ * Converts a JSON node at a specified JSON Path into an object of the provided class type.
+ *