org.springframework.data.gemfire.repository.query.GemfireQueryMethod Maven / Gradle / Ivy
/*
* Copyright 2012-2020 the original author or authors.
*
* 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
*
* https://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.springframework.data.gemfire.repository.query;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
import org.springframework.data.gemfire.repository.Query;
import org.springframework.data.gemfire.repository.query.annotation.Hint;
import org.springframework.data.gemfire.repository.query.annotation.Import;
import org.springframework.data.gemfire.repository.query.annotation.Limit;
import org.springframework.data.gemfire.repository.query.annotation.Trace;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Pivotal GemFire specific {@link QueryMethod}.
*
* @author Oliver Gierke
* @author John Blum
* @see org.springframework.data.repository.query.QueryMethod
*/
public class GemfireQueryMethod extends QueryMethod {
@SuppressWarnings("all")
protected static final String[] EMPTY_STRING_ARRAY = new String[0];
private final GemfirePersistentEntity entity;
private final Method method;
/**
* Creates a new {@link GemfireQueryMethod} from the given {@link Method} and {@link RepositoryMetadata}.
*
* @param method must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @param factory must not be {@literal null}.
* @param mappingContext must not be {@literal null}.
*/
public GemfireQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory,
MappingContext, GemfirePersistentProperty> mappingContext) {
super(method, metadata, factory);
Assert.notNull(mappingContext, "MappingContext must not be null");
assertNonPagingQueryMethod(method);
this.method = method;
this.entity = mappingContext.getPersistentEntity(getDomainClass());
}
/**
* Asserts that the query method is a non-Paging query method since Pivotal GemFire does not support pagination
* as it has no concept of a Cursor.
*
* @param method the query method to be evaluated
* @throws java.lang.IllegalStateException if the query method contains a parameter of type Pageable.
* @see org.springframework.data.domain.Pageable
* @see java.lang.reflect.Method#getParameterTypes()
*/
private void assertNonPagingQueryMethod(Method method) {
for (Class type : method.getParameterTypes()) {
if (Pageable.class.isAssignableFrom(type)) {
throw new IllegalStateException(String.format("Pagination is not supported by Pivotal GemFire Repositories;"
+ " Offending method: %1$s", method.getName()));
}
}
}
/**
* Returns the {@link GemfirePersistentEntity} the method deals with.
*
* @return the {@link GemfirePersistentEntity} the method deals with.
*/
public GemfirePersistentEntity getPersistentEntity() {
return this.entity;
}
/**
* Determines whether this query method specifies an annotated, non-empty query.
*
* @return a boolean value indicating whether the query method specifies an annotated, non-empty query.
* @see org.springframework.util.StringUtils#hasText(String)
* @see #getAnnotatedQuery()
*/
public boolean hasAnnotatedQuery() {
return StringUtils.hasText(getAnnotatedQuery());
}
/**
* Returns the annotated query for the query method if present.
*
* @return the annotated query or {@literal null} in case it's empty or not present.
* @see org.springframework.data.gemfire.repository.Query
* @see java.lang.reflect.Method#getAnnotation(Class)
*/
String getAnnotatedQuery() {
Query query = this.method.getAnnotation(Query.class);
String queryString = query != null ? (String) AnnotationUtils.getValue(query) : null;
return StringUtils.hasText(queryString) ? queryString : null;
}
/**
* Determines whether this query method uses a query HINT to tell the Pivotal GemFire OQL query engine which indexes
* to apply to the query execution.
*
* @return a boolean value to indicate whether this query method uses a query HINT.
* @see org.springframework.data.gemfire.repository.query.annotation.Hint
* @see java.lang.reflect.Method#isAnnotationPresent(Class)
*/
public boolean hasHint() {
return this.method.isAnnotationPresent(Hint.class);
}
/**
* Gets the query HINTs for this query method.
*
* @return the query HINTs for this query method or an empty array if this query method has no query HINTs.
* @see org.springframework.data.gemfire.repository.query.annotation.Hint
* @see java.lang.reflect.Method#getAnnotation(Class)
*/
public String[] getHints() {
Hint hint = method.getAnnotation(Hint.class);
return hint != null ? hint.value() : EMPTY_STRING_ARRAY;
}
/**
* Determine whether this query method declares an IMPORT statement to qualify application domain object types
* referenced in the query.
*
* @return a boolean value to indicate whether this query method declares an IMPORT statement.
* @see org.springframework.data.gemfire.repository.query.annotation.Import
* @see java.lang.reflect.Method#isAnnotationPresent(Class)
*/
public boolean hasImport() {
return this.method.isAnnotationPresent(Import.class);
}
/**
* Gets the IMPORT statement for this query method.
*
* @return the IMPORT statement for this query method or null if this query method does not have an IMPORT statement.
* @see org.springframework.data.gemfire.repository.query.annotation.Import
* @see java.lang.reflect.Method#getAnnotation(Class)
*/
public String getImport() {
Import importStatement = method.getAnnotation(Import.class);
return importStatement != null ? importStatement.value() : null;
}
/**
* Determines whether this query method defines a LIMIT on the number of results returned by the query.
*
* @return a boolean value indicating whether this query method defines a LIMIT on the result set
* returned by the query.
* @see org.springframework.data.gemfire.repository.query.annotation.Limit
* @see java.lang.reflect.Method#isAnnotationPresent(Class)
*/
public boolean hasLimit() {
return this.method.isAnnotationPresent(Limit.class);
}
/**
* Gets the LIMIT for this query method on the result set returned by the query.
*
* @return the LIMIT for this query method limiting the number of results returned by the query.
* @see org.springframework.data.gemfire.repository.query.annotation.Limit
* @see java.lang.reflect.Method#getAnnotation(Class)
*/
public int getLimit() {
Limit limit = method.getAnnotation(Limit.class);
return limit != null ? limit.value() : Integer.MAX_VALUE;
}
/**
* Determines whether this query method has TRACE (i.e. logging) enabled.
*
* @return a boolean value to indicate whether this query method has TRACE enabled.
* @see org.springframework.data.gemfire.repository.query.annotation.Limit
* @see java.lang.reflect.Method#isAnnotationPresent(Class)
*/
public boolean hasTrace() {
return this.method.isAnnotationPresent(Trace.class);
}
}