/* * Copyright 2004-2012 the original author or authors. * * 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.springframework.webflow.persistence; import javax.sql.DataSource; import junit.framework.TestCase; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.webflow.engine.EndState; import org.springframework.webflow.execution.FlowExecutionListener; import org.springframework.webflow.execution.FlowSession; import org.springframework.webflow.test.MockFlowSession; import org.springframework.webflow.test.MockRequestContext; public abstract class AbstractPersistenceContextPropagationTests extends TestCase { private MockRequestContext requestContext; private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } protected final void setUp() throws Exception { requestContext = new MockRequestContext(); DataSource dataSource = createDataSource(); jdbcTemplate = new JdbcTemplate(dataSource); populateDataBase(dataSource); setUpResources(dataSource); } public void testSessionStarting_NoPc_ParentPc() { MockFlowSession parentSession = newFlowSession(true, null); MockFlowSession childSession = newFlowSession(false, parentSession); getListener().sessionStarting(new MockRequestContext(), parentSession, null); assertSessionBound(); assertSessionInScope(parentSession); getListener().sessionStarting(new MockRequestContext(), childSession, null); assertSessionNotBound(); assertSessionNotInScope(childSession); } public void testSessionStarting_Pc_ParentPc() { MockFlowSession parentSession = newFlowSession(true, null); MockFlowSession childSession = newFlowSession(true, parentSession); getListener().sessionStarting(new MockRequestContext(), parentSession, null); assertSessionBound(); assertSessionInScope(parentSession); getListener().sessionStarting(new MockRequestContext(), childSession, null); assertSessionBound(); assertSessionInScope(childSession); assertSame("Parent PersistenceContext should be re-used", parentSession.getScope().get("persistenceContext"), childSession.getScope().get("persistenceContext")); } public void testSessionEnd_Pc_NoParentPc() { MockFlowSession parentSession = newFlowSession(false, null); MockFlowSession childSession = newFlowSession(true, parentSession); getListener().sessionStarting(requestContext, parentSession, null); getListener().sessionStarting(requestContext, childSession, null); assertCommitState(true, false); requestContext.setActiveSession(childSession); // Session ending commits, unbinds/closes PersistenceContext getListener().sessionEnding(requestContext, childSession, "success", null); assertSessionNotBound(); // sessionEnded has no effect getListener().sessionEnded(requestContext, childSession, "success", null); assertSessionNotBound(); assertCommitState(false, true); } public void testSessionEnd_Pc_ParentPc() { MockFlowSession parentSession = newFlowSession(true, null); MockFlowSession childSession = newFlowSession(true, parentSession); getListener().sessionStarting(requestContext, parentSession, null); getListener().sessionStarting(requestContext, childSession, null); assertCommitState(true, false); requestContext.setActiveSession(childSession); // sessionEnding is a no-op getListener().sessionEnding(requestContext, childSession, "success", null); assertSessionBound(); assertCommitState(true, false); // sessionEnded binds Parent PersistenceContext getListener().sessionEnded(requestContext, childSession, "success", null); assertSessionBound(); } private MockFlowSession newFlowSession(boolean persistenceContext, FlowSession parent) { MockFlowSession flowSession = new MockFlowSession(); flowSession.setParent(parent); if (persistenceContext) { flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); } EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); endState.getAttributes().put("commit", true); flowSession.setState(endState); return flowSession; } private DataSource createDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); dataSource.setUrl("jdbc:hsqldb:mem:hspcl"); dataSource.setUsername("sa"); dataSource.setPassword(""); return dataSource; } private void populateDataBase(DataSource dataSource) throws Exception { ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); databasePopulator.addScript(new ClassPathResource("test-data.sql", this.getClass())); DataSourceInitializer initializer = new DataSourceInitializer(); initializer.setDataSource(dataSource); initializer.setDatabasePopulator(databasePopulator); initializer.afterPropertiesSet(); } /* methods for subclasses */ protected abstract void setUpResources(DataSource dataSource) throws Exception; protected abstract FlowExecutionListener getListener(); protected abstract void assertSessionBound(); protected abstract void assertSessionNotBound(); protected abstract void assertCommitState(boolean b, boolean c); /* private helper methods */ private void assertSessionInScope(FlowSession session) { assertTrue(session.getScope().contains("persistenceContext")); } private void assertSessionNotInScope(FlowSession session) { assertFalse(session.getScope().contains("persistenceContext")); } }