Updated Branches:
  refs/heads/master 4c1de3267 -> 017961387

WICKET-5079 improved application context handling

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/01796138
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/01796138
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/01796138

Branch: refs/heads/master
Commit: 01796138744f6853d5c628f104fb0b7eb7131b0e
Parents: 4c1de32
Author: svenmeier <[email protected]>
Authored: Wed Mar 6 14:06:30 2013 +0100
Committer: svenmeier <[email protected]>
Committed: Wed Mar 6 14:06:30 2013 +0100

----------------------------------------------------------------------
 .../wicket/spring/SpringWebApplicationFactory.java |   63 ++++---
 .../injection/annot/SpringComponentInjector.java   |   41 ++++-
 .../spring/SpringWebApplicationFactoryTest.java    |  147 +++++++++++++++
 .../apache/wicket/spring/applicationContext.xml    |   24 +++
 4 files changed, 243 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/01796138/wicket-spring/src/main/java/org/apache/wicket/spring/SpringWebApplicationFactory.java
----------------------------------------------------------------------
diff --git 
a/wicket-spring/src/main/java/org/apache/wicket/spring/SpringWebApplicationFactory.java
 
b/wicket-spring/src/main/java/org/apache/wicket/spring/SpringWebApplicationFactory.java
index 2e385df..9c0ad8d 100644
--- 
a/wicket-spring/src/main/java/org/apache/wicket/spring/SpringWebApplicationFactory.java
+++ 
b/wicket-spring/src/main/java/org/apache/wicket/spring/SpringWebApplicationFactory.java
@@ -23,6 +23,7 @@ import javax.servlet.ServletContext;
 import org.apache.wicket.protocol.http.IWebApplicationFactory;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.protocol.http.WicketFilter;
+import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanFactoryUtils;
 import org.springframework.context.ApplicationContext;
@@ -69,8 +70,9 @@ import 
org.springframework.web.context.support.XmlWebApplicationContext;
  * </pre>
  * 
  * <p>
- * This factory is also capable of creating an additional application context 
(path to which is
- * specified via the {@code contextConfigLocation} filter param) and chaining 
it to the global one
+ * This factory is also capable of creating a {@link WebApplication}-specific 
application context
+ * (path to which is specified via the {@code contextConfigLocation} filter 
param) and chaining it
+ * to the global one
  * </p>
  * 
  * <pre>
@@ -95,12 +97,12 @@ import 
org.springframework.web.context.support.XmlWebApplicationContext;
 public class SpringWebApplicationFactory implements IWebApplicationFactory
 {
 
-       /** additional context created for this filter, if any */
-       private ConfigurableWebApplicationContext additionalContext;
+       /** web application context created for this filter, if any */
+       private ConfigurableWebApplicationContext webApplicationContext;
 
        /**
-        * Returns location of context config that will be used to create an 
additional application
-        * context for this application
+        * Returns location of context config that will be used to create a 
{@link WebApplication}
+        * -specific application context.
         * 
         * @param filter
         * @return location of context config
@@ -111,8 +113,8 @@ public class SpringWebApplicationFactory implements 
IWebApplicationFactory
        }
 
        /**
-        * Factory method used to create a new instance of the additional 
application context, by
-        * default an instance o {@link XmlWebApplicationContext} will be 
created.
+        * Factory method used to create a new instance of the web application 
context, by default an
+        * instance o {@link XmlWebApplicationContext} will be created.
         * 
         * @return application context instance
         */
@@ -127,34 +129,36 @@ public class SpringWebApplicationFactory implements 
IWebApplicationFactory
        @Override
        public WebApplication createApplication(final WicketFilter filter)
        {
-               ServletContext sc = 
filter.getFilterConfig().getServletContext();
+               ServletContext servletContext = 
filter.getFilterConfig().getServletContext();
 
-               WebApplicationContext ac = 
WebApplicationContextUtils.getWebApplicationContext(sc);
+               WebApplicationContext applicationContext = 
WebApplicationContextUtils.getWebApplicationContext(servletContext);
 
                if (getContextConfigLocation(filter) != null)
                {
-                       additionalContext = createWebApplicationContext(ac, 
filter);
+                       applicationContext = 
createWebApplicationContext(applicationContext, filter);
                }
 
                String beanName = 
filter.getFilterConfig().getInitParameter("applicationBean");
-               return createApplication((additionalContext != null) ? 
additionalContext : ac, beanName);
+               return createApplication(applicationContext, beanName);
        }
 
-       private WebApplication createApplication(final ApplicationContext ac, 
final String beanName)
+       private WebApplication createApplication(final ApplicationContext 
applicationContext,
+               final String beanName)
        {
+               WebApplication application;
+
                if (beanName != null)
                {
-                       WebApplication application = 
(WebApplication)ac.getBean(beanName);
+                       application = 
(WebApplication)applicationContext.getBean(beanName);
                        if (application == null)
                        {
                                throw new IllegalArgumentException(
                                        "Unable to find WebApplication bean 
with name [" + beanName + "]");
                        }
-                       return application;
                }
                else
                {
-                       Map<?, ?> beans = 
BeanFactoryUtils.beansOfTypeIncludingAncestors(ac,
+                       Map<?, ?> beans = 
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext,
                                WebApplication.class, false, false);
                        if (beans.size() == 0)
                        {
@@ -166,8 +170,13 @@ public class SpringWebApplicationFactory implements 
IWebApplicationFactory
                                throw new IllegalStateException("More than one 
bean of type [" +
                                        WebApplication.class.getName() + "] 
found, must have only one");
                        }
-                       return (WebApplication)beans.values().iterator().next();
+                       application = 
(WebApplication)beans.values().iterator().next();
                }
+
+               // make the application context default for 
SpringComponentInjectors
+               SpringComponentInjector.setDefaultContext(application, 
applicationContext);
+
+               return application;
        }
 
        /**
@@ -178,21 +187,21 @@ public class SpringWebApplicationFactory implements 
IWebApplicationFactory
         *            parent application context
         * @param filter
         *            wicket filter
-        * @return instance of additional application context
+        * @return instance of web application context
         * @throws BeansException
         */
        protected final ConfigurableWebApplicationContext 
createWebApplicationContext(
                final WebApplicationContext parent, final WicketFilter filter) 
throws BeansException
        {
-               ConfigurableWebApplicationContext wac = newApplicationContext();
-               wac.setParent(parent);
-               
wac.setServletContext(filter.getFilterConfig().getServletContext());
-               wac.setConfigLocation(getContextConfigLocation(filter));
+               webApplicationContext = newApplicationContext();
+               webApplicationContext.setParent(parent);
+               
webApplicationContext.setServletContext(filter.getFilterConfig().getServletContext());
+               
webApplicationContext.setConfigLocation(getContextConfigLocation(filter));
 
-               postProcessWebApplicationContext(wac, filter);
-               wac.refresh();
+               postProcessWebApplicationContext(webApplicationContext, filter);
+               webApplicationContext.refresh();
 
-               return wac;
+               return webApplicationContext;
        }
 
        /**
@@ -214,9 +223,9 @@ public class SpringWebApplicationFactory implements 
IWebApplicationFactory
        @Override
        public void destroy(final WicketFilter filter)
        {
-               if (additionalContext != null)
+               if (webApplicationContext != null)
                {
-                       additionalContext.close();
+                       webApplicationContext.close();
                }
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/01796138/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/SpringComponentInjector.java
----------------------------------------------------------------------
diff --git 
a/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/SpringComponentInjector.java
 
b/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/SpringComponentInjector.java
index 125590c..eb722d4 100644
--- 
a/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/SpringComponentInjector.java
+++ 
b/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/SpringComponentInjector.java
@@ -69,17 +69,14 @@ public class SpringComponentInjector extends Injector
        /**
         * Constructor used when spring application context is declared in the 
spring standard way and
         * can be located through
-        * {@link 
WebApplicationContextUtils#getRequiredWebApplicationContext(ServletContext)}
+        * {@link 
WebApplicationContextUtils#getRequiredWebApplicationContext(ServletContext)}.
         * 
         * @param webapp
         *            wicket web application
         */
        public SpringComponentInjector(final WebApplication webapp)
        {
-               // locate application context through spring's default location
-               // mechanism and pass it on to the proper constructor
-               this(webapp,
-                       
WebApplicationContextUtils.getRequiredWebApplicationContext(webapp.getServletContext()));
+               this(webapp, getDefaultContext(webapp));
        }
 
        /**
@@ -163,4 +160,38 @@ public class SpringComponentInjector extends Injector
 
        }
 
+       /**
+        * Try to use an already pre-configured application context or locate 
it through Spring's default
+        * location mechanism.
+        * 
+        * @param webapp
+        * @return the application context to use for injection
+        */
+       private static ApplicationContext getDefaultContext(final 
WebApplication webapp)
+       {
+               ApplicationContext context = webapp.getMetaData(CONTEXT_KEY);
+               if (context == null)
+               {
+                       context = 
WebApplicationContextUtils.getRequiredWebApplicationContext(webapp.getServletContext());
+               }
+               return context;
+       }
+
+       /**
+        * Set the default context for the given webapp.
+        * 
+        * @param webapp
+        *            web application
+        * @param context
+        *            context to use as default if non is explicitely specified 
for the injector
+        */
+       public static void setDefaultContext(final WebApplication webapp, 
ApplicationContext context)
+       {
+               Args.notNull(context, "context");
+
+               if (webapp.getMetaData(CONTEXT_KEY) == null)
+               {
+                       webapp.setMetaData(CONTEXT_KEY, context);
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/01796138/wicket-spring/src/test/java/org/apache/wicket/spring/SpringWebApplicationFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-spring/src/test/java/org/apache/wicket/spring/SpringWebApplicationFactoryTest.java
 
b/wicket-spring/src/test/java/org/apache/wicket/spring/SpringWebApplicationFactoryTest.java
new file mode 100644
index 0000000..ad1c9f5
--- /dev/null
+++ 
b/wicket-spring/src/test/java/org/apache/wicket/spring/SpringWebApplicationFactoryTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.wicket.spring;
+
+import java.util.Enumeration;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WicketFilter;
+import org.apache.wicket.protocol.http.mock.MockServletContext;
+import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
+import org.apache.wicket.util.lang.Packages;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link SpringWebApplicationFactory}.
+ * 
+ * @author svenmeier
+ */
+public class SpringWebApplicationFactoryTest extends Assert
+{
+
+       /**
+        * @throws Exception
+        */
+       @Test
+       public void test() throws Exception
+       {
+               WicketFilter filter = new WicketFilter();
+
+               filter.init(new FilterConfigImpl());
+
+               assertFalse(Destroyable.instance.destroyed);
+
+               filter.destroy();
+
+               assertTrue("is not destroyed", Destroyable.instance.destroyed);
+       }
+
+       private class FilterConfigImpl implements FilterConfig
+       {
+
+               @Override
+               public String getFilterName()
+               {
+                       return "test";
+               }
+
+               @Override
+               public ServletContext getServletContext()
+               {
+                       return new MockServletContext(null, null);
+               }
+
+               @Override
+               public String getInitParameter(String name)
+               {
+                       if ("applicationFactoryClassName".equals(name))
+                       {
+                               // use Spring factory
+                               return 
SpringWebApplicationFactory.class.getName();
+                       }
+                       if ("contextConfigLocation".equals(name))
+                       {
+                               // use application-specific context
+                               return "classpath:" + 
Packages.absolutePath(getClass(), "applicationContext.xml");
+                       }
+                       return null;
+               }
+
+               @Override
+               public Enumeration<?> getInitParameterNames()
+               {
+                       throw new UnsupportedOperationException();
+               }
+       }
+
+       /**
+        * Application configured in the application context.
+        */
+       public static class Application extends WebApplication
+       {
+               @Override
+               public Class<? extends Page> getHomePage()
+               {
+                       throw new UnsupportedOperationException();
+               }
+
+               @Override
+               protected void init()
+               {
+                       super.init();
+
+                       try
+                       {
+                               new SpringComponentInjector(this);
+                       }
+                       catch (Exception ex)
+                       {
+                               fail("does not work with application-specific 
context");
+                       }
+               }
+       }
+
+       /**
+        * A destroyable bean defined in the application context.
+        */
+       public static class Destroyable
+       {
+               static Destroyable instance;
+
+               boolean destroyed;
+
+               /**
+                */
+               public Destroyable()
+               {
+                       instance = this;
+               }
+
+               /**
+                * Called by Spring.
+                */
+               public void destroy()
+               {
+                       destroyed = true;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/01796138/wicket-spring/src/test/java/org/apache/wicket/spring/applicationContext.xml
----------------------------------------------------------------------
diff --git 
a/wicket-spring/src/test/java/org/apache/wicket/spring/applicationContext.xml 
b/wicket-spring/src/test/java/org/apache/wicket/spring/applicationContext.xml
new file mode 100644
index 0000000..d1a961d
--- /dev/null
+++ 
b/wicket-spring/src/test/java/org/apache/wicket/spring/applicationContext.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd";>
+
+<beans>
+       <bean 
class="org.apache.wicket.spring.SpringWebApplicationFactoryTest$Application" />
+       
+       <bean id="watcher" 
class="org.apache.wicket.spring.SpringWebApplicationFactoryTest$Destroyable" 
destroy-method="destroy" />
+</beans>

Reply via email to