From 437e700dfc4173da66d45abd95b6f661d7216218 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Tue, 4 Sep 2012 14:20:13 +0300 Subject: [PATCH] Remove transaction listener support (#9402) --- .../com/vaadin/server/ApplicationContext.java | 139 ------------ .../src/com/vaadin/server/VaadinPortlet.java | 32 +-- .../src/com/vaadin/server/VaadinServlet.java | 31 +-- .../TransactionListenersConcurrency.java | 201 ------------------ .../RemoveTransactionListener.java | 84 -------- 5 files changed, 15 insertions(+), 472 deletions(-) delete mode 100644 server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java delete mode 100644 uitest/src/com/vaadin/tests/applicationcontext/RemoveTransactionListener.java diff --git a/server/src/com/vaadin/server/ApplicationContext.java b/server/src/com/vaadin/server/ApplicationContext.java index 7577639a3f..2c09ed3857 100644 --- a/server/src/com/vaadin/server/ApplicationContext.java +++ b/server/src/com/vaadin/server/ApplicationContext.java @@ -16,15 +16,11 @@ package com.vaadin.server; import java.io.File; -import java.io.PrintWriter; import java.io.Serializable; -import java.io.StringWriter; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,50 +44,6 @@ import com.vaadin.Application; public abstract class ApplicationContext implements HttpSessionBindingListener, Serializable { - /** - * Interface for listening to transaction events. Implement this interface - * to listen to all transactions between the client and the application. - * - */ - public static interface TransactionListener extends Serializable { - - /** - * Invoked at the beginning of every transaction. - * - * The transaction is linked to the context, not the application so if - * you have multiple applications running in the same context you need - * to check that the request is associated with the application you are - * interested in. This can be done looking at the application parameter. - * - * @param application - * the Application object. - * @param transactionData - * the Data identifying the transaction. - */ - public void transactionStart(Application application, - Object transactionData); - - /** - * Invoked at the end of every transaction. - * - * The transaction is linked to the context, not the application so if - * you have multiple applications running in the same context you need - * to check that the request is associated with the application you are - * interested in. This can be done looking at the application parameter. - * - * @param applcation - * the Application object. - * @param transactionData - * the Data identifying the transaction. - */ - public void transactionEnd(Application application, - Object transactionData); - - } - - protected Collection listeners = Collections - .synchronizedList(new LinkedList()); - protected final HashSet applications = new HashSet(); protected WebBrowser browser = new WebBrowser(); @@ -104,97 +56,6 @@ public abstract class ApplicationContext implements HttpSessionBindingListener, private transient WrappedSession session; - /** - * Adds a transaction listener to this context. The transaction listener is - * called before and after each each request related to this session except - * when serving static resources. - * - * The transaction listener must not be null. - * - * @see com.vaadin.service.ApplicationContext#addTransactionListener(com.vaadin.service.ApplicationContext.TransactionListener) - */ - public void addTransactionListener( - ApplicationContext.TransactionListener listener) { - if (listener != null) { - listeners.add(listener); - } - } - - /** - * Removes a transaction listener from this context. - * - * @param listener - * the listener to be removed. - * @see ApplicationContext.TransactionListener - */ - public void removeTransactionListener( - ApplicationContext.TransactionListener listener) { - listeners.remove(listener); - } - - /** - * Sends a notification that a transaction is starting. - * - * @param application - * The application associated with the transaction. - * @param request - * the HTTP or portlet request that triggered the transaction. - */ - protected void startTransaction(Application application, Object request) { - ArrayList currentListeners; - synchronized (listeners) { - currentListeners = new ArrayList( - listeners); - } - for (ApplicationContext.TransactionListener listener : currentListeners) { - listener.transactionStart(application, request); - } - } - - /** - * Sends a notification that a transaction has ended. - * - * @param application - * The application associated with the transaction. - * @param request - * the HTTP or portlet request that triggered the transaction. - */ - protected void endTransaction(Application application, Object request) { - LinkedList exceptions = null; - - ArrayList currentListeners; - synchronized (listeners) { - currentListeners = new ArrayList( - listeners); - } - - for (ApplicationContext.TransactionListener listener : currentListeners) { - try { - listener.transactionEnd(application, request); - } catch (final RuntimeException t) { - if (exceptions == null) { - exceptions = new LinkedList(); - } - exceptions.add(t); - } - } - - // If any runtime exceptions occurred, throw a combined exception - if (exceptions != null) { - final StringBuffer msg = new StringBuffer(); - for (Exception e : exceptions) { - if (msg.length() == 0) { - msg.append("\n\n--------------------------\n\n"); - } - msg.append(e.getMessage() + "\n"); - final StringWriter trace = new StringWriter(); - e.printStackTrace(new PrintWriter(trace, true)); - msg.append(trace.toString()); - } - throw new RuntimeException(msg.toString()); - } - } - /** * @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent) */ diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java index 0a99644735..3d99cf603e 100644 --- a/server/src/com/vaadin/server/VaadinPortlet.java +++ b/server/src/com/vaadin/server/VaadinPortlet.java @@ -432,7 +432,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants { (ResourceResponse) response); } else { Application application = null; - boolean transactionStarted = false; boolean requestStarted = false; boolean applicationRunning = false; @@ -485,13 +484,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants { startApplication(request, application, applicationContext); applicationRunning = true; - /* - * Transaction starts. Call transaction listeners. Transaction - * end is called in the finally block below. - */ - applicationContext.startTransaction(application, request); - transactionStarted = true; - /* Notify listeners */ // Finds the window within the application @@ -592,25 +584,17 @@ public class VaadinPortlet extends GenericPortlet implements Constants { // Notifies transaction end try { - if (transactionStarted) { - ((PortletApplicationContext2) application.getContext()) - .endTransaction(application, request); + if (requestStarted) { + ((PortletRequestListener) application).onRequestEnd( + request, response); + } } finally { - try { - if (requestStarted) { - ((PortletRequestListener) application) - .onRequestEnd(request, response); + CurrentInstance.clearAll(); - } - } finally { - CurrentInstance.clearAll(); - - PortletSession session = request - .getPortletSession(false); - if (session != null) { - requestTimer.stop(getApplicationContext(session)); - } + PortletSession session = request.getPortletSession(false); + if (session != null) { + requestTimer.stop(getApplicationContext(session)); } } } diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 81569030e7..29e473a16a 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -285,7 +285,6 @@ public class VaadinServlet extends HttpServlet implements Constants { } Application application = null; - boolean transactionStarted = false; boolean requestStarted = false; boolean applicationRunning = false; @@ -350,13 +349,6 @@ public class VaadinServlet extends HttpServlet implements Constants { startApplication(request, application, webApplicationContext); applicationRunning = true; - /* - * Transaction starts. Call transaction listeners. Transaction end - * is called in the finally block below. - */ - webApplicationContext.startTransaction(application, request); - transactionStarted = true; - /* Handle the request */ if (requestType == RequestType.FILE_UPLOAD) { // UI is resolved in communication manager @@ -406,25 +398,16 @@ public class VaadinServlet extends HttpServlet implements Constants { // Notifies transaction end try { - if (transactionStarted) { - ((ServletApplicationContext) application.getContext()) - .endTransaction(application, request); - + if (requestStarted) { + ((HttpServletRequestListener) application).onRequestEnd( + request, response); } - } finally { - try { - if (requestStarted) { - ((HttpServletRequestListener) application) - .onRequestEnd(request, response); - } - } finally { - CurrentInstance.clearAll(); + CurrentInstance.clearAll(); - HttpSession session = request.getSession(false); - if (session != null) { - requestTimer.stop(getApplicationContext(session)); - } + HttpSession session = request.getSession(false); + if (session != null) { + requestTimer.stop(getApplicationContext(session)); } } diff --git a/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java b/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java deleted file mode 100644 index 05ffcd1e36..0000000000 --- a/server/tests/src/com/vaadin/tests/server/TransactionListenersConcurrency.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.vaadin.tests.server; - -import static org.easymock.EasyMock.createMock; - -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Random; - -import javax.servlet.http.HttpSession; - -import junit.framework.TestCase; - -import org.easymock.EasyMock; - -import com.vaadin.Application; -import com.vaadin.Application.ApplicationStartEvent; -import com.vaadin.server.ApplicationContext; -import com.vaadin.server.DeploymentConfiguration; -import com.vaadin.server.ServletApplicationContext; - -public class TransactionListenersConcurrency extends TestCase { - - /** - * This test starts N threads concurrently. Each thread creates an - * application which adds a transaction listener to the context. A - * transaction is then started for each application. Some semi-random delays - * are included so that calls to addTransactionListener and - * WebApplicationContext.startTransaction are mixed. - * - */ - public void testTransactionListeners() throws Exception { - final List exceptions = new ArrayList(); - - HttpSession session = createSession(); - final ServletApplicationContext context = ServletApplicationContext - .getApplicationContext(session); - List threads = new ArrayList(); - - for (int i = 0; i < 5; i++) { - Thread t = new Thread(new Runnable() { - - @Override - public void run() { - Application app = new Application() { - - @Override - public void init() { - // Sleep 0-1000ms so another transaction has time to - // start before we add the transaction listener. - try { - Thread.sleep((long) (1000 * new Random() - .nextDouble())); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - getContext().addTransactionListener( - new DelayTransactionListener(2000)); - } - - }; - - // Start the application so the transaction listener is - // called later on. - try { - DeploymentConfiguration dc = EasyMock - .createMock(DeploymentConfiguration.class); - EasyMock.expect(dc.isProductionMode()).andReturn(true); - EasyMock.expect(dc.getInitParameters()).andReturn( - new Properties()); - EasyMock.replay(dc); - - app.start(new ApplicationStartEvent(new URL( - "http://localhost/"), dc, context)); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - try { - // Call the transaction listener using reflection as - // startTransaction is protected. - - Method m = ApplicationContext.class.getDeclaredMethod( - "startTransaction", Application.class, - Object.class); - m.setAccessible(true); - m.invoke(context, app, null); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - }); - - threads.add(t); - t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - - @Override - public void uncaughtException(Thread t, Throwable e) { - if (e.getCause() != null) { - e = e.getCause(); - } - exceptions.add(e); - } - }); - } - - // Start the threads and wait for all of them to finish - for (Thread t : threads) { - t.start(); - } - int running = threads.size(); - - while (running > 0) { - for (Iterator i = threads.iterator(); i.hasNext();) { - Thread t = i.next(); - if (!t.isAlive()) { - running--; - i.remove(); - } - } - } - - for (Throwable t : exceptions) { - if (t instanceof InvocationTargetException) { - t = t.getCause(); - } - if (t != null) { - t.printStackTrace(System.err); - fail(t.getClass().getName()); - } - } - - System.out.println("Done, all ok"); - - } - - /** - * Creates a HttpSession mock - * - */ - private static HttpSession createSession() { - HttpSession session = createMock(HttpSession.class); - EasyMock.expect( - session.getAttribute(ServletApplicationContext.class.getName())) - .andReturn(null).anyTimes(); - session.setAttribute( - EasyMock.eq(ServletApplicationContext.class.getName()), - EasyMock.anyObject()); - - EasyMock.replay(session); - return session; - } - - /** - * A transaction listener that just sleeps for the given amount of time in - * transactionStart and transactionEnd. - * - */ - public static class DelayTransactionListener implements - ApplicationContext.TransactionListener { - - private int delay; - - public DelayTransactionListener(int delay) { - this.delay = delay; - } - - @Override - public void transactionStart(Application application, - Object transactionData) { - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } - - @Override - public void transactionEnd(Application application, - Object transactionData) { - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } - } - -} diff --git a/uitest/src/com/vaadin/tests/applicationcontext/RemoveTransactionListener.java b/uitest/src/com/vaadin/tests/applicationcontext/RemoveTransactionListener.java deleted file mode 100644 index 5927e9c19f..0000000000 --- a/uitest/src/com/vaadin/tests/applicationcontext/RemoveTransactionListener.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.vaadin.tests.applicationcontext; - -import com.vaadin.Application; -import com.vaadin.server.ApplicationContext; -import com.vaadin.server.ApplicationContext.TransactionListener; -import com.vaadin.tests.components.TestBase; -import com.vaadin.tests.util.Log; - -public class RemoveTransactionListener extends TestBase { - - private final Log log = new Log(10); - - @Override - protected void setup() { - // Add one listener that will remove itself from within transactionEnd - getMainWindow().getApplication().getContext() - .addTransactionListener(new TransactionListener() { - @Override - public void transactionStart(Application application, - Object transactionData) { - } - - @Override - public void transactionEnd(Application application, - Object transactionData) { - removeListener(this); - log.log("Listener removed in transactionEnd"); - } - }); - - // Add one listener that will remove itself from within transactionStart - getMainWindow().getApplication().getContext() - .addTransactionListener(new TransactionListener() { - @Override - public void transactionStart(Application application, - Object transactionData) { - removeListener(this); - log.log("Listener removed in transactionStart"); - } - - @Override - public void transactionEnd(Application application, - Object transactionData) { - } - }); - - // Add one listener to verify that all listeners are called, as thrown - // ConcurrentModificationException causes subsequent listeners to be - // ignored - getMainWindow().getApplication().getContext() - .addTransactionListener(new TransactionListener() { - @Override - public void transactionStart(Application application, - Object transactionData) { - log.log("transactionStart from last listener"); - } - - @Override - public void transactionEnd(Application application, - Object transactionData) { - log.log("transactionEnd from last listener"); - } - }); - - addComponent(log); - } - - private void removeListener(TransactionListener l) { - ApplicationContext context = getMainWindow().getApplication() - .getContext(); - context.removeTransactionListener(l); - } - - @Override - protected String getDescription() { - return "Tests that a transaction listener can be removed from within the listener."; - } - - @Override - protected Integer getTicketNumber() { - return Integer.valueOf(7065); - } - -} -- 2.39.5