DATAREDIS-1175 - Polishing.

Reformat code. Add missing nullability annotations and enforce non-null values to prevent potential null dereference.

Original pull request: #546.
This commit is contained in:
Mark Paluch
2020-07-15 09:33:07 +02:00
parent cae161feb4
commit 2f0a5600dc
3 changed files with 56 additions and 45 deletions

View File

@@ -56,7 +56,7 @@ public class Bucket {
Bucket(Map<String, byte[]> data) {
Assert.notNull(data, "Inital data must not be null!");
Assert.notNull(data, "Initial data must not be null!");
this.data = new LinkedHashMap<>(data.size());
this.data.putAll(data);
}
@@ -67,7 +67,7 @@ public class Bucket {
* @param path must not be {@literal null} or {@link String#isEmpty()}.
* @param value can be {@literal null}.
*/
public void put(String path, byte[] value) {
public void put(String path, @Nullable byte[] value) {
Assert.hasText(path, "Path to property must not be null or empty.");
data.put(path, value);

View File

@@ -175,27 +175,27 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
* @see org.springframework.data.convert.EntityReader#read(java.lang.Class, java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public <R> R read(Class<R> type, RedisData source) {
TypeInformation<?> readType = typeMapper.readType(source.getBucket().getPath(), ClassTypeInformation.from(type));
if(readType.isCollectionLike()) {
return (R) readCollectionOrArray("", ArrayList.class, Object.class, source.getBucket());
}
return readInternal("", type, source);
return readType.isCollectionLike()
? (R) readCollectionOrArray("", ArrayList.class, Object.class, source.getBucket())
: doReadInternal("", type, source);
}
@Nullable
private <R> R readInternal(String path, Class<R> type, RedisData source) {
return source.getBucket().isEmpty() ? null : doReadInternal(path, type, source);
}
@SuppressWarnings("unchecked")
@Nullable
private <R> R readInternal(String path, Class<R> type, RedisData source) {
if (source.getBucket() == null || source.getBucket().isEmpty()) {
return null;
}
private <R> R doReadInternal(String path, Class<R> type, RedisData source) {
TypeInformation<?> readType = typeMapper.readType(source.getBucket().getPath(), ClassTypeInformation.from(type));
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(readType);
if (customConversions.hasCustomReadTarget(Map.class, readType.getType())) {
Map<String, byte[]> partial = new HashMap<>();
@@ -211,6 +211,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
}
R instance = (R) conversionService.convert(partial, readType.getType());
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(readType);
if (entity != null && entity.hasIdProperty()) {
PersistentPropertyAccessor<R> propertyAccessor = entity.getPropertyAccessor(instance);
@@ -226,19 +227,20 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
readType.getType());
}
RedisPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(readType);
EntityInstantiator instantiator = entityInstantiators.getInstantiatorFor(entity);
Object instance = instantiator.createInstance((RedisPersistentEntity<RedisPersistentProperty>) entity,
new PersistentEntityParameterValueProvider<>(entity,
new ConverterAwareParameterValueProvider(path, source, conversionService), this.conversionService));
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(instance);
entity.doWithProperties((PropertyHandler<RedisPersistentProperty>) persistentProperty -> {
PreferredConstructor<?, RedisPersistentProperty> constructor = entity.getPersistenceConstructor();
if (constructor.isConstructorParameter(persistentProperty)) {
if (constructor != null && constructor.isConstructorParameter(persistentProperty)) {
return;
}
@@ -311,7 +313,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
}
private void readAssociation(String path, RedisData source, RedisPersistentEntity<?> entity,
PersistentPropertyAccessor accessor) {
PersistentPropertyAccessor<?> accessor) {
entity.doWithAssociations((AssociationHandler<RedisPersistentProperty>) association -> {
@@ -400,8 +402,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
sink.setKeyspace(entity.getKeySpace());
if(entity.getTypeInformation().isCollectionLike()) {
writeCollection(entity.getKeySpace(), "", (List) source, entity.getTypeInformation().getComponentType(), sink);
if (entity.getTypeInformation().isCollectionLike()) {
writeCollection(entity.getKeySpace(), "", (List) source, entity.getTypeInformation().getRequiredComponentType(),
sink);
} else {
writeInternal(entity.getKeySpace(), "", source, entity.getTypeInformation(), sink);
}
@@ -483,7 +486,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
if (targetProperty.isCollectionLike()) {
RedisPersistentEntity<?> ref = mappingContext.getPersistentEntity(targetProperty.getRequiredAssociation()
.getInverse().getTypeInformation().getRequiredComponentType().getActualType());
.getInverse().getTypeInformation().getRequiredComponentType().getRequiredActualType());
int i = 0;
for (Object o : (Collection<?>) pUpdate.getValue()) {
@@ -507,9 +510,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
} else if (targetProperty.isCollectionLike()) {
Collection<?> collection = pUpdate.getValue() instanceof Collection ? (Collection<?>) pUpdate.getValue()
: Collections.<Object> singleton(pUpdate.getValue());
: Collections.singleton(pUpdate.getValue());
writeCollection(entity.getKeySpace(), pUpdate.getPropertyPath(), collection,
targetProperty.getTypeInformation().getActualType(), sink);
targetProperty.getTypeInformation().getRequiredActualType(), sink);
} else if (targetProperty.isMap()) {
Map<Object, Object> map = new HashMap<>();
@@ -565,7 +568,8 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
* @param typeHint
* @param sink
*/
private void writeInternal(String keyspace, String path, @Nullable Object value, TypeInformation<?> typeHint,
private void writeInternal(@Nullable String keyspace, String path, @Nullable Object value,
TypeInformation<?> typeHint,
RedisData sink) {
if (value == null) {
@@ -576,8 +580,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
Optional<Class<?>> targetType = customConversions.getCustomWriteTarget(value.getClass());
if (!StringUtils.hasText(path) && targetType.isPresent() && ClassUtils.isAssignable(byte[].class, targetType.get())) {
sink.getBucket().put(StringUtils.hasText(path) ? path : "_raw", conversionService.convert(value, byte[].class));
if (!StringUtils.hasText(path) && targetType.isPresent()
&& ClassUtils.isAssignable(byte[].class, targetType.get())) {
sink.getBucket().put(StringUtils.hasText(path) ? path : "_raw", conversionService.convert(value, byte[].class));
} else {
if (!ClassUtils.isAssignable(typeHint.getType(), value.getClass())) {
@@ -594,7 +599,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
}
RedisPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(value.getClass());
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(value);
entity.doWithProperties((PropertyHandler<RedisPersistentProperty>) persistentProperty -> {
@@ -639,7 +644,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
if (propertyValue != null) {
writeInternal(keyspace, propertyStringPath, propertyValue,
persistentProperty.getTypeInformation().getActualType(), sink);
persistentProperty.getTypeInformation().getRequiredActualType(), sink);
}
} else {
@@ -652,13 +657,13 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
writeAssociation(path, entity, value, sink);
}
private void writeAssociation(String path, RedisPersistentEntity<?> entity, Object value, RedisData sink) {
private void writeAssociation(String path, RedisPersistentEntity<?> entity, @Nullable Object value, RedisData sink) {
if (value == null) {
return;
}
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(value);
entity.doWithAssociations((AssociationHandler<RedisPersistentProperty>) association -> {
@@ -670,7 +675,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
if (association.getInverse().isCollectionLike()) {
RedisPersistentEntity<?> ref = mappingContext.getRequiredPersistentEntity(
association.getInverse().getTypeInformation().getRequiredComponentType().getActualType());
association.getInverse().getTypeInformation().getRequiredComponentType().getRequiredActualType());
String keyspace = ref.getKeySpace();
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
@@ -691,11 +696,13 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
.getRequiredPersistentEntity(association.getInverse().getTypeInformation());
String keyspace = ref.getKeySpace();
Object refId = ref.getPropertyAccessor(refObject).getProperty(ref.getIdProperty());
if (keyspace != null) {
Object refId = ref.getPropertyAccessor(refObject).getProperty(ref.getRequiredIdProperty());
if (refId != null) {
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
sink.getBucket().put(propertyStringPath, toBytes(keyspace + ":" + refId));
if (refId != null) {
String propertyStringPath = (!path.isEmpty() ? path + "." : "") + association.getInverse().getName();
sink.getBucket().put(propertyStringPath, toBytes(keyspace + ":" + refId));
}
}
}
});
@@ -708,7 +715,8 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
* @param typeHint
* @param sink
*/
private void writeCollection(String keyspace, String path, @Nullable Iterable<?> values, TypeInformation<?> typeHint,
private void writeCollection(@Nullable String keyspace, String path, @Nullable Iterable<?> values,
TypeInformation<?> typeHint,
RedisData sink) {
if (values == null) {
@@ -769,6 +777,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
}
}
@Nullable
private Object readCollectionOrArray(String path, Class<?> collectionType, Class<?> valueType, Bucket bucket) {
List<String> keys = new ArrayList<>(bucket.extractAllKeysFor(path));
@@ -807,7 +816,8 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
* @param source
* @param sink
*/
private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?, ?> source, RedisData sink) {
private void writeMap(@Nullable String keyspace, String path, Class<?> mapValueType, Map<?, ?> source,
RedisData sink) {
if (CollectionUtils.isEmpty(source)) {
return;
@@ -905,6 +915,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
return target.isEmpty() ? null : target;
}
@Nullable
private Object extractMapKeyForPath(String path, String key, Class<?> targetType) {
String regex = "^(" + Pattern.quote(path) + "\\.\\[)(.*?)(\\])";
@@ -1173,9 +1184,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
public static final String DELIMITTER = ":";
public static final String PHANTOM_SUFFIX = DELIMITTER + PHANTOM;
private String keyspace;
private String id;
private boolean phantomKey;
private final String keyspace;
private final String id;
private final boolean phantomKey;
private KeyspaceIdentifier(String keyspace, String id, boolean phantomKey) {
@@ -1215,7 +1226,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
* @param key the key.
* @return {@literal true} if the key is valid.
*/
public static boolean isValid(String key) {
public static boolean isValid(@Nullable String key) {
if (key == null) {
return false;
@@ -1252,9 +1263,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
public static final byte DELIMITTER = ':';
public static final byte[] PHANTOM_SUFFIX = ByteUtils.concat(new byte[] { DELIMITTER }, PHANTOM);
private byte[] keyspace;
private byte[] id;
private boolean phantomKey;
private final byte[] keyspace;
private final byte[] id;
private final boolean phantomKey;
private BinaryKeyspaceIdentifier(byte[] keyspace, byte[] id, boolean phantomKey) {

View File

@@ -76,7 +76,7 @@ public class RedisData {
*
* @param id
*/
public void setId(String id) {
public void setId(@Nullable String id) {
this.id = id;
}
@@ -134,7 +134,7 @@ public class RedisData {
/**
* @param keyspace
*/
public void setKeyspace(String keyspace) {
public void setKeyspace(@Nullable String keyspace) {
this.keyspace = keyspace;
}