DATAREDIS-543 - Polishing.
Move BucketPropertyPath to Bucket. Original Pull Request: #299
This commit is contained in:
@@ -15,6 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.convert;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
@@ -203,6 +208,27 @@ public class Bucket {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link BucketPropertyPath} leading to the current {@link Bucket}.
|
||||
*
|
||||
* @return new instance of {@link BucketPropertyPath}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public BucketPropertyPath getPath() {
|
||||
return BucketPropertyPath.from(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link BucketPropertyPath} for a given property within the current {@link Bucket}.
|
||||
*
|
||||
* @param property the property to look up.
|
||||
* @return new instance of {@link BucketPropertyPath}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public BucketPropertyPath getPropertyPath(String property) {
|
||||
return BucketPropertyPath.from(this, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Bucket from a given raw map.
|
||||
*
|
||||
@@ -256,7 +282,6 @@ public class Bucket {
|
||||
}
|
||||
}
|
||||
return serialized.toString();
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -270,4 +295,65 @@ public class Bucket {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object representing a path within a {@link Bucket}. Paths can be either top-level (if the {@code prefix} is
|
||||
* {@literal null} or empty) or nested with a given {@code prefix}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
*/
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public static class BucketPropertyPath {
|
||||
|
||||
private final @NonNull Bucket bucket;
|
||||
private final @Nullable String prefix;
|
||||
|
||||
/**
|
||||
* Creates a top-level {@link BucketPropertyPath} given {@link Bucket}.
|
||||
*
|
||||
* @param bucket the bucket, must not be {@literal null}.
|
||||
* @return {@link BucketPropertyPath} within the given {@link Bucket}.
|
||||
*/
|
||||
public static BucketPropertyPath from(Bucket bucket) {
|
||||
return new BucketPropertyPath(bucket, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BucketPropertyPath} given {@link Bucket} and {@code prefix}. The resulting path is top-level if
|
||||
* {@code prefix} is empty or nested, if {@code prefix} is not empty.
|
||||
*
|
||||
* @param bucket the bucket, must not be {@literal null}.
|
||||
* @param prefix the prefix. Property path is top-level if {@code prefix} is {@literal null} or empty.
|
||||
* @return {@link BucketPropertyPath} within the given {@link Bucket} using {@code prefix}.
|
||||
*/
|
||||
public static BucketPropertyPath from(Bucket bucket, @Nullable String prefix) {
|
||||
return new BucketPropertyPath(bucket, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value at {@code key} considering top-level/nesting.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @return the resulting value, may be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] get(String key) {
|
||||
return bucket.get(getPath(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@code value} at {@code key} considering top-level/nesting.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param value the value.
|
||||
*/
|
||||
public void put(String key, byte[] value) {
|
||||
bucket.put(getPath(key), value);
|
||||
}
|
||||
|
||||
private String getPath(String key) {
|
||||
return StringUtils.hasText(prefix) ? prefix + "." + key : key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core.convert;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Value object representing a path within a {@link Bucket}. Paths can be either top-level (if the {@code prefix} is
|
||||
* {@literal null} or empty) or nested with a given {@code prefix}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
*/
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public class BucketPropertyPath {
|
||||
|
||||
private final @NonNull Bucket bucket;
|
||||
private final @Nullable String prefix;
|
||||
|
||||
/**
|
||||
* Creates a top-level {@link BucketPropertyPath} given {@link Bucket}.
|
||||
*
|
||||
* @param bucket the bucket, must not be {@literal null}.
|
||||
* @return {@link BucketPropertyPath} within the given {@link Bucket}.
|
||||
*/
|
||||
public static BucketPropertyPath from(Bucket bucket) {
|
||||
return new BucketPropertyPath(bucket, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BucketPropertyPath} given {@link Bucket} and {@code prefix}. The resulting path is top-level if
|
||||
* {@code prefix} is empty or nested, if {@code prefix} is not empty.
|
||||
*
|
||||
* @param bucket the bucket, must not be {@literal null}.
|
||||
* @param prefix the prefix. Property path is top-level if {@code prefix} is {@literal null} or empty.
|
||||
* @return {@link BucketPropertyPath} within the given {@link Bucket} using {@code prefix}.
|
||||
*/
|
||||
public static BucketPropertyPath from(Bucket bucket, @Nullable String prefix) {
|
||||
return new BucketPropertyPath(bucket, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value at {@code key} considering top-level/nesting.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @return the resulting value, may be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] get(String key) {
|
||||
return bucket.get(getPath(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@code value} at {@code key} considering top-level/nesting.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param value the value.
|
||||
*/
|
||||
public void put(String key, byte[] value) {
|
||||
bucket.put(getPath(key), value);
|
||||
}
|
||||
|
||||
private String getPath(String key) {
|
||||
return StringUtils.hasText(prefix) ? prefix + "." + key : key;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.convert.TypeInformationMapper;
|
||||
import org.springframework.data.mapping.Alias;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.redis.core.convert.Bucket.BucketPropertyPath;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -192,8 +192,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<?> readType = typeMapper.readType(BucketPropertyPath.from(source.getBucket()),
|
||||
ClassTypeInformation.from(type));
|
||||
TypeInformation<?> readType = typeMapper.readType(source.getBucket().getPath(), ClassTypeInformation.from(type));
|
||||
|
||||
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(readType);
|
||||
|
||||
@@ -278,7 +277,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
Bucket bucket = source.getBucket().extract(currentPath + ".");
|
||||
|
||||
RedisData newBucket = new RedisData(bucket);
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(BucketPropertyPath.from(bucket, currentPath),
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(bucket.getPropertyPath(currentPath),
|
||||
persistentProperty.getTypeInformation().getActualType());
|
||||
|
||||
Class<R> targetType = (Class<R>) typeInformation.getType();
|
||||
@@ -386,12 +385,12 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(source.getClass());
|
||||
|
||||
if (!customConversions.hasCustomWriteTarget(source.getClass())) {
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), BucketPropertyPath.from(sink.getBucket()));
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink.getBucket().getPath());
|
||||
}
|
||||
|
||||
if (entity == null) {
|
||||
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), BucketPropertyPath.from(sink.getBucket()));
|
||||
typeMapper.writeType(ClassUtils.getUserClass(source), sink.getBucket().getPath());
|
||||
sink.getBucket().put("_raw", conversionService.convert(source, byte[].class));
|
||||
return;
|
||||
}
|
||||
@@ -583,7 +582,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
}
|
||||
|
||||
if (value.getClass() != typeHint.getType()) {
|
||||
typeMapper.writeType(value.getClass(), BucketPropertyPath.from(sink.getBucket(), path));
|
||||
typeMapper.writeType(value.getClass(), sink.getBucket().getPropertyPath(path));
|
||||
}
|
||||
|
||||
RedisPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(value.getClass());
|
||||
@@ -743,7 +742,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
if (!targetType.filter(it -> ClassUtils.isAssignable(Map.class, it)).isPresent()
|
||||
&& customConversions.isSimpleType(value.getClass()) && value.getClass() != propertyType) {
|
||||
typeMapper.writeType(value.getClass(), BucketPropertyPath.from(sink.getBucket(), path));
|
||||
typeMapper.writeType(value.getClass(), sink.getBucket().getPropertyPath(path));
|
||||
}
|
||||
|
||||
if (targetType.filter(it -> ClassUtils.isAssignable(Map.class, it)).isPresent()) {
|
||||
@@ -779,7 +778,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
Bucket elementData = bucket.extract(key);
|
||||
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(BucketPropertyPath.from(elementData, key),
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(elementData.getPropertyPath(key),
|
||||
ClassTypeInformation.from(valueType));
|
||||
|
||||
Class<?> typeToUse = typeInformation.getType();
|
||||
@@ -885,10 +884,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
for (String key : keys) {
|
||||
|
||||
Bucket partial = source.getBucket().extract(key);
|
||||
|
||||
|
||||
Object mapKey = extractMapKeyForPath(path, key, keyType);
|
||||
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(BucketPropertyPath.from(source.getBucket(), key),
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(source.getBucket().getPropertyPath(key),
|
||||
ClassTypeInformation.from(valueType));
|
||||
|
||||
Object o = readInternal(key, typeInformation.getType(), new RedisData(partial));
|
||||
@@ -920,7 +919,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
private Class<?> getTypeHint(String path, Bucket bucket, Class<?> fallback) {
|
||||
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(BucketPropertyPath.from(bucket, path),
|
||||
TypeInformation<?> typeInformation = typeMapper.readType(bucket.getPropertyPath(path),
|
||||
ClassTypeInformation.from(fallback));
|
||||
return typeInformation.getType();
|
||||
}
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
package org.springframework.data.redis.core.convert;
|
||||
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.redis.core.convert.Bucket.BucketPropertyPath;
|
||||
|
||||
/**
|
||||
* Redis-specific {@link TypeMapper} exposing that {@link BucketPropertyPath}s might contain a type key.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
* @see BucketPropertyPath
|
||||
* @see Bucket.BucketPropertyPath
|
||||
*/
|
||||
public interface RedisTypeMapper extends TypeMapper<BucketPropertyPath> {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user