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.neo4j; 018 019import java.util.List; 020 021import org.apache.commons.logging.Log; 022import org.apache.commons.logging.LogFactory; 023import org.neo4j.ogm.session.SessionFactory; 024import org.neo4j.ogm.session.event.EventListener; 025 026import org.springframework.beans.factory.ObjectProvider; 027import org.springframework.boot.autoconfigure.AutoConfigurationPackages; 028import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 029import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 030import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 031import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 032import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 033import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 034import org.springframework.boot.autoconfigure.domain.EntityScanPackages; 035import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; 036import org.springframework.boot.context.properties.EnableConfigurationProperties; 037import org.springframework.context.ApplicationContext; 038import org.springframework.context.annotation.Bean; 039import org.springframework.context.annotation.Configuration; 040import org.springframework.context.annotation.Import; 041import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; 042import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor; 043import org.springframework.transaction.PlatformTransactionManager; 044import org.springframework.util.StringUtils; 045import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 046import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 047 048/** 049 * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Neo4j. 050 * 051 * @author Michael Hunger 052 * @author Josh Long 053 * @author Vince Bickers 054 * @author Stephane Nicoll 055 * @author Kazuki Shimizu 056 * @since 1.4.0 057 */ 058@Configuration 059@ConditionalOnClass({ SessionFactory.class, Neo4jTransactionManager.class, 060 PlatformTransactionManager.class }) 061@ConditionalOnMissingBean(SessionFactory.class) 062@EnableConfigurationProperties(Neo4jProperties.class) 063@Import(Neo4jBookmarkManagementConfiguration.class) 064public class Neo4jDataAutoConfiguration { 065 066 @Bean 067 @ConditionalOnMissingBean 068 public org.neo4j.ogm.config.Configuration configuration(Neo4jProperties properties) { 069 return properties.createConfiguration(); 070 } 071 072 @Bean 073 public SessionFactory sessionFactory(org.neo4j.ogm.config.Configuration configuration, 074 ApplicationContext applicationContext, 075 ObjectProvider<EventListener> eventListeners) { 076 SessionFactory sessionFactory = new SessionFactory(configuration, 077 getPackagesToScan(applicationContext)); 078 eventListeners.stream().forEach(sessionFactory::register); 079 return sessionFactory; 080 } 081 082 @Bean 083 @ConditionalOnMissingBean(PlatformTransactionManager.class) 084 public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory, 085 Neo4jProperties properties, 086 ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) { 087 return customize(new Neo4jTransactionManager(sessionFactory), 088 transactionManagerCustomizers.getIfAvailable()); 089 } 090 091 private Neo4jTransactionManager customize(Neo4jTransactionManager transactionManager, 092 TransactionManagerCustomizers customizers) { 093 if (customizers != null) { 094 customizers.customize(transactionManager); 095 } 096 return transactionManager; 097 } 098 099 private String[] getPackagesToScan(ApplicationContext applicationContext) { 100 List<String> packages = EntityScanPackages.get(applicationContext) 101 .getPackageNames(); 102 if (packages.isEmpty() && AutoConfigurationPackages.has(applicationContext)) { 103 packages = AutoConfigurationPackages.get(applicationContext); 104 } 105 return StringUtils.toStringArray(packages); 106 } 107 108 @Configuration 109 @ConditionalOnWebApplication(type = Type.SERVLET) 110 @ConditionalOnClass({ WebMvcConfigurer.class, OpenSessionInViewInterceptor.class }) 111 @ConditionalOnMissingBean(OpenSessionInViewInterceptor.class) 112 @ConditionalOnProperty(prefix = "spring.data.neo4j", name = "open-in-view", havingValue = "true", matchIfMissing = true) 113 protected static class Neo4jWebConfiguration { 114 115 @Configuration 116 protected static class Neo4jWebMvcConfiguration implements WebMvcConfigurer { 117 118 private static final Log logger = LogFactory 119 .getLog(Neo4jWebMvcConfiguration.class); 120 121 private final Neo4jProperties neo4jProperties; 122 123 protected Neo4jWebMvcConfiguration(Neo4jProperties neo4jProperties) { 124 this.neo4jProperties = neo4jProperties; 125 } 126 127 @Bean 128 public OpenSessionInViewInterceptor neo4jOpenSessionInViewInterceptor() { 129 if (this.neo4jProperties.getOpenInView() == null) { 130 logger.warn("spring.data.neo4j.open-in-view is enabled by default." 131 + "Therefore, database queries may be performed during view " 132 + "rendering. Explicitly configure " 133 + "spring.data.neo4j.open-in-view to disable this warning"); 134 } 135 return new OpenSessionInViewInterceptor(); 136 } 137 138 @Override 139 public void addInterceptors(InterceptorRegistry registry) { 140 registry.addWebRequestInterceptor(neo4jOpenSessionInViewInterceptor()); 141 } 142 143 } 144 145 } 146 147}