001 // Copyright 2008, 2009, 2011 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
015 package org.apache.tapestry5.spring;
016
017 import org.apache.tapestry5.internal.spring.SymbolBeanFactoryPostProcessor;
018 import org.apache.tapestry5.ioc.MappedConfiguration;
019 import org.apache.tapestry5.ioc.OrderedConfiguration;
020 import org.apache.tapestry5.ioc.annotations.Contribute;
021 import org.apache.tapestry5.ioc.annotations.Marker;
022 import org.apache.tapestry5.ioc.annotations.Primary;
023 import org.apache.tapestry5.ioc.services.ChainBuilder;
024 import org.apache.tapestry5.ioc.services.FactoryDefaults;
025 import org.apache.tapestry5.ioc.services.SymbolProvider;
026 import org.apache.tapestry5.ioc.services.SymbolSource;
027 import org.apache.tapestry5.services.ApplicationInitializer;
028 import org.apache.tapestry5.services.ApplicationInitializerFilter;
029 import org.apache.tapestry5.services.Context;
030 import org.slf4j.Logger;
031 import org.springframework.context.ApplicationContext;
032 import org.springframework.core.SpringVersion;
033 import org.springframework.web.context.ConfigurableWebApplicationContext;
034
035 import javax.servlet.ServletContext;
036 import java.util.List;
037
038 /**
039 * Module for Tapestry/Spring Integration. This module exists to force the load of the Spring ApplicationContext as part
040 * of Tapestry application initialization.
041 *
042 * @since 5.1.0.0
043 */
044 public class SpringModule
045 {
046 private final Logger logger;
047
048 public SpringModule(Logger logger)
049 {
050 this.logger = logger;
051 }
052
053 @Contribute(ApplicationInitializer.class)
054 public void reportSpringContextDetailsAtStartup(
055 OrderedConfiguration<ApplicationInitializerFilter> configuration, final ApplicationContext springContext)
056 {
057 ApplicationInitializerFilter filter = new ApplicationInitializerFilter()
058 {
059 public void initializeApplication(Context context, ApplicationInitializer initializer)
060 {
061 logger.info(String.format("Spring version %s with %,d defined beans.",
062 SpringVersion.getVersion(),
063 springContext.getBeanDefinitionCount()));
064
065 initializer.initializeApplication(context);
066 }
067 };
068
069 configuration.add("SpringContextInitialization", filter);
070 }
071
072 @Contribute(SymbolProvider.class)
073 @FactoryDefaults
074 public static void defaultExternalSpringContextOff(MappedConfiguration<String, Object> configuration)
075 {
076 configuration.add(SpringConstants.USE_EXTERNAL_SPRING_CONTEXT, false);
077 }
078
079 /**
080 * Defines a chain-of-command for handling application context customization. This allows the Spring context to be
081 * configured before it is initially {@linkplain org.springframework.context.ConfigurableApplicationContext#refresh()
082 * refreshed}.
083 */
084 @Marker(Primary.class)
085 public static ApplicationContextCustomizer buildApplicationContextCustomizer(
086 List<ApplicationContextCustomizer> configuration,
087 ChainBuilder builder)
088 {
089 return builder.build(ApplicationContextCustomizer.class, configuration);
090 }
091
092 @Contribute(ApplicationContextCustomizer.class)
093 public static void addSymbolSourceAsPropertyCustomizerForSpringBeans(
094 OrderedConfiguration<ApplicationContextCustomizer> configuration,
095 final SymbolSource symbolSource)
096 {
097 ApplicationContextCustomizer beanFactoryPostProcessorCustomizer = new ApplicationContextCustomizer()
098 {
099
100 public void customizeApplicationContext(ServletContext servletContext,
101 ConfigurableWebApplicationContext applicationContext)
102 {
103 applicationContext.addBeanFactoryPostProcessor(new SymbolBeanFactoryPostProcessor(symbolSource));
104
105 }
106 };
107
108 configuration.add("BeanFactoryPostProcessorCustomizer", beanFactoryPostProcessorCustomizer);
109 }
110 }