001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.autoconfigure.data;
018
019import java.lang.annotation.Annotation;
020
021import org.springframework.beans.BeansException;
022import org.springframework.beans.factory.BeanFactory;
023import org.springframework.beans.factory.BeanFactoryAware;
024import org.springframework.beans.factory.support.BeanDefinitionRegistry;
025import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
026import org.springframework.context.EnvironmentAware;
027import org.springframework.context.ResourceLoaderAware;
028import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
029import org.springframework.core.env.Environment;
030import org.springframework.core.io.ResourceLoader;
031import org.springframework.core.type.AnnotationMetadata;
032import org.springframework.core.type.StandardAnnotationMetadata;
033import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
034import org.springframework.data.repository.config.BootstrapMode;
035import org.springframework.data.repository.config.RepositoryConfigurationDelegate;
036import org.springframework.data.repository.config.RepositoryConfigurationExtension;
037import org.springframework.data.util.Streamable;
038
039/**
040 * Base {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data
041 * Repositories.
042 *
043 * @author Phillip Webb
044 * @author Dave Syer
045 * @author Oliver Gierke
046 */
047public abstract class AbstractRepositoryConfigurationSourceSupport
048                implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware,
049                EnvironmentAware {
050
051        private ResourceLoader resourceLoader;
052
053        private BeanFactory beanFactory;
054
055        private Environment environment;
056
057        @Override
058        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
059                        BeanDefinitionRegistry registry) {
060                new RepositoryConfigurationDelegate(getConfigurationSource(registry),
061                                this.resourceLoader, this.environment).registerRepositoriesIn(registry,
062                                                getRepositoryConfigurationExtension());
063        }
064
065        private AnnotationRepositoryConfigurationSource getConfigurationSource(
066                        BeanDefinitionRegistry beanDefinitionRegistry) {
067                StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(
068                                getConfiguration(), true);
069                return new AnnotationRepositoryConfigurationSource(metadata, getAnnotation(),
070                                this.resourceLoader, this.environment, beanDefinitionRegistry) {
071                        @Override
072                        public Streamable<String> getBasePackages() {
073                                return AbstractRepositoryConfigurationSourceSupport.this
074                                                .getBasePackages();
075                        }
076
077                        @Override
078                        public BootstrapMode getBootstrapMode() {
079                                return AbstractRepositoryConfigurationSourceSupport.this
080                                                .getBootstrapMode();
081                        }
082
083                };
084        }
085
086        protected Streamable<String> getBasePackages() {
087                return Streamable.of(AutoConfigurationPackages.get(this.beanFactory));
088        }
089
090        /**
091         * The Spring Data annotation used to enable the particular repository support.
092         * @return the annotation class
093         */
094        protected abstract Class<? extends Annotation> getAnnotation();
095
096        /**
097         * The configuration class that will be used by Spring Boot as a template.
098         * @return the configuration class
099         */
100        protected abstract Class<?> getConfiguration();
101
102        /**
103         * The {@link RepositoryConfigurationExtension} for the particular repository support.
104         * @return the repository configuration extension
105         */
106        protected abstract RepositoryConfigurationExtension getRepositoryConfigurationExtension();
107
108        /**
109         * The {@link BootstrapMode} for the particular repository support. Defaults to
110         * {@link BootstrapMode#DEFAULT}.
111         * @return the bootstrap mode
112         */
113        protected BootstrapMode getBootstrapMode() {
114                return BootstrapMode.DEFAULT;
115        }
116
117        @Override
118        public void setResourceLoader(ResourceLoader resourceLoader) {
119                this.resourceLoader = resourceLoader;
120        }
121
122        @Override
123        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
124                this.beanFactory = beanFactory;
125        }
126
127        @Override
128        public void setEnvironment(Environment environment) {
129                this.environment = environment;
130        }
131
132}