Skip to content

Commit fd47929

Browse files
DATAREDIS-425 - Provide property information to Map/List index resolution.
Provide property information when resolving index structures inside maps and lists. This avoids conversion problems and allows value lookup inside those types.
1 parent 408e050 commit fd47929

File tree

2 files changed

+86
-25
lines changed

2 files changed

+86
-25
lines changed

src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015 the original author or authors.
2+
* Copyright 2015-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -75,16 +75,16 @@ public PathIndexResolver(RedisMappingContext mappingContext) {
7575
*/
7676
public Set<IndexedData> resolveIndexesFor(TypeInformation<?> typeInformation, Object value) {
7777
return doResolveIndexesFor(mappingContext.getPersistentEntity(typeInformation).getKeySpace(), "", typeInformation,
78-
value);
78+
null, value);
7979
}
8080

8181
private Set<IndexedData> doResolveIndexesFor(final String keyspace, final String path,
82-
TypeInformation<?> typeInformation, Object value) {
82+
TypeInformation<?> typeInformation, PersistentProperty<?> fallback, Object value) {
8383

8484
RedisPersistentEntity<?> entity = mappingContext.getPersistentEntity(typeInformation);
8585

8686
if (entity == null) {
87-
return resolveIndex(keyspace, path, null, value);
87+
return resolveIndex(keyspace, path, fallback, value);
8888
}
8989

9090
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
@@ -101,34 +101,37 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
101101

102102
if (propertyValue != null) {
103103

104-
TypeInformation<?> typeHint = persistentProperty.isMap() ? persistentProperty.getTypeInformation()
105-
.getMapValueType() : persistentProperty.getTypeInformation().getActualType();
106-
107-
indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue));
104+
TypeInformation<?> typeHint = persistentProperty.isMap()
105+
? persistentProperty.getTypeInformation().getMapValueType()
106+
: persistentProperty.getTypeInformation().getActualType();
108107

109108
if (persistentProperty.isMap()) {
110109

111110
for (Entry<?, ?> entry : ((Map<?, ?>) propertyValue).entrySet()) {
112111

113112
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, entry.getValue());
114113
indexes.addAll(doResolveIndexesFor(keyspace, currentPath + "." + entry.getKey(),
115-
typeToUse.getActualType(), entry.getValue()));
114+
typeToUse.getActualType(), persistentProperty, entry.getValue()));
116115
}
117116

118117
} else if (persistentProperty.isCollectionLike()) {
119118

120119
for (Object listValue : (Iterable<?>) propertyValue) {
121120

122121
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
123-
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), listValue));
122+
indexes.addAll(
123+
doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue));
124124
}
125125
}
126126

127127
else if (persistentProperty.isEntity()
128128
|| persistentProperty.getTypeInformation().getActualType().equals(ClassTypeInformation.OBJECT)) {
129129

130130
typeHint = updateTypeHintForActualValue(typeHint, propertyValue);
131-
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeHint.getActualType(), propertyValue));
131+
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeHint.getActualType(), persistentProperty,
132+
propertyValue));
133+
} else {
134+
indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue));
132135
}
133136
}
134137

@@ -165,17 +168,17 @@ protected Set<IndexedData> resolveIndex(String keyspace, String propertyPath, Pe
165168

166169
if (indexConfiguration.hasIndexFor(keyspace, path)) {
167170

168-
IndexingContext context = new IndexingContext(keyspace, path, property != null ? property.getTypeInformation()
169-
: ClassTypeInformation.OBJECT);
171+
IndexingContext context = new IndexingContext(keyspace, path,
172+
property != null ? property.getTypeInformation() : ClassTypeInformation.OBJECT);
170173

171174
for (IndexDefinition indexDefinition : indexConfiguration.getIndexDefinitionsFor(keyspace, path)) {
172175

173176
if (!verifyConditions(indexDefinition.getConditions(), value, context)) {
174177
continue;
175178
}
176179

177-
data.add(new SimpleIndexedPropertyValue(keyspace, indexDefinition.getIndexName(), indexDefinition
178-
.valueTransformer().convert(value)));
180+
data.add(new SimpleIndexedPropertyValue(keyspace, indexDefinition.getIndexName(),
181+
indexDefinition.valueTransformer().convert(value)));
179182
}
180183
}
181184

src/test/java/org/springframework/data/redis/core/convert/PathIndexResolverUnitTests.java

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015 the original author or authors.
2+
* Copyright 2015-216 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
2727
import java.lang.annotation.Annotation;
2828
import java.util.ArrayList;
2929
import java.util.LinkedHashMap;
30+
import java.util.List;
31+
import java.util.Map;
3032
import java.util.Set;
3133

3234
import org.hamcrest.core.IsCollectionContaining;
@@ -66,8 +68,8 @@ public class PathIndexResolverUnitTests {
6668
public void setUp() {
6769

6870
indexConfig = new IndexConfiguration();
69-
this.indexResolver = new PathIndexResolver(new RedisMappingContext(new MappingConfiguration(indexConfig,
70-
new KeyspaceConfiguration())));
71+
this.indexResolver = new PathIndexResolver(
72+
new RedisMappingContext(new MappingConfiguration(indexConfig, new KeyspaceConfiguration())));
7173
}
7274

7375
/**
@@ -146,9 +148,10 @@ public void shouldResolveMultipleAnnotatedIndexesInLists() {
146148
Set<IndexedData> indexes = indexResolver.resolveIndexesFor(ClassTypeInformation.from(TheWheelOfTime.class), twot);
147149

148150
assertThat(indexes.size(), is(2));
149-
assertThat(indexes, IsCollectionContaining.<IndexedData> hasItems(new SimpleIndexedPropertyValue(KEYSPACE_TWOT,
150-
"mainCharacters.address.country", "andor"), new SimpleIndexedPropertyValue(KEYSPACE_TWOT,
151-
"mainCharacters.address.country", "saldaea")));
151+
assertThat(indexes,
152+
IsCollectionContaining.<IndexedData> hasItems(
153+
new SimpleIndexedPropertyValue(KEYSPACE_TWOT, "mainCharacters.address.country", "andor"),
154+
new SimpleIndexedPropertyValue(KEYSPACE_TWOT, "mainCharacters.address.country", "saldaea")));
152155
}
153156

154157
/**
@@ -171,8 +174,8 @@ public void shouldResolveAnnotatedIndexesInMap() {
171174
Set<IndexedData> indexes = indexResolver.resolveIndexesFor(ClassTypeInformation.from(TheWheelOfTime.class), twot);
172175

173176
assertThat(indexes.size(), is(1));
174-
assertThat(indexes, hasItem(new SimpleIndexedPropertyValue(KEYSPACE_TWOT, "places.stone-of-tear.address.country",
175-
"illian")));
177+
assertThat(indexes,
178+
hasItem(new SimpleIndexedPropertyValue(KEYSPACE_TWOT, "places.stone-of-tear.address.country", "illian")));
176179
}
177180

178181
/**
@@ -245,8 +248,8 @@ public void shouldNotResolveIndexOnReferencedEntity() {
245248
rand.addressRef.id = "emond_s_field";
246249
rand.addressRef.country = "andor";
247250

248-
Set<IndexedData> indexes = indexResolver.resolveIndexesFor(
249-
ClassTypeInformation.from(PersonWithAddressReference.class), rand);
251+
Set<IndexedData> indexes = indexResolver
252+
.resolveIndexesFor(ClassTypeInformation.from(PersonWithAddressReference.class), rand);
250253

251254
assertThat(indexes.size(), is(0));
252255
}
@@ -443,6 +446,50 @@ public void resolveIndexForTypeThatHasNoIndexDefined() {
443446
assertThat(indexes, is(empty()));
444447
}
445448

449+
/**
450+
* @see DATAREDIS-425
451+
*/
452+
@Test
453+
public void resolveIndexOnMapField() {
454+
455+
IndexedOnMapField source = new IndexedOnMapField();
456+
source.values = new LinkedHashMap<String, String>();
457+
458+
source.values.put("jon", "snow");
459+
source.values.put("arya", "stark");
460+
461+
Set<IndexedData> indexes = indexResolver.resolveIndexesFor(ClassTypeInformation.from(IndexedOnMapField.class),
462+
source);
463+
464+
assertThat(indexes.size(), is(2));
465+
assertThat(indexes,
466+
IsCollectionContaining.<IndexedData> hasItems(
467+
new SimpleIndexedPropertyValue(IndexedOnMapField.class.getName(), "values.jon", "snow"),
468+
new SimpleIndexedPropertyValue(IndexedOnMapField.class.getName(), "values.arya", "stark")));
469+
}
470+
471+
/**
472+
* @see DATAREDIS-425
473+
*/
474+
@Test
475+
public void resolveIndexOnListField() {
476+
477+
IndexedOnListField source = new IndexedOnListField();
478+
source.values = new ArrayList<String>();
479+
480+
source.values.add("jon");
481+
source.values.add("arya");
482+
483+
Set<IndexedData> indexes = indexResolver.resolveIndexesFor(ClassTypeInformation.from(IndexedOnListField.class),
484+
source);
485+
486+
assertThat(indexes.size(), is(2));
487+
assertThat(indexes,
488+
IsCollectionContaining.<IndexedData> hasItems(
489+
new SimpleIndexedPropertyValue(IndexedOnListField.class.getName(), "values", "jon"),
490+
new SimpleIndexedPropertyValue(IndexedOnListField.class.getName(), "values", "arya")));
491+
}
492+
446493
private IndexedData resolve(String path, Object value) {
447494

448495
Set<IndexedData> data = indexResolver.resolveIndex(KEYSPACE_PERSON, path, propertyMock, value);
@@ -466,4 +513,15 @@ public Class<? extends Annotation> annotationType() {
466513

467514
};
468515
}
516+
517+
static class IndexedOnListField {
518+
519+
@Indexed List<String> values;
520+
}
521+
522+
static class IndexedOnMapField {
523+
524+
@Indexed Map<String, String> values;
525+
}
526+
469527
}

0 commit comments

Comments
 (0)