Skip to content

Commit

Permalink
fix NPE when RequestSerializerFactory has no ConversionService conf…
Browse files Browse the repository at this point in the history
…igured. (#82)
  • Loading branch information
p3t authored Dec 19, 2024
1 parent 9be1624 commit 93895b2
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import io.vigier.cursorpaging.jpa.Attribute;
import io.vigier.cursorpaging.jpa.PageRequest;
import io.vigier.cursorpaging.jpa.serializer.dto.Cursor;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
Expand All @@ -15,7 +14,6 @@
import lombok.Getter;
import lombok.SneakyThrows;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;

@Builder
Expand All @@ -31,53 +29,7 @@ public class RequestSerializer<E> {
private Class<E> entityType;

@Builder.Default
private final ConversionService conversionService = new ConversionService() {
@Override
public boolean canConvert( final Class<?> sourceType, final Class<?> targetType ) {
if ( sourceType == null || targetType == null ) {
return false;
}
return sourceType.isAssignableFrom( String.class ) && (targetType.isAssignableFrom( Long.class )
|| targetType.isAssignableFrom( Integer.class ) || targetType.isAssignableFrom( Boolean.class )
|| targetType.isAssignableFrom( String.class ) || targetType.isAssignableFrom( Object.class ));
}

@Override
public boolean canConvert( final TypeDescriptor sourceType, final TypeDescriptor targetType ) {
if ( sourceType == null || targetType == null ) {
return false;
}
return canConvert( sourceType.getType(), targetType.getType() );
}

@Override
public <T> T convert( final Object source, final Class<T> targetType ) {
if ( targetType == String.class ) {
return targetType.cast( source.toString() );
}
if ( targetType == Integer.class ) {
return targetType.cast( Integer.valueOf( source.toString() ) );
}
if ( targetType == Long.class ) {
return targetType.cast( Long.valueOf( source.toString() ) );
}
if ( targetType == Boolean.class ) {
return targetType.cast( source.toString().equals( "true" ) );
}
if ( targetType == Instant.class ) {
return targetType.cast( Instant.parse( source.toString() ) );
}
if ( targetType == Object.class ) {
return targetType.cast( source );
}
return null;
}

@Override
public Object convert( final Object source, final TypeDescriptor sourceType, final TypeDescriptor targetType ) {
return convert( source, targetType.getObjectType() );
}
};
private final ConversionService conversionService = new SimpleConversionService();

@Builder.Default
private final Map<String, RuleFactory> filterRuleFactories = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
@RequiredArgsConstructor
public class RequestSerializerFactory {

private final ConversionService conversionService;
@Builder.Default
private final ConversionService conversionService = new SimpleConversionService();

@Builder.Default
private final Encrypter encrypter = Encrypter.getInstance();
Expand All @@ -46,6 +47,11 @@ public static RequestSerializerFactory create( final Consumer<RequestSerializerF
return b.build();
}

public static RequestSerializerFactory create() {
return RequestSerializerFactory.builder()
.build();
}

@SuppressWarnings( "unchecked" )
public <T> RequestSerializer<T> forEntity( final Class<T> entityClass ) {
return (RequestSerializer<T>) entitySerializers.computeIfAbsent( entityClass,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.vigier.cursorpaging.jpa.serializer;

import java.time.Instant;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;

/**
* Very simple conversion service which might help to do create some test without the need of setting up a more
* sophisticated conversion service, but is not meant to be used in production.
*/
class SimpleConversionService implements ConversionService {
@Override
public boolean canConvert( final Class<?> sourceType, final Class<?> targetType ) {
if ( sourceType == null || targetType == null ) {
return false;
}
return sourceType.isAssignableFrom( String.class ) && (targetType.isAssignableFrom( Long.class )
|| targetType.isAssignableFrom( Integer.class ) || targetType.isAssignableFrom( Boolean.class )
|| targetType.isAssignableFrom( String.class ) || targetType.isAssignableFrom( Object.class ));
}

@Override
public boolean canConvert( final TypeDescriptor sourceType, final TypeDescriptor targetType ) {
if ( sourceType == null || targetType == null ) {
return false;
}
return canConvert( sourceType.getType(), targetType.getType() );
}

@Override
public <T> T convert( final Object source, final Class<T> targetType ) {
if ( targetType == String.class ) {
return targetType.cast( source.toString() );
}
if ( targetType == Integer.class ) {
return targetType.cast( Integer.valueOf( source.toString() ) );
}
if ( targetType == Long.class ) {
return targetType.cast( Long.valueOf( source.toString() ) );
}
if ( targetType == Boolean.class ) {
return targetType.cast( "true".equals( source.toString() ) );
}
if ( targetType == Instant.class ) {
return targetType.cast( Instant.parse( source.toString() ) );
}
if ( targetType == Object.class ) {
return targetType.cast( source );
}
return null;
}

@Override
public Object convert( final Object source, final TypeDescriptor sourceType, final TypeDescriptor targetType ) {
return convert( source, targetType.getObjectType() );
}
}

0 comments on commit 93895b2

Please sign in to comment.