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.jooq;
018
019import javax.sql.DataSource;
020
021import org.jooq.ConnectionProvider;
022import org.jooq.DSLContext;
023import org.jooq.ExecuteListenerProvider;
024import org.jooq.ExecutorProvider;
025import org.jooq.RecordListenerProvider;
026import org.jooq.RecordMapperProvider;
027import org.jooq.RecordUnmapperProvider;
028import org.jooq.TransactionListenerProvider;
029import org.jooq.TransactionProvider;
030import org.jooq.VisitListenerProvider;
031import org.jooq.conf.Settings;
032import org.jooq.impl.DataSourceConnectionProvider;
033import org.jooq.impl.DefaultConfiguration;
034import org.jooq.impl.DefaultDSLContext;
035import org.jooq.impl.DefaultExecuteListenerProvider;
036
037import org.springframework.beans.factory.ObjectProvider;
038import org.springframework.boot.autoconfigure.AutoConfigureAfter;
039import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
040import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
041import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
042import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
043import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
044import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
045import org.springframework.boot.context.properties.EnableConfigurationProperties;
046import org.springframework.context.annotation.Bean;
047import org.springframework.context.annotation.Configuration;
048import org.springframework.core.annotation.Order;
049import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
050import org.springframework.transaction.PlatformTransactionManager;
051
052/**
053 * {@link EnableAutoConfiguration Auto-configuration} for JOOQ.
054 *
055 * @author Andreas Ahlenstorf
056 * @author Michael Simons
057 * @author Dmytro Nosan
058 * @since 1.3.0
059 */
060@Configuration
061@ConditionalOnClass(DSLContext.class)
062@ConditionalOnBean(DataSource.class)
063@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
064                TransactionAutoConfiguration.class })
065public class JooqAutoConfiguration {
066
067        @Bean
068        @ConditionalOnMissingBean
069        public DataSourceConnectionProvider dataSourceConnectionProvider(
070                        DataSource dataSource) {
071                return new DataSourceConnectionProvider(
072                                new TransactionAwareDataSourceProxy(dataSource));
073        }
074
075        @Bean
076        @ConditionalOnBean(PlatformTransactionManager.class)
077        public SpringTransactionProvider transactionProvider(
078                        PlatformTransactionManager txManager) {
079                return new SpringTransactionProvider(txManager);
080        }
081
082        @Bean
083        @Order(0)
084        public DefaultExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() {
085                return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
086        }
087
088        @Configuration
089        @ConditionalOnMissingBean(DSLContext.class)
090        @EnableConfigurationProperties(JooqProperties.class)
091        public static class DslContextConfiguration {
092
093                private final JooqProperties properties;
094
095                private final ConnectionProvider connection;
096
097                private final DataSource dataSource;
098
099                private final TransactionProvider transactionProvider;
100
101                private final RecordMapperProvider recordMapperProvider;
102
103                private final RecordUnmapperProvider recordUnmapperProvider;
104
105                private final Settings settings;
106
107                private final RecordListenerProvider[] recordListenerProviders;
108
109                private final ExecuteListenerProvider[] executeListenerProviders;
110
111                private final VisitListenerProvider[] visitListenerProviders;
112
113                private final TransactionListenerProvider[] transactionListenerProviders;
114
115                private final ExecutorProvider executorProvider;
116
117                public DslContextConfiguration(JooqProperties properties,
118                                ConnectionProvider connectionProvider, DataSource dataSource,
119                                ObjectProvider<TransactionProvider> transactionProvider,
120                                ObjectProvider<RecordMapperProvider> recordMapperProvider,
121                                ObjectProvider<RecordUnmapperProvider> recordUnmapperProvider,
122                                ObjectProvider<Settings> settings,
123                                ObjectProvider<RecordListenerProvider[]> recordListenerProviders,
124                                ExecuteListenerProvider[] executeListenerProviders,
125                                ObjectProvider<VisitListenerProvider[]> visitListenerProviders,
126                                ObjectProvider<TransactionListenerProvider[]> transactionListenerProviders,
127                                ObjectProvider<ExecutorProvider> executorProvider) {
128                        this.properties = properties;
129                        this.connection = connectionProvider;
130                        this.dataSource = dataSource;
131                        this.transactionProvider = transactionProvider.getIfAvailable();
132                        this.recordMapperProvider = recordMapperProvider.getIfAvailable();
133                        this.recordUnmapperProvider = recordUnmapperProvider.getIfAvailable();
134                        this.settings = settings.getIfAvailable();
135                        this.recordListenerProviders = recordListenerProviders.getIfAvailable();
136                        this.executeListenerProviders = executeListenerProviders;
137                        this.visitListenerProviders = visitListenerProviders.getIfAvailable();
138                        this.transactionListenerProviders = transactionListenerProviders
139                                        .getIfAvailable();
140                        this.executorProvider = executorProvider.getIfAvailable();
141                }
142
143                @Bean
144                public DefaultDSLContext dslContext(org.jooq.Configuration configuration) {
145                        return new DefaultDSLContext(configuration);
146                }
147
148                @Bean
149                @ConditionalOnMissingBean(org.jooq.Configuration.class)
150                public DefaultConfiguration jooqConfiguration() {
151                        DefaultConfiguration configuration = new DefaultConfiguration();
152                        configuration.set(this.properties.determineSqlDialect(this.dataSource));
153                        configuration.set(this.connection);
154                        if (this.transactionProvider != null) {
155                                configuration.set(this.transactionProvider);
156                        }
157                        if (this.recordMapperProvider != null) {
158                                configuration.set(this.recordMapperProvider);
159                        }
160                        if (this.recordUnmapperProvider != null) {
161                                configuration.set(this.recordUnmapperProvider);
162                        }
163                        if (this.settings != null) {
164                                configuration.set(this.settings);
165                        }
166                        if (this.executorProvider != null) {
167                                configuration.set(this.executorProvider);
168                        }
169                        configuration.set(this.recordListenerProviders);
170                        configuration.set(this.executeListenerProviders);
171                        configuration.set(this.visitListenerProviders);
172                        configuration
173                                        .setTransactionListenerProvider(this.transactionListenerProviders);
174                        return configuration;
175                }
176
177        }
178
179}