-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Matt Raible
committed
Feb 4, 2021
1 parent
36bc906
commit dea4974
Showing
11 changed files
with
1,342 additions
and
1,011 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
src/main/java/tech/jhipster/sample/config/couchbase/CustomCouchbaseRepositoryFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package tech.jhipster.sample.config.couchbase; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Optional; | ||
import org.springframework.data.couchbase.core.CouchbaseOperations; | ||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping; | ||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod; | ||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory; | ||
import org.springframework.data.mapping.context.MappingContext; | ||
import org.springframework.data.projection.ProjectionFactory; | ||
import org.springframework.data.repository.core.NamedQueries; | ||
import org.springframework.data.repository.core.RepositoryMetadata; | ||
import org.springframework.data.repository.query.QueryLookupStrategy; | ||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; | ||
import org.springframework.data.repository.query.RepositoryQuery; | ||
|
||
public class CustomCouchbaseRepositoryFactory extends CouchbaseRepositoryFactory { | ||
|
||
private MappingContext mappingContext; | ||
private RepositoryOperationsMapping couchbaseOperationsMapping; | ||
|
||
/** | ||
* Create a new factory. | ||
* | ||
* @param couchbaseOperationsMapping the template for the underlying actions. | ||
*/ | ||
public CustomCouchbaseRepositoryFactory(RepositoryOperationsMapping couchbaseOperationsMapping) { | ||
super(couchbaseOperationsMapping); | ||
this.couchbaseOperationsMapping = couchbaseOperationsMapping; | ||
this.mappingContext = this.couchbaseOperationsMapping.getMappingContext(); | ||
} | ||
|
||
@Override | ||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy( | ||
QueryLookupStrategy.Key key, | ||
QueryMethodEvaluationContextProvider contextProvider | ||
) { | ||
return Optional.of(new CustomCouchbaseQueryLookupStrategy(contextProvider)); | ||
} | ||
|
||
private class CustomCouchbaseQueryLookupStrategy implements QueryLookupStrategy { | ||
|
||
private final QueryMethodEvaluationContextProvider evaluationContextProvider; | ||
|
||
public CustomCouchbaseQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) { | ||
this.evaluationContextProvider = evaluationContextProvider; | ||
} | ||
|
||
@Override | ||
public RepositoryQuery resolveQuery( | ||
final Method method, | ||
final RepositoryMetadata metadata, | ||
final ProjectionFactory factory, | ||
final NamedQueries namedQueries | ||
) { | ||
final CouchbaseOperations couchbaseOperations = couchbaseOperationsMapping.resolve( | ||
metadata.getRepositoryInterface(), | ||
metadata.getDomainType() | ||
); | ||
|
||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext); | ||
return new CustomCouchbaseRepositoryQuery(couchbaseOperations, queryMethod, namedQueries); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...main/java/tech/jhipster/sample/config/couchbase/CustomCouchbaseRepositoryFactoryBean.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package tech.jhipster.sample.config.couchbase; | ||
|
||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping; | ||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory; | ||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactoryBean; | ||
|
||
public class CustomCouchbaseRepositoryFactoryBean extends CouchbaseRepositoryFactoryBean { | ||
|
||
/** | ||
* Creates a new {@link CouchbaseRepositoryFactoryBean} for the given repository interface. | ||
* | ||
* @param repositoryInterface must not be {@literal null}. | ||
*/ | ||
public CustomCouchbaseRepositoryFactoryBean(Class repositoryInterface) { | ||
super(repositoryInterface); | ||
} | ||
|
||
@Override | ||
protected CouchbaseRepositoryFactory getFactoryInstance(RepositoryOperationsMapping operationsMapping) { | ||
return new CustomCouchbaseRepositoryFactory(operationsMapping); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/tech/jhipster/sample/config/couchbase/CustomCouchbaseRepositoryQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package tech.jhipster.sample.config.couchbase; | ||
|
||
import org.springframework.data.couchbase.core.CouchbaseOperations; | ||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod; | ||
import org.springframework.data.couchbase.repository.query.CouchbaseRepositoryQuery; | ||
import org.springframework.data.repository.core.NamedQueries; | ||
import tech.jhipster.sample.config.couchbase.CustomN1qlRepositoryQueryExecutor; | ||
|
||
public class CustomCouchbaseRepositoryQuery extends CouchbaseRepositoryQuery { | ||
|
||
private CouchbaseOperations couchbaseOperations; | ||
private CouchbaseQueryMethod queryMethod; | ||
private NamedQueries namedQueries; | ||
|
||
public CustomCouchbaseRepositoryQuery(CouchbaseOperations operations, CouchbaseQueryMethod queryMethod, NamedQueries namedQueries) { | ||
super(operations, queryMethod, namedQueries); | ||
this.couchbaseOperations = operations; | ||
this.queryMethod = queryMethod; | ||
this.namedQueries = namedQueries; | ||
} | ||
|
||
@Override | ||
public Object execute(final Object[] parameters) { | ||
return new CustomN1qlRepositoryQueryExecutor(couchbaseOperations, queryMethod, namedQueries).execute(parameters); | ||
} | ||
} |
144 changes: 144 additions & 0 deletions
144
src/main/java/tech/jhipster/sample/config/couchbase/CustomN1qlQueryCreator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package tech.jhipster.sample.config.couchbase; | ||
|
||
import static org.springframework.data.couchbase.core.query.N1QLExpression.*; | ||
|
||
import java.util.Iterator; | ||
import org.springframework.core.convert.converter.Converter; | ||
import org.springframework.data.couchbase.core.CouchbaseOperations; | ||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter; | ||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; | ||
import org.springframework.data.couchbase.core.query.Query; | ||
import org.springframework.data.couchbase.core.query.QueryCriteria; | ||
import org.springframework.data.domain.Sort; | ||
import org.springframework.data.mapping.PersistentPropertyPath; | ||
import org.springframework.data.mapping.context.MappingContext; | ||
import org.springframework.data.repository.query.ParameterAccessor; | ||
import org.springframework.data.repository.query.QueryMethod; | ||
import org.springframework.data.repository.query.parser.AbstractQueryCreator; | ||
import org.springframework.data.repository.query.parser.Part; | ||
import org.springframework.data.repository.query.parser.PartTree; | ||
|
||
public class CustomN1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria> { | ||
|
||
private final CouchbaseOperations couchbaseOperations; | ||
private final ParameterAccessor accessor; | ||
private final MappingContext<?, CouchbasePersistentProperty> context; | ||
private final QueryMethod queryMethod; | ||
private final CouchbaseConverter converter; | ||
|
||
public CustomN1qlQueryCreator( | ||
final CouchbaseOperations operations, | ||
final PartTree tree, | ||
final ParameterAccessor accessor, | ||
QueryMethod queryMethod, | ||
CouchbaseConverter converter | ||
) { | ||
super(tree, accessor); | ||
this.accessor = accessor; | ||
this.context = converter.getMappingContext(); | ||
this.queryMethod = queryMethod; | ||
this.converter = converter; | ||
this.couchbaseOperations = operations; | ||
} | ||
|
||
static Converter<? super CouchbasePersistentProperty, String> cvtr = source -> | ||
new StringBuilder(source.getFieldName().length() + 2).append('`').append(source.getFieldName()).append('`').toString(); | ||
|
||
@Override | ||
protected QueryCriteria create(final Part part, final Iterator<Object> iterator) { | ||
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty()); | ||
CouchbasePersistentProperty property = path.getLeafProperty(); | ||
return from(part, property, QueryCriteria.where(addMetaIfIdProperty(path, property)), iterator); | ||
} | ||
|
||
@Override | ||
protected QueryCriteria and(Part part, QueryCriteria base, Iterator<Object> iterator) { | ||
if (base == null) { | ||
return create(part, iterator); | ||
} | ||
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty()); | ||
CouchbasePersistentProperty property = path.getLeafProperty(); | ||
return from(part, property, base.and(addMetaIfIdProperty(path, property)), iterator); | ||
} | ||
|
||
private String addMetaIfIdProperty( | ||
final PersistentPropertyPath<CouchbasePersistentProperty> path, | ||
final CouchbasePersistentProperty property | ||
) { | ||
return path.toDotPath(cvtr); | ||
} | ||
|
||
@Override | ||
protected QueryCriteria or(QueryCriteria base, QueryCriteria criteria) { | ||
return base.or(criteria); | ||
} | ||
|
||
@Override | ||
protected Query complete(QueryCriteria criteria, Sort sort) { | ||
return (criteria == null ? new Query() : new Query().addCriteria(criteria)).with(sort); | ||
} | ||
|
||
private QueryCriteria from( | ||
final Part part, | ||
final CouchbasePersistentProperty property, | ||
final QueryCriteria criteria, | ||
final Iterator<Object> parameters | ||
) { | ||
final Part.Type type = part.getType(); | ||
|
||
switch (type) { | ||
case GREATER_THAN: | ||
case AFTER: | ||
return criteria.gt(parameters.next()); | ||
case GREATER_THAN_EQUAL: | ||
return criteria.gte(parameters.next()); | ||
case LESS_THAN: | ||
case BEFORE: | ||
return criteria.lt(parameters.next()); | ||
case LESS_THAN_EQUAL: | ||
return criteria.lte(parameters.next()); | ||
case SIMPLE_PROPERTY: | ||
return criteria.eq(parameters.next()); | ||
case NEGATING_SIMPLE_PROPERTY: | ||
return criteria.ne(parameters.next()); | ||
case CONTAINING: | ||
return criteria.containing(parameters.next()); | ||
case NOT_CONTAINING: | ||
return criteria.notContaining(parameters.next()); | ||
case STARTING_WITH: | ||
return criteria.startingWith(parameters.next()); | ||
case ENDING_WITH: | ||
return criteria.endingWith(parameters.next()); | ||
case LIKE: | ||
return criteria.like(parameters.next()); | ||
case NOT_LIKE: | ||
return criteria.notLike(parameters.next()); | ||
case WITHIN: | ||
return criteria.within(parameters.next()); | ||
case IS_NULL: | ||
return criteria.isNull(); | ||
case IS_NOT_NULL: | ||
return criteria.isNotNull(); | ||
case IS_EMPTY: | ||
return criteria.isNotValued(); | ||
case IS_NOT_EMPTY: | ||
return criteria.isValued(); | ||
case EXISTS: | ||
return criteria.isNotMissing(); | ||
case REGEX: | ||
return criteria.regex(parameters.next()); | ||
case BETWEEN: | ||
return criteria.between(parameters.next(), parameters.next()); | ||
case IN: | ||
return criteria.in(parameters.next()); | ||
case NOT_IN: | ||
return criteria.notIn(parameters.next()); | ||
case TRUE: | ||
return criteria.TRUE(); | ||
case FALSE: | ||
return criteria.FALSE(); | ||
default: | ||
throw new IllegalArgumentException("Unsupported keyword!"); | ||
} | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
src/main/java/tech/jhipster/sample/config/couchbase/CustomN1qlRepositoryQueryExecutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package tech.jhipster.sample.config.couchbase; | ||
|
||
import com.couchbase.client.java.query.QueryScanConsistency; | ||
import org.springframework.data.couchbase.core.CouchbaseOperations; | ||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation; | ||
import org.springframework.data.couchbase.core.query.Query; | ||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod; | ||
import org.springframework.data.couchbase.repository.query.ReactiveN1qlRepositoryQueryExecutor; | ||
import org.springframework.data.couchbase.repository.query.StringN1qlQueryCreator; | ||
import org.springframework.data.repository.core.NamedQueries; | ||
import org.springframework.data.repository.query.ParameterAccessor; | ||
import org.springframework.data.repository.query.ParametersParameterAccessor; | ||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; | ||
import org.springframework.data.repository.query.parser.PartTree; | ||
|
||
public class CustomN1qlRepositoryQueryExecutor { | ||
|
||
private final CouchbaseOperations operations; | ||
private final CouchbaseQueryMethod queryMethod; | ||
private final NamedQueries namedQueries; | ||
|
||
public CustomN1qlRepositoryQueryExecutor( | ||
final CouchbaseOperations operations, | ||
final CouchbaseQueryMethod queryMethod, | ||
final NamedQueries namedQueries | ||
) { | ||
this.operations = operations; | ||
this.queryMethod = queryMethod; | ||
this.namedQueries = namedQueries; | ||
} | ||
|
||
/** | ||
* see also {@link ReactiveN1qlRepositoryQueryExecutor#execute(Object[] parameters) execute } | ||
* | ||
* @param parameters substitute values | ||
* @return with data | ||
*/ | ||
public Object execute(final Object[] parameters) { | ||
final Class<?> domainClass = queryMethod.getResultProcessor().getReturnedType().getDomainType(); | ||
final ParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); | ||
|
||
// this is identical to ReactiveN1qlRespositoryQueryExecutor, | ||
// except for the type of 'q', and the call to oneValue() vs one() | ||
Query query; | ||
ExecutableFindByQueryOperation.ExecutableFindByQuery q; | ||
if (queryMethod.hasN1qlAnnotation()) { | ||
query = | ||
new StringN1qlQueryCreator( | ||
accessor, | ||
queryMethod, | ||
operations.getConverter(), | ||
operations.getBucketName(), | ||
QueryMethodEvaluationContextProvider.DEFAULT, | ||
namedQueries | ||
) | ||
.createQuery(); | ||
} else { | ||
final PartTree tree = new PartTree(queryMethod.getName(), domainClass); | ||
query = new CustomN1qlQueryCreator(operations, tree, accessor, queryMethod, operations.getConverter()).createQuery(); | ||
} | ||
q = | ||
(ExecutableFindByQueryOperation.ExecutableFindByQuery) operations | ||
.findByQuery(domainClass) | ||
.consistentWith(buildQueryScanConsistency()) | ||
.matching(query); | ||
if (queryMethod.isCountQuery()) { | ||
return q.count(); | ||
} else if (queryMethod.isCollectionQuery()) { | ||
return q.all(); | ||
} else { | ||
return q.oneValue(); | ||
} | ||
} | ||
|
||
private QueryScanConsistency buildQueryScanConsistency() { | ||
QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED; | ||
if (queryMethod.hasConsistencyAnnotation()) { | ||
scanConsistency = queryMethod.getConsistencyAnnotation().value(); | ||
} else if (queryMethod.hasScanConsistencyAnnotation()) { | ||
scanConsistency = queryMethod.getScanConsistencyAnnotation().query(); | ||
} | ||
return scanConsistency; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/tech/jhipster/sample/config/couchbase/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
* Classes in this package are meant to extend Spring Data Couchbase | ||
* and fix some of the issues encountered during integration. | ||
*/ | ||
package tech.jhipster.sample.config.couchbase; |
Oops, something went wrong.