Skip to content

Commit

Permalink
✨ feat(converters, utils, query, jsonnodeconverters): Enhance…
Browse files Browse the repository at this point in the history
… converters and utilities with documentation and error handling

- Adds descriptive Javadoc comments to converters for UserAuditor, QueryFragment, ContextUtils, JsonNodeConverters, BeanUtils, and CollectionConverters.
- Introduces error handling in converters to manage exceptions during JSON processing.
- Includes initialization logs for ContextUtils and CollectionConverters.
- Refines the conversion logic with more robust type handling and clearer intent.
  • Loading branch information
vnobo committed Sep 18, 2024
1 parent 954c669 commit b44083d
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -17,21 +18,78 @@
import java.util.Collection;

/**
* @author <a href="https://github.com/vnobo">Alex bob</a>
* 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.
*
* <p>This class implements InitializingBean, ensuring that the converters are properly initialized
* upon the application's startup sequence.
*
* <h3>Components:</h3>
* <ul>
* <li>{@link CollectionReadConverter}: Converts JSON data into a Collection of objects.</li>
* <li>{@link CollectionWriteConverter}: Converts a Collection of objects into JSON format.</li>
* </ul>
* <p>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.
* <p>
* 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.
* <p>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.
* <p>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<Json, Collection<?>> {

/**
* Converts the given Json source into a Collection of objects.
* <p>
* 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 {
Expand All @@ -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.
*
* <p>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.</p>
*
* <p>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.</p>
*/
@Component
@WritingConverter
public static class CollectionWriteConverter implements Converter<Collection<?>, Json> {

/**
* Converts a given collection into its JSON representation.
*
* This method takes a collection of any type and attempts to serialize it into a JSON object
* using the Jackson {@link ObjectMapper}. If the serialization process encounters a
* {@link JsonProcessingException}, it is caught and rethrown as a {@link JsonException} with a
* descriptive error message, preserving the original exception's details.
*
* @param source The collection to be converted into JSON. Must not be null.
* @return A {@link Json} object representing the serialized form of the input collection.
* @throws JsonException If an error occurs during the JSON serialization process.
*/
@Override
public Json convert(@NonNull Collection<?> source) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,73 @@
import java.io.IOException;

/**
* @author <a href="https://github.com/vnobo">Alex bob</a>
* Configuration class for registering custom converters between JSON and Jackson's JsonNode.
* This class ensures the converters are properly initialized within a Spring context.
* It includes two inner classes: {@link JsonToNodeWriteConverter} for writing JSON to JsonNode,
* and {@link JsonToNodeReadConverter} for reading JsonNode back to JSON.
*/
@Log4j2
@Configuration(proxyBeanMethods = false)
public class JsonNodeConverters implements InitializingBean {

/**
* Invoked by the containing 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.
* <p>
* 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.
* <p>
* 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<JsonNode, Json> {
/**
* Converts a Jackson {@link JsonNode} to a custom {@link Json} object.
*
* @param source The JsonNode to be converted. Must not be null.
* @return A {@link Json} object representing the stringified input JsonNode.
* @throws NullPointerException if the source argument is null.
*/
@Override
public Json convert(@NonNull JsonNode source) {
return Json.of(source.toString());
}
}

/**
* Converts a custom {@link Json} object to a Jackson {@link JsonNode} for read operations.
* This converter is designed to be used within a Spring context and is annotated as a component
* and a reading converter.
* <p>
* 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<Json, JsonNode> {
/**
* Converts a custom {@link Json} object to a Jackson {@link JsonNode} for read operations.
*
* @param source The {@link Json} object to be converted. Must not be null.
* @return The converted {@link JsonNode} instance ready for read operations.
* @throws JsonException If an {@link IOException} occurs during the conversion process.
*/
@Override
public JsonNode convert(@NonNull Json source) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ public void afterPropertiesSet() {
@Component
@WritingConverter
public static class UserAuditorWriteConverter implements Converter<UserAuditor, String> {
/**
* Converts a {@link UserAuditor} object to its code represented as a String.
*
* @param source The {@link UserAuditor} instance to be converted. Must not be null.
* @return The code of the {@link UserAuditor} as a String.
* @throws NullPointerException if the source {@link UserAuditor} is null.
*/
@Override
public String convert(@NonNull UserAuditor source) {
return source.code();
Expand All @@ -72,6 +79,20 @@ public String convert(@NonNull UserAuditor source) {
@Component
@ReadingConverter
public static class UserAuditorReadConverter implements Converter<String, UserAuditor> {
/**
* Converts a given non-null String source representing a user auditor code
* into a {@link UserAuditor} instance.
* <p>
* 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* Logs a message indicating the start of the initialization process for BeanUtils.
*/
@Override
public void afterPropertiesSet() {
log.info("Initializing utils [BeanUtils]...");
Expand Down
Loading

0 comments on commit b44083d

Please sign in to comment.