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>