From a687b1409c52ba6434d357067793b4c13732f872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 10 Jun 2020 14:36:25 +0200 Subject: [PATCH] HSEARCH-3476 Use a dedicated object to store the context for the projection DSL Mainly for consistency with all the other search DSLs. --- .../elasticsearch/ElasticsearchExtension.java | 12 +++--- ...sticsearchSearchProjectionFactoryImpl.java | 13 +++--- .../backend/lucene/LuceneExtension.java | 12 +++--- .../LuceneSearchProjectionFactoryImpl.java | 11 ++--- .../scope/impl/MappedIndexScopeImpl.java | 5 ++- .../dsl/SearchProjectionFactoryExtension.java | 6 +-- .../CompositeProjectionOptionsStepImpl.java | 20 +++++---- .../impl/DefaultSearchProjectionFactory.java | 34 ++++++++------- ...istanceToFieldProjectionValueStepImpl.java | 7 ++-- ...entReferenceProjectionOptionsStepImpl.java | 6 +-- .../impl/EntityProjectionOptionsStepImpl.java | 6 +-- ...ityReferenceProjectionOptionsStepImpl.java | 6 +-- .../impl/FieldProjectionValueStepImpl.java | 7 ++-- .../impl/ScoreProjectionOptionsStepImpl.java | 6 +-- .../impl/SearchProjectionDslContextImpl.java | 41 +++++++++++++++++++ .../SearchProjectionFactoryExtensionStep.java | 10 ++--- .../dsl/spi/SearchProjectionDslContext.java | 24 +++++++++++ .../spi/AbstractSearchQuerySelectStep.java | 5 ++- .../search/projection/SearchProjectionIT.java | 10 ++--- 19 files changed, 160 insertions(+), 81 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionDslContextImpl.java create mode 100644 engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/SearchProjectionDslContext.java diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java index c77f20baf9b..99440138918 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/ElasticsearchExtension.java @@ -41,7 +41,7 @@ import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchQueryExtension; import org.hibernate.search.engine.search.query.dsl.SearchQueryDslExtension; @@ -186,11 +186,13 @@ public Optional extendOptional( * {@inheritDoc} */ @Override - public Optional> extendOptional( - SearchProjectionFactory original, SearchProjectionBuilderFactory factory) { - if ( factory instanceof ElasticsearchSearchProjectionBuilderFactory ) { + @SuppressWarnings("unchecked") // If the factory is an instance of ElasticsearchSearchProjectionBuilderFactory, the cast is safe + public Optional> extendOptional(SearchProjectionFactory original, + SearchProjectionDslContext dslContext) { + if ( dslContext.builderFactory() instanceof ElasticsearchSearchProjectionBuilderFactory ) { return Optional.of( new ElasticsearchSearchProjectionFactoryImpl<>( - original, (ElasticsearchSearchProjectionBuilderFactory) factory + original, + (SearchProjectionDslContext) dslContext ) ); } else { diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java index d1fff45887f..4835cfddaf1 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/search/projection/dsl/impl/ElasticsearchSearchProjectionFactoryImpl.java @@ -11,6 +11,7 @@ import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.spi.DelegatingSearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.dsl.spi.StaticProjectionFinalStep; import com.google.gson.JsonObject; @@ -19,26 +20,26 @@ public class ElasticsearchSearchProjectionFactoryImpl extends DelegatingSearchProjectionFactory implements ElasticsearchSearchProjectionFactory { - private final ElasticsearchSearchProjectionBuilderFactory factory; + private final SearchProjectionDslContext dslContext; public ElasticsearchSearchProjectionFactoryImpl(SearchProjectionFactory delegate, - ElasticsearchSearchProjectionBuilderFactory factory) { + SearchProjectionDslContext dslContext) { super( delegate ); - this.factory = factory; + this.dslContext = dslContext; } @Override public ProjectionFinalStep source() { - return new StaticProjectionFinalStep<>( factory.source() ); + return new StaticProjectionFinalStep<>( dslContext.builderFactory().source() ); } @Override public ProjectionFinalStep explanation() { - return new StaticProjectionFinalStep<>( factory.explanation() ); + return new StaticProjectionFinalStep<>( dslContext.builderFactory().explanation() ); } @Override public ProjectionFinalStep jsonHit() { - return new StaticProjectionFinalStep<>( factory.jsonHit() ); + return new StaticProjectionFinalStep<>( dslContext.builderFactory().jsonHit() ); } } diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java index 6af07f8bdab..1b1f48f2291 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/LuceneExtension.java @@ -38,6 +38,7 @@ import org.hibernate.search.engine.search.predicate.dsl.spi.SearchPredicateDslContext; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.query.dsl.SearchQueryDslExtension; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; @@ -46,7 +47,6 @@ import org.hibernate.search.engine.backend.scope.spi.IndexScope; import org.hibernate.search.engine.search.loading.context.spi.LoadingContext; import org.hibernate.search.engine.search.loading.context.spi.LoadingContextBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchQueryExtension; import org.hibernate.search.util.common.logging.impl.LoggerFactory; @@ -186,11 +186,13 @@ public Optional extendOptional( * {@inheritDoc} */ @Override - public Optional> extendOptional( - SearchProjectionFactory original, SearchProjectionBuilderFactory factory) { - if ( factory instanceof LuceneSearchProjectionBuilderFactory ) { + @SuppressWarnings("unchecked") // If the factory is an instance of LuceneSearchProjectionBuilderFactory, the cast is safe + public Optional> extendOptional(SearchProjectionFactory original, + SearchProjectionDslContext dslContext) { + if ( dslContext.builderFactory() instanceof LuceneSearchProjectionBuilderFactory ) { return Optional.of( new LuceneSearchProjectionFactoryImpl<>( - original, (LuceneSearchProjectionBuilderFactory) factory + original, + (SearchProjectionDslContext) dslContext ) ); } else { diff --git a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java index ba84279f785..3b53c21ca81 100644 --- a/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java +++ b/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/search/projection/dsl/impl/LuceneSearchProjectionFactoryImpl.java @@ -11,6 +11,7 @@ import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.projection.dsl.spi.DelegatingSearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.dsl.spi.StaticProjectionFinalStep; import org.apache.lucene.document.Document; @@ -20,21 +21,21 @@ public class LuceneSearchProjectionFactoryImpl extends DelegatingSearchProjectionFactory implements LuceneSearchProjectionFactory { - private final LuceneSearchProjectionBuilderFactory factory; + private final SearchProjectionDslContext dslContext; public LuceneSearchProjectionFactoryImpl(SearchProjectionFactory delegate, - LuceneSearchProjectionBuilderFactory factory) { + SearchProjectionDslContext dslContext) { super( delegate ); - this.factory = factory; + this.dslContext = dslContext; } @Override public ProjectionFinalStep document() { - return new StaticProjectionFinalStep<>( factory.document() ); + return new StaticProjectionFinalStep<>( dslContext.builderFactory().document() ); } @Override public ProjectionFinalStep explanation() { - return new StaticProjectionFinalStep<>( factory.explanation() ); + return new StaticProjectionFinalStep<>( dslContext.builderFactory().explanation() ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java index ba22758994b..694d14fae90 100644 --- a/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/mapper/scope/impl/MappedIndexScopeImpl.java @@ -18,6 +18,7 @@ import org.hibernate.search.engine.search.predicate.dsl.impl.SearchPredicateDslContextImpl; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.impl.DefaultSearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.impl.SearchProjectionDslContextImpl; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; import org.hibernate.search.engine.search.query.dsl.impl.DefaultSearchQuerySelectStep; import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory; @@ -64,7 +65,9 @@ public SearchSortFactory sort() { @Override public SearchProjectionFactory projection() { - return new DefaultSearchProjectionFactory<>( delegate.searchProjectionFactory() ); + return new DefaultSearchProjectionFactory<>( + SearchProjectionDslContextImpl.root( delegate.searchProjectionFactory() ) + ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactoryExtension.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactoryExtension.java index ad139569c3e..64dd9bf618b 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactoryExtension.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/SearchProjectionFactoryExtension.java @@ -10,7 +10,7 @@ import java.util.Optional; import org.hibernate.search.engine.search.projection.dsl.spi.DelegatingSearchProjectionFactory; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; /** * An extension to the search projection DSL, allowing the use of non-standard projections in a query. @@ -36,11 +36,11 @@ public interface SearchProjectionFactoryExtension { * WARNING: this method is not API, see comments at the type level. * * @param original The original, non-extended {@link SearchProjectionFactory}. - * @param factory A {@link SearchProjectionBuilderFactory}. + * @param dslContext A {@link SearchProjectionDslContext}. * @return An optional containing the extended projection factory ({@link T}) in case * of success, or an empty optional otherwise. */ Optional extendOptional(SearchProjectionFactory original, - SearchProjectionBuilderFactory factory); + SearchProjectionDslContext dslContext); } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java index 4595aeb467c..806a604f21e 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/CompositeProjectionOptionsStepImpl.java @@ -12,8 +12,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.CompositeProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.CompositeProjectionBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; import org.hibernate.search.util.common.function.TriFunction; @@ -22,31 +22,33 @@ public class CompositeProjectionOptionsStepImpl private final CompositeProjectionBuilder compositeProjectionBuilder; - public CompositeProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory, + public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, Function, T> transformer, SearchProjection[] projections) { - this.compositeProjectionBuilder = factory.composite( transformer, projections ); + this.compositeProjectionBuilder = dslContext.builderFactory().composite( transformer, projections ); } - public

CompositeProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory, + public

CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, Function transformer, SearchProjection

projection) { - this.compositeProjectionBuilder = factory.composite( transformer, projection ); + this.compositeProjectionBuilder = dslContext.builderFactory().composite( transformer, projection ); } - public CompositeProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory, + public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, BiFunction transformer, SearchProjection projection1, SearchProjection projection2) { - this.compositeProjectionBuilder = factory.composite( transformer, projection1, projection2 ); + this.compositeProjectionBuilder = dslContext.builderFactory() + .composite( transformer, projection1, projection2 ); } - public CompositeProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory, + public CompositeProjectionOptionsStepImpl(SearchProjectionDslContext dslContext, TriFunction transformer, SearchProjection projection1, SearchProjection projection2, SearchProjection projection3) { - this.compositeProjectionBuilder = factory.composite( transformer, projection1, projection2, projection3 ); + this.compositeProjectionBuilder = dslContext.builderFactory() + .composite( transformer, projection1, projection2, projection3 ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DefaultSearchProjectionFactory.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DefaultSearchProjectionFactory.java index 17cbe900b07..ccf81151d91 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DefaultSearchProjectionFactory.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DefaultSearchProjectionFactory.java @@ -23,7 +23,7 @@ import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtensionIfSupportedStep; import org.hibernate.search.engine.search.common.ValueConvert; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.spatial.GeoPoint; import org.hibernate.search.util.common.function.TriFunction; import org.hibernate.search.util.common.impl.Contracts; @@ -31,22 +31,21 @@ public class DefaultSearchProjectionFactory implements SearchProjectionFactory { - private final SearchProjectionBuilderFactory factory; + private final SearchProjectionDslContext dslContext; - public DefaultSearchProjectionFactory(SearchProjectionBuilderFactory factory) { - this.factory = factory; + public DefaultSearchProjectionFactory(SearchProjectionDslContext dslContext) { + this.dslContext = dslContext; } @Override public DocumentReferenceProjectionOptionsStep documentReference() { - return new DocumentReferenceProjectionOptionsStepImpl( factory ); + return new DocumentReferenceProjectionOptionsStepImpl( dslContext ); } @Override public FieldProjectionValueStep field(String absoluteFieldPath, Class clazz, ValueConvert convert) { Contracts.assertNotNull( clazz, "clazz" ); - - return new FieldProjectionValueStepImpl<>( factory, absoluteFieldPath, clazz, convert ); + return new FieldProjectionValueStepImpl<>( dslContext, absoluteFieldPath, clazz, convert ); } @Override @@ -56,24 +55,23 @@ public FieldProjectionValueStep field(String absoluteFieldPath, Value @Override public EntityReferenceProjectionOptionsStep entityReference() { - return new EntityReferenceProjectionOptionsStepImpl<>( factory ); + return new EntityReferenceProjectionOptionsStepImpl<>( dslContext ); } @Override public EntityProjectionOptionsStep entity() { - return new EntityProjectionOptionsStepImpl<>( factory ); + return new EntityProjectionOptionsStepImpl<>( dslContext ); } @Override public ScoreProjectionOptionsStep score() { - return new ScoreProjectionOptionsStepImpl( factory ); + return new ScoreProjectionOptionsStepImpl( dslContext ); } @Override public DistanceToFieldProjectionValueStep distance(String absoluteFieldPath, GeoPoint center) { Contracts.assertNotNull( center, "center" ); - - return new DistanceToFieldProjectionValueStepImpl( factory, absoluteFieldPath, center ); + return new DistanceToFieldProjectionValueStepImpl( dslContext, absoluteFieldPath, center ); } @Override @@ -82,7 +80,7 @@ public CompositeProjectionOptionsStep composite(Function, T> t Contracts.assertNotNull( transformer, "transformer" ); Contracts.assertNotNullNorEmpty( projections, "projections" ); - return new CompositeProjectionOptionsStepImpl<>( factory, transformer, projections ); + return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projections ); } @Override @@ -90,7 +88,7 @@ public CompositeProjectionOptionsStep composite(Function tran Contracts.assertNotNull( transformer, "transformer" ); Contracts.assertNotNull( projection, "projection" ); - return new CompositeProjectionOptionsStepImpl<>( factory, transformer, projection ); + return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection ); } @Override @@ -100,7 +98,7 @@ public CompositeProjectionOptionsStep composite(BiFunction( factory, transformer, projection1, projection2 ); + return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection1, projection2 ); } @Override @@ -111,18 +109,18 @@ public CompositeProjectionOptionsStep composite(TriFunctio Contracts.assertNotNull( projection2, "projection2" ); Contracts.assertNotNull( projection3, "projection3" ); - return new CompositeProjectionOptionsStepImpl<>( factory, transformer, projection1, projection2, projection3 ); + return new CompositeProjectionOptionsStepImpl<>( dslContext, transformer, projection1, projection2, projection3 ); } @Override public T extension(SearchProjectionFactoryExtension extension) { return DslExtensionState.returnIfSupported( - extension, extension.extendOptional( this, factory ) + extension, extension.extendOptional( this, dslContext ) ); } @Override public SearchProjectionFactoryExtensionIfSupportedStep extension() { - return new SearchProjectionFactoryExtensionStep<>( this, factory ); + return new SearchProjectionFactoryExtensionStep<>( this, dslContext ); } } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DistanceToFieldProjectionValueStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DistanceToFieldProjectionValueStepImpl.java index c90e1d34794..336725e916b 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DistanceToFieldProjectionValueStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DistanceToFieldProjectionValueStepImpl.java @@ -10,8 +10,8 @@ import org.hibernate.search.engine.search.projection.dsl.DistanceToFieldProjectionOptionsStep; import org.hibernate.search.engine.search.projection.dsl.DistanceToFieldProjectionValueStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.ListProjectionAccumulator; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; import org.hibernate.search.engine.search.projection.spi.SingleValuedProjectionAccumulator; import org.hibernate.search.engine.spatial.GeoPoint; @@ -19,9 +19,10 @@ public class DistanceToFieldProjectionValueStepImpl extends DistanceToFieldProjectionOptionsStepImpl implements DistanceToFieldProjectionValueStep, Double> { - DistanceToFieldProjectionValueStepImpl(SearchProjectionBuilderFactory factory, String absoluteFieldPath, + DistanceToFieldProjectionValueStepImpl(SearchProjectionDslContext dslContext, String absoluteFieldPath, GeoPoint center) { - super( factory.distance( absoluteFieldPath, center ), SingleValuedProjectionAccumulator.provider() ); + super( dslContext.builderFactory().distance( absoluteFieldPath, center ), + SingleValuedProjectionAccumulator.provider() ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DocumentReferenceProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DocumentReferenceProjectionOptionsStepImpl.java index e9d20fd440b..815a5b424ef 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DocumentReferenceProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/DocumentReferenceProjectionOptionsStepImpl.java @@ -9,8 +9,8 @@ import org.hibernate.search.engine.backend.common.DocumentReference; import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.DocumentReferenceProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.DocumentReferenceProjectionBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; public class DocumentReferenceProjectionOptionsStepImpl @@ -18,8 +18,8 @@ public class DocumentReferenceProjectionOptionsStepImpl private final DocumentReferenceProjectionBuilder documentReferenceProjectionBuilder; - DocumentReferenceProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory) { - this.documentReferenceProjectionBuilder = factory.documentReference(); + DocumentReferenceProjectionOptionsStepImpl(SearchProjectionDslContext dslContext) { + this.documentReferenceProjectionBuilder = dslContext.builderFactory().documentReference(); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityProjectionOptionsStepImpl.java index 23527d3ece5..f68188090f6 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityProjectionOptionsStepImpl.java @@ -8,8 +8,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.EntityProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.EntityProjectionBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; public class EntityProjectionOptionsStepImpl @@ -17,8 +17,8 @@ public class EntityProjectionOptionsStepImpl private final EntityProjectionBuilder entityProjectionBuilder; - EntityProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory) { - this.entityProjectionBuilder = factory.entity(); + EntityProjectionOptionsStepImpl(SearchProjectionDslContext dslContext) { + this.entityProjectionBuilder = dslContext.builderFactory().entity(); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityReferenceProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityReferenceProjectionOptionsStepImpl.java index 7443780815b..a897c9ba5e1 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityReferenceProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/EntityReferenceProjectionOptionsStepImpl.java @@ -8,8 +8,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.EntityReferenceProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.EntityReferenceProjectionBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; public class EntityReferenceProjectionOptionsStepImpl @@ -17,8 +17,8 @@ public class EntityReferenceProjectionOptionsStepImpl private final EntityReferenceProjectionBuilder entityReferenceProjectionBuilder; - EntityReferenceProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory) { - this.entityReferenceProjectionBuilder = factory.entityReference(); + EntityReferenceProjectionOptionsStepImpl(SearchProjectionDslContext dslContext) { + this.entityReferenceProjectionBuilder = dslContext.builderFactory().entityReference(); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/FieldProjectionValueStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/FieldProjectionValueStepImpl.java index af4accf5537..74f20d7eebd 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/FieldProjectionValueStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/FieldProjectionValueStepImpl.java @@ -12,8 +12,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.FieldProjectionOptionsStep; import org.hibernate.search.engine.search.projection.dsl.FieldProjectionValueStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.ListProjectionAccumulator; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; import org.hibernate.search.engine.search.projection.spi.SingleValuedProjectionAccumulator; @@ -21,9 +21,10 @@ public class FieldProjectionValueStepImpl extends FieldProjectionOptionsStepImpl implements FieldProjectionValueStep, T> { - FieldProjectionValueStepImpl(SearchProjectionBuilderFactory factory, String absoluteFieldPath, Class clazz, + FieldProjectionValueStepImpl(SearchProjectionDslContext dslContext, String absoluteFieldPath, Class clazz, ValueConvert convert) { - super( factory.field( absoluteFieldPath, clazz, convert ), SingleValuedProjectionAccumulator.provider() ); + super( dslContext.builderFactory().field( absoluteFieldPath, clazz, convert ), + SingleValuedProjectionAccumulator.provider() ); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/ScoreProjectionOptionsStepImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/ScoreProjectionOptionsStepImpl.java index 23ecea359aa..80188f77423 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/ScoreProjectionOptionsStepImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/ScoreProjectionOptionsStepImpl.java @@ -8,8 +8,8 @@ import org.hibernate.search.engine.search.projection.SearchProjection; import org.hibernate.search.engine.search.projection.dsl.ScoreProjectionOptionsStep; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.projection.spi.ScoreProjectionBuilder; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; public class ScoreProjectionOptionsStepImpl @@ -17,8 +17,8 @@ public class ScoreProjectionOptionsStepImpl private final ScoreProjectionBuilder scoreProjectionBuilder; - ScoreProjectionOptionsStepImpl(SearchProjectionBuilderFactory factory) { - this.scoreProjectionBuilder = factory.score(); + ScoreProjectionOptionsStepImpl(SearchProjectionDslContext dslContext) { + this.scoreProjectionBuilder = dslContext.builderFactory().score(); } @Override diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionDslContextImpl.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionDslContextImpl.java new file mode 100644 index 00000000000..2adc3df9bfe --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionDslContextImpl.java @@ -0,0 +1,41 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.impl; + +import java.util.function.Function; + +import org.hibernate.search.engine.mapper.scope.spi.MappedIndexScope; +import org.hibernate.search.engine.search.projection.SearchProjection; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; +import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; +import org.hibernate.search.engine.search.query.dsl.SearchQueryOptionsStep; + +/** + * A DSL context used when building a {@link SearchProjection} object, + * either when calling {@link MappedIndexScope#sort()} from a search scope + * or when calling {@link SearchQueryOptionsStep#sort(Function)} to build the sort using a lambda + * (in which case the lambda may retrieve the resulting {@link SearchProjection} object and cache it). + */ +public final class SearchProjectionDslContextImpl + implements SearchProjectionDslContext { + + public static + SearchProjectionDslContext root(F factory) { + return new SearchProjectionDslContextImpl<>( factory ); + } + + private final F factory; + + private SearchProjectionDslContextImpl(F factory) { + this.factory = factory; + } + + @Override + public F builderFactory() { + return factory; + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionFactoryExtensionStep.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionFactoryExtensionStep.java index 8c8070995ca..acd4988ee0b 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionFactoryExtensionStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/impl/SearchProjectionFactoryExtensionStep.java @@ -13,27 +13,27 @@ import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtensionIfSupportedMoreStep; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; public class SearchProjectionFactoryExtensionStep implements SearchProjectionFactoryExtensionIfSupportedMoreStep { private final SearchProjectionFactory parent; - private final SearchProjectionBuilderFactory factory; + private final SearchProjectionDslContext dslContext; private final DslExtensionState> state = new DslExtensionState<>(); SearchProjectionFactoryExtensionStep(SearchProjectionFactory parent, - SearchProjectionBuilderFactory factory) { + SearchProjectionDslContext dslContext) { this.parent = parent; - this.factory = factory; + this.dslContext = dslContext; } @Override public SearchProjectionFactoryExtensionIfSupportedMoreStep ifSupported( SearchProjectionFactoryExtension extension, Function> projectionContributor) { - state.ifSupported( extension, extension.extendOptional( parent, factory ), projectionContributor ); + state.ifSupported( extension, extension.extendOptional( parent, dslContext ), projectionContributor ); return this; } diff --git a/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/SearchProjectionDslContext.java b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/SearchProjectionDslContext.java new file mode 100644 index 00000000000..01a1f8b97c0 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/search/projection/dsl/spi/SearchProjectionDslContext.java @@ -0,0 +1,24 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.search.projection.dsl.spi; + +import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; + +/** + * Represents the current context in the search DSL, + * including in particular the projection builder factory. + * + * @param The type of predicate builder factory. + */ +public interface SearchProjectionDslContext { + + /** + * @return The aggregation builder factory. Will always return the exact same instance. + */ + F builderFactory(); + +} diff --git a/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/spi/AbstractSearchQuerySelectStep.java b/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/spi/AbstractSearchQuerySelectStep.java index d9cbec4256f..b5fa6614d64 100644 --- a/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/spi/AbstractSearchQuerySelectStep.java +++ b/engine/src/main/java/org/hibernate/search/engine/search/query/dsl/spi/AbstractSearchQuerySelectStep.java @@ -11,6 +11,7 @@ import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.projection.dsl.impl.DefaultSearchProjectionFactory; +import org.hibernate.search.engine.search.projection.dsl.impl.SearchProjectionDslContextImpl; import org.hibernate.search.engine.search.query.dsl.SearchQueryOptionsStep; import org.hibernate.search.engine.search.query.dsl.SearchQueryDslExtension; import org.hibernate.search.engine.search.query.dsl.SearchQuerySelectStep; @@ -39,7 +40,9 @@ this, indexScope(), sessionContext(), loadingContextBuilder() } protected final SearchProjectionFactory createDefaultProjectionFactory() { - return new DefaultSearchProjectionFactory<>( indexScope().searchProjectionFactory() ); + return new DefaultSearchProjectionFactory<>( + SearchProjectionDslContextImpl.root( indexScope().searchProjectionFactory() ) + ); } protected abstract IndexScope indexScope(); diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java index 2152da3d3b6..bace9d126b6 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/projection/SearchProjectionIT.java @@ -27,12 +27,12 @@ import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactory; import org.hibernate.search.engine.search.loading.context.spi.LoadingContext; import org.hibernate.search.engine.backend.common.spi.DocumentReferenceConverter; +import org.hibernate.search.engine.search.projection.dsl.spi.SearchProjectionDslContext; import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.engine.search.query.SearchResult; import org.hibernate.search.engine.search.projection.dsl.SearchProjectionFactoryExtension; import org.hibernate.search.engine.search.projection.dsl.ProjectionFinalStep; import org.hibernate.search.engine.search.loading.spi.EntityLoader; -import org.hibernate.search.engine.search.projection.spi.SearchProjectionBuilderFactory; import org.hibernate.search.integrationtest.backend.tck.testsupport.configuration.DefaultAnalysisDefinitions; import org.hibernate.search.integrationtest.backend.tck.testsupport.stub.StubDocumentReferenceConverter; import org.hibernate.search.integrationtest.backend.tck.testsupport.stub.StubEntityLoader; @@ -668,9 +668,9 @@ private static class SupportedExtension implements SearchProjectionFactoryExtension, R, E> { @Override public Optional> extendOptional(SearchProjectionFactory original, - SearchProjectionBuilderFactory factory) { + SearchProjectionDslContext dslContext) { Assertions.assertThat( original ).isNotNull(); - Assertions.assertThat( factory ).isNotNull(); + Assertions.assertThat( dslContext ).isNotNull(); return Optional.of( new MyExtendedFactory<>( original ) ); } } @@ -679,9 +679,9 @@ private static class UnSupportedExtension implements SearchProjectionFactoryExtension, R, E> { @Override public Optional> extendOptional(SearchProjectionFactory original, - SearchProjectionBuilderFactory factory) { + SearchProjectionDslContext dslContext) { Assertions.assertThat( original ).isNotNull(); - Assertions.assertThat( factory ).isNotNull(); + Assertions.assertThat( dslContext ).isNotNull(); return Optional.empty(); } }