Skip to content

Commit 82af678

Browse files
committed
Polishing
Rename ReferenceReader to ReferenceLookupDelegate. Rename LazyLoadingProxyGenerator to LazyLoadingProxyFactory. Rename DefaultReferenceLoader to MongoDatabaseFactoryReferenceLoader. Reduce scope of LookupFunction and move it to ReferenceLookupDelegate. Extract some checks into methods to reflect the underlying concepts. Simplify code, convert variables to constants where possible. Original pull request: #3647. Closes #3602.
1 parent 6ed274b commit 82af678

15 files changed

+204
-166
lines changed

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.springframework.data.mongodb.MongoDatabaseFactory;
4848
import org.springframework.data.mongodb.MongoDatabaseUtils;
4949
import org.springframework.data.mongodb.core.convert.ReferenceLoader.DocumentReferenceQuery;
50+
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty;
5051
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
5152
import org.springframework.lang.Nullable;
5253
import org.springframework.objenesis.ObjenesisStd;
@@ -83,7 +84,7 @@ public class DefaultDbRefResolver extends DefaultReferenceResolver implements Db
8384
*/
8485
public DefaultDbRefResolver(MongoDatabaseFactory mongoDbFactory) {
8586

86-
super(new DefaultReferenceLoader(mongoDbFactory));
87+
super(new MongoDatabaseFactoryReferenceLoader(mongoDbFactory));
8788

8889
Assert.notNull(mongoDbFactory, "MongoDbFactory translator must not be null!");
8990

@@ -117,7 +118,7 @@ public Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbr
117118
*/
118119
@Override
119120
public Document fetch(DBRef dbRef) {
120-
return getReferenceLoader().fetch(DocumentReferenceQuery.singleReferenceFilter(Filters.eq("_id", dbRef.getId())),
121+
return getReferenceLoader().fetchOne(DocumentReferenceQuery.forSingleDocument(Filters.eq("_id", dbRef.getId())),
121122
ReferenceCollection.fromDBRef(dbRef));
122123
}
123124

@@ -159,7 +160,7 @@ public List<Document> bulkFetch(List<DBRef> refs) {
159160
}
160161

161162
List<Document> result = mongoCollection //
162-
.find(new Document("_id", new Document("$in", ids))) //
163+
.find(new Document(BasicMongoPersistentProperty.ID_FIELD_NAME, new Document("$in", ids))) //
163164
.into(new ArrayList<>());
164165

165166
return ids.stream() //
@@ -239,7 +240,7 @@ private boolean isLazyDbRef(MongoPersistentProperty property) {
239240
private static Stream<Document> documentWithId(Object identifier, Collection<Document> documents) {
240241

241242
return documents.stream() //
242-
.filter(it -> it.get("_id").equals(identifier)) //
243+
.filter(it -> it.get(BasicMongoPersistentProperty.ID_FIELD_NAME).equals(identifier)) //
243244
.limit(1);
244245
}
245246

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultReferenceResolver.java

+23-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
*/
1616
package org.springframework.data.mongodb.core.convert;
1717

18-
import org.springframework.data.mongodb.core.mapping.DocumentReference;
18+
import static org.springframework.data.mongodb.core.convert.ReferenceLookupDelegate.*;
19+
20+
import java.util.Collections;
21+
1922
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
2023
import org.springframework.lang.Nullable;
2124

@@ -37,21 +40,32 @@ public ReferenceLoader getReferenceLoader() {
3740

3841
@Nullable
3942
@Override
40-
public Object resolveReference(MongoPersistentProperty property, Object source, ReferenceReader referenceReader,
41-
LookupFunction lookupFunction, ResultConversionFunction resultConversionFunction) {
43+
public Object resolveReference(MongoPersistentProperty property, Object source,
44+
ReferenceLookupDelegate referenceLookupDelegate, MongoEntityReader entityReader) {
45+
46+
LookupFunction lookupFunction = (filter, ctx) -> {
47+
if (property.isCollectionLike() || property.isMap()) {
48+
return getReferenceLoader().fetchMany(filter, ctx);
49+
50+
}
51+
52+
Object target = getReferenceLoader().fetchOne(filter, ctx);
53+
return target == null ? Collections.emptyList()
54+
: Collections.singleton(getReferenceLoader().fetchOne(filter, ctx));
55+
};
4256

4357
if (isLazyReference(property)) {
44-
return createLazyLoadingProxy(property, source, referenceReader, lookupFunction, resultConversionFunction);
58+
return createLazyLoadingProxy(property, source, referenceLookupDelegate, lookupFunction, entityReader);
4559
}
4660

47-
return referenceReader.readReference(property, source, lookupFunction, resultConversionFunction);
61+
return referenceLookupDelegate.readReference(property, source, lookupFunction, entityReader);
4862
}
4963

5064
private Object createLazyLoadingProxy(MongoPersistentProperty property, Object source,
51-
ReferenceReader referenceReader, LookupFunction lookupFunction,
52-
ResultConversionFunction resultConversionFunction) {
53-
return new LazyLoadingProxyGenerator(referenceReader).createLazyLoadingProxy(property, source, lookupFunction,
54-
resultConversionFunction);
65+
ReferenceLookupDelegate referenceLookupDelegate, LookupFunction lookupFunction,
66+
MongoEntityReader entityReader) {
67+
return new LazyLoadingProxyFactory(referenceLookupDelegate).createLazyLoadingProxy(property, source, lookupFunction,
68+
entityReader);
5569
}
5670

5771
protected boolean isLazyReference(MongoPersistentProperty property) {

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java

+27-12
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
import java.util.HashMap;
1919
import java.util.LinkedHashMap;
20+
import java.util.Locale;
2021
import java.util.Map;
2122
import java.util.Map.Entry;
2223
import java.util.regex.Matcher;
2324
import java.util.regex.Pattern;
2425

2526
import org.bson.Document;
27+
2628
import org.springframework.core.convert.ConversionService;
2729
import org.springframework.data.mapping.PersistentPropertyAccessor;
2830
import org.springframework.data.mapping.context.MappingContext;
@@ -37,9 +39,9 @@
3739
*/
3840
class DocumentPointerFactory {
3941

40-
private ConversionService conversionService;
41-
private MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
42-
private Map<String, LinkageDocument> linkageMap;
42+
private final ConversionService conversionService;
43+
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
44+
private final Map<String, LinkageDocument> linkageMap;
4345

4446
public DocumentPointerFactory(ConversionService conversionService,
4547
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
@@ -60,15 +62,24 @@ public DocumentPointer<?> computePointer(MongoPersistentProperty property, Objec
6062
} else {
6163

6264
MongoPersistentEntity<?> persistentEntity = mappingContext
63-
.getPersistentEntity(property.getAssociationTargetType());
65+
.getRequiredPersistentEntity(property.getAssociationTargetType());
6466

65-
if (!property.getDocumentReference().lookup().toLowerCase().replaceAll("\\s", "").replaceAll("'", "")
67+
// TODO: Extract method
68+
if (!property.getDocumentReference().lookup().toLowerCase(Locale.ROOT).replaceAll("\\s", "").replaceAll("'", "")
6669
.equals("{_id:?#{#target}}")) {
6770

68-
return () -> linkageMap.computeIfAbsent(property.getDocumentReference().lookup(), key -> {
69-
return new LinkageDocument(key);
70-
}).get(persistentEntity,
71-
BeanWrapperPropertyAccessorFactory.INSTANCE.getPropertyAccessor(property.getOwner(), value));
71+
MongoPersistentEntity<?> valueEntity = mappingContext.getPersistentEntity(value.getClass());
72+
PersistentPropertyAccessor<Object> propertyAccessor;
73+
if (valueEntity == null) {
74+
propertyAccessor = BeanWrapperPropertyAccessorFactory.INSTANCE.getPropertyAccessor(property.getOwner(),
75+
value);
76+
} else {
77+
propertyAccessor = valueEntity.getPropertyAccessor(value);
78+
79+
}
80+
81+
return () -> linkageMap.computeIfAbsent(property.getDocumentReference().lookup(), LinkageDocument::new)
82+
.get(persistentEntity, propertyAccessor);
7283
}
7384

7485
// just take the id as a reference
@@ -78,6 +89,8 @@ public DocumentPointer<?> computePointer(MongoPersistentProperty property, Objec
7889

7990
static class LinkageDocument {
8091

92+
static final Pattern pattern = Pattern.compile("\\?#\\{#?[\\w\\d]*\\}");
93+
8194
String lookup;
8295
org.bson.Document fetchDocument;
8396
Map<Integer, String> mapMap;
@@ -87,16 +100,18 @@ public LinkageDocument(String lookup) {
87100
this.lookup = lookup;
88101
String targetLookup = lookup;
89102

90-
Pattern pattern = Pattern.compile("\\?#\\{#?[\\w\\d]*\\}");
91103

92104
Matcher matcher = pattern.matcher(lookup);
93105
int index = 0;
94106
mapMap = new LinkedHashMap<>();
107+
108+
// TODO: Make explicit what's happening here
95109
while (matcher.find()) {
96110

97111
String expr = matcher.group();
98-
mapMap.put(Integer.valueOf(index), expr.substring(0, expr.length() - 1).replace("?#{#", "").replace("?#{", "")
99-
.replace("target.", "").replaceAll("'", ""));
112+
String sanitized = expr.substring(0, expr.length() - 1).replace("?#{#", "").replace("?#{", "")
113+
.replace("target.", "").replaceAll("'", "");
114+
mapMap.put(index, sanitized);
100115
targetLookup = targetLookup.replace(expr, index + "");
101116
index++;
102117
}

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyGenerator.java renamed to spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java

+30-28
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,46 @@
1515
*/
1616
package org.springframework.data.mongodb.core.convert;
1717

18+
import static org.springframework.data.mongodb.core.convert.ReferenceLookupDelegate.*;
1819
import static org.springframework.util.ReflectionUtils.*;
1920

2021
import java.io.Serializable;
2122
import java.lang.reflect.Method;
2223

23-
import javax.annotation.Nonnull;
24-
import javax.annotation.Nullable;
25-
2624
import org.aopalliance.intercept.MethodInterceptor;
2725
import org.aopalliance.intercept.MethodInvocation;
26+
2827
import org.springframework.aop.framework.ProxyFactory;
2928
import org.springframework.cglib.proxy.Callback;
3029
import org.springframework.cglib.proxy.Enhancer;
3130
import org.springframework.cglib.proxy.Factory;
3231
import org.springframework.cglib.proxy.MethodProxy;
33-
import org.springframework.data.mongodb.core.convert.ReferenceResolver.LookupFunction;
34-
import org.springframework.data.mongodb.core.convert.ReferenceResolver.ResultConversionFunction;
32+
import org.springframework.data.mongodb.core.convert.ReferenceResolver.MongoEntityReader;
3533
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
34+
import org.springframework.lang.Nullable;
3635
import org.springframework.objenesis.ObjenesisStd;
3736
import org.springframework.util.ReflectionUtils;
3837

3938
/**
4039
* @author Christoph Strobl
4140
*/
42-
class LazyLoadingProxyGenerator {
41+
class LazyLoadingProxyFactory {
4342

4443
private final ObjenesisStd objenesis;
45-
private final ReferenceReader referenceReader;
44+
private final ReferenceLookupDelegate lookupDelegate;
4645

47-
public LazyLoadingProxyGenerator(ReferenceReader referenceReader) {
46+
public LazyLoadingProxyFactory(ReferenceLookupDelegate lookupDelegate) {
4847

49-
this.referenceReader = referenceReader;
48+
this.lookupDelegate = lookupDelegate;
5049
this.objenesis = new ObjenesisStd(true);
5150
}
5251

5352
public Object createLazyLoadingProxy(MongoPersistentProperty property, Object source, LookupFunction lookupFunction,
54-
ResultConversionFunction resultConversionFunction) {
53+
MongoEntityReader entityReader) {
5554

5655
Class<?> propertyType = property.getType();
57-
LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, source, referenceReader, lookupFunction,
58-
resultConversionFunction);
56+
LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, source, lookupDelegate, lookupFunction,
57+
entityReader);
5958

6059
if (!propertyType.isInterface()) {
6160

@@ -97,13 +96,13 @@ private Class<?> getEnhancedTypeFor(Class<?> type) {
9796
public static class LazyLoadingInterceptor
9897
implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor, Serializable {
9998

100-
private final ReferenceReader referenceReader;
101-
MongoPersistentProperty property;
99+
private final ReferenceLookupDelegate referenceLookupDelegate;
100+
private final MongoPersistentProperty property;
102101
private volatile boolean resolved;
103-
private @org.springframework.lang.Nullable Object result;
104-
private Object source;
105-
private LookupFunction lookupFunction;
106-
private ResultConversionFunction resultConversionFunction;
102+
private @Nullable Object result;
103+
private final Object source;
104+
private final LookupFunction lookupFunction;
105+
private final MongoEntityReader entityReader;
107106

108107
private final Method INITIALIZE_METHOD, TO_DBREF_METHOD, FINALIZE_METHOD, GET_SOURCE_METHOD;
109108

@@ -118,22 +117,23 @@ public static class LazyLoadingInterceptor
118117
}
119118
}
120119

121-
public LazyLoadingInterceptor(MongoPersistentProperty property, Object source, ReferenceReader reader,
122-
LookupFunction lookupFunction, ResultConversionFunction resultConversionFunction) {
120+
public LazyLoadingInterceptor(MongoPersistentProperty property, Object source, ReferenceLookupDelegate reader,
121+
LookupFunction lookupFunction, MongoEntityReader entityReader) {
123122

124123
this.property = property;
125124
this.source = source;
126-
this.referenceReader = reader;
125+
this.referenceLookupDelegate = reader;
127126
this.lookupFunction = lookupFunction;
128-
this.resultConversionFunction = resultConversionFunction;
127+
this.entityReader = entityReader;
129128
}
130129

131130
@Nullable
132131
@Override
133-
public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
132+
public Object invoke(MethodInvocation invocation) throws Throwable {
134133
return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null);
135134
}
136135

136+
@Nullable
137137
@Override
138138
public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {
139139

@@ -180,6 +180,7 @@ public Object intercept(Object o, Method method, Object[] args, MethodProxy prox
180180
return method.invoke(target, args);
181181
}
182182

183+
@Nullable
183184
private Object ensureResolved() {
184185

185186
if (!resolved) {
@@ -190,7 +191,7 @@ private Object ensureResolved() {
190191
return this.result;
191192
}
192193

193-
private String proxyToString(Object source) {
194+
private String proxyToString(@Nullable Object source) {
194195

195196
StringBuilder description = new StringBuilder();
196197
if (source != null) {
@@ -203,7 +204,7 @@ private String proxyToString(Object source) {
203204
return description.toString();
204205
}
205206

206-
private boolean proxyEquals(@org.springframework.lang.Nullable Object proxy, Object that) {
207+
private boolean proxyEquals(@Nullable Object proxy, Object that) {
207208

208209
if (!(that instanceof LazyLoadingProxy)) {
209210
return false;
@@ -216,11 +217,11 @@ private boolean proxyEquals(@org.springframework.lang.Nullable Object proxy, Obj
216217
return proxyToString(proxy).equals(that.toString());
217218
}
218219

219-
private int proxyHashCode(@org.springframework.lang.Nullable Object proxy) {
220+
private int proxyHashCode(@Nullable Object proxy) {
220221
return proxyToString(proxy).hashCode();
221222
}
222223

223-
@org.springframework.lang.Nullable
224+
@Nullable
224225
private synchronized Object resolve() {
225226

226227
if (resolved) {
@@ -238,7 +239,7 @@ private synchronized Object resolve() {
238239
// property.getOwner() != null ? property.getOwner().getName() : "unknown", property.getName());
239240
// }
240241

241-
return referenceReader.readReference(property, source, lookupFunction, resultConversionFunction);
242+
return referenceLookupDelegate.readReference(property, source, lookupFunction, entityReader);
242243

243244
} catch (RuntimeException ex) {
244245
throw ex;
@@ -254,4 +255,5 @@ private synchronized Object resolve() {
254255
}
255256
}
256257
}
258+
257259
}

0 commit comments

Comments
 (0)