UpdateJobDtoFactory.java
package com.wilzwert.myjobs.infrastructure.api.rest.dto.job;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wilzwert.myjobs.core.domain.shared.exception.ValidationException;
import com.wilzwert.myjobs.core.domain.shared.validation.ErrorCode;
import com.wilzwert.myjobs.core.domain.shared.validation.ValidationError;
import com.wilzwert.myjobs.core.domain.shared.validation.ValidationErrors;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Wilhelm Zwertvaegher
* Date:05/06/2025
* Time:10:20
*/
@Service
public class UpdateJobDtoFactory {
private static final Map<String, Class<? extends UpdateJobDto>> keyToDto = Map.of(
"status", UpdateJobStatusRequest.class,
"rating", UpdateJobRatingRequest.class,
"title", UpdateJobTitleRequest.class,
"description", UpdateJobDescriptionRequest.class,
"profile", UpdateJobProfileRequest.class,
"company", UpdateJobCompanyRequest.class,
"comment", UpdateJobCommentRequest.class,
"url", UpdateJobUrlRequest.class,
"salary", UpdateJobSalaryRequest.class
);
private final ObjectMapper objectMapper;
UpdateJobDtoFactory(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public UpdateJobDto createUpdateJobDto(Map<String, Object> requestFields) {
if (requestFields.isEmpty()) {
throw new IllegalArgumentException("Request fields cannot be empty");
}
if(requestFields.size() > 1) {
return objectMapper.convertValue(requestFields, UpdateJobRequest.class);
}
// we know we only have one key, so it's safe to get it
String key = requestFields.keySet().iterator().next();
if(!keyToDto.containsKey(key)) {
throw new UnsupportedOperationException("Unknown key: " + key);
}
Map<String, Object> enrichedRequestFields = new HashMap<>(requestFields);
enrichedRequestFields.put("field", key);
enrichedRequestFields.put("value", requestFields.get(key));
try {
return objectMapper.convertValue(enrichedRequestFields, keyToDto.get(key));
}
catch (Exception e) {
Throwable cause = e.getCause();
if (cause instanceof JsonMappingException ife) {
List<JsonMappingException.Reference> path = ife.getPath();
if (!path.isEmpty()) {
String fieldName = path.getFirst().getFieldName();
ValidationErrors errors = new ValidationErrors();
errors.add(new ValidationError(fieldName, ErrorCode.INVALID_VALUE));
throw new ValidationException(errors);
}
}
throw new IllegalArgumentException(ErrorCode.VALIDATION_FAILED.name(), e);
}
}
}