org.springframework.data.gemfire.repository.cdi.GemfireRepositoryExtension Maven / Gradle / Ivy
/*
* Copyright 2012 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.gemfire.repository.cdi;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.ProcessBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
import org.springframework.data.repository.cdi.CdiRepositoryBean;
import org.springframework.data.repository.cdi.CdiRepositoryExtensionSupport;
import com.gemstone.gemfire.cache.Region;
/**
* The GemfireRepositoryExtension class...
*
* @author John Blum
* @see org.springframework.data.repository.cdi.CdiRepositoryExtensionSupport
* @since 1.8.0
*/
@SuppressWarnings("unused")
public class GemfireRepositoryExtension extends CdiRepositoryExtensionSupport {
protected final Logger logger = LoggerFactory.getLogger(getClass());
final Map, Bean> mappingContexts =
new HashMap, Bean>();
final Set> regionBeans = new HashSet>();
/* (non-Javadoc) */
public GemfireRepositoryExtension() {
logger.info("Activating CDI extension for Spring Data GemFire Repositories");
}
/**
* Implementation of an observer that captures GemFire Region beans defined in the CDI container, storing them
* along with any defined GemfireMappingContexts for later construction of the Repository beans.
*
* @param class type of the bean instance.
* @param processBean annotated type as defined by CDI.
* @see javax.enterprise.inject.spi.ProcessBean
* @see javax.enterprise.event.Observes
*/
@SuppressWarnings("unchecked")
void processBean(@Observes ProcessBean processBean) {
Bean bean = processBean.getBean();
for (Type type : bean.getTypes()) {
Type resolvedType = (type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type);
if (resolvedType instanceof Class) {
Class classType = (Class) resolvedType;
if (Region.class.isAssignableFrom(classType)) {
logger.debug("Found Region bean with name {}", bean.getName());
regionBeans.add((Bean) bean);
}
else if (GemfireMappingContext.class.isAssignableFrom(classType)) {
logger.debug("Discovered {} bean with types {} having qualifiers {}",
GemfireMappingContext.class.getName(), bean.getTypes(), bean.getQualifiers());
mappingContexts.put(bean.getQualifiers(), (Bean) bean);
}
}
}
}
/**
* Implementation of an observer that registers beans in the CDI container for the detected Spring Data
* Repositories.
*
* Repository beans are associated to the appropriate GemfireMappingContexts based on their qualifiers.
*
* @param beanManager the BeanManager instance.
* @see javax.enterprise.inject.spi.AfterBeanDiscovery
* @see javax.enterprise.inject.spi.BeanManager
* @see javax.enterprise.event.Observes
*/
void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
for (Map.Entry, Set> entry : getRepositoryTypes()) {
Class repositoryType = entry.getKey();
Set qualifiers = entry.getValue();
// Create the bean representing the Repository.
CdiRepositoryBean repositoryBean = createRepositoryBean(beanManager, repositoryType, qualifiers);
logger.info("Registering bean for '{}' with qualifiers {}.", repositoryType.getName(), qualifiers);
// Register the bean with the extension and the container.
registerBean(repositoryBean);
afterBeanDiscovery.addBean(repositoryBean);
}
}
/* (non-Javadoc) */
CdiRepositoryBean createRepositoryBean(BeanManager beanManager, Class repositoryType,
Set qualifiers) {
// Determine the GemfireMappingContext bean that matches the qualifiers of the Repository.
Bean gemfireMappingContextBean = mappingContexts.get(qualifiers);
// Construct and return a GemFire Repository bean.
return new GemfireRepositoryBean(beanManager, repositoryType, qualifiers, getCustomImplementationDetector(),
gemfireMappingContextBean, regionBeans);
}
}