Skip to content

Commit

Permalink
Polishing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mp911de committed May 21, 2021
1 parent 6ed274b commit 82af678
Show file tree
Hide file tree
Showing 15 changed files with 204 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoDatabaseUtils;
import org.springframework.data.mongodb.core.convert.ReferenceLoader.DocumentReferenceQuery;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.lang.Nullable;
import org.springframework.objenesis.ObjenesisStd;
Expand Down Expand Up @@ -83,7 +84,7 @@ public class DefaultDbRefResolver extends DefaultReferenceResolver implements Db
*/
public DefaultDbRefResolver(MongoDatabaseFactory mongoDbFactory) {

super(new DefaultReferenceLoader(mongoDbFactory));
super(new MongoDatabaseFactoryReferenceLoader(mongoDbFactory));

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

Expand Down Expand Up @@ -117,7 +118,7 @@ public Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbr
*/
@Override
public Document fetch(DBRef dbRef) {
return getReferenceLoader().fetch(DocumentReferenceQuery.singleReferenceFilter(Filters.eq("_id", dbRef.getId())),
return getReferenceLoader().fetchOne(DocumentReferenceQuery.forSingleDocument(Filters.eq("_id", dbRef.getId())),
ReferenceCollection.fromDBRef(dbRef));
}

Expand Down Expand Up @@ -159,7 +160,7 @@ public List<Document> bulkFetch(List<DBRef> refs) {
}

List<Document> result = mongoCollection //
.find(new Document("_id", new Document("$in", ids))) //
.find(new Document(BasicMongoPersistentProperty.ID_FIELD_NAME, new Document("$in", ids))) //
.into(new ArrayList<>());

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

return documents.stream() //
.filter(it -> it.get("_id").equals(identifier)) //
.filter(it -> it.get(BasicMongoPersistentProperty.ID_FIELD_NAME).equals(identifier)) //
.limit(1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
*/
package org.springframework.data.mongodb.core.convert;

import org.springframework.data.mongodb.core.mapping.DocumentReference;
import static org.springframework.data.mongodb.core.convert.ReferenceLookupDelegate.*;

import java.util.Collections;

import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.lang.Nullable;

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

@Nullable
@Override
public Object resolveReference(MongoPersistentProperty property, Object source, ReferenceReader referenceReader,
LookupFunction lookupFunction, ResultConversionFunction resultConversionFunction) {
public Object resolveReference(MongoPersistentProperty property, Object source,
ReferenceLookupDelegate referenceLookupDelegate, MongoEntityReader entityReader) {

LookupFunction lookupFunction = (filter, ctx) -> {
if (property.isCollectionLike() || property.isMap()) {
return getReferenceLoader().fetchMany(filter, ctx);

}

Object target = getReferenceLoader().fetchOne(filter, ctx);
return target == null ? Collections.emptyList()
: Collections.singleton(getReferenceLoader().fetchOne(filter, ctx));
};

if (isLazyReference(property)) {
return createLazyLoadingProxy(property, source, referenceReader, lookupFunction, resultConversionFunction);
return createLazyLoadingProxy(property, source, referenceLookupDelegate, lookupFunction, entityReader);
}

return referenceReader.readReference(property, source, lookupFunction, resultConversionFunction);
return referenceLookupDelegate.readReference(property, source, lookupFunction, entityReader);
}

private Object createLazyLoadingProxy(MongoPersistentProperty property, Object source,
ReferenceReader referenceReader, LookupFunction lookupFunction,
ResultConversionFunction resultConversionFunction) {
return new LazyLoadingProxyGenerator(referenceReader).createLazyLoadingProxy(property, source, lookupFunction,
resultConversionFunction);
ReferenceLookupDelegate referenceLookupDelegate, LookupFunction lookupFunction,
MongoEntityReader entityReader) {
return new LazyLoadingProxyFactory(referenceLookupDelegate).createLazyLoadingProxy(property, source, lookupFunction,
entityReader);
}

protected boolean isLazyReference(MongoPersistentProperty property) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bson.Document;

import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
Expand All @@ -37,9 +39,9 @@
*/
class DocumentPointerFactory {

private ConversionService conversionService;
private MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
private Map<String, LinkageDocument> linkageMap;
private final ConversionService conversionService;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
private final Map<String, LinkageDocument> linkageMap;

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

MongoPersistentEntity<?> persistentEntity = mappingContext
.getPersistentEntity(property.getAssociationTargetType());
.getRequiredPersistentEntity(property.getAssociationTargetType());

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

return () -> linkageMap.computeIfAbsent(property.getDocumentReference().lookup(), key -> {
return new LinkageDocument(key);
}).get(persistentEntity,
BeanWrapperPropertyAccessorFactory.INSTANCE.getPropertyAccessor(property.getOwner(), value));
MongoPersistentEntity<?> valueEntity = mappingContext.getPersistentEntity(value.getClass());
PersistentPropertyAccessor<Object> propertyAccessor;
if (valueEntity == null) {
propertyAccessor = BeanWrapperPropertyAccessorFactory.INSTANCE.getPropertyAccessor(property.getOwner(),
value);
} else {
propertyAccessor = valueEntity.getPropertyAccessor(value);

}

return () -> linkageMap.computeIfAbsent(property.getDocumentReference().lookup(), LinkageDocument::new)
.get(persistentEntity, propertyAccessor);
}

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

static class LinkageDocument {

static final Pattern pattern = Pattern.compile("\\?#\\{#?[\\w\\d]*\\}");

String lookup;
org.bson.Document fetchDocument;
Map<Integer, String> mapMap;
Expand All @@ -87,16 +100,18 @@ public LinkageDocument(String lookup) {
this.lookup = lookup;
String targetLookup = lookup;

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

Matcher matcher = pattern.matcher(lookup);
int index = 0;
mapMap = new LinkedHashMap<>();

// TODO: Make explicit what's happening here
while (matcher.find()) {

String expr = matcher.group();
mapMap.put(Integer.valueOf(index), expr.substring(0, expr.length() - 1).replace("?#{#", "").replace("?#{", "")
.replace("target.", "").replaceAll("'", ""));
String sanitized = expr.substring(0, expr.length() - 1).replace("?#{#", "").replace("?#{", "")
.replace("target.", "").replaceAll("'", "");
mapMap.put(index, sanitized);
targetLookup = targetLookup.replace(expr, index + "");
index++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,46 @@
*/
package org.springframework.data.mongodb.core.convert;

import static org.springframework.data.mongodb.core.convert.ReferenceLookupDelegate.*;
import static org.springframework.util.ReflectionUtils.*;

import java.io.Serializable;
import java.lang.reflect.Method;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.framework.ProxyFactory;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.data.mongodb.core.convert.ReferenceResolver.LookupFunction;
import org.springframework.data.mongodb.core.convert.ReferenceResolver.ResultConversionFunction;
import org.springframework.data.mongodb.core.convert.ReferenceResolver.MongoEntityReader;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.lang.Nullable;
import org.springframework.objenesis.ObjenesisStd;
import org.springframework.util.ReflectionUtils;

/**
* @author Christoph Strobl
*/
class LazyLoadingProxyGenerator {
class LazyLoadingProxyFactory {

private final ObjenesisStd objenesis;
private final ReferenceReader referenceReader;
private final ReferenceLookupDelegate lookupDelegate;

public LazyLoadingProxyGenerator(ReferenceReader referenceReader) {
public LazyLoadingProxyFactory(ReferenceLookupDelegate lookupDelegate) {

this.referenceReader = referenceReader;
this.lookupDelegate = lookupDelegate;
this.objenesis = new ObjenesisStd(true);
}

public Object createLazyLoadingProxy(MongoPersistentProperty property, Object source, LookupFunction lookupFunction,
ResultConversionFunction resultConversionFunction) {
MongoEntityReader entityReader) {

Class<?> propertyType = property.getType();
LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, source, referenceReader, lookupFunction,
resultConversionFunction);
LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, source, lookupDelegate, lookupFunction,
entityReader);

if (!propertyType.isInterface()) {

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

private final ReferenceReader referenceReader;
MongoPersistentProperty property;
private final ReferenceLookupDelegate referenceLookupDelegate;
private final MongoPersistentProperty property;
private volatile boolean resolved;
private @org.springframework.lang.Nullable Object result;
private Object source;
private LookupFunction lookupFunction;
private ResultConversionFunction resultConversionFunction;
private @Nullable Object result;
private final Object source;
private final LookupFunction lookupFunction;
private final MongoEntityReader entityReader;

private final Method INITIALIZE_METHOD, TO_DBREF_METHOD, FINALIZE_METHOD, GET_SOURCE_METHOD;

Expand All @@ -118,22 +117,23 @@ public static class LazyLoadingInterceptor
}
}

public LazyLoadingInterceptor(MongoPersistentProperty property, Object source, ReferenceReader reader,
LookupFunction lookupFunction, ResultConversionFunction resultConversionFunction) {
public LazyLoadingInterceptor(MongoPersistentProperty property, Object source, ReferenceLookupDelegate reader,
LookupFunction lookupFunction, MongoEntityReader entityReader) {

this.property = property;
this.source = source;
this.referenceReader = reader;
this.referenceLookupDelegate = reader;
this.lookupFunction = lookupFunction;
this.resultConversionFunction = resultConversionFunction;
this.entityReader = entityReader;
}

@Nullable
@Override
public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
public Object invoke(MethodInvocation invocation) throws Throwable {
return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null);
}

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

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

@Nullable
private Object ensureResolved() {

if (!resolved) {
Expand All @@ -190,7 +191,7 @@ private Object ensureResolved() {
return this.result;
}

private String proxyToString(Object source) {
private String proxyToString(@Nullable Object source) {

StringBuilder description = new StringBuilder();
if (source != null) {
Expand All @@ -203,7 +204,7 @@ private String proxyToString(Object source) {
return description.toString();
}

private boolean proxyEquals(@org.springframework.lang.Nullable Object proxy, Object that) {
private boolean proxyEquals(@Nullable Object proxy, Object that) {

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

private int proxyHashCode(@org.springframework.lang.Nullable Object proxy) {
private int proxyHashCode(@Nullable Object proxy) {
return proxyToString(proxy).hashCode();
}

@org.springframework.lang.Nullable
@Nullable
private synchronized Object resolve() {

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

return referenceReader.readReference(property, source, lookupFunction, resultConversionFunction);
return referenceLookupDelegate.readReference(property, source, lookupFunction, entityReader);

} catch (RuntimeException ex) {
throw ex;
Expand All @@ -254,4 +255,5 @@ private synchronized Object resolve() {
}
}
}

}
Loading

0 comments on commit 82af678

Please # to comment.