You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2009/12/09 04:44:36 UTC

svn commit: r888692 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/services/ test/java/org/apache/tapestry5/internal/services/

Author: hlship
Date: Wed Dec  9 03:44:34 2009
New Revision: 888692

URL: http://svn.apache.org/viewvc?rev=888692&view=rev
Log:
TAP5-834: BaseOptimizedSessionPersistedObject does not work correctly with Tomcat & Jetty

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SessionImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SessionImplTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.java?rev=888692&r1=888691&r2=888692&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.java Wed Dec  9 03:44:34 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -18,12 +18,20 @@
 import javax.servlet.http.HttpSessionBindingListener;
 
 /**
- * Base implementation of {@link org.apache.tapestry5.OptimizedSessionPersistedObject}.  Subclasses should invoke {@link
- * #markDirty()} when internal state of the object changes.
- *
+ * Base implementation of
+ * {@link org.apache.tapestry5.OptimizedSessionPersistedObject}. Subclasses
+ * should invoke {@link #markDirty()} when internal state of the object changes.
+ * <p>
+ * Note that (due to TAP5-834), the object will receive a spurious
+ * <code>valueUnbound()</code> notification when dirty. Tapestry sets dirty
+ * session attributes to null, then to the persisted object, to force a
+ * <code>valueBound()</code> notification, and that unfortunately also sends the
+ * <code>valueUnbound()</code>.
+ * 
  * @since 5.1.1.0
  */
-public abstract class BaseOptimizedSessionPersistedObject implements OptimizedSessionPersistedObject, HttpSessionBindingListener
+public abstract class BaseOptimizedSessionPersistedObject implements
+        OptimizedSessionPersistedObject, HttpSessionBindingListener
 {
     private transient boolean dirty;
 
@@ -33,8 +41,10 @@
     }
 
     /**
-     * Invoked by the servlet container when the value is stored (or re-stored) as an attribute of the session. This
-     * clears the dirty flag. Subclasses may override this method, but should invoke this implementation.
+     * Invoked by the servlet container when the value is stored (or re-stored)
+     * as an attribute of the session. This
+     * clears the dirty flag. Subclasses may override this method, but should
+     * invoke this implementation.
      */
     public void valueBound(HttpSessionBindingEvent event)
     {
@@ -49,7 +59,8 @@
     }
 
     /**
-     * Invoked by the subclass whenever the internal state of the object changes. Typically, this is invoked from
+     * Invoked by the subclass whenever the internal state of the object
+     * changes. Typically, this is invoked from
      * mutator methods.
      */
     protected final void markDirty()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SessionImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SessionImpl.java?rev=888692&r1=888691&r2=888692&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SessionImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SessionImpl.java Wed Dec  9 03:44:34 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -37,7 +37,8 @@
     private boolean invalidated = false;
 
     /**
-     * Cache of attribute objects read from, or written to, the real session. This is needed for end-of-request
+     * Cache of attribute objects read from, or written to, the real session.
+     * This is needed for end-of-request
      * processing.
      */
     private final Map<String, Object> sessionAttributeCache = CollectionFactory.newMap();
@@ -122,11 +123,18 @@
 
             Object attributeValue = entry.getValue();
 
-            if (attributeValue == null)
-                continue;
+            if (attributeValue == null) continue;
 
             if (analyzer.isDirty(attributeValue))
+            {
+                // TAP5-384: Jetty & Tomcat work by object identity, will not update the attribute
+                // and fire the session binding event unless there's a real change. So we set the
+                // attribute to null and then to the new value and that should force the necessary
+                // notification.
+                
+                session.setAttribute(attributeName, null);
                 session.setAttribute(attributeName, attributeValue);
+            }
         }
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SessionImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SessionImplTest.java?rev=888692&r1=888691&r2=888692&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SessionImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SessionImplTest.java Wed Dec  9 03:44:34 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,15 +14,17 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.internal.test.InternalBaseTestCase;
-import org.apache.tapestry5.services.Session;
-import org.testng.annotations.Test;
-
-import javax.servlet.http.HttpSession;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 
+import javax.servlet.http.HttpSession;
+
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.services.Session;
+import org.apache.tapestry5.services.SessionPersistedObjectAnalyzer;
+import org.testng.annotations.Test;
+
 public class SessionImplTest extends InternalBaseTestCase
 {
     @Test
@@ -108,4 +110,33 @@
 
         verify();
     }
+
+    @Test
+    public void dirty_persisted_object_is_forced_to_update()
+    {
+        HttpSession hs = mockHttpSession();
+        SessionPersistedObjectAnalyzer analyzer = newMock(SessionPersistedObjectAnalyzer.class);
+        Object dirty = new Object();
+
+        train_getAttribute(hs, "dirty", dirty);
+
+        replay();
+
+        Session session = new SessionImpl(hs, analyzer);
+
+        assertSame(session.getAttribute("dirty"), dirty);
+
+        verify();
+
+        expect(analyzer.isDirty(dirty)).andReturn(true);
+
+        hs.setAttribute("dirty", null);
+        hs.setAttribute("dirty", dirty);
+
+        replay();
+
+        session.restoreDirtyObjects();
+
+        verify();
+    }
 }



Re: svn commit: r888692 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/services/ test/java/org/apache/tapestry5/internal/services/

Posted by Ulrich Stärk <ul...@spielviel.de>.
On 09.12.2009 04:44 schrieb hlship@apache.org:
> Author: hlship
> Date: Wed Dec  9 03:44:34 2009
> New Revision: 888692
>
> URL: http://svn.apache.org/viewvc?rev=888692&view=rev
> Log:
> TAP5-834: BaseOptimizedSessionPersistedObject does not work correctly with Tomcat&  Jetty



> +                // TAP5-384: Jetty&  Tomcat work by object identity, will not update the attribute

It's TAP5-834

> +                // and fire the session binding event unless there's a real change. So we set the
> +                // attribute to null and then to the new value and that should force the necessary

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org