org.springframework.cloud.gcp.data.datastore.repository.support.DatastoreRepositoryFactory Maven / Gradle / Ivy
/*
* Copyright 2017-2018 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.cloud.gcp.data.datastore.repository.support;
import java.util.Optional;
import org.springframework.beans.BeansException;
import org.springframework.cloud.gcp.data.datastore.core.DatastoreOperations;
import org.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreMappingContext;
import org.springframework.cloud.gcp.data.datastore.core.mapping.DatastorePersistentEntity;
import org.springframework.cloud.gcp.data.datastore.core.mapping.DatastorePersistentEntityInformation;
import org.springframework.cloud.gcp.data.datastore.repository.query.DatastoreQueryLookupStrategy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Repository factory for Datastore.
*
* @author Chengyuan Zhao
*
* @since 1.1
*/
public class DatastoreRepositoryFactory extends RepositoryFactorySupport
implements ApplicationContextAware {
private final DatastoreMappingContext datastoreMappingContext;
private final DatastoreOperations datastoreOperations;
private ApplicationContext applicationContext;
/**
* Constructor.
* @param datastoreMappingContext the mapping context used to get mapping metadata for
* entity types.
* @param datastoreOperations the Datastore operations object used by Datastore
* repositories.
*/
DatastoreRepositoryFactory(DatastoreMappingContext datastoreMappingContext,
DatastoreOperations datastoreOperations) {
Assert.notNull(datastoreMappingContext,
"A non-null Datastore mapping context is required.");
Assert.notNull(datastoreOperations,
"A non-null Datastore template object is required.");
this.datastoreMappingContext = datastoreMappingContext;
this.datastoreOperations = datastoreOperations;
}
@Override
@SuppressWarnings("unchecked")
public EntityInformation getEntityInformation(Class domainClass) {
DatastorePersistentEntity entity = this.datastoreMappingContext
.getPersistentEntity(domainClass);
if (entity == null) {
throw new MappingException(
"Could not lookup mapping metadata for domain class: "
+ domainClass.getName());
}
return new DatastorePersistentEntityInformation<>(entity);
}
@Override
protected Object getTargetRepository(RepositoryInformation metadata) {
return getTargetRepositoryViaReflection(metadata, this.datastoreOperations,
metadata.getDomainType());
}
@Override
protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {
return SimpleDatastoreRepository.class;
}
@Override
protected Optional getQueryLookupStrategy(@Nullable Key key,
QueryMethodEvaluationContextProvider evaluationContextProvider) {
return Optional.of(new DatastoreQueryLookupStrategy(this.datastoreMappingContext,
this.datastoreOperations,
delegateContextProvider(evaluationContextProvider)));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
private QueryMethodEvaluationContextProvider delegateContextProvider(
QueryMethodEvaluationContextProvider evaluationContextProvider) {
return new QueryMethodEvaluationContextProvider() {
@Override
public > EvaluationContext getEvaluationContext(
T parameters, Object[] parameterValues) {
StandardEvaluationContext evaluationContext = (StandardEvaluationContext)
evaluationContextProvider
.getEvaluationContext(parameters, parameterValues);
evaluationContext.setRootObject(
DatastoreRepositoryFactory.this.applicationContext);
evaluationContext.addPropertyAccessor(new BeanFactoryAccessor());
evaluationContext.setBeanResolver(new BeanFactoryResolver(
DatastoreRepositoryFactory.this.applicationContext));
return evaluationContext;
}
};
}
}