|
|
|
@ -131,6 +131,7 @@ import org.springframework.data.mongodb.core.timeseries.Granularity; |
|
|
|
import org.springframework.data.mongodb.core.validation.Validator; |
|
|
|
import org.springframework.data.mongodb.core.validation.Validator; |
|
|
|
import org.springframework.data.projection.EntityProjection; |
|
|
|
import org.springframework.data.projection.EntityProjection; |
|
|
|
import org.springframework.data.util.CloseableIterator; |
|
|
|
import org.springframework.data.util.CloseableIterator; |
|
|
|
|
|
|
|
import org.springframework.data.util.Lazy; |
|
|
|
import org.springframework.data.util.Optionals; |
|
|
|
import org.springframework.data.util.Optionals; |
|
|
|
import org.springframework.lang.Contract; |
|
|
|
import org.springframework.lang.Contract; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
@ -516,13 +517,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
protected <T> Stream<T> doStream(Query query, Class<?> entityType, String collectionName, Class<T> returnType) { |
|
|
|
protected <T> Stream<T> doStream(Query query, Class<?> entityType, String collectionName, Class<T> returnType) { |
|
|
|
|
|
|
|
return doStream(query, entityType, collectionName, returnType, QueryResultConverter.entity()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
|
|
|
|
<T, R> Stream<R> doStream(Query query, Class<?> entityType, String collectionName, Class<T> returnType, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends R> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(entityType, "Entity type must not be null"); |
|
|
|
Assert.notNull(entityType, "Entity type must not be null"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
Assert.notNull(returnType, "ReturnType must not be null"); |
|
|
|
Assert.notNull(returnType, "ReturnType must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
return execute(collectionName, (CollectionCallback<Stream<T>>) collection -> { |
|
|
|
return execute(collectionName, (CollectionCallback<Stream<R>>) collection -> { |
|
|
|
|
|
|
|
|
|
|
|
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityType); |
|
|
|
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityType); |
|
|
|
|
|
|
|
|
|
|
|
@ -536,8 +543,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
FindIterable<Document> cursor = new QueryCursorPreparer(query, entityType).initiateFind(collection, |
|
|
|
FindIterable<Document> cursor = new QueryCursorPreparer(query, entityType).initiateFind(collection, |
|
|
|
col -> readPreference.prepare(col).find(mappedQuery, Document.class).projection(mappedFields)); |
|
|
|
col -> readPreference.prepare(col).find(mappedQuery, Document.class).projection(mappedFields)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<R> resultReader = getResultReader(projection, collectionName, resultConverter); |
|
|
|
|
|
|
|
|
|
|
|
return new CloseableIterableCursorAdapter<>(cursor, exceptionTranslator, |
|
|
|
return new CloseableIterableCursorAdapter<>(cursor, exceptionTranslator, |
|
|
|
new ProjectingReadCallback<>(mongoConverter, projection, collectionName)).stream(); |
|
|
|
resultReader).stream(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -936,10 +945,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <T> Window<T> scroll(Query query, Class<T> entityType, String collectionName) { |
|
|
|
public <T> Window<T> scroll(Query query, Class<T> entityType, String collectionName) { |
|
|
|
return doScroll(query, entityType, entityType, collectionName); |
|
|
|
return doScroll(query, entityType, entityType, QueryResultConverter.entity(), collectionName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
<T> Window<T> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, String collectionName) { |
|
|
|
<T, R> Window<R> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends R> resultConverter, String collectionName) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(collectionName, "CollectionName must not be null"); |
|
|
|
Assert.notNull(collectionName, "CollectionName must not be null"); |
|
|
|
@ -947,7 +957,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
Assert.notNull(targetClass, "Target type must not be null"); |
|
|
|
Assert.notNull(targetClass, "Target type must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(targetClass, sourceClass); |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(targetClass, sourceClass); |
|
|
|
ProjectingReadCallback<?, T> callback = new ProjectingReadCallback<>(mongoConverter, projection, collectionName); |
|
|
|
DocumentCallback<R> callback = getResultReader(projection, collectionName, resultConverter); |
|
|
|
int limit = query.isLimited() ? query.getLimit() + 1 : Integer.MAX_VALUE; |
|
|
|
int limit = query.isLimited() ? query.getLimit() + 1 : Integer.MAX_VALUE; |
|
|
|
|
|
|
|
|
|
|
|
if (query.hasKeyset()) { |
|
|
|
if (query.hasKeyset()) { |
|
|
|
@ -955,14 +965,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
KeysetScrollQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query, |
|
|
|
KeysetScrollQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query, |
|
|
|
operations.getIdPropertyName(sourceClass)); |
|
|
|
operations.getIdPropertyName(sourceClass)); |
|
|
|
|
|
|
|
|
|
|
|
List<T> result = doFind(collectionName, createDelegate(query), keysetPaginationQuery.query(), |
|
|
|
List<R> result = doFind(collectionName, createDelegate(query), keysetPaginationQuery.query(), |
|
|
|
keysetPaginationQuery.fields(), sourceClass, |
|
|
|
keysetPaginationQuery.fields(), sourceClass, |
|
|
|
new QueryCursorPreparer(query, keysetPaginationQuery.sort(), limit, 0, sourceClass), callback); |
|
|
|
new QueryCursorPreparer(query, keysetPaginationQuery.sort(), limit, 0, sourceClass), callback); |
|
|
|
|
|
|
|
|
|
|
|
return ScrollUtils.createWindow(query, result, sourceClass, operations); |
|
|
|
return ScrollUtils.createWindow(query, result, sourceClass, operations); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<T> result = doFind(collectionName, createDelegate(query), query.getQueryObject(), query.getFieldsObject(), |
|
|
|
List<R> result = doFind(collectionName, createDelegate(query), query.getQueryObject(), query.getFieldsObject(), |
|
|
|
sourceClass, new QueryCursorPreparer(query, query.getSortObject(), limit, query.getSkip(), sourceClass), |
|
|
|
sourceClass, new QueryCursorPreparer(query, query.getSortObject(), limit, query.getSkip(), sourceClass), |
|
|
|
callback); |
|
|
|
callback); |
|
|
|
|
|
|
|
|
|
|
|
@ -1054,6 +1064,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public <T> GeoResults<T> geoNear(NearQuery near, Class<?> domainType, String collectionName, Class<T> returnType) { |
|
|
|
public <T> GeoResults<T> geoNear(NearQuery near, Class<?> domainType, String collectionName, Class<T> returnType) { |
|
|
|
|
|
|
|
return doGeoNear(near, domainType, collectionName, returnType, QueryResultConverter.entity()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<T, R> GeoResults<R> doGeoNear(NearQuery near, Class<?> domainType, String collectionName, Class<T> returnType, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends R> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
if (near == null) { |
|
|
|
if (near == null) { |
|
|
|
throw new InvalidDataAccessApiUsageException("NearQuery must not be null"); |
|
|
|
throw new InvalidDataAccessApiUsageException("NearQuery must not be null"); |
|
|
|
@ -1085,15 +1100,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
AggregationResults<Document> results = aggregate($geoNear, collection, Document.class); |
|
|
|
AggregationResults<Document> results = aggregate($geoNear, collection, Document.class); |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(returnType, domainType); |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(returnType, domainType); |
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<GeoResult<T>> callback = new GeoNearResultDocumentCallback<>(distanceField, |
|
|
|
DocumentCallback<GeoResult<R>> callback = new GeoNearResultDocumentCallback<>(distanceField, |
|
|
|
new ProjectingReadCallback<>(mongoConverter, projection, collection), near.getMetric()); |
|
|
|
getResultReader(projection, collectionName, resultConverter), near.getMetric()); |
|
|
|
|
|
|
|
|
|
|
|
List<GeoResult<T>> result = new ArrayList<>(results.getMappedResults().size()); |
|
|
|
List<GeoResult<R>> result = new ArrayList<>(results.getMappedResults().size()); |
|
|
|
|
|
|
|
|
|
|
|
BigDecimal aggregate = BigDecimal.ZERO; |
|
|
|
BigDecimal aggregate = BigDecimal.ZERO; |
|
|
|
for (Document element : results) { |
|
|
|
for (Document element : results) { |
|
|
|
|
|
|
|
|
|
|
|
GeoResult<T> geoResult = callback.doWith(element); |
|
|
|
GeoResult<R> geoResult = callback.doWith(element); |
|
|
|
aggregate = aggregate.add(BigDecimal.valueOf(geoResult.getDistance().getValue())); |
|
|
|
aggregate = aggregate.add(BigDecimal.valueOf(geoResult.getDistance().getValue())); |
|
|
|
result.add(geoResult); |
|
|
|
result.add(geoResult); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -2060,7 +2075,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, String inputCollectionName, |
|
|
|
public <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, String inputCollectionName, |
|
|
|
Class<O> outputType) { |
|
|
|
Class<O> outputType) { |
|
|
|
return aggregate(aggregation, inputCollectionName, outputType, null); |
|
|
|
return aggregate(aggregation, inputCollectionName, outputType, (AggregationOperationContext) null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -2073,7 +2088,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> outputType) { |
|
|
|
public <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> outputType) { |
|
|
|
return aggregate(aggregation, collectionName, outputType, null); |
|
|
|
return doAggregate(aggregation, collectionName, outputType, QueryResultConverter.entity()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -2204,11 +2219,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
return doAggregate(aggregation, collectionName, outputType, context.getAggregationOperationContext()); |
|
|
|
return doAggregate(aggregation, collectionName, outputType, context.getAggregationOperationContext()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<T, O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<T> outputType, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends O> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return doAggregate(aggregation, collectionName, outputType, resultConverter, queryOperations |
|
|
|
|
|
|
|
.createAggregation(aggregation, (AggregationOperationContext) null).getAggregationOperationContext()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
protected <O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<O> outputType, |
|
|
|
protected <O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<O> outputType, |
|
|
|
AggregationOperationContext context) { |
|
|
|
AggregationOperationContext context) { |
|
|
|
|
|
|
|
return doAggregate(aggregation, collectionName, outputType, QueryResultConverter.entity(), context); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
|
|
|
|
<T, O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<T> outputType, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends O> resultConverter, AggregationOperationContext context) { |
|
|
|
|
|
|
|
|
|
|
|
ReadDocumentCallback<O> callback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName); |
|
|
|
DocumentCallback<O> callback = new QueryResultConverterCallback<>(resultConverter, |
|
|
|
|
|
|
|
new ReadDocumentCallback<>(mongoConverter, outputType, collectionName)); |
|
|
|
|
|
|
|
|
|
|
|
AggregationOptions options = aggregation.getOptions(); |
|
|
|
AggregationOptions options = aggregation.getOptions(); |
|
|
|
AggregationUtil aggregationUtil = new AggregationUtil(queryMapper, mappingContext); |
|
|
|
AggregationUtil aggregationUtil = new AggregationUtil(queryMapper, mappingContext); |
|
|
|
@ -2287,9 +2316,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
|
|
|
|
protected <O> Stream<O> aggregateStream(Aggregation aggregation, String collectionName, Class<O> outputType, |
|
|
|
protected <O> Stream<O> aggregateStream(Aggregation aggregation, String collectionName, Class<O> outputType, |
|
|
|
@Nullable AggregationOperationContext context) { |
|
|
|
@Nullable AggregationOperationContext context) { |
|
|
|
|
|
|
|
return doAggregateStream(aggregation, collectionName, outputType, QueryResultConverter.entity(), context); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
|
|
|
|
protected <T, O> Stream<O> doAggregateStream(Aggregation aggregation, String collectionName, Class<T> outputType, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends O> resultConverter, |
|
|
|
|
|
|
|
@Nullable AggregationOperationContext context) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(aggregation, "Aggregation pipeline must not be null"); |
|
|
|
Assert.notNull(aggregation, "Aggregation pipeline must not be null"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
@ -2306,7 +2341,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
String.format("Streaming aggregation: %s in collection %s", serializeToJsonSafely(pipeline), collectionName)); |
|
|
|
String.format("Streaming aggregation: %s in collection %s", serializeToJsonSafely(pipeline), collectionName)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName); |
|
|
|
DocumentCallback<O> readCallback = new QueryResultConverterCallback<>(resultConverter, |
|
|
|
|
|
|
|
new ReadDocumentCallback<>(mongoConverter, outputType, collectionName)); |
|
|
|
|
|
|
|
|
|
|
|
return execute(collectionName, (CollectionCallback<Stream<O>>) collection -> { |
|
|
|
return execute(collectionName, (CollectionCallback<Stream<O>>) collection -> { |
|
|
|
|
|
|
|
|
|
|
|
@ -2670,11 +2706,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
* |
|
|
|
* |
|
|
|
* @since 2.0 |
|
|
|
* @since 2.0 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
<S, T> List<T> doFind(CollectionPreparer<MongoCollection<Document>> collectionPreparer, String collectionName, |
|
|
|
<T, R> List<R> doFind(CollectionPreparer<MongoCollection<Document>> collectionPreparer, String collectionName, |
|
|
|
Document query, Document fields, Class<S> sourceClass, Class<T> targetClass, CursorPreparer preparer) { |
|
|
|
Document query, Document fields, Class<?> sourceClass, Class<T> targetClass, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends R> resultConverter, CursorPreparer preparer) { |
|
|
|
|
|
|
|
|
|
|
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(sourceClass); |
|
|
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(sourceClass); |
|
|
|
EntityProjection<T, S> projection = operations.introspectProjection(targetClass, sourceClass); |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(targetClass, sourceClass); |
|
|
|
|
|
|
|
|
|
|
|
QueryContext queryContext = queryOperations.createQueryContext(new BasicQuery(query, fields)); |
|
|
|
QueryContext queryContext = queryOperations.createQueryContext(new BasicQuery(query, fields)); |
|
|
|
Document mappedFields = queryContext.getMappedFields(entity, projection); |
|
|
|
Document mappedFields = queryContext.getMappedFields(entity, projection); |
|
|
|
@ -2690,8 +2727,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
collectionName)); |
|
|
|
collectionName)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<R> callback = getResultReader(projection, collectionName, resultConverter); |
|
|
|
return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields, null), preparer, |
|
|
|
return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields, null), preparer, |
|
|
|
new ProjectingReadCallback<>(mongoConverter, projection, collectionName), collectionName); |
|
|
|
callback, collectionName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -3014,6 +3052,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
private <T, R> DocumentCallback<R> getResultReader(EntityProjection<T, ?> projection, String collectionName, |
|
|
|
|
|
|
|
QueryResultConverter<? super T, ? extends R> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<T> readCallback = new ProjectingReadCallback<>(mongoConverter, projection, collectionName); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return resultConverter == QueryResultConverter.entity() ? (DocumentCallback<R>) readCallback |
|
|
|
|
|
|
|
: new QueryResultConverterCallback<T, R>(resultConverter, readCallback); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public PersistenceExceptionTranslator getExceptionTranslator() { |
|
|
|
public PersistenceExceptionTranslator getExceptionTranslator() { |
|
|
|
return exceptionTranslator; |
|
|
|
return exceptionTranslator; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -3373,6 +3421,24 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static final class QueryResultConverterCallback<T, R> implements DocumentCallback<R> { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final QueryResultConverter<? super T, ? extends R> converter; |
|
|
|
|
|
|
|
private final DocumentCallback<T> delegate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QueryResultConverterCallback(QueryResultConverter<? super T, ? extends R> converter, DocumentCallback<T> delegate) { |
|
|
|
|
|
|
|
this.converter = converter; |
|
|
|
|
|
|
|
this.delegate = delegate; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public R doWith(Document object) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lazy<T> lazy = Lazy.of(() -> delegate.doWith(object)); |
|
|
|
|
|
|
|
return converter.mapDocument(object, lazy::get); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link DocumentCallback} transforming {@link Document} into the given {@code targetType} or decorating the |
|
|
|
* {@link DocumentCallback} transforming {@link Document} into the given {@code targetType} or decorating the |
|
|
|
* {@code sourceType} with a {@literal projection} in case the {@code targetType} is an {@literal interface}. |
|
|
|
* {@code sourceType} with a {@literal projection} in case the {@code targetType} is an {@literal interface}. |
|
|
|
|