Author: hlship
Date: Mon Jan  5 13:44:04 2009
New Revision: 731736

URL: http://svn.apache.org/viewvc?rev=731736&view=rev
Log:
TAP5-431: When using an externally configuration Spring ApplicationContext, 
beans of the context should be registered as services (as was the case in 
Tapestry 5.0)

Added:
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringBeanServiceDef.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/StaticObjectCreator.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/ApplicationContextCustomizer.java
      - copied, changed from r730009, 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/ApplicationContextCustomizer.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringConstants.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringModule.java
      - copied, changed from r730216, 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModule.java
Removed:
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/ApplicationContextCustomizer.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModule.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/CustomizedFilter.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
    tapestry/tapestry5/trunk/tapestry-spring/pom.xml
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/CustomizingContextLoader.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModuleDef.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/TapestrySpringFilter.java
    tapestry/tapestry5/trunk/tapestry-spring/src/site/apt/index.apt
    
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/internal/spring/SpringModuleDefTest.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/spring/TapestrySpringIntegrationTest.java
    
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/AppModule.java
    tapestry/tapestry5/trunk/tapestry-spring/src/test/webapp/WEB-INF/web.xml

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
 Mon Jan  5 13:44:04 2009
@@ -99,14 +99,6 @@
      */
     public static final String SCRIPTS_AT_TOP = "tapestry.script-at-top";
 
-    /**
-     * If true, then Tapestry will attempt to use an externally configured 
Spring ApplicationContext rather than create
-     * its own. This will disable the ability to inject Tapestry IoC services 
and objects into Spring beans.
-     *
-     * @since 5.1.0.0
-     */
-    public static final String USE_EXTERNAL_SPRING_CONTEXT = 
"tapestry.use-external-spring-context";
-
 
     /**
      * Identifies the default persistence strategy for all pages that do not 
provide an override (using this value as

Modified: tapestry/tapestry5/trunk/tapestry-spring/pom.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/pom.xml?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-spring/pom.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-spring/pom.xml Mon Jan  5 13:44:04 2009
@@ -76,7 +76,7 @@
                     <archive>
                         <manifestEntries>
                             <Tapestry-Module-Classes>
-                                
org.apache.tapestry5.internal.spring.SpringModule
+                                org.apache.tapestry5.spring.SpringModule
                             </Tapestry-Module-Classes>
                         </manifestEntries>
                     </archive>

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/CustomizingContextLoader.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/CustomizingContextLoader.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/CustomizingContextLoader.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/CustomizingContextLoader.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.internal.spring;
 
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.spring.ApplicationContextCustomizer;
 import org.apache.tapestry5.spring.TapestryApplicationContext;
 import org.springframework.context.ApplicationContextException;
 import org.springframework.web.context.ConfigurableWebApplicationContext;

Added: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringBeanServiceDef.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringBeanServiceDef.java?rev=731736&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringBeanServiceDef.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringBeanServiceDef.java
 Mon Jan  5 13:44:04 2009
@@ -0,0 +1,84 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.spring;
+
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ScopeConstants;
+import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.def.ServiceDef2;
+import org.springframework.context.ApplicationContext;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class SpringBeanServiceDef implements ServiceDef2
+{
+    private final String beanName;
+
+    private final ApplicationContext context;
+
+    public SpringBeanServiceDef(String beanName, ApplicationContext context)
+    {
+        this.beanName = beanName;
+        this.context = context;
+    }
+
+    public boolean isPreventDecoration()
+    {
+        return true;
+    }
+
+    public ObjectCreator createServiceCreator(ServiceBuilderResources 
resources)
+    {
+        return new ObjectCreator()
+        {
+            public Object createObject()
+            {
+                return context.getBean(beanName);
+            }
+
+            @Override
+            public String toString()
+            {
+                return String.format("ObjectCreator<Spring Bean '%s'>", 
beanName);
+            }
+        };
+    }
+
+    public String getServiceId()
+    {
+        return beanName;
+    }
+
+    public Set<Class> getMarkers()
+    {
+        return Collections.emptySet();
+    }
+
+    public Class getServiceInterface()
+    {
+        return context.getType(beanName);
+    }
+
+    public String getServiceScope()
+    {
+        return ScopeConstants.DEFAULT;
+    }
+
+    public boolean isEagerLoad()
+    {
+        return false;
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModuleDef.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModuleDef.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModuleDef.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModuleDef.java
 Mon Jan  5 13:44:04 2009
@@ -14,9 +14,9 @@
 
 package org.apache.tapestry5.internal.spring;
 
-import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.internal.AbstractContributionDef;
 import org.apache.tapestry5.ioc.*;
+import org.apache.tapestry5.ioc.annotations.Primary;
 import org.apache.tapestry5.ioc.def.ContributionDef;
 import org.apache.tapestry5.ioc.def.DecoratorDef;
 import org.apache.tapestry5.ioc.def.ModuleDef;
@@ -24,7 +24,12 @@
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.internal.util.Invokable;
-import org.apache.tapestry5.ioc.services.*;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
+import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
+import org.apache.tapestry5.ioc.services.RegistryShutdownListener;
+import org.apache.tapestry5.spring.ApplicationContextCustomizer;
+import org.apache.tapestry5.spring.SpringConstants;
+import org.springframework.beans.factory.BeanFactoryUtils;
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.SpringVersion;
 import org.springframework.web.context.ConfigurableWebApplicationContext;
@@ -46,70 +51,54 @@
 
     private final Map<String, ServiceDef> services = 
CollectionFactory.newMap();
 
+    private final boolean compatibilityMode;
+
     private final AtomicBoolean applicationContextCreated = new 
AtomicBoolean(false);
 
     private final ServletContext servletContext;
 
-    private final ApplicationContextCustomizer customizer;
-
-    private class ExternalApplicationContextLookupCreator implements 
ObjectCreator
+    private ConfigurableWebApplicationContext locateExternalContext()
     {
-        private final OperationTracker tracker;
-
-        public ExternalApplicationContextLookupCreator(OperationTracker 
tracker)
-        {
-            this.tracker = tracker;
-        }
-
-        public Object createObject()
-        {
-            return tracker.invoke(
-                    "Obtaining Spring ApplicationContext from ServletContext",
-                    new Invokable<Object>()
-                    {
-                        public Object invoke()
-                        {
-                            ConfigurableWebApplicationContext context = 
(ConfigurableWebApplicationContext) servletContext.getAttribute(
-                                    
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+        ConfigurableWebApplicationContext context = 
(ConfigurableWebApplicationContext) servletContext.getAttribute(
+                WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
 
-                            if (context == null)
-                                throw new NullPointerException(String.format(
-                                        "No Spring ApplicationContext stored 
in the ServletContext as attribute '%s'. " +
-                                                "You should either re-enable 
Tapestry as the creator of the ApplicationContext, or " +
-                                                "add a Spring 
ContextLoaderListener to web.xml.",
-                                        
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE));
+        if (context == null)
+            throw new NullPointerException(String.format(
+                    "No Spring ApplicationContext stored in the ServletContext 
as attribute '%s'. " +
+                            "You should either re-enable Tapestry as the 
creator of the ApplicationContext, or " +
+                            "add a Spring ContextLoaderListener to web.xml.",
+                    
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE));
 
-                            applicationContextCreated.set(true);
+        applicationContextCreated.set(true);
 
-                            return context;
-                        }
-                    });
-        }
+        return context;
     }
 
-    public SpringModuleDef(ServletContext servletContext, final 
ApplicationContextCustomizer customizer)
+    public SpringModuleDef(ServletContext servletContext)
     {
         this.servletContext = servletContext;
-        this.customizer = customizer;
 
-        ServiceDef sd = new ServiceDef()
+        compatibilityMode = Boolean.parseBoolean(
+                
servletContext.getInitParameter(SpringConstants.USE_EXTERNAL_SPRING_CONTEXT));
+
+        final ApplicationContext externalContext =
+                compatibilityMode ? locateExternalContext() : null;
+
+        if (compatibilityMode)
+            addServiceDefsForSpringBeans(externalContext);
+
+        ServiceDef applicationContextServiceDef = new ServiceDef()
         {
             public ObjectCreator createServiceCreator(final 
ServiceBuilderResources resources)
             {
-                TypeCoercer coercer = resources.getService(TypeCoercer.class);
-                SymbolSource symbolSource = 
resources.getService(SymbolSource.class);
-
-                boolean useExternal = coercer.coerce(
-                        
symbolSource.valueForSymbol(SymbolConstants.USE_EXTERNAL_SPRING_CONTEXT), 
boolean.class);
+                if (compatibilityMode)
+                    return new StaticObjectCreator(externalContext, 
"externally configured Spring ApplicationContext");
 
-                final OperationTracker tracker = resources.getTracker();
 
-                if (useExternal)
-                {
-                    return new 
ExternalApplicationContextLookupCreator(tracker);
-                }
+                ApplicationContextCustomizer customizer = 
resources.getService("ApplicationContextCustomizer",
+                                                                               
ApplicationContextCustomizer.class);
 
-                return constructObjectCreatorForApplicationContext(resources);
+                return constructObjectCreatorForApplicationContext(resources, 
customizer);
             }
 
             public String getServiceId()
@@ -124,7 +113,9 @@
 
             public Class getServiceInterface()
             {
-                return ConfigurableWebApplicationContext.class;
+                return compatibilityMode
+                       ? externalContext.getClass()
+                       : ConfigurableWebApplicationContext.class;
             }
 
             public String getServiceScope()
@@ -138,11 +129,20 @@
             }
         };
 
-        services.put(SERVICE_ID, sd);
+        services.put(SERVICE_ID, applicationContextServiceDef);
     }
 
-    private ObjectCreator constructObjectCreatorForApplicationContext(final 
ServiceBuilderResources resources
-    )
+    private void addServiceDefsForSpringBeans(ApplicationContext context)
+    {
+        for (final String beanName : 
BeanFactoryUtils.beanNamesIncludingAncestors(context))
+        {
+            services.put(beanName, new SpringBeanServiceDef(beanName, 
context));
+        }
+    }
+
+    private ObjectCreator constructObjectCreatorForApplicationContext(final 
ServiceBuilderResources resources,
+                                                                      @Primary
+                                                                      
ApplicationContextCustomizer customizer)
     {
         final CustomizingContextLoader loader = new 
CustomizingContextLoader(customizer);
 
@@ -279,6 +279,9 @@
                     public <T> T provide(Class<T> objectType, 
AnnotationProvider annotationProvider,
                                          ObjectLocator locator)
                     {
+                        // I think the following line is the only reason we 
put the SpringBeanProvider here,
+                        // rather than in SpringModule.
+
                         if (!applicationContextCreated.get()) return null;
 
                         return springBeanProviderInvoker.provide(objectType, 
annotationProvider, locator);

Added: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/StaticObjectCreator.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/StaticObjectCreator.java?rev=731736&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/StaticObjectCreator.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/StaticObjectCreator.java
 Mon Jan  5 13:44:04 2009
@@ -0,0 +1,45 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.spring;
+
+import org.apache.tapestry5.ioc.ObjectCreator;
+
+/**
+ * An {...@link org.apache.tapestry5.ioc.ObjectCreator} for a statically 
identified object (typically, a bean from the
+ * Spring application context).
+ */
+public class StaticObjectCreator implements ObjectCreator
+{
+    private final Object object;
+
+    private final String description;
+
+    public StaticObjectCreator(Object object, String description)
+    {
+        this.object = object;
+        this.description = description;
+    }
+
+    public Object createObject()
+    {
+        return object;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("<ObjectCreator for %s>", description);
+    }
+}

Copied: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/ApplicationContextCustomizer.java
 (from r730009, 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/ApplicationContextCustomizer.java)
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/ApplicationContextCustomizer.java?p2=tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/ApplicationContextCustomizer.java&p1=tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/ApplicationContextCustomizer.java&r1=730009&r2=731736&rev=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/ApplicationContextCustomizer.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/ApplicationContextCustomizer.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,17 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry5.internal.spring;
+package org.apache.tapestry5.spring;
 
+import org.apache.tapestry5.ioc.annotations.UsesOrderedConfiguration;
 import org.springframework.web.context.ConfigurableWebApplicationContext;
 
 import javax.servlet.ServletContext;
 
 /**
- * A bridge from Spring's approach to customizing the application context, 
over to Tapestry's.  This is how it is
- * possible to subclass and override {...@link  
org.apache.tapestry5.spring.TapestrySpringFilter#customizeApplicationContext(javax.servlet.ServletContext,
- * org.springframework.web.context.ConfigurableWebApplicationContext)}.
+ * A bridge from Spring's approach to customizing the application context, 
over to Tapestry's approach. This is a
+ * chain-of-command service.
  */
+...@usesorderedconfiguration(ApplicationContextCustomizer.class)
 public interface ApplicationContextCustomizer
 {
     /**

Added: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringConstants.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringConstants.java?rev=731736&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringConstants.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringConstants.java
 Mon Jan  5 13:44:04 2009
@@ -0,0 +1,30 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.spring;
+
+/**
+ * Constants used with the Spring integration library.
+ *
+ * @since 5.1.0.0
+ */
+public class SpringConstants
+{
+    /**
+     * If true, then Tapestry will attempt to use an externally configured 
Spring ApplicationContext rather than create
+     * its own. This will disable the ability to inject Tapestry IoC services 
and objects into Spring beans. This
+     * <em>must</em> be configured as a conetxt &lt;init-parameter&gt; in 
web.xml.
+     */
+    public static final String USE_EXTERNAL_SPRING_CONTEXT = 
"tapestry.use-external-spring-context";
+}

Copied: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringModule.java
 (from r730216, 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModule.java)
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringModule.java?p2=tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringModule.java&p1=tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModule.java&r1=730216&r2=731736&rev=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/internal/spring/SpringModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/SpringModule.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,11 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry5.internal.spring;
+package org.apache.tapestry5.spring;
 
-import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.ioc.MappedConfiguration;
 import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.annotations.Marker;
+import org.apache.tapestry5.ioc.annotations.Primary;
+import org.apache.tapestry5.ioc.services.ChainBuilder;
 import org.apache.tapestry5.services.ApplicationInitializer;
 import org.apache.tapestry5.services.ApplicationInitializerFilter;
 import org.apache.tapestry5.services.Context;
@@ -24,6 +26,8 @@
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.SpringVersion;
 
+import java.util.List;
+
 /**
  * Module for Tapestry/Spring Integration. This module exists to force the 
load of the Spring ApplicationContext as part
  * of Tapestry application initialization.
@@ -57,6 +61,19 @@
 
     public static void contributeFactoryDefaults(MappedConfiguration<String, 
String> configuration)
     {
-        configuration.add(SymbolConstants.USE_EXTERNAL_SPRING_CONTEXT, 
"false");
+        configuration.add(SpringConstants.USE_EXTERNAL_SPRING_CONTEXT, 
"false");
+    }
+
+    /**
+     * Defines a chain-of-command for handling application context 
customization. This allows the Spring context to be
+     * configured before it is initially {...@linkplain 
org.springframework.context.ConfigurableApplicationContext#refresh()
+     * refreshed}.
+     */
+    @Marker(Primary.class)
+    public static ApplicationContextCustomizer 
buildApplicationContextCustomizer(
+            List<ApplicationContextCustomizer> configuration,
+            ChainBuilder builder)
+    {
+        return builder.build(ApplicationContextCustomizer.class, 
configuration);
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/TapestrySpringFilter.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/TapestrySpringFilter.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/TapestrySpringFilter.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/main/java/org/apache/tapestry5/spring/TapestrySpringFilter.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,38 +15,24 @@
 package org.apache.tapestry5.spring;
 
 import org.apache.tapestry5.TapestryFilter;
-import org.apache.tapestry5.internal.spring.ApplicationContextCustomizer;
 import org.apache.tapestry5.internal.spring.SpringModuleDef;
 import org.apache.tapestry5.ioc.def.ModuleDef;
-import org.springframework.context.ApplicationContext;
-import org.springframework.web.context.ConfigurableWebApplicationContext;
 
 import javax.servlet.ServletContext;
 
 /**
- * Adds a {...@link ModuleDef} that contains all the beans defined by the 
Spring {...@link ApplicationContext}, as if they
- * were Tapestry IoC services. This is done using a filter, so that the Spring 
beans can be "mixed into" the Tapestry
- * IoC Registry before it even starts up.
+ * Add logic to setup for Spring integration at startup.  In 5.1, this means 
creating a Spring ApplicationContext, and
+ * wiring parts of it to resolve Tapestry objects.  In {...@linkplain 
org.apache.tapestry5.spring.SpringConstants#USE_EXTERNAL_SPRING_CONTEXT
+ * compatibility mode}, this means locating the externally configuration 
context and exposing each bean in it as a
+ * Tapestry IoC service.
  */
-public class TapestrySpringFilter extends TapestryFilter implements 
ApplicationContextCustomizer
+public class TapestrySpringFilter extends TapestryFilter
 {
     @Override
     protected ModuleDef[] provideExtraModuleDefs(ServletContext context)
     {
         return new ModuleDef[] {
-                new SpringModuleDef(context, this)
+                new SpringModuleDef(context)
         };
     }
-
-    /**
-     * This implementation does nothing; subclasses may override to perform 
additional customizations and
-     * initializations of the application context.
-     *
-     * @param servletContext
-     * @param applicationContext
-     */
-    public void customizeApplicationContext(ServletContext servletContext,
-                                            ConfigurableWebApplicationContext 
applicationContext)
-    {
-    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-spring/src/site/apt/index.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/site/apt/index.apt?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-spring/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-spring/src/site/apt/index.apt Mon Jan  5 
13:44:04 2009
@@ -15,7 +15,7 @@
 
  The dependency on Spring is no longer scope "provider" and has changed to 
2.5.6.
 
- <<Spring Beans are no longer exposed as services.>>
+ <<Spring Beans are no longer exposed as services, unless 5.0 compatibility 
mode is enabled.>>
 
  You no longer create a ContextLoaderListener.
 
@@ -79,13 +79,23 @@
 
   The Spring ApplicationContext is also added as a service.
 
-External Configuration
+ApplicationContextCustomizer
 
- In some circumstances, it is desirable to configure the Spring 
ApplicationContext externally. The  symbol
+  A new chain-of-command service,
+  
{{{../apidocs/org/apache/tapestry5/spring/ApplicationContextCustomizer.html}ApplicationContextCustomizer}}
+  allows the application context, created by Tapestry, to be customized as it 
is created.  You may contribute
+  your own ApplicationContextCustomizer instances as needed.
+
+5.0 Compatibility Mode
+
+ In some circumstances, it is desirable to configure the Spring 
ApplicationContext externally. The  context \<config-param\>
  "tapestry.use-external-spring-context" can be configured to "true".  Tapestry 
will then use an existing ApplicationContext,
  provided by a Spring ContextLoaderListener. You will still be able to inject 
Spring beans into Tapestry components and services,
  and the ApplicationContext service will be visible ... but you will not be 
able to inject Tapestry IoC services into Spring beans.
 
+ This option provides compatibility with the tapestry-spring 5.0, including 
exposing Spring beans as Tapestry IoC services
+ (something that no longer occurs unless compatibility mode is enabled).
+
 Limitations
 
   Non-singleton beans are not handled properly. Tapestry will request the 
beans from the application context in a manner unsuitable for their lifecycle.

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/internal/spring/SpringModuleDefTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/internal/spring/SpringModuleDefTest.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/internal/spring/SpringModuleDefTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/internal/spring/SpringModuleDefTest.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,13 +14,11 @@
 
 package org.apache.tapestry5.internal.spring;
 
-import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ScopeConstants;
 import org.apache.tapestry5.ioc.ServiceBuilderResources;
 import org.apache.tapestry5.ioc.def.ServiceDef;
-import org.apache.tapestry5.ioc.internal.QuietOperationTracker;
-import org.apache.tapestry5.ioc.services.SymbolSource;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.spring.SpringConstants;
 import org.apache.tapestry5.spring.SpringTestCase;
 import org.springframework.web.context.ConfigurableWebApplicationContext;
 import org.springframework.web.context.WebApplicationContext;
@@ -34,21 +32,21 @@
     public void load_application_context_externally()
     {
         ServletContext servletContext = mockServletContext();
-        TypeCoercer tc = mockTypeCoercer();
-        SymbolSource ss = mockSymbolSource();
         ConfigurableWebApplicationContext ac = 
newMock(ConfigurableWebApplicationContext.class);
+        Runnable fred = mockRunnable();
 
         ServiceBuilderResources resources = mockServiceBuilderResources();
 
-        train_for_external_spring_context(resources, tc, ss);
+        train_getInitParameter(servletContext, 
SpringConstants.USE_EXTERNAL_SPRING_CONTEXT, "true");
 
         train_getAttribute(servletContext, 
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ac);
 
-        train_getTracker(resources, new QuietOperationTracker());
+        expect(ac.getBeanNamesForType(Object.class)).andReturn(new String[] 
{"fred", "barney"});
+        expect(ac.getParentBeanFactory()).andReturn(null);
 
         replay();
 
-        SpringModuleDef moduleDef = new SpringModuleDef(servletContext, null);
+        SpringModuleDef moduleDef = new SpringModuleDef(servletContext);
 
         ServiceDef serviceDef = 
moduleDef.getServiceDef(SpringModuleDef.SERVICE_ID);
 
@@ -57,34 +55,49 @@
         assertSame(serviceCreator.createObject(), ac);
 
         verify();
+
+        // Now, let's test for some of the services.
+
+        ServiceDef sd = moduleDef.getServiceDef("ApplicationContext");
+
+        assertEquals(sd.getServiceInterface(), ac.getClass());
+        assertEquals(sd.createServiceCreator(null).toString(),
+                     "<ObjectCreator for externally configured Spring 
ApplicationContext>");
+
+        expect(ac.getType("fred")).andReturn(Runnable.class);
+        expect(ac.getBean("fred")).andReturn(fred);
+
+
+        sd = moduleDef.getServiceDef("fred");
+
+        replay();
+
+        assertEquals(sd.getServiceId(), "fred");
+        assertEquals(sd.getServiceInterface(), Runnable.class);
+        assertEquals(sd.getServiceScope(), ScopeConstants.DEFAULT);
+        assertSame(sd.createServiceCreator(null).createObject(), fred);
+        assertTrue(sd.getMarkers().isEmpty());
+        assertFalse(sd.isEagerLoad());
+        assertEquals(sd.createServiceCreator(null).toString(), 
"ObjectCreator<Spring Bean 'fred'>");
+
+        verify();
     }
 
     @Test
     public void missing_external_application_context()
     {
         ServletContext servletContext = mockServletContext();
-        TypeCoercer tc = mockTypeCoercer();
-        SymbolSource ss = mockSymbolSource();
-
-        ServiceBuilderResources resources = mockServiceBuilderResources();
 
-        train_for_external_spring_context(resources, tc, ss);
+        train_getInitParameter(servletContext, 
SpringConstants.USE_EXTERNAL_SPRING_CONTEXT, "true");
 
         train_getAttribute(servletContext, 
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
 
-        train_getTracker(resources, new QuietOperationTracker());
-
         replay();
 
-        SpringModuleDef moduleDef = new SpringModuleDef(servletContext, null);
-
-        ServiceDef serviceDef = 
moduleDef.getServiceDef(SpringModuleDef.SERVICE_ID);
-
-        ObjectCreator serviceCreator = 
serviceDef.createServiceCreator(resources);
-
         try
         {
-            serviceCreator.createObject();
+            new SpringModuleDef(servletContext);
+
             unreachable();
         }
         catch (NullPointerException ex)
@@ -96,15 +109,4 @@
 
         verify();
     }
-
-    private void train_for_external_spring_context(ServiceBuilderResources 
resources, TypeCoercer coercer,
-                                                   SymbolSource source)
-    {
-
-        train_getService(resources, TypeCoercer.class, coercer);
-        train_getService(resources, SymbolSource.class, source);
-
-        
expect(source.valueForSymbol(SymbolConstants.USE_EXTERNAL_SPRING_CONTEXT)).andReturn("true");
-        train_coerce(coercer, "true", boolean.class, true);
-    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/spring/TapestrySpringIntegrationTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/spring/TapestrySpringIntegrationTest.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/spring/TapestrySpringIntegrationTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/apache/tapestry5/spring/TapestrySpringIntegrationTest.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -45,11 +45,11 @@
     }
 
     @Test
-    public void customize_method_of_filter_subclass_invoked() throws Exception
+    public void customize_pipeline_is_invoked() throws Exception
     {
         open(BASE_URL);
 
-        assertText("message", "SPRING VERSION 2.5.6: FILTER INITIALIZED");
+        assertText("message", "SPRING VERSION 2.5.6: PIPELINE WAS INVOKED");
     }
 
     @Test

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/AppModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/AppModule.java?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/AppModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-spring/src/test/java/org/example/testapp/services/AppModule.java
 Mon Jan  5 13:44:04 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,10 +15,15 @@
 package org.example.testapp.services;
 
 import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.internal.spring.SpringModule;
 import org.apache.tapestry5.ioc.MappedConfiguration;
+import org.apache.tapestry5.ioc.OrderedConfiguration;
 import org.apache.tapestry5.ioc.ServiceBinder;
 import org.apache.tapestry5.ioc.annotations.SubModule;
+import org.apache.tapestry5.spring.ApplicationContextCustomizer;
+import org.apache.tapestry5.spring.SpringModule;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
+
+import javax.servlet.ServletContext;
 
 @SubModule(SpringModule.class)
 public class AppModule
@@ -32,4 +37,17 @@
     {
         configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
     }
+
+    public static void contributeApplicationContextCustomizer(
+            OrderedConfiguration<ApplicationContextCustomizer> configuration)
+    {
+        configuration.add("WasInvoked", new ApplicationContextCustomizer()
+        {
+            public void customizeApplicationContext(ServletContext 
servletContext,
+                                                    
ConfigurableWebApplicationContext applicationContext)
+            {
+                servletContext.setAttribute("status-message", "Pipeline Was 
Invoked");
+            }
+        });
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-spring/src/test/webapp/WEB-INF/web.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-spring/src/test/webapp/WEB-INF/web.xml?rev=731736&r1=731735&r2=731736&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-spring/src/test/webapp/WEB-INF/web.xml 
(original)
+++ tapestry/tapestry5/trunk/tapestry-spring/src/test/webapp/WEB-INF/web.xml 
Mon Jan  5 13:44:04 2009
@@ -1,7 +1,7 @@
 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 
2.3//EN"
         "http://java.sun.com/dtd/web-app_2_3.dtd";>
 <!-- 
-   Copyright 2007 The Apache Software Foundation
+   Copyright 2007, 2009 The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -24,8 +24,7 @@
     </context-param>
     <filter>
         <filter-name>app</filter-name>
-        <!-- Special filter that adds in a T5 IoC module derived from the 
Spring WebApplicationContext. -->
-        
<filter-class>org.example.testapp.services.CustomizedFilter</filter-class>
+        
<filter-class>org.apache.tapestry5.spring.TapestrySpringFilter</filter-class>
     </filter>
     <filter-mapping>
         <filter-name>app</filter-name>


Reply via email to