001// Copyright 2008-2013 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.spring.modules; 016 017import org.apache.tapestry5.internal.spring.SymbolBeanFactoryPostProcessor; 018import org.apache.tapestry5.ioc.MappedConfiguration; 019import org.apache.tapestry5.ioc.OrderedConfiguration; 020import org.apache.tapestry5.ioc.annotations.Contribute; 021import org.apache.tapestry5.ioc.annotations.Marker; 022import org.apache.tapestry5.ioc.annotations.Primary; 023import org.apache.tapestry5.ioc.services.ChainBuilder; 024import org.apache.tapestry5.ioc.services.FactoryDefaults; 025import org.apache.tapestry5.ioc.services.SymbolProvider; 026import org.apache.tapestry5.ioc.services.SymbolSource; 027import org.apache.tapestry5.services.ApplicationInitializer; 028import org.apache.tapestry5.services.ApplicationInitializerFilter; 029import org.apache.tapestry5.services.Context; 030import org.apache.tapestry5.spring.ApplicationContextCustomizer; 031import org.apache.tapestry5.spring.SpringConstants; 032import org.slf4j.Logger; 033import org.springframework.context.ApplicationContext; 034import org.springframework.core.SpringVersion; 035import org.springframework.web.context.ConfigurableWebApplicationContext; 036 037import javax.servlet.ServletContext; 038import java.util.List; 039 040/** 041 * Module for Tapestry/Spring Integration. This module exists to force the load of the Spring ApplicationContext as part 042 * of Tapestry application initialization. 043 * 044 * @since 5.1.0.0 045 */ 046public class SpringModule 047{ 048 private final Logger logger; 049 050 public SpringModule(Logger logger) 051 { 052 this.logger = logger; 053 } 054 055 @Contribute(ApplicationInitializer.class) 056 public void reportSpringContextDetailsAtStartup( 057 OrderedConfiguration<ApplicationInitializerFilter> configuration, final ApplicationContext springContext) 058 { 059 ApplicationInitializerFilter filter = new ApplicationInitializerFilter() 060 { 061 public void initializeApplication(Context context, ApplicationInitializer initializer) 062 { 063 logger.info(String.format("Spring version %s with %,d defined beans.", 064 SpringVersion.getVersion(), 065 springContext.getBeanDefinitionCount())); 066 067 initializer.initializeApplication(context); 068 } 069 }; 070 071 configuration.add("SpringContextInitialization", filter); 072 } 073 074 @Contribute(SymbolProvider.class) 075 @FactoryDefaults 076 public static void defaultExternalSpringContextOff(MappedConfiguration<String, Object> configuration) 077 { 078 configuration.add(SpringConstants.USE_EXTERNAL_SPRING_CONTEXT, false); 079 } 080 081 /** 082 * Defines a chain-of-command for handling application context customization. This allows the Spring context to be 083 * configured before it is initially {@linkplain org.springframework.context.ConfigurableApplicationContext#refresh() 084 * refreshed}. 085 */ 086 @Marker(Primary.class) 087 public static ApplicationContextCustomizer buildApplicationContextCustomizer( 088 List<ApplicationContextCustomizer> configuration, 089 ChainBuilder builder) 090 { 091 return builder.build(ApplicationContextCustomizer.class, configuration); 092 } 093 094 @Contribute(ApplicationContextCustomizer.class) 095 public static void addSymbolSourceAsPropertyCustomizerForSpringBeans( 096 OrderedConfiguration<ApplicationContextCustomizer> configuration, 097 final SymbolSource symbolSource) 098 { 099 ApplicationContextCustomizer beanFactoryPostProcessorCustomizer = new ApplicationContextCustomizer() 100 { 101 102 public void customizeApplicationContext(ServletContext servletContext, 103 ConfigurableWebApplicationContext applicationContext) 104 { 105 applicationContext.addBeanFactoryPostProcessor(new SymbolBeanFactoryPostProcessor(symbolSource)); 106 107 } 108 }; 109 110 configuration.add("BeanFactoryPostProcessorCustomizer", beanFactoryPostProcessorCustomizer); 111 } 112}