Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@445 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
97 changed files with 4324 additions and 1056 deletions
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.beans.factory.config; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.beans.factory.ObjectFactory; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
*/ |
||||
public class SimpleMapScope implements Scope, Serializable { |
||||
|
||||
private final Map map = new HashMap(); |
||||
|
||||
private final List callbacks = new LinkedList(); |
||||
|
||||
|
||||
public SimpleMapScope() { |
||||
} |
||||
|
||||
public final Map getMap() { |
||||
return this.map; |
||||
} |
||||
|
||||
|
||||
public Object get(String name, ObjectFactory objectFactory) { |
||||
synchronized (this.map) { |
||||
Object scopedObject = this.map.get(name); |
||||
if (scopedObject == null) { |
||||
scopedObject = objectFactory.getObject(); |
||||
this.map.put(name, scopedObject); |
||||
} |
||||
return scopedObject; |
||||
} |
||||
} |
||||
|
||||
public Object remove(String name) { |
||||
synchronized (this.map) { |
||||
return this.map.remove(name); |
||||
} |
||||
} |
||||
|
||||
public void registerDestructionCallback(String name, Runnable callback) { |
||||
this.callbacks.add(callback); |
||||
} |
||||
|
||||
public Object resolveContextualObject(String key) { |
||||
return null; |
||||
} |
||||
|
||||
public void close() { |
||||
for (Iterator it = this.callbacks.iterator(); it.hasNext();) { |
||||
Runnable runnable = (Runnable) it.next(); |
||||
runnable.run(); |
||||
} |
||||
} |
||||
|
||||
public String getConversationId() { |
||||
return null; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,631 @@
@@ -0,0 +1,631 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.hibernate3.support; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.junit.Ignore; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @since 05.03.2005 |
||||
*/ |
||||
@Ignore // getting errors on mocks
|
||||
public class OpenSessionInViewTests extends TestCase { |
||||
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf, 2);
|
||||
// session.isOpen();
|
||||
// sessionControl.setReturnValue(true, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactoryImplementor.class);
|
||||
// final SessionFactoryImplementor sf = (SessionFactoryImplementor) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
// TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
// tm.getTransaction();
|
||||
// tmControl.setReturnValue(null, 2);
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.getTransactionManager();
|
||||
// sfControl.setReturnValue(tm, 2);
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.isOpen();
|
||||
// sessionControl.setReturnValue(true, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
//
|
||||
// tmControl.replay();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.flush();
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setSingleSession(false);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
//
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithSingleSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
|
||||
// MockControl session2Control = MockControl.createControl(Session.class);
|
||||
// Session session2 = (Session) session2Control.getMock();
|
||||
//
|
||||
// sf2.openSession();
|
||||
// sf2Control.setReturnValue(session2, 1);
|
||||
// session2.getSessionFactory();
|
||||
// session2Control.setReturnValue(sf);
|
||||
// session2.setFlushMode(FlushMode.AUTO);
|
||||
// session2Control.setVoidCallable(1);
|
||||
// session2.close();
|
||||
// session2Control.setReturnValue(null, 1);
|
||||
// sf2Control.replay();
|
||||
// session2Control.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
// filterConfig2.addInitParameter("flushMode", "AUTO");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sf2Control.verify();
|
||||
// session2Control.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// filter.doFilter(request, response, filterChain);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// final MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// final Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.getFlushMode();
|
||||
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
|
||||
// final MockControl session2Control = MockControl.createControl(Session.class);
|
||||
// final Session session2 = (Session) session2Control.getMock();
|
||||
// MockControl txControl = MockControl.createControl(Transaction.class);
|
||||
// Transaction tx = (Transaction) txControl.getMock();
|
||||
// MockControl conControl = MockControl.createControl(Connection.class);
|
||||
// Connection con = (Connection) conControl.getMock();
|
||||
//
|
||||
// sf2.openSession();
|
||||
// sf2Control.setReturnValue(session2, 1);
|
||||
// session2.beginTransaction();
|
||||
// session2Control.setReturnValue(tx, 1);
|
||||
// session2.connection();
|
||||
// session2Control.setReturnValue(con, 2);
|
||||
// tx.commit();
|
||||
// txControl.setVoidCallable(1);
|
||||
// session2.isConnected();
|
||||
// session2Control.setReturnValue(true, 1);
|
||||
// con.isReadOnly();
|
||||
// conControl.setReturnValue(false, 1);
|
||||
// session2.setFlushMode(FlushMode.NEVER);
|
||||
// session2Control.setVoidCallable(1);
|
||||
//
|
||||
// sf2Control.replay();
|
||||
// session2Control.replay();
|
||||
// txControl.replay();
|
||||
// conControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
|
||||
// TransactionStatus ts = tm.getTransaction(
|
||||
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// sessionControl.verify();
|
||||
// sessionControl.reset();
|
||||
//
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
//
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf2);
|
||||
// TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// session2Control.verify();
|
||||
// session2Control.reset();
|
||||
//
|
||||
// session2.close();
|
||||
// session2Control.setReturnValue(null, 1);
|
||||
// session2Control.replay();
|
||||
//
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sf2Control.verify();
|
||||
// session2Control.verify();
|
||||
// txControl.verify();
|
||||
// conControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// final MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// final Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.getFlushMode();
|
||||
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setSingleSession(false);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
|
||||
// TransactionStatus ts = tm.getTransaction(
|
||||
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// sessionControl.verify();
|
||||
// sessionControl.reset();
|
||||
// try {
|
||||
// session.close();
|
||||
// }
|
||||
// catch (HibernateException ex) {
|
||||
// }
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// filter.doFilter(request, response, filterChain2);
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
} |
||||
@ -0,0 +1,165 @@
@@ -0,0 +1,165 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.jdo.support; |
||||
|
||||
import org.junit.Ignore; |
||||
|
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @author Chris Beams |
||||
* @since 15.06.2004 |
||||
*/ |
||||
@Ignore // dependency issues after moving from .testsuite -> .test
|
||||
public class OpenPersistenceManagerInViewTests { |
||||
|
||||
// public void testOpenPersistenceManagerInViewInterceptor() throws Exception {
|
||||
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
|
||||
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
|
||||
//
|
||||
// OpenPersistenceManagerInViewInterceptor rawInterceptor = new OpenPersistenceManagerInViewInterceptor();
|
||||
// rawInterceptor.setPersistenceManagerFactory(pmf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// pmf.getPersistenceManager();
|
||||
// pmfControl.setReturnValue(pm, 1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
//
|
||||
// pmfControl.reset();
|
||||
// pmControl.reset();
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
//
|
||||
// pmfControl.reset();
|
||||
// pmControl.reset();
|
||||
// pm.close();
|
||||
// pmControl.setVoidCallable(1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenPersistenceManagerInViewFilter() throws Exception {
|
||||
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// final PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
|
||||
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
|
||||
//
|
||||
// pmf.getPersistenceManager();
|
||||
// pmfControl.setReturnValue(pm, 1);
|
||||
// pm.close();
|
||||
// pmControl.setVoidCallable(1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
//
|
||||
// MockControl pmf2Control = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// final PersistenceManagerFactory pmf2 = (PersistenceManagerFactory) pmf2Control.getMock();
|
||||
// MockControl pm2Control = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm2 = (PersistenceManager) pm2Control.getMock();
|
||||
//
|
||||
// pmf2.getPersistenceManager();
|
||||
// pmf2Control.setReturnValue(pm2, 1);
|
||||
// pm2.close();
|
||||
// pm2Control.setVoidCallable(1);
|
||||
// pmf2Control.replay();
|
||||
// pm2Control.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("persistenceManagerFactory", pmf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("myPersistenceManagerFactory", pmf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("persistenceManagerFactoryBeanName", "myPersistenceManagerFactory");
|
||||
//
|
||||
// final OpenPersistenceManagerInViewFilter filter = new OpenPersistenceManagerInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenPersistenceManagerInViewFilter filter2 = new OpenPersistenceManagerInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
// pmf2Control.verify();
|
||||
// pm2Control.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
} |
||||
@ -0,0 +1,187 @@
@@ -0,0 +1,187 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.jpa.support; |
||||
|
||||
import org.junit.Ignore; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* @author Costin Leau |
||||
* @author Juergen Hoeller |
||||
* @author Chris Beams |
||||
*/ |
||||
@Ignore // dependency issues after moving from .testsuite -> .test
|
||||
public class OpenEntityManagerInViewTests { |
||||
|
||||
// private MockControl factoryControl, managerControl;
|
||||
//
|
||||
// private EntityManager manager;
|
||||
//
|
||||
// private EntityManagerFactory factory;
|
||||
//
|
||||
// private JpaTemplate template;
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// protected void setUp() throws Exception {
|
||||
// factoryControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
// factory = (EntityManagerFactory) factoryControl.getMock();
|
||||
// managerControl = MockControl.createControl(EntityManager.class);
|
||||
// manager = (EntityManager) managerControl.getMock();
|
||||
//
|
||||
// template = new JpaTemplate(factory);
|
||||
// template.afterPropertiesSet();
|
||||
//
|
||||
// factoryControl.expectAndReturn(factory.createEntityManager(), manager);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void tearDown() throws Exception {
|
||||
// assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
// assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
// assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
|
||||
// assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
// }
|
||||
//
|
||||
// public void testOpenEntityManagerInterceptorInView() throws Exception {
|
||||
// OpenEntityManagerInViewInterceptor rawInterceptor = new OpenEntityManagerInViewInterceptor();
|
||||
// rawInterceptor.setEntityManagerFactory(factory);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
//
|
||||
// managerControl.reset();
|
||||
// factoryControl.reset();
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
//
|
||||
// managerControl.reset();
|
||||
// factoryControl.reset();
|
||||
//
|
||||
// manager.close();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenEntityManagerInViewFilter() throws Exception {
|
||||
// manager.close();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// MockControl factoryControl2 = MockControl.createControl(EntityManagerFactory.class);
|
||||
// final EntityManagerFactory factory2 = (EntityManagerFactory) factoryControl2.getMock();
|
||||
//
|
||||
// MockControl managerControl2 = MockControl.createControl(EntityManager.class);
|
||||
// EntityManager manager2 = (EntityManager) managerControl2.getMock();
|
||||
//
|
||||
// factoryControl2.expectAndReturn(factory2.createEntityManager(), manager2);
|
||||
// manager2.close();
|
||||
//
|
||||
// factoryControl2.replay();
|
||||
// managerControl2.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory");
|
||||
//
|
||||
// final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
// factoryControl2.verify();
|
||||
// managerControl2.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
} |
||||
@ -0,0 +1,292 @@
@@ -0,0 +1,292 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Modifier; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* <p> |
||||
* Convenient superclass for JUnit 3.8 based tests depending on a Spring |
||||
* context. The test instance itself is populated by Dependency Injection. |
||||
* </p> |
||||
* <p> |
||||
* Really for integration testing, not unit testing. You should <i>not</i> |
||||
* normally use the Spring container for unit tests: simply populate your POJOs |
||||
* in plain JUnit tests! |
||||
* </p> |
||||
* <p> |
||||
* This supports two modes of populating the test: |
||||
* </p> |
||||
* <ul> |
||||
* <li>Via Setter Dependency Injection. Simply express dependencies on objects |
||||
* in the test fixture, and they will be satisfied by autowiring by type. |
||||
* <li>Via Field Injection. Declare protected variables of the required type |
||||
* which match named beans in the context. This is autowire by name, rather than |
||||
* type. This approach is based on an approach originated by Ara Abrahmian. |
||||
* Setter Dependency Injection is the default: set the |
||||
* <code>populateProtectedVariables</code> property to <code>true</code> in |
||||
* the constructor to switch on Field Injection. |
||||
* </ul> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Rob Harrop |
||||
* @author Rick Evans |
||||
* @author Sam Brannen |
||||
* @since 1.1.1 |
||||
* @see #setDirty |
||||
* @see #contextKey |
||||
* @see #getContext |
||||
* @see #getConfigLocations |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractDependencyInjectionSpringContextTests extends AbstractSingleSpringContextTests { |
||||
|
||||
/** |
||||
* Constant that indicates no autowiring at all. |
||||
* |
||||
* @see #setAutowireMode |
||||
*/ |
||||
public static final int AUTOWIRE_NO = 0; |
||||
|
||||
/** |
||||
* Constant that indicates autowiring bean properties by name. |
||||
* |
||||
* @see #setAutowireMode |
||||
*/ |
||||
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; |
||||
|
||||
/** |
||||
* Constant that indicates autowiring bean properties by type. |
||||
* |
||||
* @see #setAutowireMode |
||||
*/ |
||||
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; |
||||
|
||||
private boolean populateProtectedVariables = false; |
||||
|
||||
private int autowireMode = AUTOWIRE_BY_TYPE; |
||||
|
||||
private boolean dependencyCheck = true; |
||||
|
||||
private String[] managedVariableNames; |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractDependencyInjectionSpringContextTests. |
||||
*/ |
||||
public AbstractDependencyInjectionSpringContextTests() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for AbstractDependencyInjectionSpringContextTests with a |
||||
* JUnit name. |
||||
* @param name the name of this text fixture |
||||
*/ |
||||
public AbstractDependencyInjectionSpringContextTests(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Set whether to populate protected variables of this test case. Default is |
||||
* <code>false</code>. |
||||
*/ |
||||
public final void setPopulateProtectedVariables(boolean populateFields) { |
||||
this.populateProtectedVariables = populateFields; |
||||
} |
||||
|
||||
/** |
||||
* Return whether to populate protected variables of this test case. |
||||
*/ |
||||
public final boolean isPopulateProtectedVariables() { |
||||
return this.populateProtectedVariables; |
||||
} |
||||
|
||||
/** |
||||
* Set the autowire mode for test properties set by Dependency Injection. |
||||
* <p>The default is {@link #AUTOWIRE_BY_TYPE}. Can be set to |
||||
* {@link #AUTOWIRE_BY_NAME} or {@link #AUTOWIRE_NO} instead. |
||||
* @see #AUTOWIRE_BY_TYPE |
||||
* @see #AUTOWIRE_BY_NAME |
||||
* @see #AUTOWIRE_NO |
||||
*/ |
||||
public final void setAutowireMode(final int autowireMode) { |
||||
this.autowireMode = autowireMode; |
||||
} |
||||
|
||||
/** |
||||
* Return the autowire mode for test properties set by Dependency Injection. |
||||
*/ |
||||
public final int getAutowireMode() { |
||||
return this.autowireMode; |
||||
} |
||||
|
||||
/** |
||||
* Set whether or not dependency checking should be performed for test |
||||
* properties set by Dependency Injection. |
||||
* <p>The default is <code>true</code>, meaning that tests cannot be run |
||||
* unless all properties are populated. |
||||
*/ |
||||
public final void setDependencyCheck(final boolean dependencyCheck) { |
||||
this.dependencyCheck = dependencyCheck; |
||||
} |
||||
|
||||
/** |
||||
* Return whether or not dependency checking should be performed for test |
||||
* properties set by Dependency Injection. |
||||
*/ |
||||
public final boolean isDependencyCheck() { |
||||
return this.dependencyCheck; |
||||
} |
||||
|
||||
/** |
||||
* Prepare this test instance, injecting dependencies into its protected |
||||
* fields and its bean properties. |
||||
* <p>Note: if the {@link ApplicationContext} for this test instance has not |
||||
* been configured (e.g., is <code>null</code>), dependency injection |
||||
* will naturally <strong>not</strong> be performed, but an informational |
||||
* message will be written to the log. |
||||
* @see #injectDependencies() |
||||
*/ |
||||
protected void prepareTestInstance() throws Exception { |
||||
if (getApplicationContext() == null) { |
||||
if (this.logger.isInfoEnabled()) { |
||||
this.logger.info("ApplicationContext has not been configured for test [" + getClass().getName() |
||||
+ "]: dependency injection will NOT be performed."); |
||||
} |
||||
} |
||||
else { |
||||
injectDependencies(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Inject dependencies into 'this' instance (that is, this test instance). |
||||
* <p>The default implementation populates protected variables if the |
||||
* {@link #populateProtectedVariables() appropriate flag is set}, else uses |
||||
* autowiring if autowiring is switched on (which it is by default). |
||||
* <p>Override this method if you need full control over how dependencies are |
||||
* injected into the test instance. |
||||
* @throws Exception in case of dependency injection failure |
||||
* @throws IllegalStateException if the {@link ApplicationContext} for this |
||||
* test instance has not been configured |
||||
* @see #populateProtectedVariables() |
||||
*/ |
||||
protected void injectDependencies() throws Exception { |
||||
Assert.state(getApplicationContext() != null, |
||||
"injectDependencies() called without first configuring an ApplicationContext"); |
||||
if (isPopulateProtectedVariables()) { |
||||
if (this.managedVariableNames == null) { |
||||
initManagedVariableNames(); |
||||
} |
||||
populateProtectedVariables(); |
||||
} |
||||
getApplicationContext().getBeanFactory().autowireBeanProperties(this, getAutowireMode(), isDependencyCheck()); |
||||
} |
||||
|
||||
private void initManagedVariableNames() throws IllegalAccessException { |
||||
List managedVarNames = new LinkedList(); |
||||
Class clazz = getClass(); |
||||
do { |
||||
Field[] fields = clazz.getDeclaredFields(); |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Found " + fields.length + " fields on " + clazz); |
||||
} |
||||
for (int i = 0; i < fields.length; i++) { |
||||
Field field = fields[i]; |
||||
field.setAccessible(true); |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Candidate field: " + field); |
||||
} |
||||
if (isProtectedInstanceField(field)) { |
||||
Object oldValue = field.get(this); |
||||
if (oldValue == null) { |
||||
managedVarNames.add(field.getName()); |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Added managed variable '" + field.getName() + "'"); |
||||
} |
||||
} |
||||
else { |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Rejected managed variable '" + field.getName() + "'"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
clazz = clazz.getSuperclass(); |
||||
} while (!clazz.equals(AbstractDependencyInjectionSpringContextTests.class)); |
||||
|
||||
this.managedVariableNames = (String[]) managedVarNames.toArray(new String[managedVarNames.size()]); |
||||
} |
||||
|
||||
private boolean isProtectedInstanceField(Field field) { |
||||
int modifiers = field.getModifiers(); |
||||
return !Modifier.isStatic(modifiers) && Modifier.isProtected(modifiers); |
||||
} |
||||
|
||||
private void populateProtectedVariables() throws IllegalAccessException { |
||||
for (int i = 0; i < this.managedVariableNames.length; i++) { |
||||
String varName = this.managedVariableNames[i]; |
||||
Object bean = null; |
||||
try { |
||||
Field field = findField(getClass(), varName); |
||||
bean = getApplicationContext().getBean(varName, field.getType()); |
||||
field.setAccessible(true); |
||||
field.set(this, bean); |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Populated field: " + field); |
||||
} |
||||
} |
||||
catch (NoSuchFieldException ex) { |
||||
if (this.logger.isWarnEnabled()) { |
||||
this.logger.warn("No field with name '" + varName + "'"); |
||||
} |
||||
} |
||||
catch (NoSuchBeanDefinitionException ex) { |
||||
if (this.logger.isWarnEnabled()) { |
||||
this.logger.warn("No bean with name '" + varName + "'"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private Field findField(Class clazz, String name) throws NoSuchFieldException { |
||||
try { |
||||
return clazz.getDeclaredField(name); |
||||
} |
||||
catch (NoSuchFieldException ex) { |
||||
Class superclass = clazz.getSuperclass(); |
||||
if (superclass != AbstractSpringContextTests.class) { |
||||
return findField(superclass, name); |
||||
} |
||||
else { |
||||
throw ex; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,362 @@
@@ -0,0 +1,362 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test; |
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.support.GenericApplicationContext; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.util.ResourceUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* <p> |
||||
* Abstract JUnit 3.8 test class that holds and exposes a single Spring |
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}. |
||||
* </p> |
||||
* <p> |
||||
* This class will cache contexts based on a <i>context key</i>: normally the |
||||
* config locations String array describing the Spring resource descriptors |
||||
* making up the context. Unless the {@link #setDirty()} method is called by a |
||||
* test, the context will not be reloaded, even across different subclasses of |
||||
* this test. This is particularly beneficial if your context is slow to |
||||
* construct, for example if you are using Hibernate and the time taken to load |
||||
* the mappings is an issue. |
||||
* </p> |
||||
* <p> |
||||
* For such standard usage, simply override the {@link #getConfigLocations()} |
||||
* method and provide the desired config files. For alternative configuration |
||||
* options, see {@link #getConfigPath()} and {@link #getConfigPaths()}. |
||||
* </p> |
||||
* <p> |
||||
* If you don't want to load a standard context from an array of config |
||||
* locations, you can override the {@link #contextKey()} method. In conjunction |
||||
* with this you typically need to override the {@link #loadContext(Object)} |
||||
* method, which by default loads the locations specified in the |
||||
* {@link #getConfigLocations()} method. |
||||
* </p> |
||||
* <p> |
||||
* <b>WARNING:</b> When doing integration tests from within Eclipse, only use |
||||
* classpath resource URLs. Else, you may see misleading failures when changing |
||||
* context locations. |
||||
* </p> |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
* @see #getConfigLocations() |
||||
* @see #contextKey() |
||||
* @see #loadContext(Object) |
||||
* @see #getApplicationContext() |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests { |
||||
|
||||
/** Application context this test will run against */ |
||||
protected ConfigurableApplicationContext applicationContext; |
||||
|
||||
private int loadCount = 0; |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractSingleSpringContextTests. |
||||
*/ |
||||
public AbstractSingleSpringContextTests() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for AbstractSingleSpringContextTests with a JUnit name. |
||||
* @param name the name of this text fixture |
||||
*/ |
||||
public AbstractSingleSpringContextTests(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
/** |
||||
* This implementation is final. Override <code>onSetUp</code> for custom behavior. |
||||
* @see #onSetUp() |
||||
*/ |
||||
protected final void setUp() throws Exception { |
||||
// lazy load, in case getApplicationContext() has not yet been called.
|
||||
if (this.applicationContext == null) { |
||||
this.applicationContext = getContext(contextKey()); |
||||
} |
||||
prepareTestInstance(); |
||||
onSetUp(); |
||||
} |
||||
|
||||
/** |
||||
* Prepare this test instance, for example populating its fields. |
||||
* The context has already been loaded at the time of this callback. |
||||
* <p>The default implementation does nothing. |
||||
* @throws Exception in case of preparation failure |
||||
*/ |
||||
protected void prepareTestInstance() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method in place of the <code>setUp()</code> |
||||
* method, which is final in this class. |
||||
* <p>The default implementation does nothing. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onSetUp() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Called to say that the "applicationContext" instance variable is dirty |
||||
* and should be reloaded. We need to do this if a test has modified the |
||||
* context (for example, by replacing a bean definition). |
||||
*/ |
||||
protected void setDirty() { |
||||
setDirty(contextKey()); |
||||
} |
||||
|
||||
/** |
||||
* This implementation is final. Override <code>onTearDown</code> for |
||||
* custom behavior. |
||||
* @see #onTearDown() |
||||
*/ |
||||
protected final void tearDown() throws Exception { |
||||
onTearDown(); |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this to add custom behavior on teardown. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onTearDown() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Return a key for this context. Default is the config location array as |
||||
* determined by {@link #getConfigLocations()}. |
||||
* <p>If you override this method, you will typically have to override |
||||
* {@link #loadContext(Object)} as well, being able to handle the key type |
||||
* that this method returns. |
||||
* @return the context key |
||||
* @see #getConfigLocations() |
||||
*/ |
||||
protected Object contextKey() { |
||||
return getConfigLocations(); |
||||
} |
||||
|
||||
/** |
||||
* This implementation assumes a key of type String array and loads a |
||||
* context from the given locations. |
||||
* <p>If you override {@link #contextKey()}, you will typically have to |
||||
* override this method as well, being able to handle the key type that |
||||
* <code>contextKey()</code> returns. |
||||
* @see #getConfigLocations() |
||||
*/ |
||||
protected ConfigurableApplicationContext loadContext(Object key) throws Exception { |
||||
return loadContextLocations((String[]) key); |
||||
} |
||||
|
||||
/** |
||||
* Load a Spring ApplicationContext from the given config locations. |
||||
* <p>The default implementation creates a standard |
||||
* {@link #createApplicationContext GenericApplicationContext}, allowing |
||||
* for customizing the internal bean factory through |
||||
* {@link #customizeBeanFactory}. |
||||
* @param locations the config locations (as Spring resource locations, |
||||
* e.g. full classpath locations or any kind of URL) |
||||
* @return the corresponding ApplicationContext instance (potentially cached) |
||||
* @throws Exception if context loading failed |
||||
* @see #createApplicationContext(String[]) |
||||
*/ |
||||
protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception { |
||||
++this.loadCount; |
||||
if (this.logger.isInfoEnabled()) { |
||||
this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations)); |
||||
} |
||||
return createApplicationContext(locations); |
||||
} |
||||
|
||||
/** |
||||
* Create a Spring {@link ConfigurableApplicationContext} for use by this test. |
||||
* <p>The default implementation creates a standard {@link GenericApplicationContext} |
||||
* instance, calls the {@link #prepareApplicationContext} prepareApplicationContext} |
||||
* method and the {@link #customizeBeanFactory customizeBeanFactory} method to allow |
||||
* for customizing the context and its DefaultListableBeanFactory, populates the |
||||
* context from the specified config <code>locations</code> through the configured |
||||
* {@link #createBeanDefinitionReader(GenericApplicationContext) BeanDefinitionReader}, |
||||
* and finally {@link ConfigurableApplicationContext#refresh() refreshes} the context. |
||||
* @param locations the config locations (as Spring resource locations, |
||||
* e.g. full classpath locations or any kind of URL) |
||||
* @return the GenericApplicationContext instance |
||||
* @see #loadContextLocations(String[]) |
||||
* @see #customizeBeanFactory(DefaultListableBeanFactory) |
||||
* @see #createBeanDefinitionReader(GenericApplicationContext) |
||||
*/ |
||||
protected ConfigurableApplicationContext createApplicationContext(String[] locations) { |
||||
GenericApplicationContext context = new GenericApplicationContext(); |
||||
prepareApplicationContext(context); |
||||
customizeBeanFactory(context.getDefaultListableBeanFactory()); |
||||
createBeanDefinitionReader(context).loadBeanDefinitions(locations); |
||||
context.refresh(); |
||||
return context; |
||||
} |
||||
|
||||
/** |
||||
* Prepare the GenericApplicationContext used by this test. |
||||
* Called before bean definitions are read. |
||||
* <p>The default implementation is empty. Can be overridden in subclasses to |
||||
* customize GenericApplicationContext's standard settings. |
||||
* @param context the context for which the BeanDefinitionReader should be created |
||||
* @see #createApplicationContext |
||||
* @see org.springframework.context.support.GenericApplicationContext#setResourceLoader |
||||
* @see org.springframework.context.support.GenericApplicationContext#setId |
||||
*/ |
||||
protected void prepareApplicationContext(GenericApplicationContext context) { |
||||
} |
||||
|
||||
/** |
||||
* Customize the internal bean factory of the ApplicationContext used by |
||||
* this test. Called before bean definitions are read. |
||||
* <p>The default implementation is empty. Can be overridden in subclasses to |
||||
* customize DefaultListableBeanFactory's standard settings. |
||||
* @param beanFactory the newly created bean factory for this context |
||||
* @see #loadContextLocations |
||||
* @see #createApplicationContext |
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding |
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading |
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences |
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping |
||||
*/ |
||||
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { |
||||
} |
||||
|
||||
/** |
||||
* Factory method for creating new {@link BeanDefinitionReader}s for |
||||
* loading bean definitions into the supplied |
||||
* {@link GenericApplicationContext context}. |
||||
* <p>The default implementation creates a new {@link XmlBeanDefinitionReader}. |
||||
* Can be overridden in subclasses to provide a different |
||||
* BeanDefinitionReader implementation. |
||||
* @param context the context for which the BeanDefinitionReader should be created |
||||
* @return a BeanDefinitionReader for the supplied context |
||||
* @see #createApplicationContext(String[]) |
||||
* @see BeanDefinitionReader |
||||
* @see XmlBeanDefinitionReader |
||||
*/ |
||||
protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) { |
||||
return new XmlBeanDefinitionReader(context); |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to return the locations of their |
||||
* config files, unless they override {@link #contextKey()} and |
||||
* {@link #loadContext(Object)} instead. |
||||
* <p>A plain path will be treated as class path location, e.g.: |
||||
* "org/springframework/whatever/foo.xml". Note however that you may prefix |
||||
* path locations with standard Spring resource prefixes. Therefore, a |
||||
* config location path prefixed with "classpath:" with behave the same as a |
||||
* plain path, but a config location such as |
||||
* "file:/some/path/path/location/appContext.xml" will be treated as a |
||||
* filesystem location. |
||||
* <p>The default implementation builds config locations for the config paths |
||||
* specified through {@link #getConfigPaths()}. |
||||
* @return an array of config locations |
||||
* @see #getConfigPaths() |
||||
* @see org.springframework.core.io.ResourceLoader#getResource(String) |
||||
*/ |
||||
protected String[] getConfigLocations() { |
||||
String[] paths = getConfigPaths(); |
||||
String[] locations = new String[paths.length]; |
||||
for (int i = 0; i < paths.length; i++) { |
||||
String path = paths[i]; |
||||
if (path.startsWith("/")) { |
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path; |
||||
} |
||||
else { |
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + |
||||
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path); |
||||
} |
||||
} |
||||
return locations; |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to return paths to their config |
||||
* files, relative to the concrete test class. |
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource |
||||
* from the same package that the concrete test class is defined in. A path |
||||
* starting with a slash is treated as fully qualified class path location, |
||||
* e.g.: "/org/springframework/whatever/foo.xml". |
||||
* <p>The default implementation builds an array for the config path specified |
||||
* through {@link #getConfigPath()}. |
||||
* @return an array of config locations |
||||
* @see #getConfigPath() |
||||
* @see java.lang.Class#getResource(String) |
||||
*/ |
||||
protected String[] getConfigPaths() { |
||||
String path = getConfigPath(); |
||||
return (path != null ? new String[] { path } : new String[0]); |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to return a single path to a config |
||||
* file, relative to the concrete test class. |
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource |
||||
* from the same package that the concrete test class is defined in. A path |
||||
* starting with a slash is treated as fully qualified class path location, |
||||
* e.g.: "/org/springframework/whatever/foo.xml". |
||||
* <p>The default implementation simply returns <code>null</code>. |
||||
* @return an array of config locations |
||||
* @see #getConfigPath() |
||||
* @see java.lang.Class#getResource(String) |
||||
*/ |
||||
protected String getConfigPath() { |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Return the ApplicationContext that this base class manages; may be |
||||
* <code>null</code>. |
||||
*/ |
||||
public final ConfigurableApplicationContext getApplicationContext() { |
||||
// lazy load, in case setUp() has not yet been called.
|
||||
if (this.applicationContext == null) { |
||||
try { |
||||
this.applicationContext = getContext(contextKey()); |
||||
} |
||||
catch (Exception e) { |
||||
// log and continue...
|
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Caught exception while retrieving the ApplicationContext for test [" + |
||||
getClass().getName() + "." + getName() + "].", e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return this.applicationContext; |
||||
} |
||||
|
||||
/** |
||||
* Return the current number of context load attempts. |
||||
*/ |
||||
public final int getLoadCount() { |
||||
return this.loadCount; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,171 @@
@@ -0,0 +1,171 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* <p> |
||||
* Superclass for JUnit 3.8 test cases using Spring |
||||
* {@link org.springframework.context.ApplicationContext ApplicationContexts}. |
||||
* </p> |
||||
* <p> |
||||
* Maintains a static cache of contexts by key. This has significant performance |
||||
* benefit if initializing the context would take time. While initializing a |
||||
* Spring context itself is very quick, some beans in a context, such as a |
||||
* LocalSessionFactoryBean for working with Hibernate, may take some time to |
||||
* initialize. Hence it often makes sense to do that initializing once. |
||||
* </p> |
||||
* <p> |
||||
* Any ApplicationContext created by this class will be asked to register a JVM |
||||
* shutdown hook for itself. Unless the context gets closed early, all context |
||||
* instances will be automatically closed on JVM shutdown. This allows for |
||||
* freeing external resources held by beans within the context, e.g. temporary |
||||
* files. |
||||
* </p> |
||||
* <p> |
||||
* Normally you won't extend this class directly but rather one of its |
||||
* subclasses. |
||||
* </p> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Juergen Hoeller |
||||
* @author Sam Brannen |
||||
* @since 1.1.1 |
||||
* @see AbstractSingleSpringContextTests |
||||
* @see AbstractDependencyInjectionSpringContextTests |
||||
* @see AbstractTransactionalSpringContextTests |
||||
* @see AbstractTransactionalDataSourceSpringContextTests |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractSpringContextTests extends ConditionalTestCase { |
||||
|
||||
/** |
||||
* Map of context keys returned by subclasses of this class, to Spring |
||||
* contexts. This needs to be static, as JUnit tests are destroyed and |
||||
* recreated between running individual test methods. |
||||
*/ |
||||
private static Map<String, ConfigurableApplicationContext> contextKeyToContextMap = |
||||
new HashMap<String, ConfigurableApplicationContext>(); |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractSpringContextTests. |
||||
*/ |
||||
public AbstractSpringContextTests() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for AbstractSpringContextTests with a JUnit name. |
||||
*/ |
||||
public AbstractSpringContextTests(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Explicitly add an ApplicationContext instance under a given key. |
||||
* <p>This is not meant to be used by subclasses. It is rather exposed for |
||||
* special test suite environments. |
||||
* @param key the context key |
||||
* @param context the ApplicationContext instance |
||||
*/ |
||||
public final void addContext(Object key, ConfigurableApplicationContext context) { |
||||
Assert.notNull(context, "ApplicationContext must not be null"); |
||||
contextKeyToContextMap.put(contextKeyString(key), context); |
||||
} |
||||
|
||||
/** |
||||
* Return whether there is a cached context for the given key. |
||||
* @param key the context key |
||||
*/ |
||||
protected final boolean hasCachedContext(Object key) { |
||||
return contextKeyToContextMap.containsKey(contextKeyString(key)); |
||||
} |
||||
|
||||
/** |
||||
* Determine if the supplied context <code>key</code> is <em>empty</em>. |
||||
* <p>By default, <code>null</code> values, empty strings, and zero-length |
||||
* arrays are considered <em>empty</em>. |
||||
* @param key the context key to check |
||||
* @return <code>true</code> if the supplied context key is empty |
||||
*/ |
||||
protected boolean isContextKeyEmpty(Object key) { |
||||
return (key == null) || ((key instanceof String) && !StringUtils.hasText((String) key)) || |
||||
((key instanceof Object[]) && ObjectUtils.isEmpty((Object[]) key)); |
||||
} |
||||
|
||||
/** |
||||
* Obtain an ApplicationContext for the given key, potentially cached. |
||||
* @param key the context key; may be <code>null</code>. |
||||
* @return the corresponding ApplicationContext instance (potentially cached), |
||||
* or <code>null</code> if the provided <code>key</code> is <em>empty</em> |
||||
*/ |
||||
protected final ConfigurableApplicationContext getContext(Object key) throws Exception { |
||||
if (isContextKeyEmpty(key)) { |
||||
return null; |
||||
} |
||||
String keyString = contextKeyString(key); |
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.get(keyString); |
||||
if (ctx == null) { |
||||
ctx = loadContext(key); |
||||
ctx.registerShutdownHook(); |
||||
contextKeyToContextMap.put(keyString, ctx); |
||||
} |
||||
return ctx; |
||||
} |
||||
|
||||
/** |
||||
* Mark the context with the given key as dirty. This will cause the cached |
||||
* context to be reloaded before the next test case is executed. |
||||
* <p>Call this method only if you change the state of a singleton bean, |
||||
* potentially affecting future tests. |
||||
*/ |
||||
protected final void setDirty(Object contextKey) { |
||||
String keyString = contextKeyString(contextKey); |
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.remove(keyString); |
||||
if (ctx != null) { |
||||
ctx.close(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this to return a String representation of their |
||||
* context key for use in caching and logging. |
||||
* @param contextKey the context key |
||||
*/ |
||||
protected String contextKeyString(Object contextKey) { |
||||
return ObjectUtils.nullSafeToString(contextKey); |
||||
} |
||||
|
||||
/** |
||||
* Load a new ApplicationContext for the given key. |
||||
* <p>To be implemented by subclasses. |
||||
* @param key the context key |
||||
* @return the corresponding ApplicationContext instance (new) |
||||
*/ |
||||
protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception; |
||||
|
||||
} |
||||
@ -0,0 +1,199 @@
@@ -0,0 +1,199 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.LineNumberReader; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
|
||||
import javax.sql.DataSource; |
||||
|
||||
import org.springframework.core.io.support.EncodedResource; |
||||
import org.springframework.dao.DataAccessException; |
||||
import org.springframework.dao.DataAccessResourceFailureException; |
||||
import org.springframework.jdbc.core.JdbcTemplate; |
||||
import org.springframework.test.jdbc.JdbcTestUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Subclass of AbstractTransactionalSpringContextTests that adds some convenience |
||||
* functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean |
||||
* to be defined in the Spring application context. |
||||
* |
||||
* <p>This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate} |
||||
* and provides an easy way to delete from the database in a new transaction. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Juergen Hoeller |
||||
* @author Thomas Risberg |
||||
* @since 1.1.1 |
||||
* @see #setDataSource(javax.sql.DataSource) |
||||
* @see #getJdbcTemplate() |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractTransactionalDataSourceSpringContextTests |
||||
extends AbstractTransactionalSpringContextTests { |
||||
|
||||
protected JdbcTemplate jdbcTemplate; |
||||
|
||||
private String sqlScriptEncoding; |
||||
|
||||
/** |
||||
* Did this test delete any tables? If so, we forbid transaction completion, |
||||
* and only allow rollback. |
||||
*/ |
||||
private boolean zappedTables; |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractTransactionalDataSourceSpringContextTests. |
||||
*/ |
||||
public AbstractTransactionalDataSourceSpringContextTests() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for AbstractTransactionalDataSourceSpringContextTests with a JUnit name. |
||||
*/ |
||||
public AbstractTransactionalDataSourceSpringContextTests(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Setter: DataSource is provided by Dependency Injection. |
||||
*/ |
||||
public void setDataSource(DataSource dataSource) { |
||||
this.jdbcTemplate = new JdbcTemplate(dataSource); |
||||
} |
||||
|
||||
/** |
||||
* Return the JdbcTemplate that this base class manages. |
||||
*/ |
||||
public final JdbcTemplate getJdbcTemplate() { |
||||
return this.jdbcTemplate; |
||||
} |
||||
|
||||
/** |
||||
* Specify the encoding for SQL scripts, if different from the platform encoding. |
||||
* @see #executeSqlScript |
||||
*/ |
||||
public void setSqlScriptEncoding(String sqlScriptEncoding) { |
||||
this.sqlScriptEncoding = sqlScriptEncoding; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Convenient method to delete all rows from these tables. |
||||
* Calling this method will make avoidance of rollback by calling |
||||
* <code>setComplete()</code> impossible. |
||||
* @see #setComplete |
||||
*/ |
||||
protected void deleteFromTables(String[] names) { |
||||
for (int i = 0; i < names.length; i++) { |
||||
int rowCount = this.jdbcTemplate.update("DELETE FROM " + names[i]); |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Deleted " + rowCount + " rows from table " + names[i]); |
||||
} |
||||
} |
||||
this.zappedTables = true; |
||||
} |
||||
|
||||
/** |
||||
* Overridden to prevent the transaction committing if a number of tables have been |
||||
* cleared, as a defensive measure against accidental <i>permanent</i> wiping of a database. |
||||
* @see org.springframework.test.AbstractTransactionalSpringContextTests#setComplete() |
||||
*/ |
||||
protected final void setComplete() { |
||||
if (this.zappedTables) { |
||||
throw new IllegalStateException("Cannot set complete after deleting tables"); |
||||
} |
||||
super.setComplete(); |
||||
} |
||||
|
||||
/** |
||||
* Count the rows in the given table |
||||
* @param tableName table name to count rows in |
||||
* @return the number of rows in the table |
||||
*/ |
||||
protected int countRowsInTable(String tableName) { |
||||
return this.jdbcTemplate.queryForInt("SELECT COUNT(0) FROM " + tableName); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Execute the given SQL script. Will be rolled back by default, |
||||
* according to the fate of the current transaction. |
||||
* @param sqlResourcePath Spring resource path for the SQL script. |
||||
* Should normally be loaded by classpath. |
||||
* <p>Statements should be delimited with a semicolon. If statements are not delimited with |
||||
* a semicolon then there should be one statement per line. Statements are allowed to span |
||||
* lines only if they are delimited with a semicolon. |
||||
* <p><b>Do not use this method to execute DDL if you expect rollback.</b> |
||||
* @param continueOnError whether or not to continue without throwing |
||||
* an exception in the event of an error |
||||
* @throws DataAccessException if there is an error executing a statement |
||||
* and continueOnError was false |
||||
*/ |
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Executing SQL script '" + sqlResourcePath + "'"); |
||||
} |
||||
|
||||
EncodedResource resource = |
||||
new EncodedResource(getApplicationContext().getResource(sqlResourcePath), this.sqlScriptEncoding); |
||||
long startTime = System.currentTimeMillis(); |
||||
List statements = new LinkedList(); |
||||
try { |
||||
LineNumberReader lnr = new LineNumberReader(resource.getReader()); |
||||
String script = JdbcTestUtils.readScript(lnr); |
||||
char delimiter = ';'; |
||||
if (!JdbcTestUtils.containsSqlScriptDelimiters(script, delimiter)) { |
||||
delimiter = '\n'; |
||||
} |
||||
JdbcTestUtils.splitSqlScript(script, delimiter, statements); |
||||
for (Iterator itr = statements.iterator(); itr.hasNext(); ) { |
||||
String statement = (String) itr.next(); |
||||
try { |
||||
int rowsAffected = this.jdbcTemplate.update(statement); |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug(rowsAffected + " rows affected by SQL: " + statement); |
||||
} |
||||
} |
||||
catch (DataAccessException ex) { |
||||
if (continueOnError) { |
||||
if (logger.isWarnEnabled()) { |
||||
logger.warn("SQL: " + statement + " failed", ex); |
||||
} |
||||
} |
||||
else { |
||||
throw ex; |
||||
} |
||||
} |
||||
} |
||||
long elapsedTime = System.currentTimeMillis() - startTime; |
||||
logger.info("Done executing SQL scriptBuilder '" + sqlResourcePath + "' in " + elapsedTime + " ms"); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new DataAccessResourceFailureException("Failed to open SQL script '" + sqlResourcePath + "'", ex); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,359 @@
@@ -0,0 +1,359 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test; |
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager; |
||||
import org.springframework.transaction.TransactionDefinition; |
||||
import org.springframework.transaction.TransactionException; |
||||
import org.springframework.transaction.TransactionStatus; |
||||
import org.springframework.transaction.support.DefaultTransactionDefinition; |
||||
|
||||
/** |
||||
* Convenient base class for JUnit 3.8 based tests that should occur in a |
||||
* transaction, but normally will roll the transaction back on the completion of |
||||
* each test. |
||||
* |
||||
* <p>This is useful in a range of circumstances, allowing the following benefits: |
||||
* <ul> |
||||
* <li>Ability to delete or insert any data in the database, without affecting |
||||
* other tests |
||||
* <li>Providing a transactional context for any code requiring a transaction |
||||
* <li>Ability to write anything to the database without any need to clean up. |
||||
* </ul> |
||||
* |
||||
* <p>This class is typically very fast, compared to traditional setup/teardown |
||||
* scripts. |
||||
* |
||||
* <p>If data should be left in the database, call the {@link #setComplete()} |
||||
* method in each test. The {@link #setDefaultRollback "defaultRollback"} |
||||
* property, which defaults to "true", determines whether transactions will |
||||
* complete by default. |
||||
* |
||||
* <p>It is even possible to end the transaction early; for example, to verify lazy |
||||
* loading behavior of an O/R mapping tool. (This is a valuable away to avoid |
||||
* unexpected errors when testing a web UI, for example.) Simply call the |
||||
* {@link #endTransaction()} method. Execution will then occur without a |
||||
* transactional context. |
||||
* |
||||
* <p>The {@link #startNewTransaction()} method may be called after a call to |
||||
* {@link #endTransaction()} if you wish to create a new transaction, quite |
||||
* independent of the old transaction. The new transaction's default fate will |
||||
* be to roll back, unless {@link #setComplete()} is called again during the |
||||
* scope of the new transaction. Any number of transactions may be created and |
||||
* ended in this way. The final transaction will automatically be rolled back |
||||
* when the test case is torn down. |
||||
* |
||||
* <p>Transactional behavior requires a single bean in the context implementing the |
||||
* {@link PlatformTransactionManager} interface. This will be set by the |
||||
* superclass's Dependency Injection mechanism. If using the superclass's Field |
||||
* Injection mechanism, the implementation should be named "transactionManager". |
||||
* This mechanism allows the use of the |
||||
* {@link AbstractDependencyInjectionSpringContextTests} superclass even when |
||||
* there is more than one transaction manager in the context. |
||||
* |
||||
* <p><b>This base class can also be used without transaction management, if no |
||||
* PlatformTransactionManager bean is found in the context provided.</b> Be |
||||
* careful about using this mode, as it allows the potential to permanently |
||||
* modify data. This mode is available only if dependency checking is turned off |
||||
* in the {@link AbstractDependencyInjectionSpringContextTests} superclass. The |
||||
* non-transactional capability is provided to enable use of the same subclass |
||||
* in different environments. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Juergen Hoeller |
||||
* @author Sam Brannen |
||||
* @since 1.1.1 |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests { |
||||
|
||||
/** The transaction manager to use */ |
||||
protected PlatformTransactionManager transactionManager; |
||||
|
||||
/** Should we roll back by default? */ |
||||
private boolean defaultRollback = true; |
||||
|
||||
/** Should we commit the current transaction? */ |
||||
private boolean complete = false; |
||||
|
||||
/** Number of transactions started */ |
||||
private int transactionsStarted = 0; |
||||
|
||||
/** |
||||
* Transaction definition used by this test class: by default, a plain |
||||
* DefaultTransactionDefinition. Subclasses can change this to cause |
||||
* different behavior. |
||||
*/ |
||||
protected TransactionDefinition transactionDefinition= new DefaultTransactionDefinition(); |
||||
|
||||
/** |
||||
* TransactionStatus for this test. Typical subclasses won't need to use it. |
||||
*/ |
||||
protected TransactionStatus transactionStatus; |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractTransactionalSpringContextTests. |
||||
*/ |
||||
public AbstractTransactionalSpringContextTests() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for AbstractTransactionalSpringContextTests with a JUnit name. |
||||
*/ |
||||
public AbstractTransactionalSpringContextTests(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Specify the transaction manager to use. No transaction management will be |
||||
* available if this is not set. Populated through dependency injection by |
||||
* the superclass. |
||||
* <p> |
||||
* This mode works only if dependency checking is turned off in the |
||||
* {@link AbstractDependencyInjectionSpringContextTests} superclass. |
||||
*/ |
||||
public void setTransactionManager(PlatformTransactionManager transactionManager) { |
||||
this.transactionManager = transactionManager; |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can set this value in their constructor to change the default, |
||||
* which is always to roll the transaction back. |
||||
*/ |
||||
public void setDefaultRollback(final boolean defaultRollback) { |
||||
this.defaultRollback = defaultRollback; |
||||
} |
||||
/** |
||||
* Get the <em>default rollback</em> flag for this test. |
||||
* @see #setDefaultRollback(boolean) |
||||
* @return The <em>default rollback</em> flag. |
||||
*/ |
||||
protected boolean isDefaultRollback() { |
||||
return this.defaultRollback; |
||||
} |
||||
|
||||
/** |
||||
* Determines whether or not to rollback transactions for the current test. |
||||
* <p>The default implementation delegates to {@link #isDefaultRollback()}. |
||||
* Subclasses can override as necessary. |
||||
*/ |
||||
protected boolean isRollback() { |
||||
return isDefaultRollback(); |
||||
} |
||||
|
||||
/** |
||||
* Call this method in an overridden {@link #runBare()} method to prevent |
||||
* transactional execution. |
||||
*/ |
||||
protected void preventTransaction() { |
||||
this.transactionDefinition = null; |
||||
} |
||||
|
||||
/** |
||||
* Call this method in an overridden {@link #runBare()} method to override |
||||
* the transaction attributes that will be used, so that {@link #setUp()} |
||||
* and {@link #tearDown()} behavior is modified. |
||||
* @param customDefinition the custom transaction definition |
||||
*/ |
||||
protected void setTransactionDefinition(TransactionDefinition customDefinition) { |
||||
this.transactionDefinition = customDefinition; |
||||
} |
||||
|
||||
/** |
||||
* This implementation creates a transaction before test execution. |
||||
* <p>Override {@link #onSetUpBeforeTransaction()} and/or |
||||
* {@link #onSetUpInTransaction()} to add custom set-up behavior for |
||||
* transactional execution. Alternatively, override this method for general |
||||
* set-up behavior, calling <code>super.onSetUp()</code> as part of your |
||||
* method implementation. |
||||
* @throws Exception simply let any exception propagate |
||||
* @see #onTearDown() |
||||
*/ |
||||
protected void onSetUp() throws Exception { |
||||
this.complete = !this.isRollback(); |
||||
|
||||
if (this.transactionManager == null) { |
||||
this.logger.info("No transaction manager set: test will NOT run within a transaction"); |
||||
} |
||||
else if (this.transactionDefinition == null) { |
||||
this.logger.info("No transaction definition set: test will NOT run within a transaction"); |
||||
} |
||||
else { |
||||
onSetUpBeforeTransaction(); |
||||
startNewTransaction(); |
||||
try { |
||||
onSetUpInTransaction(); |
||||
} |
||||
catch (final Exception ex) { |
||||
endTransaction(); |
||||
throw ex; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to perform any setup operations, such |
||||
* as populating a database table, <i>before</i> the transaction created by |
||||
* this class. Only invoked if there <i>is</i> a transaction: that is, if |
||||
* {@link #preventTransaction()} has not been invoked in an overridden |
||||
* {@link #runTest()} method. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onSetUpBeforeTransaction() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to perform any setup operations, such |
||||
* as populating a database table, <i>within</i> the transaction created by |
||||
* this class. |
||||
* <p><b>NB:</b> Not called if there is no transaction management, due to no |
||||
* transaction manager being provided in the context. |
||||
* <p>If any {@link Throwable} is thrown, the transaction that has been started |
||||
* prior to the execution of this method will be |
||||
* {@link #endTransaction() ended} (or rather an attempt will be made to |
||||
* {@link #endTransaction() end it gracefully}); The offending |
||||
* {@link Throwable} will then be rethrown. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onSetUpInTransaction() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* This implementation ends the transaction after test execution. |
||||
* <p>Override {@link #onTearDownInTransaction()} and/or |
||||
* {@link #onTearDownAfterTransaction()} to add custom tear-down behavior |
||||
* for transactional execution. Alternatively, override this method for |
||||
* general tear-down behavior, calling <code>super.onTearDown()</code> as |
||||
* part of your method implementation. |
||||
* <p>Note that {@link #onTearDownInTransaction()} will only be called if a |
||||
* transaction is still active at the time of the test shutdown. In |
||||
* particular, it will <i>not</i> be called if the transaction has been |
||||
* completed with an explicit {@link #endTransaction()} call before. |
||||
* @throws Exception simply let any exception propagate |
||||
* @see #onSetUp() |
||||
*/ |
||||
protected void onTearDown() throws Exception { |
||||
// Call onTearDownInTransaction and end transaction if the transaction
|
||||
// is still active.
|
||||
if (this.transactionStatus != null && !this.transactionStatus.isCompleted()) { |
||||
try { |
||||
onTearDownInTransaction(); |
||||
} |
||||
finally { |
||||
endTransaction(); |
||||
} |
||||
} |
||||
|
||||
// Call onTearDownAfterTransaction if there was at least one
|
||||
// transaction, even if it has been completed early through an
|
||||
// endTransaction() call.
|
||||
if (this.transactionsStarted > 0) { |
||||
onTearDownAfterTransaction(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to run invariant tests here. The |
||||
* transaction is <i>still active</i> at this point, so any changes made in |
||||
* the transaction will still be visible. However, there is no need to clean |
||||
* up the database, as a rollback will follow automatically. |
||||
* <p><b>NB:</b> Not called if there is no actual transaction, for example due |
||||
* to no transaction manager being provided in the application context. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onTearDownInTransaction() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this method to perform cleanup after a |
||||
* transaction here. At this point, the transaction is <i>not active anymore</i>. |
||||
* @throws Exception simply let any exception propagate |
||||
*/ |
||||
protected void onTearDownAfterTransaction() throws Exception { |
||||
} |
||||
|
||||
/** |
||||
* Cause the transaction to commit for this test method, even if the test |
||||
* method is configured to {@link #isRollback() rollback}. |
||||
* @throws IllegalStateException if the operation cannot be set to complete |
||||
* as no transaction manager was provided |
||||
*/ |
||||
protected void setComplete() { |
||||
if (this.transactionManager == null) { |
||||
throw new IllegalStateException("No transaction manager set"); |
||||
} |
||||
this.complete = true; |
||||
} |
||||
|
||||
/** |
||||
* Immediately force a commit or rollback of the transaction, according to |
||||
* the <code>complete</code> and {@link #isRollback() rollback} flags. |
||||
* <p>Can be used to explicitly let the transaction end early, for example to |
||||
* check whether lazy associations of persistent objects work outside of a |
||||
* transaction (that is, have been initialized properly). |
||||
* @see #setComplete() |
||||
*/ |
||||
protected void endTransaction() { |
||||
final boolean commit = this.complete || !isRollback(); |
||||
if (this.transactionStatus != null) { |
||||
try { |
||||
if (commit) { |
||||
this.transactionManager.commit(this.transactionStatus); |
||||
this.logger.debug("Committed transaction after execution of test [" + getName() + "]."); |
||||
} |
||||
else { |
||||
this.transactionManager.rollback(this.transactionStatus); |
||||
this.logger.debug("Rolled back transaction after execution of test [" + getName() + "]."); |
||||
} |
||||
} |
||||
finally { |
||||
this.transactionStatus = null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Start a new transaction. Only call this method if |
||||
* {@link #endTransaction()} has been called. {@link #setComplete()} can be |
||||
* used again in the new transaction. The fate of the new transaction, by |
||||
* default, will be the usual rollback. |
||||
* @throws TransactionException if starting the transaction failed |
||||
*/ |
||||
protected void startNewTransaction() throws TransactionException { |
||||
if (this.transactionStatus != null) { |
||||
throw new IllegalStateException("Cannot start new transaction without ending existing transaction: " |
||||
+ "Invoke endTransaction() before startNewTransaction()"); |
||||
} |
||||
if (this.transactionManager == null) { |
||||
throw new IllegalStateException("No transaction manager set"); |
||||
} |
||||
|
||||
this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition); |
||||
++this.transactionsStarted; |
||||
this.complete = !this.isRollback(); |
||||
|
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Began transaction (" + this.transactionsStarted + "): transaction manager [" |
||||
+ this.transactionManager + "]; rollback [" + this.isRollback() + "]."); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test; |
||||
|
||||
import junit.framework.TestCase; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
/** |
||||
* Superclass for JUnit 3.8 based tests that allows conditional test execution |
||||
* at the individual test method level. The |
||||
* {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()} |
||||
* method is invoked before the execution of each test method. Subclasses can |
||||
* override that method to return whether or not the given test should be |
||||
* executed. Note that the tests will still appear to have executed and passed; |
||||
* however, log output will show that the test was not executed. |
||||
* |
||||
* @author Rod Johnson |
||||
* @since 2.0 |
||||
* @see #isDisabledInThisEnvironment |
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework |
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) |
||||
*/ |
||||
@Deprecated |
||||
public abstract class ConditionalTestCase extends TestCase { |
||||
|
||||
private static int disabledTestCount; |
||||
|
||||
|
||||
/** |
||||
* Return the number of tests disabled in this environment. |
||||
*/ |
||||
public static int getDisabledTestCount() { |
||||
return disabledTestCount; |
||||
} |
||||
|
||||
|
||||
/** Logger available to subclasses */ |
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
|
||||
/** |
||||
* Default constructor for ConditionalTestCase. |
||||
*/ |
||||
public ConditionalTestCase() { |
||||
} |
||||
|
||||
/** |
||||
* Constructor for ConditionalTestCase with a JUnit name. |
||||
*/ |
||||
public ConditionalTestCase(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
public void runBare() throws Throwable { |
||||
// getName will return the name of the method being run
|
||||
if (isDisabledInThisEnvironment(getName())) { |
||||
recordDisabled(); |
||||
this.logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: " |
||||
+ "Total disabled tests = " + getDisabledTestCount()); |
||||
return; |
||||
} |
||||
|
||||
// Let JUnit handle execution
|
||||
super.runBare(); |
||||
} |
||||
|
||||
/** |
||||
* Should this test run? |
||||
* @param testMethodName name of the test method |
||||
* @return whether the test should execute in the current environment |
||||
*/ |
||||
protected boolean isDisabledInThisEnvironment(String testMethodName) { |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Record a disabled test. |
||||
* @return the current disabled test count |
||||
*/ |
||||
protected int recordDisabled() { |
||||
return ++disabledTestCount; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,309 @@
@@ -0,0 +1,309 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.lang.reflect.Modifier; |
||||
import java.util.Map; |
||||
|
||||
import javax.sql.DataSource; |
||||
|
||||
import junit.framework.AssertionFailedError; |
||||
|
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; |
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; |
||||
import org.springframework.transaction.TransactionDefinition; |
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; |
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* <p> |
||||
* Java 5 specific subclass of |
||||
* {@link AbstractTransactionalDataSourceSpringContextTests}, exposing a |
||||
* {@link SimpleJdbcTemplate} and obeying annotations for transaction control. |
||||
* </p> |
||||
* <p> |
||||
* For example, test methods can be annotated with the regular Spring |
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional} |
||||
* annotation (e.g., to force execution in a read-only transaction) or with the |
||||
* {@link NotTransactional @NotTransactional} annotation to prevent any |
||||
* transaction being created at all. In addition, individual test methods can be |
||||
* annotated with {@link Rollback @Rollback} to override the |
||||
* {@link #isDefaultRollback() default rollback} settings. |
||||
* </p> |
||||
* <p> |
||||
* The following list constitutes all annotations currently supported by |
||||
* AbstractAnnotationAwareTransactionalTests: |
||||
* </p> |
||||
* <ul> |
||||
* <li>{@link DirtiesContext @DirtiesContext}</li> |
||||
* <li>{@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li> |
||||
* <li>{@link IfProfileValue @IfProfileValue}</li> |
||||
* <li>{@link ExpectedException @ExpectedException}</li> |
||||
* <li>{@link Timed @Timed}</li> |
||||
* <li>{@link Repeat @Repeat}</li> |
||||
* <li>{@link org.springframework.transaction.annotation.Transactional @Transactional}</li> |
||||
* <li>{@link NotTransactional @NotTransactional}</li> |
||||
* <li>{@link Rollback @Rollback}</li> |
||||
* </ul> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @author Juergen Hoeller |
||||
* @since 2.0 |
||||
*/ |
||||
public abstract class AbstractAnnotationAwareTransactionalTests extends |
||||
AbstractTransactionalDataSourceSpringContextTests { |
||||
|
||||
protected SimpleJdbcTemplate simpleJdbcTemplate; |
||||
|
||||
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource(); |
||||
|
||||
/** |
||||
* {@link ProfileValueSource} available to subclasses but primarily intended |
||||
* for use in {@link #isDisabledInThisEnvironment(Method)}. |
||||
* <p>Set to {@link SystemProfileValueSource} by default for backwards |
||||
* compatibility; however, the value may be changed in the |
||||
* {@link #AbstractAnnotationAwareTransactionalTests(String)} constructor. |
||||
*/ |
||||
protected ProfileValueSource profileValueSource = SystemProfileValueSource.getInstance(); |
||||
|
||||
|
||||
/** |
||||
* Default constructor for AbstractAnnotationAwareTransactionalTests, which |
||||
* delegates to {@link #AbstractAnnotationAwareTransactionalTests(String)}. |
||||
*/ |
||||
public AbstractAnnotationAwareTransactionalTests() { |
||||
this(null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new AbstractAnnotationAwareTransactionalTests instance with |
||||
* the specified JUnit <code>name</code> and retrieves the configured (or |
||||
* default) {@link ProfileValueSource}. |
||||
* @param name the name of the current test |
||||
* @see ProfileValueUtils#retrieveProfileValueSource(Class) |
||||
*/ |
||||
public AbstractAnnotationAwareTransactionalTests(String name) { |
||||
super(name); |
||||
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void setDataSource(DataSource dataSource) { |
||||
super.setDataSource(dataSource); |
||||
// JdbcTemplate will be identically configured
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(this.jdbcTemplate); |
||||
} |
||||
|
||||
/** |
||||
* Search for a unique {@link ProfileValueSource} in the supplied |
||||
* {@link ApplicationContext}. If found, the |
||||
* <code>profileValueSource</code> for this test will be set to the unique |
||||
* {@link ProfileValueSource}. |
||||
* @param applicationContext the ApplicationContext in which to search for |
||||
* the ProfileValueSource; may not be <code>null</code> |
||||
* @deprecated Use {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} instead. |
||||
*/ |
||||
@Deprecated |
||||
protected void findUniqueProfileValueSourceFromContext(ApplicationContext applicationContext) { |
||||
Assert.notNull(applicationContext, "Can not search for a ProfileValueSource in a null ApplicationContext."); |
||||
ProfileValueSource uniqueProfileValueSource = null; |
||||
Map<?, ?> beans = applicationContext.getBeansOfType(ProfileValueSource.class); |
||||
if (beans.size() == 1) { |
||||
uniqueProfileValueSource = (ProfileValueSource) beans.values().iterator().next(); |
||||
} |
||||
if (uniqueProfileValueSource != null) { |
||||
this.profileValueSource = uniqueProfileValueSource; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Overridden to populate transaction definition from annotations. |
||||
*/ |
||||
@Override |
||||
public void runBare() throws Throwable { |
||||
// getName will return the name of the method being run.
|
||||
if (isDisabledInThisEnvironment(getName())) { |
||||
// Let superclass log that we didn't run the test.
|
||||
super.runBare(); |
||||
return; |
||||
} |
||||
|
||||
final Method testMethod = getTestMethod(); |
||||
|
||||
if (isDisabledInThisEnvironment(testMethod)) { |
||||
recordDisabled(); |
||||
this.logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: " |
||||
+ "Total disabled tests=" + getDisabledTestCount()); |
||||
return; |
||||
} |
||||
|
||||
TransactionDefinition explicitTransactionDefinition = |
||||
this.transactionAttributeSource.getTransactionAttribute(testMethod, getClass()); |
||||
if (explicitTransactionDefinition != null) { |
||||
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method [" |
||||
+ getName() + "]."); |
||||
setTransactionDefinition(explicitTransactionDefinition); |
||||
} |
||||
else if (testMethod.isAnnotationPresent(NotTransactional.class)) { |
||||
// Don't have any transaction...
|
||||
preventTransaction(); |
||||
} |
||||
|
||||
// Let JUnit handle execution. We're just changing the state of the test class first.
|
||||
runTestTimed(new TestExecutionCallback() { |
||||
public void run() throws Throwable { |
||||
try { |
||||
AbstractAnnotationAwareTransactionalTests.super.runBare(); |
||||
} |
||||
finally { |
||||
// Mark the context to be blown away if the test was
|
||||
// annotated to result in setDirty being invoked
|
||||
// automatically.
|
||||
if (testMethod.isAnnotationPresent(DirtiesContext.class)) { |
||||
AbstractAnnotationAwareTransactionalTests.this.setDirty(); |
||||
} |
||||
} |
||||
} |
||||
}, testMethod); |
||||
} |
||||
|
||||
/** |
||||
* Determine if the test for the supplied <code>testMethod</code> should |
||||
* run in the current environment. |
||||
* <p>The default implementation is based on |
||||
* {@link IfProfileValue @IfProfileValue} semantics. |
||||
* @param testMethod the test method |
||||
* @return <code>true</code> if the test is <em>disabled</em> in the current environment |
||||
* @see ProfileValueUtils#isTestEnabledInThisEnvironment |
||||
*/ |
||||
protected boolean isDisabledInThisEnvironment(Method testMethod) { |
||||
return !ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass()); |
||||
} |
||||
|
||||
/** |
||||
* Get the current test method. |
||||
*/ |
||||
protected Method getTestMethod() { |
||||
assertNotNull("TestCase.getName() cannot be null", getName()); |
||||
Method testMethod = null; |
||||
try { |
||||
// Use same algorithm as JUnit itself to retrieve the test method
|
||||
// about to be executed (the method name is returned by getName). It
|
||||
// has to be public so we can retrieve it.
|
||||
testMethod = getClass().getMethod(getName(), (Class[]) null); |
||||
} |
||||
catch (NoSuchMethodException ex) { |
||||
fail("Method '" + getName() + "' not found"); |
||||
} |
||||
if (!Modifier.isPublic(testMethod.getModifiers())) { |
||||
fail("Method '" + getName() + "' should be public"); |
||||
} |
||||
return testMethod; |
||||
} |
||||
|
||||
/** |
||||
* Determine whether or not to rollback transactions for the current test |
||||
* by taking into consideration the |
||||
* {@link #isDefaultRollback() default rollback} flag and a possible |
||||
* method-level override via the {@link Rollback @Rollback} annotation. |
||||
* @return the <em>rollback</em> flag for the current test |
||||
*/ |
||||
@Override |
||||
protected boolean isRollback() { |
||||
boolean rollback = isDefaultRollback(); |
||||
Rollback rollbackAnnotation = getTestMethod().getAnnotation(Rollback.class); |
||||
if (rollbackAnnotation != null) { |
||||
boolean rollbackOverride = rollbackAnnotation.value(); |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("Method-level @Rollback(" + rollbackOverride + ") overrides default rollback [" |
||||
+ rollback + "] for test [" + getName() + "]."); |
||||
} |
||||
rollback = rollbackOverride; |
||||
} |
||||
else { |
||||
if (this.logger.isDebugEnabled()) { |
||||
this.logger.debug("No method-level @Rollback override: using default rollback [" + rollback |
||||
+ "] for test [" + getName() + "]."); |
||||
} |
||||
} |
||||
return rollback; |
||||
} |
||||
|
||||
private void runTestTimed(TestExecutionCallback tec, Method testMethod) throws Throwable { |
||||
Timed timed = testMethod.getAnnotation(Timed.class); |
||||
if (timed == null) { |
||||
runTest(tec, testMethod); |
||||
} |
||||
else { |
||||
long startTime = System.currentTimeMillis(); |
||||
try { |
||||
runTest(tec, testMethod); |
||||
} |
||||
finally { |
||||
long elapsed = System.currentTimeMillis() - startTime; |
||||
if (elapsed > timed.millis()) { |
||||
fail("Took " + elapsed + " ms; limit was " + timed.millis()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void runTest(TestExecutionCallback tec, Method testMethod) throws Throwable { |
||||
ExpectedException expectedExceptionAnnotation = testMethod.getAnnotation(ExpectedException.class); |
||||
boolean exceptionIsExpected = (expectedExceptionAnnotation != null && expectedExceptionAnnotation.value() != null); |
||||
Class<? extends Throwable> expectedException = (exceptionIsExpected ? expectedExceptionAnnotation.value() : null); |
||||
|
||||
Repeat repeat = testMethod.getAnnotation(Repeat.class); |
||||
int runs = ((repeat != null) && (repeat.value() > 1)) ? repeat.value() : 1; |
||||
|
||||
for (int i = 0; i < runs; i++) { |
||||
try { |
||||
if (runs > 1 && this.logger != null && this.logger.isInfoEnabled()) { |
||||
this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName()); |
||||
} |
||||
tec.run(); |
||||
if (exceptionIsExpected) { |
||||
fail("Expected exception: " + expectedException.getName()); |
||||
} |
||||
} |
||||
catch (Throwable t) { |
||||
if (!exceptionIsExpected) { |
||||
throw t; |
||||
} |
||||
if (!expectedException.isAssignableFrom(t.getClass())) { |
||||
// Wrap the unexpected throwable with an explicit message.
|
||||
AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected<" + |
||||
expectedException.getName() + "> but was<" + t.getClass().getName() + ">"); |
||||
assertionError.initCause(t); |
||||
throw assertionError; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
private static interface TestExecutionCallback { |
||||
|
||||
void run() throws Throwable; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* <p> |
||||
* Test annotation to indicate that a test method <em>dirties</em> the context |
||||
* for the current test. |
||||
* </p> |
||||
* <p> |
||||
* Using this annotation in conjunction with |
||||
* {@link AbstractAnnotationAwareTransactionalTests} is less error-prone than |
||||
* calling |
||||
* {@link org.springframework.test.AbstractSingleSpringContextTests#setDirty() setDirty()} |
||||
* explicitly because the call to <code>setDirty()</code> is guaranteed to |
||||
* occur, even if the test failed. If only a particular code path in the test |
||||
* dirties the context, prefer calling <code>setDirty()</code> explicitly -- |
||||
* and take care! |
||||
* </p> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
* @see org.springframework.test.AbstractSingleSpringContextTests |
||||
*/ |
||||
@Target( { ElementType.METHOD }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface DirtiesContext { |
||||
|
||||
} |
||||
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* Test annotation to indicate that a test method is required to throw the |
||||
* specified exception. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
*/ |
||||
@Target( { ElementType.METHOD }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface ExpectedException { |
||||
|
||||
Class<? extends Throwable> value(); |
||||
|
||||
} |
||||
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Inherited; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* <p> |
||||
* Test annotation to indicate that a test is enabled for a specific testing |
||||
* profile or environment. If the configured {@link ProfileValueSource} returns |
||||
* a matching {@link #value() value} for the provided {@link #name() name}, the |
||||
* test will be enabled. |
||||
* </p> |
||||
* <p> |
||||
* Note: {@link IfProfileValue @IfProfileValue} can be applied at either the |
||||
* class or method level. |
||||
* </p> |
||||
* <p> |
||||
* Examples: when using {@link SystemProfileValueSource} as the |
||||
* {@link ProfileValueSource} implementation, you can configure a test method to |
||||
* run only on Java VMs from Sun Microsystems as follows: |
||||
* </p> |
||||
* |
||||
* <pre class="code"> |
||||
* {@link IfProfileValue @IfProfileValue}(name="java.vendor", value="Sun Microsystems Inc.") |
||||
* testSomething() { |
||||
* // ...
|
||||
* } |
||||
* </pre> |
||||
* |
||||
* <p> |
||||
* You can alternatively configure {@link IfProfileValue @IfProfileValue} with |
||||
* <em>OR</em> semantics for multiple {@link #values() values} as follows |
||||
* (assuming a {@link ProfileValueSource} has been appropriately configured for |
||||
* the "test-groups" name): |
||||
* </p> |
||||
* |
||||
* <pre class="code"> |
||||
* {@link IfProfileValue @IfProfileValue}(name="test-groups", values={"unit-tests", "integration-tests"}) |
||||
* public void testWhichRunsForUnitOrIntegrationTestGroups() { |
||||
* // ...
|
||||
* } |
||||
* </pre> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
* @see ProfileValueSource |
||||
* @see ProfileValueSourceConfiguration |
||||
* @see ProfileValueUtils |
||||
* @see AbstractAnnotationAwareTransactionalTests |
||||
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests |
||||
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests |
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner |
||||
*/ |
||||
@Target({ElementType.TYPE, ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Inherited |
||||
@Documented |
||||
public @interface IfProfileValue { |
||||
|
||||
/** |
||||
* The <code>name</code> of the <em>profile value</em> against which to test. |
||||
*/ |
||||
String name(); |
||||
|
||||
/** |
||||
* A single, permissible <code>value</code> of the <em>profile value</em> |
||||
* for the given {@link #name() name}. |
||||
* <p>Note: Assigning values to both {@link #value()} and {@link #values()} |
||||
* will lead to a configuration conflict. |
||||
*/ |
||||
String value() default ""; |
||||
|
||||
/** |
||||
* A list of all permissible <code>values</code> of the |
||||
* <em>profile value</em> for the given {@link #name() name}. |
||||
* <p>Note: Assigning values to both {@link #value()} and {@link #values()} |
||||
* will lead to a configuration conflict. |
||||
*/ |
||||
String[] values() default {}; |
||||
|
||||
} |
||||
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* Test annotation to indicate that a method is not transactional. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
*/ |
||||
@Target( { ElementType.METHOD }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface NotTransactional { |
||||
|
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
/** |
||||
* <p> |
||||
* Strategy interface for retrieving <em>profile values</em> for a given |
||||
* testing environment. |
||||
* </p> |
||||
* <p> |
||||
* Concrete implementations must provide a <code>public</code> no-args |
||||
* constructor. |
||||
* </p> |
||||
* <p> |
||||
* Spring provides the following out-of-the-box implementations: |
||||
* </p> |
||||
* <ul> |
||||
* <li>{@link SystemProfileValueSource}</li> |
||||
* </ul> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
* @see ProfileValueSourceConfiguration |
||||
* @see IfProfileValue |
||||
* @see ProfileValueUtils |
||||
*/ |
||||
public interface ProfileValueSource { |
||||
|
||||
/** |
||||
* Get the <em>profile value</em> indicated by the specified key. |
||||
* @param key the name of the <em>profile value</em> |
||||
* @return the String value of the <em>profile value</em>, or <code>null</code> |
||||
* if there is no <em>profile value</em> with that key |
||||
*/ |
||||
String get(String key); |
||||
|
||||
} |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Inherited; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* <p> |
||||
* ProfileValueSourceConfiguration is a class-level annotation which is used to |
||||
* specify what type of {@link ProfileValueSource} to use when retrieving |
||||
* <em>profile values</em> configured via the |
||||
* {@link IfProfileValue @IfProfileValue} annotation. |
||||
* </p> |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 2.5 |
||||
* @see ProfileValueSource |
||||
* @see IfProfileValue |
||||
* @see ProfileValueUtils |
||||
*/ |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target(ElementType.TYPE) |
||||
@Inherited |
||||
@Documented |
||||
public @interface ProfileValueSourceConfiguration { |
||||
|
||||
/** |
||||
* <p> |
||||
* The type of {@link ProfileValueSource} to use when retrieving |
||||
* <em>profile values</em>. |
||||
* </p> |
||||
* |
||||
* @see SystemProfileValueSource |
||||
*/ |
||||
Class<? extends ProfileValueSource> value() default SystemProfileValueSource.class; |
||||
|
||||
} |
||||
@ -0,0 +1,213 @@
@@ -0,0 +1,213 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* General utility methods for working with <em>profile values</em>. |
||||
* |
||||
* @author Sam Brannen |
||||
* @author Juergen Hoeller |
||||
* @since 2.5 |
||||
* @see ProfileValueSource |
||||
* @see ProfileValueSourceConfiguration |
||||
* @see IfProfileValue |
||||
*/ |
||||
public abstract class ProfileValueUtils { |
||||
|
||||
private static final Log logger = LogFactory.getLog(ProfileValueUtils.class); |
||||
|
||||
|
||||
/** |
||||
* Retrieves the {@link ProfileValueSource} type for the specified |
||||
* {@link Class test class} as configured via the |
||||
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} |
||||
* annotation and instantiates a new instance of that type. |
||||
* <p> |
||||
* If |
||||
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} |
||||
* is not present on the specified class or if a custom |
||||
* {@link ProfileValueSource} is not declared, the default |
||||
* {@link SystemProfileValueSource} will be returned instead. |
||||
* |
||||
* @param testClass The test class for which the ProfileValueSource should |
||||
* be retrieved |
||||
* @return the configured (or default) ProfileValueSource for the specified |
||||
* class
|
||||
* @see SystemProfileValueSource |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public static ProfileValueSource retrieveProfileValueSource(Class<?> testClass) { |
||||
Assert.notNull(testClass, "testClass must not be null"); |
||||
|
||||
Class<ProfileValueSourceConfiguration> annotationType = ProfileValueSourceConfiguration.class; |
||||
ProfileValueSourceConfiguration config = testClass.getAnnotation(annotationType); |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class [" |
||||
+ testClass.getName() + "]"); |
||||
} |
||||
|
||||
Class<? extends ProfileValueSource> profileValueSourceType; |
||||
if (config != null) { |
||||
profileValueSourceType = config.value(); |
||||
} |
||||
else { |
||||
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType); |
||||
} |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class [" |
||||
+ testClass.getName() + "]"); |
||||
} |
||||
|
||||
ProfileValueSource profileValueSource; |
||||
if (SystemProfileValueSource.class.equals(profileValueSourceType)) { |
||||
profileValueSource = SystemProfileValueSource.getInstance(); |
||||
} |
||||
else { |
||||
try { |
||||
profileValueSource = profileValueSourceType.newInstance(); |
||||
} |
||||
catch (Exception e) { |
||||
if (logger.isWarnEnabled()) { |
||||
logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType |
||||
+ "] for class [" + testClass.getName() + "]: using default.", e); |
||||
} |
||||
profileValueSource = SystemProfileValueSource.getInstance(); |
||||
} |
||||
} |
||||
|
||||
return profileValueSource; |
||||
} |
||||
|
||||
/** |
||||
* Determine if the supplied <code>testClass</code> is <em>enabled</em> |
||||
* in the current environment, as specified by the |
||||
* {@link IfProfileValue @IfProfileValue} annotation at the class level. |
||||
* <p> |
||||
* Defaults to <code>true</code> if no |
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared. |
||||
* |
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the |
||||
* current environment |
||||
*/ |
||||
public static boolean isTestEnabledInThisEnvironment(Class<?> testClass) { |
||||
IfProfileValue ifProfileValue = testClass.getAnnotation(IfProfileValue.class); |
||||
if (ifProfileValue == null) { |
||||
return true; |
||||
} |
||||
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass); |
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue); |
||||
} |
||||
|
||||
/** |
||||
* Determine if the supplied <code>testMethod</code> is <em>enabled</em> |
||||
* in the current environment, as specified by the |
||||
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared |
||||
* on the test method itself or at the class level. |
||||
* <p> |
||||
* Defaults to <code>true</code> if no |
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared. |
||||
* |
||||
* @param testMethod the test method |
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the |
||||
* current environment |
||||
*/ |
||||
public static boolean isTestEnabledInThisEnvironment(Method testMethod, Class<?> testClass) { |
||||
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class); |
||||
if (ifProfileValue == null) { |
||||
ifProfileValue = testClass.getAnnotation(IfProfileValue.class); |
||||
if (ifProfileValue == null) { |
||||
return true; |
||||
} |
||||
} |
||||
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass); |
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue); |
||||
} |
||||
|
||||
/** |
||||
* Determine if the supplied <code>testMethod</code> is <em>enabled</em> |
||||
* in the current environment, as specified by the |
||||
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared |
||||
* on the test method itself or at the class level. |
||||
* <p> |
||||
* Defaults to <code>true</code> if no |
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared. |
||||
* |
||||
* @param profileValueSource the ProfileValueSource to use to determine if |
||||
* the test is enabled |
||||
* @param testMethod the test method |
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the |
||||
* current environment |
||||
*/ |
||||
public static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, Method testMethod, |
||||
Class<?> testClass) { |
||||
|
||||
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class); |
||||
if (ifProfileValue == null) { |
||||
ifProfileValue = testClass.getAnnotation(IfProfileValue.class); |
||||
if (ifProfileValue == null) { |
||||
return true; |
||||
} |
||||
} |
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue); |
||||
} |
||||
|
||||
/** |
||||
* Determine if the <code>value</code> (or one of the <code>values</code>) |
||||
* in the supplied {@link IfProfileValue @IfProfileValue} annotation is |
||||
* <em>enabled</em> in the current environment. |
||||
* |
||||
* @param profileValueSource the ProfileValueSource to use to determine if |
||||
* the test is enabled |
||||
* @param ifProfileValue the annotation to introspect |
||||
* @return <code>true</code> if the test is <em>enabled</em> in the |
||||
* current environment |
||||
*/ |
||||
private static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, |
||||
IfProfileValue ifProfileValue) { |
||||
|
||||
String environmentValue = profileValueSource.get(ifProfileValue.name()); |
||||
String[] annotatedValues = ifProfileValue.values(); |
||||
if (StringUtils.hasLength(ifProfileValue.value())) { |
||||
if (annotatedValues.length > 0) { |
||||
throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes " |
||||
+ "of @IfProfileValue is not allowed: choose one or the other."); |
||||
} |
||||
annotatedValues = new String[] { ifProfileValue.value() }; |
||||
} |
||||
|
||||
for (String value : annotatedValues) { |
||||
if (ObjectUtils.nullSafeEquals(value, environmentValue)) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* Test annotation to indicate that a test method should be invoked repeatedly. |
||||
* <p /> |
||||
* Note that the scope of execution to be repeated includes execution of the |
||||
* test method itself as well as any <em>set up</em> or <em>tear down</em> |
||||
* of the test fixture. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
*/ |
||||
@Target( { ElementType.METHOD }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Repeat { |
||||
|
||||
int value() default 1; |
||||
|
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* Test annotation to indicate whether or not the transaction for the annotated |
||||
* test method should be <em>rolled back</em> after the test method has |
||||
* completed. If <code>true</code>, the transaction will be rolled back; |
||||
* otherwise, the transaction will be committed. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 2.5 |
||||
*/ |
||||
@Target( { ElementType.METHOD }) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Rollback { |
||||
|
||||
/** |
||||
* <p> |
||||
* Whether or not the transaction for the annotated method should be rolled |
||||
* back after the method has completed. |
||||
* </p> |
||||
*/ |
||||
boolean value() default true; |
||||
|
||||
} |
||||
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.annotation; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Implementation of {@link ProfileValueSource} which uses system properties as |
||||
* the underlying source. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
*/ |
||||
public class SystemProfileValueSource implements ProfileValueSource { |
||||
|
||||
private static final SystemProfileValueSource INSTANCE = new SystemProfileValueSource(); |
||||
|
||||
|
||||
/** |
||||
* Obtain the canonical instance of this ProfileValueSource. |
||||
*/ |
||||
public static final SystemProfileValueSource getInstance() { |
||||
return INSTANCE; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Private constructor, enforcing the singleton pattern. |
||||
*/ |
||||
private SystemProfileValueSource() { |
||||
} |
||||
|
||||
/** |
||||
* Get the <em>profile value</em> indicated by the specified key from the |
||||
* system properties. |
||||
* @see System#getProperty(String) |
||||
*/ |
||||
public String get(String key) { |
||||
Assert.hasText(key, "'key' must not be empty"); |
||||
return System.getProperty(key); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.annotation; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* <p> |
||||
* Test-specific annotation to indicate that a test method has to finish |
||||
* execution in a {@link #millis() specified time period}. |
||||
* </p> |
||||
* <p> |
||||
* If the text execution takes longer than the specified time period, then the |
||||
* test is to be considered failed. |
||||
* </p> |
||||
* <p> |
||||
* Note that the time period includes execution of the test method itself, any |
||||
* {@link Repeat repetitions} of the test, and any <em>set up</em> or |
||||
* <em>tear down</em> of the test fixture. |
||||
* </p> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Sam Brannen |
||||
* @since 2.0 |
||||
* @see Repeat |
||||
* @see AbstractAnnotationAwareTransactionalTests |
||||
*/ |
||||
@Target({ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Timed { |
||||
|
||||
/** |
||||
* The maximum amount of time (in milliseconds) that a test execution can |
||||
* take without being marked as failed due to taking too long. |
||||
*/ |
||||
long millis(); |
||||
|
||||
} |
||||
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.jdbc; |
||||
|
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import java.util.List; |
||||
import java.io.LineNumberReader; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* JdbcTestUtils is a collection of JDBC related utility methods for |
||||
* use in unit and integration testing scenarios. |
||||
* |
||||
* @author Thomas Risberg |
||||
* @since 2.5.4 |
||||
*/ |
||||
public class JdbcTestUtils { |
||||
|
||||
/** |
||||
* Read a script from the LineNumberReaded and build a String containing the lines. |
||||
* @param lineNumberReader the <code>LineNumberReader</> containing the script to be processed |
||||
* @return <code>String</code> containing the script lines |
||||
* @throws IOException |
||||
*/ |
||||
public static String readScript(LineNumberReader lineNumberReader) throws IOException { |
||||
String currentStatement = lineNumberReader.readLine(); |
||||
StringBuilder scriptBuilder = new StringBuilder(); |
||||
while (currentStatement != null) { |
||||
if (StringUtils.hasText(currentStatement)) { |
||||
if (scriptBuilder.length() > 0) { |
||||
scriptBuilder.append('\n'); |
||||
} |
||||
scriptBuilder.append(currentStatement); |
||||
} |
||||
currentStatement = lineNumberReader.readLine(); |
||||
} |
||||
return scriptBuilder.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Does the provided SQL script contain the specified delimiter? |
||||
* @param script the SQL script |
||||
* @param delim charecter delimiting each statement - typically a ';' character |
||||
*/ |
||||
public static boolean containsSqlScriptDelimiters(String script, char delim) { |
||||
boolean inLiteral = false; |
||||
char[] content = script.toCharArray(); |
||||
for (int i = 0; i < script.length(); i++) { |
||||
if (content[i] == '\'') { |
||||
inLiteral = !inLiteral; |
||||
} |
||||
if (content[i] == delim && !inLiteral) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Split an SQL script into separate statements delimited with the provided delimiter character. Each |
||||
* individual statement will be added to the provided <code>List</code>. |
||||
* @param script the SQL script |
||||
* @param delim charecter delimiting each statement - typically a ';' character |
||||
* @param statements the List that will contain the individual statements |
||||
*/ |
||||
public static void splitSqlScript(String script, char delim, List<String> statements) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
boolean inLiteral = false; |
||||
char[] content = script.toCharArray(); |
||||
for (int i = 0; i < script.length(); i++) { |
||||
if (content[i] == '\'') { |
||||
inLiteral = !inLiteral; |
||||
} |
||||
if (content[i] == delim && !inLiteral) { |
||||
if (sb.length() > 0) { |
||||
statements.add(sb.toString()); |
||||
sb = new StringBuilder(); |
||||
} |
||||
} |
||||
else { |
||||
sb.append(content[i]); |
||||
} |
||||
} |
||||
if (sb.length() > 0) { |
||||
statements.add(sb.toString()); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,363 @@
@@ -0,0 +1,363 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.test.jpa; |
||||
|
||||
import java.lang.instrument.ClassFileTransformer; |
||||
import java.lang.reflect.Constructor; |
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.InvocationTargetException; |
||||
import java.lang.reflect.Method; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import javax.persistence.EntityManager; |
||||
import javax.persistence.EntityManagerFactory; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.springframework.beans.BeanUtils; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.config.BeanPostProcessor; |
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; |
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.support.GenericApplicationContext; |
||||
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; |
||||
import org.springframework.instrument.classloading.LoadTimeWeaver; |
||||
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader; |
||||
import org.springframework.instrument.classloading.ShadowingClassLoader; |
||||
import org.springframework.orm.jpa.ExtendedEntityManagerCreator; |
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; |
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator; |
||||
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; |
||||
import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Convenient support class for JPA-related tests. Offers the same contract as |
||||
* AbstractTransactionalDataSourceSpringContextTests and equally good performance, |
||||
* even when performing the instrumentation required by the JPA specification. |
||||
* |
||||
* <p>Exposes an EntityManagerFactory and a shared EntityManager. |
||||
* Requires an EntityManagerFactory to be injected, plus the DataSource and |
||||
* JpaTransactionManager through the superclass. |
||||
* |
||||
* <p>When using Xerces, make sure a post 2.0.2 version is available on the classpath |
||||
* to avoid a critical |
||||
* <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16014"/>bug</a> |
||||
* that leads to StackOverflow. Maven users are likely to encounter this problem since |
||||
* 2.0.2 is used by default. |
||||
* |
||||
* <p>A workaround is to explicitly specify the Xerces version inside the Maven POM: |
||||
* <pre> |
||||
* <dependency> |
||||
* <groupId>xerces</groupId> |
||||
* <artifactId>xercesImpl</artifactId> |
||||
* <version>2.8.1</version> |
||||
* </dependency> |
||||
* </pre> |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Rob Harrop |
||||
* @author Juergen Hoeller |
||||
* @since 2.0 |
||||
*/ |
||||
public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactionalTests { |
||||
|
||||
private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml"; |
||||
|
||||
/** |
||||
* Map from String defining unique combination of config locations, to ApplicationContext. |
||||
* Values are intentionally not strongly typed, to avoid potential class cast exceptions |
||||
* through use between different class loaders. |
||||
*/ |
||||
private static Map<String, Object> contextCache = new HashMap<String, Object>(); |
||||
|
||||
private static Map<String, ClassLoader> classLoaderCache = new HashMap<String, ClassLoader>(); |
||||
|
||||
protected EntityManagerFactory entityManagerFactory; |
||||
|
||||
/** |
||||
* If this instance is in a shadow loader, this variable |
||||
* will contain the parent instance of the subclass. |
||||
* The class will not be the same as the class of the |
||||
* shadow instance, as it was loaded by a different class loader, |
||||
* but it can be invoked reflectively. The shadowParent |
||||
* and the shadow loader can communicate reflectively |
||||
* but not through direct invocation. |
||||
*/ |
||||
private Object shadowParent; |
||||
|
||||
/** |
||||
* Subclasses can use this in test cases. |
||||
* It will participate in any current transaction. |
||||
*/ |
||||
protected EntityManager sharedEntityManager; |
||||
|
||||
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { |
||||
this.entityManagerFactory = entityManagerFactory; |
||||
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory); |
||||
} |
||||
|
||||
/** |
||||
* Create an EntityManager that will always automatically enlist itself in current |
||||
* transactions, in contrast to an EntityManager returned by |
||||
* <code>EntityManagerFactory.createEntityManager()</code> |
||||
* (which requires an explicit <code>joinTransaction()</code> call). |
||||
*/ |
||||
protected EntityManager createContainerManagedEntityManager() { |
||||
return ExtendedEntityManagerCreator.createContainerManagedEntityManager(this.entityManagerFactory); |
||||
} |
||||
|
||||
/** |
||||
* Subclasses should override this method if they wish to disable shadow class loading. |
||||
* <p>The default implementation deactivates shadow class loading if Spring's |
||||
* InstrumentationSavingAgent has been configured on VM startup. |
||||
*/ |
||||
protected boolean shouldUseShadowLoader() { |
||||
return !InstrumentationLoadTimeWeaver.isInstrumentationAvailable(); |
||||
} |
||||
|
||||
@Override |
||||
public void setDirty() { |
||||
super.setDirty(); |
||||
contextCache.remove(cacheKeys()); |
||||
classLoaderCache.remove(cacheKeys()); |
||||
|
||||
// If we are a shadow loader, we need to invoke
|
||||
// the shadow parent to set it dirty, as
|
||||
// it is the shadow parent that maintains the cache state,
|
||||
// not the child
|
||||
if (this.shadowParent != null) { |
||||
try { |
||||
Method m = shadowParent.getClass().getMethod("setDirty", (Class[]) null); |
||||
m.invoke(shadowParent, (Object[]) null); |
||||
} |
||||
catch (Exception ex) { |
||||
throw new RuntimeException(ex); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void runBare() throws Throwable { |
||||
if (!shouldUseShadowLoader()) { |
||||
super.runBare(); |
||||
return; |
||||
} |
||||
|
||||
String combinationOfContextLocationsForThisTestClass = cacheKeys(); |
||||
ClassLoader classLoaderForThisTestClass = getClass().getClassLoader(); |
||||
// save the TCCL
|
||||
ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader(); |
||||
|
||||
if (this.shadowParent != null) { |
||||
Thread.currentThread().setContextClassLoader(classLoaderForThisTestClass); |
||||
super.runBare(); |
||||
} |
||||
|
||||
else { |
||||
ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache.get(combinationOfContextLocationsForThisTestClass); |
||||
|
||||
if (shadowingClassLoader == null) { |
||||
shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass); |
||||
classLoaderCache.put(combinationOfContextLocationsForThisTestClass, shadowingClassLoader); |
||||
} |
||||
try { |
||||
Thread.currentThread().setContextClassLoader(shadowingClassLoader); |
||||
String[] configLocations = getConfigLocations(); |
||||
|
||||
// Do not strongly type, to avoid ClassCastException.
|
||||
Object cachedContext = contextCache.get(combinationOfContextLocationsForThisTestClass); |
||||
|
||||
if (cachedContext == null) { |
||||
|
||||
// Create the LoadTimeWeaver.
|
||||
Class shadowingLoadTimeWeaverClass = shadowingClassLoader.loadClass(ShadowingLoadTimeWeaver.class.getName()); |
||||
Constructor constructor = shadowingLoadTimeWeaverClass.getConstructor(ClassLoader.class); |
||||
constructor.setAccessible(true); |
||||
Object ltw = constructor.newInstance(shadowingClassLoader); |
||||
|
||||
// Create the BeanFactory.
|
||||
Class beanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName()); |
||||
Object beanFactory = BeanUtils.instantiateClass(beanFactoryClass); |
||||
|
||||
// Create the BeanDefinitionReader.
|
||||
Class beanDefinitionReaderClass = shadowingClassLoader.loadClass(XmlBeanDefinitionReader.class.getName()); |
||||
Class beanDefinitionRegistryClass = shadowingClassLoader.loadClass(BeanDefinitionRegistry.class.getName()); |
||||
Object reader = beanDefinitionReaderClass.getConstructor(beanDefinitionRegistryClass).newInstance(beanFactory); |
||||
|
||||
// Load the bean definitions into the BeanFactory.
|
||||
Method loadBeanDefinitions = beanDefinitionReaderClass.getMethod("loadBeanDefinitions", String[].class); |
||||
loadBeanDefinitions.invoke(reader, new Object[] {configLocations}); |
||||
|
||||
// Create LoadTimeWeaver-injecting BeanPostProcessor.
|
||||
Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader.loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class.getName()); |
||||
Class loadTimeWeaverClass = shadowingClassLoader.loadClass(LoadTimeWeaver.class.getName()); |
||||
Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass.getConstructor(loadTimeWeaverClass); |
||||
bppConstructor.setAccessible(true); |
||||
Object beanPostProcessor = bppConstructor.newInstance(ltw); |
||||
|
||||
// Add LoadTimeWeaver-injecting BeanPostProcessor.
|
||||
Class beanPostProcessorClass = shadowingClassLoader.loadClass(BeanPostProcessor.class.getName()); |
||||
Method addBeanPostProcessor = beanFactoryClass.getMethod("addBeanPostProcessor", beanPostProcessorClass); |
||||
addBeanPostProcessor.invoke(beanFactory, beanPostProcessor); |
||||
|
||||
// Create the GenericApplicationContext.
|
||||
Class genericApplicationContextClass = shadowingClassLoader.loadClass(GenericApplicationContext.class.getName()); |
||||
Class defaultListableBeanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName()); |
||||
cachedContext = genericApplicationContextClass.getConstructor(defaultListableBeanFactoryClass).newInstance(beanFactory); |
||||
|
||||
// Invoke the context's "refresh" method.
|
||||
genericApplicationContextClass.getMethod("refresh").invoke(cachedContext); |
||||
|
||||
// Store the context reference in the cache.
|
||||
contextCache.put(combinationOfContextLocationsForThisTestClass, cachedContext); |
||||
} |
||||
// create the shadowed test
|
||||
Class shadowedTestClass = shadowingClassLoader.loadClass(getClass().getName()); |
||||
|
||||
// So long as JUnit is excluded from shadowing we
|
||||
// can minimize reflective invocation here
|
||||
TestCase shadowedTestCase = (TestCase) BeanUtils.instantiateClass(shadowedTestClass); |
||||
|
||||
/* shadowParent = this */ |
||||
Class thisShadowedClass = shadowingClassLoader.loadClass(AbstractJpaTests.class.getName()); |
||||
Field shadowed = thisShadowedClass.getDeclaredField("shadowParent"); |
||||
shadowed.setAccessible(true); |
||||
shadowed.set(shadowedTestCase, this); |
||||
|
||||
/* AbstractSpringContextTests.addContext(Object, ApplicationContext) */ |
||||
Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName()); |
||||
Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass); |
||||
addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext); |
||||
|
||||
// Invoke tests on shadowed test case
|
||||
shadowedTestCase.setName(getName()); |
||||
shadowedTestCase.runBare(); |
||||
} |
||||
catch (InvocationTargetException ex) { |
||||
// Unwrap this for better exception reporting
|
||||
// when running tests
|
||||
throw ex.getTargetException(); |
||||
} |
||||
finally { |
||||
Thread.currentThread().setContextClassLoader(initialClassLoader); |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected String cacheKeys() { |
||||
return StringUtils.arrayToCommaDelimitedString(getConfigLocations()); |
||||
} |
||||
|
||||
/** |
||||
* NB: This method must <b>not</b> have a return type of ShadowingClassLoader as that would cause that |
||||
* class to be loaded eagerly when this test case loads, creating verify errors at runtime. |
||||
*/ |
||||
protected ClassLoader createShadowingClassLoader(ClassLoader classLoader) { |
||||
OrmXmlOverridingShadowingClassLoader orxl = new OrmXmlOverridingShadowingClassLoader(classLoader, |
||||
getActualOrmXmlLocation()); |
||||
customizeResourceOverridingShadowingClassLoader(orxl); |
||||
return orxl; |
||||
} |
||||
|
||||
/** |
||||
* Customize the shadowing class loader. |
||||
* @param shadowingClassLoader this parameter is actually of type |
||||
* ResourceOverridingShadowingClassLoader, and can safely to be cast to |
||||
* that type. However, the signature must not be of that type as that |
||||
* would cause the present class loader to load that type. |
||||
*/ |
||||
protected void customizeResourceOverridingShadowingClassLoader(ClassLoader shadowingClassLoader) { |
||||
// empty
|
||||
} |
||||
|
||||
/** |
||||
* Subclasses can override this to return the real location path for |
||||
* orm.xml or null if they do not wish to find any orm.xml |
||||
* @return orm.xml path or null to hide any such file |
||||
*/ |
||||
protected String getActualOrmXmlLocation() { |
||||
return DEFAULT_ORM_XML_LOCATION; |
||||
} |
||||
|
||||
|
||||
private static class LoadTimeWeaverInjectingBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { |
||||
|
||||
private final LoadTimeWeaver ltw; |
||||
|
||||
public LoadTimeWeaverInjectingBeanPostProcessor(LoadTimeWeaver ltw) { |
||||
this.ltw = ltw; |
||||
} |
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
||||
if (bean instanceof LocalContainerEntityManagerFactoryBean) { |
||||
((LocalContainerEntityManagerFactoryBean) bean).setLoadTimeWeaver(this.ltw); |
||||
} |
||||
if (bean instanceof DefaultPersistenceUnitManager) { |
||||
((DefaultPersistenceUnitManager) bean).setLoadTimeWeaver(this.ltw); |
||||
} |
||||
return bean; |
||||
} |
||||
} |
||||
|
||||
|
||||
private static class ShadowingLoadTimeWeaver implements LoadTimeWeaver { |
||||
|
||||
private final ClassLoader shadowingClassLoader; |
||||
|
||||
public ShadowingLoadTimeWeaver(ClassLoader shadowingClassLoader) { |
||||
this.shadowingClassLoader = shadowingClassLoader; |
||||
} |
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) { |
||||
try { |
||||
Method addClassFileTransformer = |
||||
this.shadowingClassLoader.getClass().getMethod("addTransformer", ClassFileTransformer.class); |
||||
addClassFileTransformer.setAccessible(true); |
||||
addClassFileTransformer.invoke(this.shadowingClassLoader, transformer); |
||||
} |
||||
catch (Exception ex) { |
||||
throw new RuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
public ClassLoader getInstrumentableClassLoader() { |
||||
return this.shadowingClassLoader; |
||||
} |
||||
|
||||
public ClassLoader getThrowawayClassLoader() { |
||||
// Be sure to copy the same resource overrides and same class file transformers:
|
||||
// We want the throwaway class loader to behave like the instrumentable class loader.
|
||||
ResourceOverridingShadowingClassLoader roscl = |
||||
new ResourceOverridingShadowingClassLoader(getClass().getClassLoader()); |
||||
if (this.shadowingClassLoader instanceof ShadowingClassLoader) { |
||||
roscl.copyTransformers((ShadowingClassLoader) this.shadowingClassLoader); |
||||
} |
||||
if (this.shadowingClassLoader instanceof ResourceOverridingShadowingClassLoader) { |
||||
roscl.copyOverrides((ResourceOverridingShadowingClassLoader) this.shadowingClassLoader); |
||||
} |
||||
return roscl; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.test.jpa; |
||||
|
||||
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader; |
||||
|
||||
/** |
||||
* Subclass of ShadowingClassLoader that overrides attempts to |
||||
* locate <code>orm.xml</code>. |
||||
* |
||||
* <p>This class must <b>not</b> be an inner class of AbstractJpaTests |
||||
* to avoid it being loaded until first used. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Adrian Colyer |
||||
* @author Juergen Hoeller |
||||
* @since 2.0 |
||||
*/ |
||||
class OrmXmlOverridingShadowingClassLoader extends ResourceOverridingShadowingClassLoader { |
||||
|
||||
/** |
||||
* Default location of the <code>orm.xml</code> file in the class path: |
||||
* "META-INF/orm.xml" |
||||
*/ |
||||
public static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml"; |
||||
|
||||
|
||||
public OrmXmlOverridingShadowingClassLoader(ClassLoader loader, String realOrmXmlLocation) { |
||||
super(loader); |
||||
|
||||
// Automatically exclude classes from these well-known persistence providers.
|
||||
// Do NOT exclude Hibernate classes --
|
||||
// this causes class casts due to use of CGLIB by Hibernate.
|
||||
// Same goes for OpenJPA which will not enhance the domain classes.
|
||||
excludePackage("oracle.toplink.essentials"); |
||||
excludePackage("junit"); |
||||
|
||||
override(DEFAULT_ORM_XML_LOCATION, realOrmXmlLocation); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright 2002-2005 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.transaction; |
||||
|
||||
import javax.transaction.Status; |
||||
import javax.transaction.Synchronization; |
||||
import javax.transaction.xa.XAResource; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @since 31.08.2004 |
||||
*/ |
||||
public class MockJtaTransaction implements javax.transaction.Transaction { |
||||
|
||||
private Synchronization synchronization; |
||||
|
||||
public int getStatus() { |
||||
return Status.STATUS_ACTIVE; |
||||
} |
||||
|
||||
public void registerSynchronization(Synchronization synchronization) { |
||||
this.synchronization = synchronization; |
||||
} |
||||
|
||||
public Synchronization getSynchronization() { |
||||
return synchronization; |
||||
} |
||||
|
||||
public boolean enlistResource(XAResource xaResource) { |
||||
return false; |
||||
} |
||||
|
||||
public boolean delistResource(XAResource xaResource, int i) { |
||||
return false; |
||||
} |
||||
|
||||
public void commit() { |
||||
} |
||||
|
||||
public void rollback() { |
||||
} |
||||
|
||||
public void setRollbackOnly() { |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/* |
||||
* The Spring Framework is published under the terms |
||||
* of the Apache Software License. |
||||
*/ |
||||
|
||||
package org.springframework.util; |
||||
|
||||
import java.awt.Point; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.NotSerializableException; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
import java.io.OutputStream; |
||||
import java.io.Serializable; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.springframework.beans.TestBean; |
||||
|
||||
/** |
||||
* Utilities for testing serializability of objects. |
||||
* Exposes static methods for use in other test cases. |
||||
* Extends TestCase only to test itself. |
||||
* |
||||
* @author Rod Johnson |
||||
*/ |
||||
public class SerializationTestUtils extends TestCase { |
||||
|
||||
public static void testSerialization(Object o) throws IOException { |
||||
OutputStream baos = new ByteArrayOutputStream(); |
||||
ObjectOutputStream oos = new ObjectOutputStream(baos); |
||||
oos.writeObject(o); |
||||
} |
||||
|
||||
public static boolean isSerializable(Object o) throws IOException { |
||||
try { |
||||
testSerialization(o); |
||||
return true; |
||||
} |
||||
catch (NotSerializableException ex) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { |
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
ObjectOutputStream oos = new ObjectOutputStream(baos); |
||||
oos.writeObject(o); |
||||
oos.flush(); |
||||
baos.flush(); |
||||
byte[] bytes = baos.toByteArray(); |
||||
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes); |
||||
ObjectInputStream ois = new ObjectInputStream(is); |
||||
Object o2 = ois.readObject(); |
||||
|
||||
return o2; |
||||
} |
||||
|
||||
public SerializationTestUtils(String s) { |
||||
super(s); |
||||
} |
||||
|
||||
public void testWithNonSerializableObject() throws IOException { |
||||
TestBean o = new TestBean(); |
||||
assertFalse(o instanceof Serializable); |
||||
|
||||
assertFalse(isSerializable(o)); |
||||
|
||||
try { |
||||
testSerialization(o); |
||||
fail(); |
||||
} |
||||
catch (NotSerializableException ex) { |
||||
// Ok
|
||||
} |
||||
} |
||||
|
||||
public void testWithSerializableObject() throws Exception { |
||||
int x = 5; |
||||
int y = 10; |
||||
Point p = new Point(x, y); |
||||
assertTrue(p instanceof Serializable); |
||||
|
||||
testSerialization(p); |
||||
|
||||
assertTrue(isSerializable(p)); |
||||
|
||||
Point p2 = (Point) serializeAndDeserialize(p); |
||||
assertNotSame(p, p2); |
||||
assertEquals(x, (int) p2.getX()); |
||||
assertEquals(y, (int) p2.getY()); |
||||
} |
||||
|
||||
} |
||||
@ -1,663 +0,0 @@
@@ -1,663 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.hibernate3.support; |
||||
|
||||
import java.io.IOException; |
||||
import java.sql.Connection; |
||||
|
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
import javax.transaction.TransactionManager; |
||||
|
||||
import junit.framework.TestCase; |
||||
import org.easymock.MockControl; |
||||
import org.hibernate.FlushMode; |
||||
import org.hibernate.HibernateException; |
||||
import org.hibernate.SessionFactory; |
||||
import org.hibernate.Transaction; |
||||
import org.hibernate.classic.Session; |
||||
import org.hibernate.engine.SessionFactoryImplementor; |
||||
import org.junit.Ignore; |
||||
|
||||
import org.springframework.mock.web.MockFilterConfig; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.mock.web.MockServletContext; |
||||
import org.springframework.mock.web.PassThroughFilterChain; |
||||
import org.springframework.orm.hibernate3.HibernateAccessor; |
||||
import org.springframework.orm.hibernate3.HibernateTransactionManager; |
||||
import org.springframework.orm.hibernate3.SessionFactoryUtils; |
||||
import org.springframework.transaction.TransactionDefinition; |
||||
import org.springframework.transaction.TransactionStatus; |
||||
import org.springframework.transaction.support.DefaultTransactionDefinition; |
||||
import org.springframework.transaction.support.TransactionSynchronizationManager; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
import org.springframework.web.context.support.StaticWebApplicationContext; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @since 05.03.2005 |
||||
*/ |
||||
@Ignore // getting errors on mocks
|
||||
public class OpenSessionInViewTests extends TestCase { |
||||
|
||||
public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf, 2); |
||||
session.isOpen(); |
||||
sessionControl.setReturnValue(true, 1); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.preHandle(request, response, "handler"); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
|
||||
// check that further invocations simply participate
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
assertEquals(session, SessionFactoryUtils.getSession(sf, false)); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactoryImplementor.class); |
||||
final SessionFactoryImplementor sf = (SessionFactoryImplementor) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class); |
||||
TransactionManager tm = (TransactionManager) tmControl.getMock(); |
||||
tm.getTransaction(); |
||||
tmControl.setReturnValue(null, 2); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
sf.getTransactionManager(); |
||||
sfControl.setReturnValue(tm, 2); |
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.isOpen(); |
||||
sessionControl.setReturnValue(true, 1); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
|
||||
tmControl.replay(); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
|
||||
// check that further invocations simply participate
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
assertEquals(session, SessionFactoryUtils.getSession(sf, false)); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
rawInterceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.preHandle(request, response, "handler"); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
session.flush(); |
||||
sessionControl.setVoidCallable(1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf)); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
rawInterceptor.setSingleSession(false); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf, 1); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); |
||||
SessionFactoryUtils.releaseSession(sess, sf); |
||||
|
||||
// check that further invocations simply participate
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
sfControl.reset(); |
||||
sessionControl.reset(); |
||||
|
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewFilterWithSingleSession() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
MockControl sf2Control = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf2 = (SessionFactory) sf2Control.getMock(); |
||||
MockControl session2Control = MockControl.createControl(Session.class); |
||||
Session session2 = (Session) session2Control.getMock(); |
||||
|
||||
sf2.openSession(); |
||||
sf2Control.setReturnValue(session2, 1); |
||||
session2.getSessionFactory(); |
||||
session2Control.setReturnValue(sf); |
||||
session2.setFlushMode(FlushMode.AUTO); |
||||
session2Control.setVoidCallable(1); |
||||
session2.close(); |
||||
session2Control.setReturnValue(null, 1); |
||||
sf2Control.replay(); |
||||
session2Control.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); |
||||
filterConfig2.addInitParameter("flushMode", "AUTO"); |
||||
|
||||
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); |
||||
filter.init(filterConfig); |
||||
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); |
||||
filter2.init(filterConfig2); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
final FilterChain filterChain2 = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) |
||||
throws IOException, ServletException { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf2)); |
||||
filter.doFilter(servletRequest, servletResponse, filterChain); |
||||
} |
||||
}; |
||||
|
||||
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); |
||||
|
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf2)); |
||||
filter2.doFilter(request, response, filterChain3); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(sf2)); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
sf2Control.verify(); |
||||
session2Control.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
MockControl sessionControl = MockControl.createControl(Session.class); |
||||
Session session = (Session) sessionControl.getMock(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); |
||||
filter.init(filterConfig); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
filter.doFilter(request, response, filterChain); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(sf)); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewFilterWithDeferredClose() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
final MockControl sessionControl = MockControl.createControl(Session.class); |
||||
final Session session = (Session) sessionControl.getMock(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf); |
||||
session.getFlushMode(); |
||||
sessionControl.setReturnValue(FlushMode.NEVER, 1); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
MockControl sf2Control = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf2 = (SessionFactory) sf2Control.getMock(); |
||||
final MockControl session2Control = MockControl.createControl(Session.class); |
||||
final Session session2 = (Session) session2Control.getMock(); |
||||
MockControl txControl = MockControl.createControl(Transaction.class); |
||||
Transaction tx = (Transaction) txControl.getMock(); |
||||
MockControl conControl = MockControl.createControl(Connection.class); |
||||
Connection con = (Connection) conControl.getMock(); |
||||
|
||||
sf2.openSession(); |
||||
sf2Control.setReturnValue(session2, 1); |
||||
session2.beginTransaction(); |
||||
session2Control.setReturnValue(tx, 1); |
||||
session2.connection(); |
||||
session2Control.setReturnValue(con, 2); |
||||
tx.commit(); |
||||
txControl.setVoidCallable(1); |
||||
session2.isConnected(); |
||||
session2Control.setReturnValue(true, 1); |
||||
con.isReadOnly(); |
||||
conControl.setReturnValue(false, 1); |
||||
session2.setFlushMode(FlushMode.NEVER); |
||||
session2Control.setVoidCallable(1); |
||||
|
||||
sf2Control.replay(); |
||||
session2Control.replay(); |
||||
txControl.replay(); |
||||
conControl.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig.addInitParameter("singleSession", "false"); |
||||
filterConfig2.addInitParameter("singleSession", "false"); |
||||
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); |
||||
|
||||
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); |
||||
filter.init(filterConfig); |
||||
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); |
||||
filter2.init(filterConfig2); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
HibernateTransactionManager tm = new HibernateTransactionManager(sf); |
||||
TransactionStatus ts = tm.getTransaction( |
||||
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); |
||||
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); |
||||
SessionFactoryUtils.releaseSession(sess, sf); |
||||
tm.commit(ts); |
||||
|
||||
sessionControl.verify(); |
||||
sessionControl.reset(); |
||||
|
||||
session.close(); |
||||
sessionControl.setReturnValue(null, 1); |
||||
sessionControl.replay(); |
||||
|
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
final FilterChain filterChain2 = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) |
||||
throws IOException, ServletException { |
||||
|
||||
HibernateTransactionManager tm = new HibernateTransactionManager(sf2); |
||||
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition()); |
||||
tm.commit(ts); |
||||
|
||||
session2Control.verify(); |
||||
session2Control.reset(); |
||||
|
||||
session2.close(); |
||||
session2Control.setReturnValue(null, 1); |
||||
session2Control.replay(); |
||||
|
||||
filter.doFilter(servletRequest, servletResponse, filterChain); |
||||
} |
||||
}; |
||||
|
||||
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); |
||||
|
||||
filter2.doFilter(request, response, filterChain3); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
sf2Control.verify(); |
||||
session2Control.verify(); |
||||
txControl.verify(); |
||||
conControl.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception { |
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class); |
||||
final SessionFactory sf = (SessionFactory) sfControl.getMock(); |
||||
final MockControl sessionControl = MockControl.createControl(Session.class); |
||||
final Session session = (Session) sessionControl.getMock(); |
||||
|
||||
sf.openSession(); |
||||
sfControl.setReturnValue(session, 1); |
||||
session.getSessionFactory(); |
||||
sessionControl.setReturnValue(sf); |
||||
session.getFlushMode(); |
||||
sessionControl.setReturnValue(FlushMode.NEVER, 1); |
||||
session.setFlushMode(FlushMode.NEVER); |
||||
sessionControl.setVoidCallable(1); |
||||
sfControl.replay(); |
||||
sessionControl.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig.addInitParameter("singleSession", "false"); |
||||
filterConfig2.addInitParameter("singleSession", "false"); |
||||
filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory"); |
||||
|
||||
OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor(); |
||||
rawInterceptor.setSessionFactory(sf); |
||||
rawInterceptor.setSingleSession(false); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
final OpenSessionInViewFilter filter = new OpenSessionInViewFilter(); |
||||
filter.init(filterConfig); |
||||
final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter(); |
||||
filter2.init(filterConfig2); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
HibernateTransactionManager tm = new HibernateTransactionManager(sf); |
||||
TransactionStatus ts = tm.getTransaction( |
||||
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); |
||||
org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true); |
||||
SessionFactoryUtils.releaseSession(sess, sf); |
||||
tm.commit(ts); |
||||
|
||||
sessionControl.verify(); |
||||
sessionControl.reset(); |
||||
try { |
||||
session.close(); |
||||
} |
||||
catch (HibernateException ex) { |
||||
} |
||||
sessionControl.setReturnValue(null, 1); |
||||
sessionControl.replay(); |
||||
|
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
FilterChain filterChain2 = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) |
||||
throws IOException, ServletException { |
||||
filter.doFilter(servletRequest, servletResponse, filterChain); |
||||
} |
||||
}; |
||||
|
||||
filter.doFilter(request, response, filterChain2); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
sfControl.verify(); |
||||
sessionControl.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
} |
||||
@ -1,183 +0,0 @@
@@ -1,183 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.jdo.support; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import javax.jdo.PersistenceManager; |
||||
import javax.jdo.PersistenceManagerFactory; |
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
|
||||
import junit.framework.TestCase; |
||||
import org.easymock.MockControl; |
||||
|
||||
import org.springframework.mock.web.MockFilterConfig; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.mock.web.MockServletContext; |
||||
import org.springframework.mock.web.PassThroughFilterChain; |
||||
import org.springframework.transaction.support.TransactionSynchronizationManager; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
import org.springframework.web.context.support.StaticWebApplicationContext; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @since 15.06.2004 |
||||
*/ |
||||
public class OpenPersistenceManagerInViewTests extends TestCase { |
||||
|
||||
public void testOpenPersistenceManagerInViewInterceptor() throws Exception { |
||||
MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class); |
||||
PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock(); |
||||
MockControl pmControl = MockControl.createControl(PersistenceManager.class); |
||||
PersistenceManager pm = (PersistenceManager) pmControl.getMock(); |
||||
|
||||
OpenPersistenceManagerInViewInterceptor rawInterceptor = new OpenPersistenceManagerInViewInterceptor(); |
||||
rawInterceptor.setPersistenceManagerFactory(pmf); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
pmf.getPersistenceManager(); |
||||
pmfControl.setReturnValue(pm, 1); |
||||
pmfControl.replay(); |
||||
pmControl.replay(); |
||||
interceptor.preHandle(request, response, "handler"); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(pmf)); |
||||
|
||||
// check that further invocations simply participate
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
pmfControl.verify(); |
||||
pmControl.verify(); |
||||
|
||||
pmfControl.reset(); |
||||
pmControl.reset(); |
||||
pmfControl.replay(); |
||||
pmControl.replay(); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(pmf)); |
||||
pmfControl.verify(); |
||||
pmControl.verify(); |
||||
|
||||
pmfControl.reset(); |
||||
pmControl.reset(); |
||||
pm.close(); |
||||
pmControl.setVoidCallable(1); |
||||
pmfControl.replay(); |
||||
pmControl.replay(); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(pmf)); |
||||
pmfControl.verify(); |
||||
pmControl.verify(); |
||||
} |
||||
|
||||
public void testOpenPersistenceManagerInViewFilter() throws Exception { |
||||
MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class); |
||||
final PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock(); |
||||
MockControl pmControl = MockControl.createControl(PersistenceManager.class); |
||||
PersistenceManager pm = (PersistenceManager) pmControl.getMock(); |
||||
|
||||
pmf.getPersistenceManager(); |
||||
pmfControl.setReturnValue(pm, 1); |
||||
pm.close(); |
||||
pmControl.setVoidCallable(1); |
||||
pmfControl.replay(); |
||||
pmControl.replay(); |
||||
|
||||
MockControl pmf2Control = MockControl.createControl(PersistenceManagerFactory.class); |
||||
final PersistenceManagerFactory pmf2 = (PersistenceManagerFactory) pmf2Control.getMock(); |
||||
MockControl pm2Control = MockControl.createControl(PersistenceManager.class); |
||||
PersistenceManager pm2 = (PersistenceManager) pm2Control.getMock(); |
||||
|
||||
pmf2.getPersistenceManager(); |
||||
pmf2Control.setReturnValue(pm2, 1); |
||||
pm2.close(); |
||||
pm2Control.setVoidCallable(1); |
||||
pmf2Control.replay(); |
||||
pm2Control.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("persistenceManagerFactory", pmf); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("myPersistenceManagerFactory", pmf2); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig2.addInitParameter("persistenceManagerFactoryBeanName", "myPersistenceManagerFactory"); |
||||
|
||||
final OpenPersistenceManagerInViewFilter filter = new OpenPersistenceManagerInViewFilter(); |
||||
filter.init(filterConfig); |
||||
final OpenPersistenceManagerInViewFilter filter2 = new OpenPersistenceManagerInViewFilter(); |
||||
filter2.init(filterConfig2); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(pmf)); |
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
final FilterChain filterChain2 = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) |
||||
throws IOException, ServletException { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(pmf2)); |
||||
filter.doFilter(servletRequest, servletResponse, filterChain); |
||||
} |
||||
}; |
||||
|
||||
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); |
||||
|
||||
assertFalse(TransactionSynchronizationManager.hasResource(pmf)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(pmf2)); |
||||
filter2.doFilter(request, response, filterChain3); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(pmf)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(pmf2)); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
pmfControl.verify(); |
||||
pmControl.verify(); |
||||
pmf2Control.verify(); |
||||
pm2Control.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
} |
||||
@ -1,206 +0,0 @@
@@ -1,206 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2007 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.orm.jpa.support; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import javax.persistence.EntityManager; |
||||
import javax.persistence.EntityManagerFactory; |
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
|
||||
import junit.framework.TestCase; |
||||
import org.easymock.MockControl; |
||||
|
||||
import org.springframework.mock.web.MockFilterConfig; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockHttpServletResponse; |
||||
import org.springframework.mock.web.MockServletContext; |
||||
import org.springframework.mock.web.PassThroughFilterChain; |
||||
import org.springframework.orm.jpa.JpaTemplate; |
||||
import org.springframework.transaction.support.TransactionSynchronizationManager; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
import org.springframework.web.context.support.StaticWebApplicationContext; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter; |
||||
|
||||
/** |
||||
* @author Costin Leau |
||||
* @author Juergen Hoeller |
||||
*/ |
||||
public class OpenEntityManagerInViewTests extends TestCase { |
||||
|
||||
private MockControl factoryControl, managerControl; |
||||
|
||||
private EntityManager manager; |
||||
|
||||
private EntityManagerFactory factory; |
||||
|
||||
private JpaTemplate template; |
||||
|
||||
|
||||
@Override |
||||
protected void setUp() throws Exception { |
||||
factoryControl = MockControl.createControl(EntityManagerFactory.class); |
||||
factory = (EntityManagerFactory) factoryControl.getMock(); |
||||
managerControl = MockControl.createControl(EntityManager.class); |
||||
manager = (EntityManager) managerControl.getMock(); |
||||
|
||||
template = new JpaTemplate(factory); |
||||
template.afterPropertiesSet(); |
||||
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), manager); |
||||
} |
||||
|
||||
@Override |
||||
protected void tearDown() throws Exception { |
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); |
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); |
||||
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); |
||||
assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); |
||||
} |
||||
|
||||
public void testOpenEntityManagerInterceptorInView() throws Exception { |
||||
OpenEntityManagerInViewInterceptor rawInterceptor = new OpenEntityManagerInViewInterceptor(); |
||||
rawInterceptor.setEntityManagerFactory(factory); |
||||
HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
managerControl.replay(); |
||||
factoryControl.replay(); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(factory)); |
||||
|
||||
// check that further invocations simply participate
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
interceptor.preHandle(request, response, "handler"); |
||||
interceptor.postHandle(request, response, "handler", null); |
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
|
||||
factoryControl.verify(); |
||||
managerControl.verify(); |
||||
|
||||
managerControl.reset(); |
||||
factoryControl.reset(); |
||||
managerControl.replay(); |
||||
factoryControl.replay(); |
||||
|
||||
interceptor.postHandle(request, response, "handler", null); |
||||
assertTrue(TransactionSynchronizationManager.hasResource(factory)); |
||||
|
||||
factoryControl.verify(); |
||||
managerControl.verify(); |
||||
|
||||
managerControl.reset(); |
||||
factoryControl.reset(); |
||||
|
||||
manager.close(); |
||||
|
||||
managerControl.replay(); |
||||
factoryControl.replay(); |
||||
|
||||
interceptor.afterCompletion(request, response, "handler", null); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(factory)); |
||||
|
||||
factoryControl.verify(); |
||||
managerControl.verify(); |
||||
} |
||||
|
||||
public void testOpenEntityManagerInViewFilter() throws Exception { |
||||
manager.close(); |
||||
|
||||
managerControl.replay(); |
||||
factoryControl.replay(); |
||||
|
||||
MockControl factoryControl2 = MockControl.createControl(EntityManagerFactory.class); |
||||
final EntityManagerFactory factory2 = (EntityManagerFactory) factoryControl2.getMock(); |
||||
|
||||
MockControl managerControl2 = MockControl.createControl(EntityManager.class); |
||||
EntityManager manager2 = (EntityManager) managerControl2.getMock(); |
||||
|
||||
factoryControl2.expectAndReturn(factory2.createEntityManager(), manager2); |
||||
manager2.close(); |
||||
|
||||
factoryControl2.replay(); |
||||
managerControl2.replay(); |
||||
|
||||
MockServletContext sc = new MockServletContext(); |
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext(); |
||||
wac.setServletContext(sc); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory); |
||||
wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2); |
||||
wac.refresh(); |
||||
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(sc); |
||||
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter"); |
||||
MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2"); |
||||
filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory"); |
||||
|
||||
final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter(); |
||||
filter.init(filterConfig); |
||||
final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter(); |
||||
filter2.init(filterConfig2); |
||||
|
||||
final FilterChain filterChain = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(factory)); |
||||
servletRequest.setAttribute("invoked", Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
final FilterChain filterChain2 = new FilterChain() { |
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) |
||||
throws IOException, ServletException { |
||||
assertTrue(TransactionSynchronizationManager.hasResource(factory2)); |
||||
filter.doFilter(servletRequest, servletResponse, filterChain); |
||||
} |
||||
}; |
||||
|
||||
FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2); |
||||
|
||||
assertFalse(TransactionSynchronizationManager.hasResource(factory)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(factory2)); |
||||
filter2.doFilter(request, response, filterChain3); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(factory)); |
||||
assertFalse(TransactionSynchronizationManager.hasResource(factory2)); |
||||
assertNotNull(request.getAttribute("invoked")); |
||||
|
||||
factoryControl.verify(); |
||||
managerControl.verify(); |
||||
factoryControl2.verify(); |
||||
managerControl2.verify(); |
||||
|
||||
wac.close(); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue