RentalPatchRequestValidator.java
package com.github.jenkaby.bikerental.rental.web.command.dto.validation;
import com.github.jenkaby.bikerental.rental.domain.model.RentalStatus;
import com.github.jenkaby.bikerental.rental.web.command.dto.RentalPatchOperation;
import com.github.jenkaby.bikerental.rental.web.command.dto.RentalUpdateJsonPatchRequest;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Validates the entire JSON Patch request for Rental.
*/
public class RentalPatchRequestValidator implements ConstraintValidator<ValidRentalPatchRequest, RentalUpdateJsonPatchRequest> {
private static final Set<String> VALID_STATUSES = Arrays.stream(RentalStatus.values())
.map(Enum::name)
.collect(Collectors.toSet());
@Override
public boolean isValid(RentalUpdateJsonPatchRequest request, ConstraintValidatorContext context) {
if (request == null || request.getOperations() == null) {
return true;
}
boolean isValid = true;
context.disableDefaultConstraintViolation();
List<RentalPatchOperation> operations = request.getOperations();
// Validate status values using RentalStatus enum
boolean hasInvalidStatus = operations.stream()
.filter(op -> "/status".equals(op.getPath()) && op.getValue() != null)
.anyMatch(op -> {
String statusValue = op.getValue().toString();
try {
RentalStatus.valueOf(statusValue);
return false; // Valid status
} catch (IllegalArgumentException e) {
context.buildConstraintViolationWithTemplate(
String.format("Invalid status value '%s'. Allowed values: %s",
statusValue, VALID_STATUSES))
.addConstraintViolation();
return true; // Invalid status
}
});
if (hasInvalidStatus) {
isValid = false;
}
return isValid;
}
}