You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/03/04 00:39:02 UTC

svn commit: r514275 - in /tapestry/tapestry5/tapestry-spring-integration/trunk/src: main/java/org/apache/tapestry/internal/spring/ main/java/org/apache/tapestry/spring/ main/resources/org/apache/tapestry/internal/spring/ main/resources/org/apache/tapes...

Author: hlship
Date: Sat Mar  3 15:39:01 2007
New Revision: 514275

URL: http://svn.apache.org/viewvc?view=rev&rev=514275
Log:
Move classes up to org.apache.tapestry.spring (but make them package private).
Split off a new service, tapestry.spring.WebApplicationContext.
Add documentation.

Added:
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringMessages.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringObjectProvider.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties
      - copied, changed from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/internal/spring/SpringStrings.properties
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringBean.java
      - copied, changed from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringBean.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringModuleTest.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringObjectProviderTest.java
      - copied, changed from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringObjectProviderTest.java
Removed:
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/internal/spring/SpringMessages.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/internal/spring/SpringObjectProvider.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/internal/spring/SpringStrings.properties
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringBean.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringObjectProviderTest.java
Modified:
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringModule.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/site/apt/index.apt
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/testng.xml
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/webdefault.xml
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/example/testapp/pages/Start.java
    tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/webapp/WEB-INF/web.xml

Added: tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringMessages.java?view=auto&rev=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringMessages.java (added)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringMessages.java Sat Mar  3 15:39:01 2007
@@ -0,0 +1,47 @@
+// Copyright 2007 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.tapestry.spring;
+
+import java.util.Collection;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.springframework.web.context.ContextLoaderListener;
+
+class SpringMessages
+{
+  private static final Messages MESSAGES = MessagesImpl.forClass(SpringMessages.class);
+
+  static String failureObtainingContext(Throwable cause)
+  {
+    return MESSAGES.format("failure-obtaining-context", cause);
+  }
+
+  static String missingContext()
+  {
+    return MESSAGES.format("missing-context", ContextLoaderListener.class.getName());
+  }
+
+  static String contextStartup(Collection<String> beanNames)
+  {
+    return MESSAGES.format("context-startup", InternalUtils.joinSorted(beanNames));
+  }
+
+  static String beanAccessFailure(String beanName, Class beanType, Throwable cause)
+  {
+    return MESSAGES.format("bean-access-failure", beanName, beanType.getName(), cause);
+  }
+}

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringModule.java?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringModule.java (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringModule.java Sat Mar  3 15:39:01 2007
@@ -15,7 +15,6 @@
 package org.apache.tapestry.spring;
 
 import org.apache.commons.logging.Log;
-import org.apache.tapestry.internal.spring.SpringObjectProvider;
 import org.apache.tapestry.ioc.MappedConfiguration;
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.annotations.Contribute;
@@ -30,15 +29,39 @@
 {
   /**
    * Provider that interprets expressions as the names of beans within the Spring
-   * {@link WebApplicationContext}. Spring <em>is case sensitive</em>, unlike Tapestry 5 IoC.
-   * The context must be configured in the <a
+   * {@link WebApplicationContext}.
+   */
+  public static ObjectProvider buildSpringObjectProvider(Log log,
+      @Inject("service:WebApplicationContext")
+      WebApplicationContext context)
+  {
+    return new SpringObjectProvider(log, context);
+  }
+
+  /**
+   * Obtains and returns the Spring WebApplicationContext, which is stored in the Servlet context
+   * using a well-known name. The WebApplicationContext must be configured in the <a
    * href="http://static.springframework.org/spring/docs/1.2.x/reference/beans.html#context-create">standard
    * way</a> (which involves adding a listener to the web.xml deployment descriptor).
    */
-  public static ObjectProvider buildSpringObjectProvider(Log log, @Inject("infrastructure:context")
+  public static WebApplicationContext buildWebApplicationContext(@Inject("infrastructure:context")
   Context context)
   {
-    return new SpringObjectProvider(log, context);
+    WebApplicationContext springContext = null;
+
+    try
+    {
+      springContext = (WebApplicationContext) context
+          .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+    }
+    catch (Exception ex)
+    {
+      throw new RuntimeException(SpringMessages.failureObtainingContext(ex), ex);
+    }
+
+    if (springContext == null) throw new RuntimeException(SpringMessages.missingContext());
+
+    return springContext;
   }
 
   /**

Added: tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringObjectProvider.java?view=auto&rev=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringObjectProvider.java (added)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/java/org/apache/tapestry/spring/SpringObjectProvider.java Sat Mar  3 15:39:01 2007
@@ -0,0 +1,75 @@
+// Copyright 2007 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.tapestry.spring;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.ServiceLocator;
+import org.springframework.web.context.WebApplicationContext;
+
+/**
+ * Provides an object from the Spring bean context (configured in web.xml).
+ * <p>
+ * This is just a first pass; later we'll have the provider check to see if beans are singletons,
+ * and provide a proxy to the singleton rather than the raw object itself.
+ */
+class SpringObjectProvider implements ObjectProvider
+{
+  private final WebApplicationContext _context;
+
+  private final Map<String, String> _beanNames = newCaseInsensitiveMap();
+
+  public SpringObjectProvider(Log log, WebApplicationContext context)
+  {
+    _context = context;
+
+    // Build up a case-insensitive mapping of bean names.
+
+    for (String name : _context.getBeanDefinitionNames())
+    {
+      _beanNames.put(name, name);
+    }
+
+    log.info(SpringMessages.contextStartup(_beanNames.keySet()));
+  }
+
+  /**
+   * The expression is the name of a spring bean inside the context.
+   */
+  public <T> T provide(String expression, Class<T> objectType, ServiceLocator locator)
+  {
+    // Attempt to convert from the base insensitive name to the name as defined by Spring
+    // (which is, to my knowledge) case sensitive.
+    String effectiveName = _beanNames.containsKey(expression) ? _beanNames.get(expression)
+        : expression;
+
+    try
+    {
+      Object raw = _context.getBean(effectiveName, objectType);
+
+      return objectType.cast(raw);
+    }
+    catch (Exception ex)
+    {
+      throw new RuntimeException(SpringMessages.beanAccessFailure(effectiveName, objectType, ex),
+          ex);
+    }
+  }
+
+}

Copied: tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties (from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/internal/spring/SpringStrings.properties)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties?view=diff&rev=514275&p1=tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/internal/spring/SpringStrings.properties&r1=514053&p2=tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/internal/spring/SpringStrings.properties (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties Sat Mar  3 15:39:01 2007
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-failure-obtaining-context=An exception occurred obtained the Spring WebApplicationContext: %s
+failure-obtaining-context=An exception occurred obtaining the Spring WebApplicationContext: %s
 missing-context=The Spring WebApplicationContext is not present. The likely cause is that the %s listener was not declared inside the application's web.xml deployment descriptor.
-using-context=Using Spring WebApplicationContext %s.
+context-startup=Using Spring WebApplicationContext containing beans: %s
 bean-access-failure=A failure occured obtaining Spring bean '%s' (of type %s): %s

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/site/apt/index.apt?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/site/apt/index.apt Sat Mar  3 15:39:01 2007
@@ -7,4 +7,75 @@
   Provides integration between Tapestry and Spring, allowing beans defined by Spring to be injected into Tapestry IoC services, and into
   Tapestry components.
   
-  
\ No newline at end of file
+Version
+
+  This module is compiled and tested against Spring 1.8.2.  However, Spring 2.0 is fully backwards compatible to Spring 1.8.2.
+  
+  This module uses the Maven scope "provided" for the dependencies on Spring. This means that in your own POM, you will need to specify your own
+  dependency to Spring, including the correct version.  Example:
+  
++---+
+<dependency>
+  <groupId>org.springframework</groupId>
+  <artifactId>spring-web</artifactId>
+  <version>1.2.8</version>
+</dependency>    
++----+
+
+  With the default Maven scope, the Spring JARs and dependencies will be packaged into your application's WAR file.
+  
+  
+Usage
+
+  The integration is designed to be a very thin layer on top of Spring's normal configuration for a web application.
+  
+  Detailed instructions are available in the
+  {{{http://static.springframework.org/spring/docs/1.2.x/reference/beans.html#context-create}Spring 1.2.x documentation}}.
+  
+* web.xml changes
+  
+  The short form is that you must make a small change to your application's web.xml:
+ 
++---+
+<context-param>
+  <param-name>contextConfigLocation</param-name>
+  <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
+</context-param>
+
+<listener>
+  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+</listener>
++---+
+
+  The \<context-param\> lists the Spring bean configuration file.  It is optional and defaults to just /WEB-INF/applicationContext.xml if omitted.
+  
+  The ContextLoaderListener is responsible for reading the bean configuration file (or files) and storing the result in the application context, where
+  the Tapestry-Spring integration code can make use of it.
+  
+* Injecting beans
+
+  Inside your component classes, you may use the 
+  {{{http://tapestry.apache.org/tapestry5/tapestry-core/apidocs/org/apache/tapestry/annotations/Inject.html}Inject}} annotation.  The annotation
+  value should be "spring:" + the name of the bean.  Example:
+  
++----+
+  @Inject("spring:userDAO")
+  private UserDAO _userDAO;
++----+
+
+Case Insensitivity
+
+  At startup, the names of all the beans provided by the Spring application context is obtained and use to build a case-insensitive map.
+  When a bean is requested, it is filtered through this map to get the case-sensitive name required by Spring. The upshot of this is that
+  you should not have to be concerned with case: in the above example "Spring:UserDAO" or "SPRING:userdao" would work equally well.
+  
+Limitations
+
+  Case insensitivity is limited to beans whose names are available at application startup; it is possible to programatically add bean definitions
+  at runtime, but these will not be available case-insensitively (but using exactly matching case will still work).
+  
+  No check is made for name clashes that would occur when two beans have names that differ only in case.
+  
+  Non-singleton beans are not handled properly. Tapestry will request the beans from the application context in a manner unsuitable for their lifecycle.
+  For the moment, you should consider the non-singleton beans to be not-injectable.  Instead, inject the tapestry.spring.WebApplicationContext service and
+  obtain the non-singleton beans as needed.

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/testng.xml?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/testng.xml Sat Mar  3 15:39:01 2007
@@ -19,7 +19,6 @@
   <test name="Tapestry Spring Integration">
     <parameter name="tapestry.integration-webapp" value="src/test/webapp"/>
     <packages>
-      <package name="org.apache.tapestry.internal.spring"/>
       <package name="org.apache.tapestry.spring"/>
     </packages>
   </test>

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/webdefault.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/webdefault.xml?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/webdefault.xml (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/conf/webdefault.xml Sat Mar  3 15:39:01 2007
@@ -14,6 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
+
 <web-app 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

Copied: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringBean.java (from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringBean.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringBean.java?view=diff&rev=514275&p1=tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringBean.java&r1=514053&p2=tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringBean.java&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringBean.java (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringBean.java Sat Mar  3 15:39:01 2007
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.spring;
+package org.apache.tapestry.spring;
 
 public interface SpringBean
 {

Added: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringModuleTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringModuleTest.java?view=auto&rev=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringModuleTest.java (added)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringModuleTest.java Sat Mar  3 15:39:01 2007
@@ -0,0 +1,92 @@
+// Copyright 2007 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.tapestry.spring;
+
+import org.apache.tapestry.services.Context;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.springframework.web.context.WebApplicationContext;
+import org.testng.annotations.Test;
+
+public class SpringModuleTest extends TapestryTestCase
+{
+
+  @Test
+  public void missing_spring_context()
+  {
+    Context context = newContext(null);
+
+    replay();
+
+    try
+    {
+      SpringModule.buildWebApplicationContext(context);
+
+      unreachable();
+    }
+    catch (RuntimeException ex)
+    {
+      assertEquals(
+          ex.getMessage(),
+          "The Spring WebApplicationContext is not present. The likely cause is that the org.springframework.web.context.ContextLoaderListener listener was not declared inside the application\'s web.xml deployment descriptor.");
+    }
+
+    verify();
+  }
+
+  @Test
+  public void success()
+  {
+    WebApplicationContext webContext = newMock(WebApplicationContext.class);
+    Context context = newContext(webContext);
+
+    replay();
+
+    assertSame(SpringModule.buildWebApplicationContext(context), webContext);
+
+    verify();
+  }
+
+  protected final Context newContext(Object webApplicationContext)
+  {
+    Context context = newContext();
+
+    expect(context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE))
+        .andReturn(webApplicationContext);
+
+    return context;
+  }
+
+  @Test
+  public void error_getting_spring_context()
+  {
+    Context context = newContext("[Placeholder]");
+
+    replay();
+
+    try
+    {
+      SpringModule.buildWebApplicationContext(context);
+      unreachable();
+    }
+    catch (RuntimeException ex)
+    {
+      assertTrue(ex.getMessage().startsWith(
+          "An exception occurred obtaining the Spring WebApplicationContext"));
+    }
+
+    verify();
+  }
+
+}

Copied: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringObjectProviderTest.java (from r514053, tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringObjectProviderTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringObjectProviderTest.java?view=diff&rev=514275&p1=tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringObjectProviderTest.java&r1=514053&p2=tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringObjectProviderTest.java&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/internal/spring/SpringObjectProviderTest.java (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/apache/tapestry/spring/SpringObjectProviderTest.java Sat Mar  3 15:39:01 2007
@@ -12,141 +12,132 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.spring;
+package org.apache.tapestry.spring;
 
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.ServiceLocator;
-import org.apache.tapestry.services.Context;
 import org.apache.tapestry.test.TapestryTestCase;
 import org.springframework.web.context.WebApplicationContext;
 import org.testng.annotations.Test;
 
 public class SpringObjectProviderTest extends TapestryTestCase
 {
-  private static final String STARTUP_MESSAGE = "Using Spring WebApplicationContext [Mock WebApplicationContext].";
+  private static final String STARTUP_MESSAGE = "Using Spring WebApplicationContext containing beans: ";
 
   private static final String BEAN_NAME = "mySpringBean";
 
-  private static final String DISPLAY_NAME = "[Mock WebApplicationContext]";
-
   @Test
-  public void missing_spring_context()
+  public void failure_getting_bean_from_context()
   {
     Log log = newLog();
-    Context context = newContext(null);
+    WebApplicationContext webContext = newWebApplicationContext();
+    ServiceLocator locator = newServiceLocator();
+    Throwable t = new RuntimeException("Simulated failure.");
+
+    train_getBeanDefinitionNames(webContext, BEAN_NAME);
+
+    log.info(STARTUP_MESSAGE + BEAN_NAME);
+
+    expect(webContext.getBean(BEAN_NAME, SpringBean.class)).andThrow(t);
 
     replay();
 
+    ObjectProvider provider = new SpringObjectProvider(log, webContext);
+
     try
     {
-      new SpringObjectProvider(log, context);
+      provider.provide(BEAN_NAME, SpringBean.class, locator);
       unreachable();
     }
     catch (RuntimeException ex)
     {
       assertEquals(
           ex.getMessage(),
-          "The Spring WebApplicationContext is not present. The likely cause is that the org.springframework.web.context.ContextLoaderListener listener was not declared inside the application\'s web.xml deployment descriptor.");
+          "A failure occured obtaining Spring bean \'mySpringBean\' (of type org.apache.tapestry.spring.SpringBean): Simulated failure.");
+      assertSame(ex.getCause(), t);
     }
 
     verify();
   }
 
   @Test
-  public void error_getting_spring_context()
+  public void get_bean_from_context()
   {
     Log log = newLog();
-    Context context = newContext("[Placeholder]");
+    WebApplicationContext webContext = newWebApplicationContext();
+    ServiceLocator locator = newServiceLocator();
     SpringBean bean = newMock(SpringBean.class);
 
+    train_getBeanDefinitionNames(webContext, "fred", "barney", BEAN_NAME);
+
+    log.info(STARTUP_MESSAGE + "barney, fred, " + BEAN_NAME);
+
+    expect(webContext.getBean(BEAN_NAME, SpringBean.class)).andReturn(bean);
+
     replay();
 
-    try
-    {
-      new SpringObjectProvider(log, context);
-      unreachable();
-    }
-    catch (RuntimeException ex)
-    {
-      assertTrue(ex.getMessage().startsWith(
-          "An exception occurred obtained the Spring WebApplicationContext"));
-    }
+    ObjectProvider provider = new SpringObjectProvider(log, webContext);
+
+    assertSame(provider.provide(BEAN_NAME, SpringBean.class, locator), bean);
 
     verify();
   }
 
   @Test
-  public void get_bean_from_context()
+  public void bean_name_is_case_insensitive_if_in_bean_definitions()
   {
     Log log = newLog();
-    WebApplicationContext webContext = newWebApplicationContext(DISPLAY_NAME);
-    Context context = newContext(webContext);
+    WebApplicationContext webContext = newWebApplicationContext();
     ServiceLocator locator = newServiceLocator();
     SpringBean bean = newMock(SpringBean.class);
 
-    log.info(STARTUP_MESSAGE);
+    train_getBeanDefinitionNames(webContext, "fred", "barney", BEAN_NAME);
+
+    log.info(STARTUP_MESSAGE + "barney, fred, " + BEAN_NAME);
 
     expect(webContext.getBean(BEAN_NAME, SpringBean.class)).andReturn(bean);
 
     replay();
 
-    ObjectProvider provider = new SpringObjectProvider(log, context);
+    ObjectProvider provider = new SpringObjectProvider(log, webContext);
 
-    assertSame(provider.provide(BEAN_NAME, SpringBean.class, locator), bean);
+    assertSame(provider.provide(BEAN_NAME.toUpperCase(), SpringBean.class, locator), bean);
 
     verify();
   }
 
   @Test
-  public void failure_getting_bean_from_context()
+  public void bean_name_outside_of_bean_definitions_supported_with_provided_case()
   {
     Log log = newLog();
-    WebApplicationContext webContext = newWebApplicationContext(DISPLAY_NAME);
-    Context context = newContext(webContext);
+    WebApplicationContext webContext = newWebApplicationContext();
     ServiceLocator locator = newServiceLocator();
-    Throwable t = new RuntimeException("Simulated failure.");
+    SpringBean bean = newMock(SpringBean.class);
 
-    log.info(STARTUP_MESSAGE);
+    train_getBeanDefinitionNames(webContext, "fred", "barney");
 
-    expect(webContext.getBean(BEAN_NAME, SpringBean.class)).andThrow(t);
+    log.info(STARTUP_MESSAGE + "barney, fred");
+
+    expect(webContext.getBean(BEAN_NAME, SpringBean.class)).andReturn(bean);
 
     replay();
 
-    ObjectProvider provider = new SpringObjectProvider(log, context);
+    ObjectProvider provider = new SpringObjectProvider(log, webContext);
 
-    try
-    {
-      provider.provide(BEAN_NAME, SpringBean.class, locator);
-      unreachable();
-    }
-    catch (RuntimeException ex)
-    {
-      assertEquals(
-          ex.getMessage(),
-          "A failure occured obtaining Spring bean \'mySpringBean\' (of type org.apache.tapestry.internal.spring.SpringBean): Simulated failure.");
-      assertSame(ex.getCause(), t);
-    }
+    assertSame(provider.provide(BEAN_NAME, SpringBean.class, locator), bean);
 
     verify();
   }
 
-  protected final WebApplicationContext newWebApplicationContext(String name)
+  protected final void train_getBeanDefinitionNames(WebApplicationContext context, String... names)
   {
-    WebApplicationContext context = newMock(WebApplicationContext.class);
-
-    expect(context.getDisplayName()).andReturn(name).atLeastOnce();
-
-    return context;
+    expect(context.getBeanDefinitionNames()).andReturn(names);
   }
 
-  protected final Context newContext(Object webApplicationContext)
+  protected final WebApplicationContext newWebApplicationContext()
   {
-    Context context = newContext();
-
-    expect(context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE))
-        .andReturn(webApplicationContext);
-
-    return context;
+    return newMock(WebApplicationContext.class);
   }
+
 }

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/example/testapp/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/example/testapp/pages/Start.java?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/example/testapp/pages/Start.java (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/java/org/example/testapp/pages/Start.java Sat Mar  3 15:39:01 2007
@@ -23,7 +23,8 @@
   @Retain
   private String _input;
 
-  @Inject("spring:upcase")
+  // Demonstrating case insensitivity
+  @Inject("Spring:Upcase")
   private Upcase _upcaseBean;
 
   void onSuccess()

Modified: tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/webapp/WEB-INF/web.xml?view=diff&rev=514275&r1=514274&r2=514275
==============================================================================
--- tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/webapp/WEB-INF/web.xml (original)
+++ tapestry/tapestry5/tapestry-spring-integration/trunk/src/test/webapp/WEB-INF/web.xml Sat Mar  3 15:39:01 2007
@@ -1,21 +1,20 @@
-<!DOCTYPE web-app
-      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
-      "http://java.sun.com/dtd/web-app_2_3.dtd">      
+<!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
-  
-  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.
--->      
+   Copyright 2007 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.
+-->
+
 <web-app>
   <display-name>Tapestry-Spring Integration Test Application</display-name>
   <context-param>