Skip to content

Commit

Permalink
Generate project
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Raible committed Feb 4, 2021
1 parent 36bc906 commit dea4974
Show file tree
Hide file tree
Showing 11 changed files with 1,342 additions and 1,011 deletions.
1,972 changes: 963 additions & 1,009 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@
import reactor.core.publisher.Flux;
import tech.jhipster.config.JHipsterConstants;
import tech.jhipster.config.JHipsterProperties;
import tech.jhipster.sample.config.couchbase.CustomCouchbaseRepositoryFactoryBean;

@Configuration
@Profile("!" + JHipsterConstants.SPRING_PROFILE_CLOUD)
@EnableReactiveCouchbaseRepositories(basePackages = "tech.jhipster.sample.repository")
@EnableReactiveCouchbaseRepositories(
basePackages = "tech.jhipster.sample.repository",
repositoryFactoryBeanClass = CustomCouchbaseRepositoryFactoryBean.class
)
public class DatabaseConfiguration extends AbstractCouchbaseConfiguration {

private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
Expand Down
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);
}
}
}
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);
}
}
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);
}
}
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!");
}
}
}
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;
}
}
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;
Loading

0 comments on commit dea4974

Please sign in to comment.