DATAJPA-564 - Extracted SPI into Spring Data Commons.
This commit is contained in:
@@ -131,6 +131,4 @@ public @interface EnableJpaRepositories {
|
||||
* repositories infrastructure.
|
||||
*/
|
||||
boolean considerNestedRepositories() default false;
|
||||
|
||||
String expressionEvaluationContextProviderRef() default "expressionEvaluationContextProvider";
|
||||
}
|
||||
|
||||
@@ -36,13 +36,11 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext;
|
||||
import org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor;
|
||||
import org.springframework.data.jpa.repository.support.ExtensibleEvaluationContextProvider;
|
||||
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationSource;
|
||||
import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* JPA specific configuration extension parsing custom attributes from the XML namespace and
|
||||
@@ -59,8 +57,6 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensionSupport {
|
||||
|
||||
private static final String EXPRESSION_EVALUATION_CONTEXT_PROVIDER = "expressionEvaluationContextProvider";
|
||||
|
||||
public static final String JPA_MAPPING_CONTEXT_BEAN_NAME = "jpaMapppingContext";
|
||||
|
||||
private static final Class<?> PAB_POST_PROCESSOR = PersistenceAnnotationBeanPostProcessor.class;
|
||||
@@ -101,11 +97,6 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi
|
||||
}
|
||||
|
||||
builder.addPropertyReference("mappingContext", JPA_MAPPING_CONTEXT_BEAN_NAME);
|
||||
|
||||
String expressionEvaluationContextProviderRef = source.getAttribute("expressionEvaluationContextProviderRef");
|
||||
if (StringUtils.hasText(expressionEvaluationContextProviderRef)) {
|
||||
builder.addPropertyReference(EXPRESSION_EVALUATION_CONTEXT_PROVIDER, expressionEvaluationContextProviderRef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,11 +159,6 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi
|
||||
|
||||
registerWithSourceAndGeneratedBeanName(registry, new RootBeanDefinition(PAB_POST_PROCESSOR), source);
|
||||
}
|
||||
|
||||
if (!registry.containsBeanDefinition(EXPRESSION_EVALUATION_CONTEXT_PROVIDER)) {
|
||||
registry.registerBeanDefinition(EXPRESSION_EVALUATION_CONTEXT_PROVIDER,
|
||||
BeanDefinitionBuilder.rootBeanDefinition(ExtensibleEvaluationContextProvider.class).getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@ import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository.query;
|
||||
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
@@ -92,7 +93,7 @@ class ExpressionAwareParameterBinder extends ParameterBinder {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected StandardEvaluationContext getEvaluationContext() {
|
||||
return evaluationContextProvider.getEvaluationContext(getValues(), getParameters());
|
||||
protected EvaluationContext getEvaluationContext() {
|
||||
return evaluationContextProvider.getEvaluationContext(getParameters(), getValues());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.persistence.EntityManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ import java.lang.reflect.Method;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.jpa.repository.query;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.jpa.repository.query;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.jpa.repository.query;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding;
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.persistence.Query;
|
||||
import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.LikeParameterBinding;
|
||||
import org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding;
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A base class for {@link EvaluationContextExtension}s.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class DefaultEvaluationContextExtension implements EvaluationContextExtension {
|
||||
|
||||
@Override
|
||||
public String getScope() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getProperties() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getVariables() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Method> getFunctions() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
|
||||
/**
|
||||
* A SPI that allows a user to add a set of properties and function definitions accessible via the root of an
|
||||
* {@link EvaluationContext} provided by a {@link ExtensibleEvaluationContextProvider}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface EvaluationContextExtension {
|
||||
|
||||
/**
|
||||
* @return the scope
|
||||
*/
|
||||
String getScope();
|
||||
|
||||
/**
|
||||
* @return the properties
|
||||
*/
|
||||
Map<String, Object> getProperties();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> getVariables();
|
||||
|
||||
/**
|
||||
* @return the functions
|
||||
*/
|
||||
Map<String, Method> getFunctions();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.support;
|
||||
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Provides a way to access a centrally defined potentially shared {@link StandardEvaluationContext}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface EvaluationContextProvider {
|
||||
|
||||
/**
|
||||
* Returns a potentially new {@link StandardEvaluationContext}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
StandardEvaluationContext getEvaluationContext(Object[] parameterValues, Iterable<? extends Parameter> parameters);
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.MethodExecutor;
|
||||
import org.springframework.expression.MethodResolver;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.expression.spel.SpelMessage;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.TypeUtils;
|
||||
|
||||
/**
|
||||
* A {@link EvaluationContextProvider} that assembles an {@link EvaluationContext} from a set of
|
||||
* {@link EvaluationContextExtension} beans that are defined in the application context.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.7
|
||||
*/
|
||||
public class ExtensibleEvaluationContextProvider implements EvaluationContextProvider, ApplicationContextAware {
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExtensibleEvaluationContextProvider}.
|
||||
*/
|
||||
public ExtensibleEvaluationContextProvider() {}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.repository.support.EvaluationContextProvider#getEvaluationContext()
|
||||
*/
|
||||
@Override
|
||||
public StandardEvaluationContext getEvaluationContext(Object[] parameterValues,
|
||||
Iterable<? extends Parameter> parameters) {
|
||||
|
||||
StandardEvaluationContext ec = new StandardEvaluationContext();
|
||||
ec.setBeanResolver(new BeanFactoryResolver(beanFactory));
|
||||
|
||||
List<EvaluationContextExtension> extensions = new ArrayList<EvaluationContextExtension>(beanFactory.getBeansOfType(
|
||||
EvaluationContextExtension.class).values());
|
||||
|
||||
if (extensions.isEmpty()) {
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec.setPropertyAccessors(new ArrayList<PropertyAccessor>());
|
||||
ec.setMethodResolvers(new ArrayList<MethodResolver>());
|
||||
|
||||
new EvaluationContextExtensionMerger(extensions).copyInto(ec);
|
||||
|
||||
ec.getPropertyAccessors().add(new ReflectivePropertyAccessor());
|
||||
|
||||
ec.setRootObject(parameterValues);
|
||||
|
||||
for (Parameter param : parameters) {
|
||||
if (param.isNamedParameter()) {
|
||||
ec.setVariable(param.getName(), parameterValues[param.getIndex()]);
|
||||
}
|
||||
}
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
static class EvaluationContextExtensionMerger extends ReadOnlyPropertyAccessor implements MethodResolver {
|
||||
|
||||
private final Map<String, Object> properties;
|
||||
private final Map<String, Object> variables;
|
||||
private final Map<String, Object> functions;
|
||||
|
||||
public EvaluationContextExtensionMerger(List<EvaluationContextExtension> extensions) {
|
||||
|
||||
Map<String, Object> properties = new HashMap<String, Object>();
|
||||
Map<String, Object> variables = new HashMap<String, Object>();
|
||||
Map<String, Object> functions = new HashMap<String, Object>();
|
||||
|
||||
for (EvaluationContextExtension ext : extensions) {
|
||||
|
||||
if (ext.getScope() != null) {
|
||||
properties.put(ext.getScope(), ext.getProperties());
|
||||
variables.put(ext.getScope(), ext.getVariables());
|
||||
functions.put(ext.getScope(), ext.getFunctions());
|
||||
}
|
||||
|
||||
properties.putAll(ext.getProperties());
|
||||
variables.putAll(ext.getVariables());
|
||||
functions.putAll(ext.getFunctions());
|
||||
}
|
||||
|
||||
this.properties = properties;
|
||||
this.variables = variables;
|
||||
this.functions = functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the collected information form the {@link EvaluationContextExtension}s into the given
|
||||
* {@link StandardEvaluationContext}.
|
||||
*
|
||||
* @param ec
|
||||
*/
|
||||
public void copyInto(StandardEvaluationContext ec) {
|
||||
|
||||
ec.getPropertyAccessors().add(this);
|
||||
ec.getMethodResolvers().add(this);
|
||||
ec.setVariables(variables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
|
||||
if (target instanceof Map) {
|
||||
return ((Map) target).containsKey(name);
|
||||
}
|
||||
|
||||
return properties.containsKey(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
|
||||
Object value = null;
|
||||
|
||||
if (target instanceof Map) {
|
||||
value = ((Map) target).get(name);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
value = properties.get(name);
|
||||
}
|
||||
|
||||
return new TypedValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
|
||||
List<TypeDescriptor> argumentTypes) throws AccessException {
|
||||
|
||||
final Method function = targetObject instanceof Map && ((Map) targetObject).containsKey(name) ? (Method) ((Map) targetObject)
|
||||
.get(name) : (Method) functions.get(name);
|
||||
|
||||
Class<?>[] parameterTypes = function.getParameterTypes();
|
||||
if (parameterTypes.length != argumentTypes.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (!TypeUtils.isAssignable(parameterTypes[i], argumentTypes.get(i).getType())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new MethodExecutor() {
|
||||
|
||||
@Override
|
||||
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
|
||||
try {
|
||||
return new TypedValue(function.invoke(null, arguments));
|
||||
} catch (Exception e) {
|
||||
throw new SpelEvaluationException(e, SpelMessage.FUNCTION_REFERENCE_CANNOT_BE_INVOKED, function.getName(),
|
||||
function.getDeclaringClass());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
static abstract class ReadOnlyPropertyAccessor implements PropertyAccessor {
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean canRead(EvaluationContext context, Object target, String name) throws AccessException;
|
||||
|
||||
@Override
|
||||
public abstract TypedValue read(EvaluationContext context, Object target, String name) throws AccessException;
|
||||
|
||||
@Override
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.beanFactory = applicationContext;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.jpa.repository.query.QueryExtractor;
|
||||
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -41,7 +42,6 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
private final EntityManager entityManager;
|
||||
private final QueryExtractor extractor;
|
||||
private final CrudMethodMetadataPostProcessor lockModePostProcessor;
|
||||
private final EvaluationContextProvider evaluationContextProvider;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaRepositoryFactory}.
|
||||
@@ -49,23 +49,12 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
* @param entityManager must not be {@literal null}
|
||||
*/
|
||||
public JpaRepositoryFactory(EntityManager entityManager) {
|
||||
this(entityManager, StandardEvaluationContextProvider.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaRepositoryFactory}.
|
||||
*
|
||||
* @param entityManager must not be {@literal null}
|
||||
* @param evaluationContextProvider must not be {@literal null}
|
||||
*/
|
||||
public JpaRepositoryFactory(EntityManager entityManager, EvaluationContextProvider evaluationContextProvider) {
|
||||
|
||||
Assert.notNull(entityManager);
|
||||
|
||||
this.entityManager = entityManager;
|
||||
this.extractor = PersistenceProvider.fromEntityManager(entityManager);
|
||||
this.lockModePostProcessor = CrudMethodMetadataPostProcessor.INSTANCE;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
|
||||
addRepositoryProxyPostProcessor(lockModePostProcessor);
|
||||
}
|
||||
@@ -133,17 +122,12 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport#
|
||||
* getQueryLookupStrategy
|
||||
* (org.springframework.data.repository.query.QueryLookupStrategy.Key)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
|
||||
*/
|
||||
@Override
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(Key key) {
|
||||
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) {
|
||||
return JpaQueryLookupStrategy.create(entityManager, key, extractor, evaluationContextProvider);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
private EvaluationContextProvider expressionEvaluationContextProvider = StandardEvaluationContextProvider.INSTANCE;
|
||||
|
||||
/**
|
||||
* The {@link EntityManager} to be used.
|
||||
*
|
||||
@@ -60,13 +58,6 @@ public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends
|
||||
super.setMappingContext(mappingContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param evaluationContextProvider the {@link EvaluationContextProvider} to set
|
||||
*/
|
||||
public void setExpressionEvaluationContextProvider(EvaluationContextProvider evaluationContextProvider) {
|
||||
this.expressionEvaluationContextProvider = evaluationContextProvider;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -85,7 +76,7 @@ public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends
|
||||
* @return
|
||||
*/
|
||||
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
|
||||
return new JpaRepositoryFactory(entityManager, expressionEvaluationContextProvider);
|
||||
return new JpaRepositoryFactory(entityManager);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.support;
|
||||
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link EvaluationContextProvider} that always creates a new {@link EvaluationContext}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public enum StandardEvaluationContextProvider implements EvaluationContextProvider {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public StandardEvaluationContext getEvaluationContext(Object[] parameterValues,
|
||||
Iterable<? extends Parameter> parameters) {
|
||||
return new StandardEvaluationContext();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.jpa.repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
@@ -34,13 +35,14 @@ import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.jpa.repository.sample.SampleEvaluationContextExtension;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepositoryImpl;
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextExtension;
|
||||
import org.springframework.data.jpa.repository.support.ExtensibleEvaluationContextProvider;
|
||||
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
|
||||
import org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
@@ -58,7 +60,8 @@ public class JavaConfigUserRepositoryTests extends UserRepositoryTests {
|
||||
static class Config {
|
||||
|
||||
@PersistenceContext EntityManager entityManager;
|
||||
@Autowired BeanFactory beanFactory;
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
@Autowired List<EvaluationContextExtension> extensions;
|
||||
|
||||
@Bean
|
||||
public EvaluationContextExtension sampleEvaluationContextExtension() {
|
||||
@@ -68,16 +71,17 @@ public class JavaConfigUserRepositoryTests extends UserRepositoryTests {
|
||||
@Bean
|
||||
public UserRepository userRepository() throws Exception {
|
||||
|
||||
ExtensibleEvaluationContextProvider evaluationContextProvider = new ExtensibleEvaluationContextProvider();
|
||||
evaluationContextProvider.setApplicationContext((ApplicationContext) beanFactory);
|
||||
ExtensionAwareEvaluationContextProvider evaluationContextProvider = new ExtensionAwareEvaluationContextProvider(
|
||||
extensions);
|
||||
evaluationContextProvider.setApplicationContext(applicationContext);
|
||||
|
||||
JpaRepositoryFactoryBean<UserRepository, User, Integer> factory = new JpaRepositoryFactoryBean<UserRepository, User, Integer>();
|
||||
factory.setEntityManager(entityManager);
|
||||
factory.setBeanFactory(beanFactory);
|
||||
factory.setBeanFactory(applicationContext);
|
||||
factory.setRepositoryInterface(UserRepository.class);
|
||||
factory.setCustomImplementation(new UserRepositoryImpl());
|
||||
factory.setNamedQueries(namedQueries());
|
||||
factory.setExpressionEvaluationContextProvider(evaluationContextProvider);
|
||||
factory.setEvaluationContextProvider(evaluationContextProvider);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
return factory.getObject();
|
||||
|
||||
@@ -58,8 +58,8 @@ import org.springframework.data.jpa.domain.sample.Address;
|
||||
import org.springframework.data.jpa.domain.sample.Role;
|
||||
import org.springframework.data.jpa.domain.sample.SpecialUser;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.SampleSecurity.SampleSecurityContextHolder;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.jpa.repository.sample.SampleSecurity.SampleSecurityContextHolder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -36,12 +36,12 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.support.StandardEvaluationContextProvider;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.DefaultEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ public class JpaQueryLookupStrategyUnitTests {
|
||||
public void invalidAnnotatedQueryCausesException() throws Exception {
|
||||
|
||||
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor,
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
Method method = UserRepository.class.getMethod("findByFoo", String.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
|
||||
|
||||
@@ -96,7 +96,7 @@ public class JpaQueryLookupStrategyUnitTests {
|
||||
public void sholdThrowMorePreciseExceptionIfTryingToUsePaginationInNativeQueries() throws Exception {
|
||||
|
||||
QueryLookupStrategy strategy = JpaQueryLookupStrategy.create(em, Key.CREATE_IF_NOT_FOUND, extractor,
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
Method method = UserRepository.class.getMethod("findByInvalidNativeQuery", String.class, Pageable.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class);
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.jpa.repository.support.DefaultJpaEntityMetadata;
|
||||
import org.springframework.data.jpa.repository.support.JpaEntityMetadata;
|
||||
import org.springframework.data.jpa.repository.support.StandardEvaluationContextProvider;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.DefaultEvaluationContextProvider;
|
||||
|
||||
/**
|
||||
* Unit test for {@link SimpleJpaQuery}.
|
||||
@@ -97,7 +97,7 @@ public class SimpleJpaQueryUnitTests {
|
||||
when(em.createQuery("foo", Long.class)).thenReturn(query);
|
||||
|
||||
SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "select u from User u",
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
|
||||
assertThat(jpaQuery.createCountQuery(new Object[] {}), is(query));
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public class SimpleJpaQueryUnitTests {
|
||||
JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor);
|
||||
|
||||
AbstractJpaQuery jpaQuery = new SimpleJpaQuery(queryMethod, em, "select u from User u",
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
jpaQuery.createCountQuery(new Object[] { new PageRequest(1, 10) });
|
||||
|
||||
verify(query, times(0)).setFirstResult(anyInt());
|
||||
@@ -128,7 +128,7 @@ public class SimpleJpaQueryUnitTests {
|
||||
Method method = SampleRepository.class.getMethod("findNativeByLastname", String.class);
|
||||
JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor);
|
||||
AbstractJpaQuery jpaQuery = JpaQueryFactory.INSTANCE.fromQueryAnnotation(queryMethod, em,
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
|
||||
assertThat(jpaQuery instanceof NativeJpaQuery, is(true));
|
||||
|
||||
@@ -210,7 +210,7 @@ public class SimpleJpaQueryUnitTests {
|
||||
|
||||
JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor);
|
||||
return JpaQueryFactory.INSTANCE.fromQueryAnnotation(queryMethod, em,
|
||||
StandardEvaluationContextProvider.INSTANCE);
|
||||
DefaultEvaluationContextProvider.INSTANCE);
|
||||
}
|
||||
|
||||
interface SampleRepository {
|
||||
|
||||
@@ -13,24 +13,24 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.jpa.repository;
|
||||
package org.springframework.data.jpa.repository.sample;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.jpa.repository.SampleSecurity.SampleSecurityContextHolder;
|
||||
import org.springframework.data.jpa.repository.support.DefaultEvaluationContextExtension;
|
||||
import org.springframework.data.jpa.repository.support.EvaluationContextExtension;
|
||||
import org.springframework.data.jpa.repository.sample.SampleSecurity.SampleSecurityContextHolder;
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport;
|
||||
|
||||
/**
|
||||
* A sample implementation of a custom {@link EvaluationContextExtension}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class SampleEvaluationContextExtension extends DefaultEvaluationContextExtension {
|
||||
public class SampleEvaluationContextExtension extends EvaluationContextExtensionSupport {
|
||||
|
||||
@Override
|
||||
public String getScope() {
|
||||
public String getExtensionId() {
|
||||
return "security";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.jpa.repository;
|
||||
package org.springframework.data.jpa.repository.sample;
|
||||
|
||||
/**
|
||||
* Minimalistic thread-scoped security context analogous to Spring Security for testing.
|
||||
@@ -56,7 +56,7 @@ public class JpaRepositoryFactoryUnitTests {
|
||||
public void setUp() {
|
||||
|
||||
// Setup standard factory configuration
|
||||
factory = new JpaRepositoryFactory(entityManager, StandardEvaluationContextProvider.INSTANCE) {
|
||||
factory = new JpaRepositoryFactory(entityManager) {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
</bean>
|
||||
</property>
|
||||
|
||||
<property name="expressionEvaluationContextProvider" ref="expressionEvaluationContextProvider"/>
|
||||
<property name="evaluationContextProvider" ref="expressionEvaluationContextProvider"/>
|
||||
</bean>
|
||||
|
||||
<bean id="roleDao" class="org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean">
|
||||
<property name="repositoryInterface" value="org.springframework.data.jpa.repository.sample.RoleRepository" />
|
||||
<property name="expressionEvaluationContextProvider" ref="expressionEvaluationContextProvider"/>
|
||||
<property name="evaluationContextProvider" ref="expressionEvaluationContextProvider"/>
|
||||
</bean>
|
||||
|
||||
<!-- Necessary to get the entity manager injected into the factory bean -->
|
||||
@@ -38,5 +38,7 @@
|
||||
|
||||
<!-- Adds dependency checks for setters annotated with @Required -->
|
||||
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
|
||||
|
||||
<bean id="expressionEvaluationContextProvider" class="org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean name="expressionEvaluationContextProvider" class="org.springframework.data.jpa.repository.support.ExtensibleEvaluationContextProvider"/>
|
||||
<bean name="sampleEvaluationContextExtension" class="org.springframework.data.jpa.repository.SampleEvaluationContextExtension"/>
|
||||
</bean>
|
||||
|
||||
<bean name="sampleEvaluationContextExtension" class="org.springframework.data.jpa.repository.sample.SampleEvaluationContextExtension"/>
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL">
|
||||
<jdbc:script execution="INIT" separator="/;" location="classpath:scripts/schema-stored-procedures.sql"/>
|
||||
|
||||
Reference in New Issue
Block a user