Skip to content

Commit

Permalink
act: improve converter
Browse files Browse the repository at this point in the history
  • Loading branch information
ngocnhan-tran1996 committed Jul 27, 2024
1 parent 34c6c40 commit 14535a6
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.spring.jdbc.oracle.converter.ConvertKey;
import io.spring.jdbc.oracle.converter.GenericOracleConverter;
import io.spring.jdbc.oracle.converter.OracleConverters;
import io.spring.jdbc.oracle.utils.Mappers;
import java.util.Arrays;
import java.util.List;
import org.springframework.core.convert.TypeDescriptor;
Expand All @@ -22,8 +23,11 @@ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {

this.converter.matches(sourceType, targetType);

return Object[].class.isAssignableFrom(sourceType.getType())
&& Object[].class.isAssignableFrom(targetType.getType());
var source = Mappers.resolveArrayTypeDescriptor(sourceType).getType();
var target = Mappers.resolveArrayTypeDescriptor(targetType).getType();

return Object[].class.isAssignableFrom(source)
&& Object[].class.isAssignableFrom(target);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.spring.jdbc.oracle.converter.ConvertKey;
import io.spring.jdbc.oracle.converter.GenericOracleConverter;
import io.spring.jdbc.oracle.converter.OracleConverters;
import io.spring.jdbc.oracle.utils.Mappers;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -27,7 +28,9 @@ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
this.sourceType = sourceType;
this.targetType = targetType;

return Object[].class.isAssignableFrom(sourceType.getType())
var source = Mappers.resolveArrayTypeDescriptor(sourceType).getType();

return Object[].class.isAssignableFrom(source)
&& Collection.class.isAssignableFrom(targetType.getType());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.spring.jdbc.oracle.converter.ConvertKey;
import io.spring.jdbc.oracle.converter.GenericOracleConverter;
import io.spring.jdbc.oracle.converter.OracleConverters;
import io.spring.jdbc.oracle.utils.Mappers;
import io.spring.jdbc.oracle.utils.Validators;
import java.lang.reflect.Array;
import java.util.Collection;
Expand All @@ -25,8 +26,10 @@ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
this.sourceType = sourceType;
this.targetType = targetType;

var target = Mappers.resolveArrayTypeDescriptor(targetType).getType();

return Collection.class.isAssignableFrom(sourceType.getType())
&& Object[].class.isAssignableFrom(targetType.getType());
&& Object[].class.isAssignableFrom(target);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ public void addConverter(OracleConverter<?, ?> converter) {
throw new ValueException(DETERMINE_EXCEPTION.formatted(converter));
}

if (this.converterCaches.containsKey(convertKey)) {

return;
}

this.converterCaches.put(convertKey, new ConvertAdapter(converter));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

Expand Down Expand Up @@ -65,4 +66,17 @@ public static Object convertValue(TypeProperty typeProperty, Object value) {
return ReflectionUtils.invokeMethod(method, instance, value);
}

public static TypeDescriptor resolveArrayTypeDescriptor(TypeDescriptor typeDescriptor) {

var sourceElementType = typeDescriptor.getElementTypeDescriptor();

if (sourceElementType == null) {

return typeDescriptor;
}

var resolveClass = ClassUtils.resolvePrimitiveIfNecessary(sourceElementType.getType());
return TypeDescriptor.array(TypeDescriptor.valueOf(resolveClass));
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package io.spring.jdbc.oracle.converter.support;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import io.spring.jdbc.oracle.converter.ConvertKey;
import io.spring.jdbc.oracle.converter.GenericOracleConverter;
import io.spring.jdbc.oracle.converter.OracleConverter;
import io.spring.jdbc.oracle.converter.OracleConverters;
import io.spring.jdbc.oracle.exception.ValueException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
Expand All @@ -12,12 +17,15 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.ReflectionUtils;

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class DefaultOracleConvertersTest {
Expand All @@ -30,6 +38,87 @@ void return_null_if_input_is_null(TypeDescriptor sourceType, TypeDescriptor targ
.isNull();
}

@Test
void throw_exception_when_adding_null_converter() {

assertThatExceptionOfType(ValueException.class)
.isThrownBy(() -> oracleConverters.addGenericConverter(null));

assertThatExceptionOfType(ValueException.class)
.isThrownBy(() -> oracleConverters.addConverter(null));
}

@SuppressWarnings("unchecked")
@Test
void do_nothing_when_adding_replicate_converter() {

oracleConverters.addGenericConverter(new ClonedNumberToString());
oracleConverters.addConverter(new ClonedLocalDatetimeToTimestampOracleConverter());

var converterCachesField = ReflectionUtils.findField(
DefaultOracleConverters.class,
"converterCaches"
);
ReflectionUtils.makeAccessible(converterCachesField);
var converterCaches =
(Map<ConvertKey, Object>) ReflectionUtils.getField(
converterCachesField,
oracleConverters
);
assertThat(converterCaches)
.hasSize(2);

var genericConvertersField = ReflectionUtils.findField(
DefaultOracleConverters.class,
"genericConverters"
);
ReflectionUtils.makeAccessible(genericConvertersField);
var genericConverters = (Set<Object>) ReflectionUtils.getField(
genericConvertersField,
oracleConverters
);
assertThat(genericConverters)
.hasSize(5);
}

record ClonedLocalDatetimeToTimestampOracleConverter() implements
OracleConverter<LocalDateTime, Timestamp> {

@Override
public Timestamp convert(LocalDateTime source) {

return Optional.ofNullable(source)
.map(Timestamp::valueOf)
.orElse(null);
}

}

record ClonedNumberToString() implements GenericOracleConverter {

@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {

return Number.class.isAssignableFrom(sourceType.getType())
&& String.class.isAssignableFrom(targetType.getType());
}

@Override
public ConvertKey getConvertKey() {

return new ConvertKey(Number.class, String.class);
}

@Override
public Object convert(Object source) {

return Optional.ofNullable((Number) source)
.map(Number::toString)
.orElse(null);
}

}

@Nested
class DetermineJavaClassForJdbcTypeCode {

Expand Down Expand Up @@ -132,6 +221,36 @@ void convert_Collection_to_Collection() {
return_null_if_input_is_null(source, listTarget);
}

@Test
void convert_Array_to_Array() {

var source = TypeDescriptor.valueOf(int[].class);
var target = TypeDescriptor.valueOf(String[].class);

var output = oracleConverters.convert(new Object[0], source, target);
assertThat(output).isEqualTo(new Object[0]);

output = oracleConverters.convert(new int[]{1, 2}, source, target);
assertThat(output).isEqualTo(new String[]{"1", "2"});

return_null_if_input_is_null(source, target);
}

@Test
void convert_Collection_to_Array() {

var source = TypeDescriptor.valueOf(Collection.class);
var target = TypeDescriptor.valueOf(int[].class);

var output = oracleConverters.convert(Collections.emptyList(), source, target);
assertThat(output).isEqualTo(new int[0]);

output = oracleConverters.convert(List.of(1, 2), source, target);
assertThat(output).isEqualTo(new int[]{1, 2});

return_null_if_input_is_null(source, target);
}

}

@Nested
Expand Down

0 comments on commit 14535a6

Please sign in to comment.