All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.data.gemfire.repository.cdi.GemfireRepositoryBean Maven / Gradle / Ivy

There is a newer version: 2.3.9.RELEASE
Show newest version
/*
 * 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.HashSet;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

import org.springframework.data.gemfire.mapping.GemfireMappingContext;
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory;
import org.springframework.data.repository.cdi.CdiRepositoryBean;
import org.springframework.data.repository.config.CustomRepositoryImplementationDetector;

import com.gemstone.gemfire.cache.Region;

/**
 * A CDI-based bean that represents a GemFire Repository.
 *
 * @author John Blum
 * @param  class type of the Repository.
 * @see javax.enterprise.context.spi.CreationalContext
 * @see javax.enterprise.inject.spi.Bean
 * @see javax.enterprise.inject.spi.BeanManager
 * @see org.springframework.data.gemfire.mapping.GemfireMappingContext
 * @see org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory
 * @see org.springframework.data.repository.cdi.CdiRepositoryBean
 * @see org.springframework.data.repository.config.CustomRepositoryImplementationDetector
 * @see com.gemstone.gemfire.cache.Region
 * @since 1.8.0
 */
class GemfireRepositoryBean extends CdiRepositoryBean {

	static final GemfireMappingContext DEFAULT_GEMFIRE_MAPPING_CONTEXT = new GemfireMappingContext();

	private final Bean gemfireMappingContextBean;

	private final BeanManager beanManager;

	private final Set> regionBeans;

	/* (non-Javadoc) */
	@SuppressWarnings("unchecked")
	GemfireRepositoryBean(BeanManager beanManager, Class repositoryType, Set qualifiers,
			CustomRepositoryImplementationDetector detector, Bean gemfireMappingContextBean,
			Set> regionBeans) {

		super(qualifiers, repositoryType, beanManager, detector);

		this.beanManager = beanManager;
		this.gemfireMappingContextBean = gemfireMappingContextBean;
		this.regionBeans = regionBeans;
	}

	/**
	 * Returns an instance of the given {@link Bean} from the container.
	 *
	 * @param  the actual class type of the {@link Bean}.
	 * @param bean the {@link Bean} defining the instance to create.
	 * @param type the expected component type of the instance created from the {@link Bean}.
	 * @return an instance of the given {@link Bean}.
	 * @see javax.enterprise.inject.spi.BeanManager#getReference(Bean, Type, CreationalContext)
	 * @see javax.enterprise.inject.spi.Bean
	 * @see java.lang.reflect.Type
	 */
	@SuppressWarnings("unchecked")
	protected  S getDependencyInstance(Bean bean, Type type) {
		return (S) beanManager.getReference(bean, type, beanManager.createCreationalContext(bean));
	}

	/**
	 * Resolves the desired, actual component type from the {@link Bean} in which the instance is created.
	 *
	 * @param  the class type of the component.
	 * @param bean the {@link Bean} from which the types are evaluated and an instance is created.
	 * @param targetType the desired class type of the component.
	 * @return a resolved component {@link Type} of the {@link Bean}instance.
	 * @throws IllegalStateException if the desired class type cannot be resolved.
	 * @see javax.enterprise.inject.spi.Bean#getTypes()
	 * @see java.lang.Class
	 */
	@SuppressWarnings("unchecked")
	protected  Type resolveType(Bean bean, Class targetType) {
		for (Type type : bean.getTypes()) {
			Type assignableType = (type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type);

			if (assignableType instanceof Class && targetType.isAssignableFrom((Class) assignableType)) {
				return type;
			}
		}

		throw new IllegalStateException(String.format(
			"unable to resolve bean instance of type [%1$s] from bean definition [%2$s]",
				targetType, bean));
	}

	/* (non-Javadoc) */
	Iterable> resolveGemfireRegions() {
		Set> regions = new HashSet>(regionBeans.size());

		for (Bean regionBean : regionBeans) {
			regions.add(getDependencyInstance(regionBean, resolveType(regionBean, Region.class)));
		}

		return regions;
	}

	/* (non-Javadoc) */
	GemfireMappingContext resolveGemfireMappingContext() {
		return (gemfireMappingContextBean != null
			? getDependencyInstance(gemfireMappingContextBean, GemfireMappingContext.class)
				: DEFAULT_GEMFIRE_MAPPING_CONTEXT);
	}

	/* (non-Javadoc) */
	GemfireRepositoryFactory newGemfireRepositoryFactory() {
		return new GemfireRepositoryFactory(resolveGemfireRegions(), resolveGemfireMappingContext());
	}

	/**
	 * Creates an instance of the given Repository type as a bean instance in the CDI container.
	 *
	 * @param creationalContext operations used by the {@link javax.enterprise.context.spi.Contextual} implementation
	 * during creation of the bean instance.
	 * @param repositoryType the actual class type of the SD (GemFire) Repository.
	 * @param customImplementation the supporting custom Repository implementing class.
	 * @return a factory used to create instance of {@link org.springframework.data.gemfire.repository.GemfireRepository}.
	 * @see javax.enterprise.context.spi.Contextual#create(javax.enterprise.context.spi.CreationalContext)
	 * @see #newGemfireRepositoryFactory()
	 */
	@Override
	protected T create(CreationalContext creationalContext, Class repositoryType, Object customImplementation) {
		return newGemfireRepositoryFactory().getRepository(repositoryType, customImplementation);
	}

}