DynamoDBQueryMethod.java
/*
* Copyright © 2018 spring-data-dynamodb (https://github.com/prasanna0586/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.socialsignin.spring.data.dynamodb.repository.query;
import org.socialsignin.spring.data.dynamodb.repository.*;
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityMetadataSupport;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;
import java.util.Optional;
import static org.socialsignin.spring.data.dynamodb.repository.QueryConstants.QUERY_LIMIT_UNLIMITED;
/**
* A QueryMethod implementation for DynamoDB repositories that provides metadata about
* a query method including projection expressions, filters, and scan settings.
* @param <T> the entity type
* @param <ID> the ID type of the entity
* @author Prasanna Kumar Ramachandran
*/
public class DynamoDBQueryMethod<T, ID> extends QueryMethod {
@NonNull
private final Method method;
private final boolean scanEnabledForRepository;
private final boolean scanCountEnabledForRepository;
@Nullable
private final String projectionExpression;
@Nullable
private final Integer limitResults;
@Nullable
private final String filterExpression;
@Nullable
private final ExpressionAttribute[] expressionAttributeNames;
@Nullable
private final ExpressionAttribute[] expressionAttributeValues;
private final QueryConstants.ConsistentReadMode consistentReadMode;
/**
* Creates a new DynamoDBQueryMethod.
* @param method the query method
* @param metadata the repository metadata
* @param factory the projection factory
*/
public DynamoDBQueryMethod(@NonNull Method method, @NonNull RepositoryMetadata metadata, @NonNull ProjectionFactory factory) {
super(method, metadata, factory);
this.method = method;
this.scanEnabledForRepository = metadata.getRepositoryInterface().isAnnotationPresent(EnableScan.class);
this.scanCountEnabledForRepository = metadata.getRepositoryInterface()
.isAnnotationPresent(EnableScanCount.class);
Query query = method.getAnnotation(Query.class);
if (query != null) {
String projections = query.fields();
if (StringUtils.hasLength(projections)) {
this.projectionExpression = query.fields();
} else {
this.projectionExpression = null;
}
String filterExp = query.filterExpression();
if (StringUtils.hasLength(filterExp)) {
this.filterExpression = filterExp;
} else {
this.filterExpression = null;
}
this.expressionAttributeValues = query.expressionMappingValues();
this.expressionAttributeNames = query.expressionMappingNames();
int limit = query.limit();
if (limit != QUERY_LIMIT_UNLIMITED) {
this.limitResults = query.limit();
} else {
this.limitResults = null;
}
this.consistentReadMode = query.consistentReads();
} else {
this.projectionExpression = null;
this.limitResults = null;
this.consistentReadMode = QueryConstants.ConsistentReadMode.DEFAULT;
this.filterExpression = null;
this.expressionAttributeNames = null;
this.expressionAttributeValues = null;
}
}
/**
* Checks if scan operations are enabled for this query method.
* @return true if scan is enabled, false otherwise
*/
public boolean isScanEnabled() {
return scanEnabledForRepository || method.isAnnotationPresent(EnableScan.class);
}
/**
* Checks if scan count operations are enabled for this query method.
* @return true if scan count is enabled, false otherwise
*/
public boolean isScanCountEnabled() {
return scanCountEnabledForRepository || method.isAnnotationPresent(EnableScanCount.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryMethod#getEntityInformation()
*/
@NonNull
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public DynamoDBEntityInformation<T, ID> getEntityInformation() {
return new DynamoDBEntityMetadataSupport(getDomainClass()).getEntityInformation();
}
/**
* Gets the entity type for this query method.
* @return the entity type
*/
@NonNull
public Class<T> getEntityType() {
return getEntityInformation().getJavaType();
}
/**
* Gets the projection expression if configured.
* @return optional containing the projection expression
*/
@NonNull
public Optional<String> getProjectionExpression() {
return Optional.ofNullable(this.projectionExpression);
}
/**
* Gets the limit for query results if configured.
* @return optional containing the limit
*/
@NonNull
public Optional<Integer> getLimitResults() {
return Optional.ofNullable(this.limitResults);
}
/**
* Gets the consistent read mode configuration.
* @return the consistent read mode
*/
public QueryConstants.ConsistentReadMode getConsistentReadMode() {
return this.consistentReadMode;
}
/**
* Gets the filter expression if configured.
* @return optional containing the filter expression
*/
@NonNull
public Optional<String> getFilterExpression() {
return Optional.ofNullable(this.filterExpression);
}
/**
* Gets the expression attribute names for the query.
* @return array of expression attribute names or null
*/
@Nullable
public ExpressionAttribute[] getExpressionAttributeNames() {
if (expressionAttributeNames != null) {
return expressionAttributeNames.clone();
}
return null;
}
/**
* Gets the expression attribute values for the query.
* @return array of expression attribute values or null
*/
@Nullable
public ExpressionAttribute[] getExpressionAttributeValues() {
if (expressionAttributeValues != null) {
return expressionAttributeValues.clone();
}
return null;
}
}