TAPESTRY-218: Persistent properties can't be set to null.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/tapestry/branches/branch-3-0@244059 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/org/apache/tapestry/record/SessionPageRecorder.java b/framework/src/org/apache/tapestry/record/SessionPageRecorder.java
index b1053c4..a3fc705 100644
--- a/framework/src/org/apache/tapestry/record/SessionPageRecorder.java
+++ b/framework/src/org/apache/tapestry/record/SessionPageRecorder.java
@@ -32,55 +32,44 @@
 import org.apache.tapestry.util.StringSplitter;
 
 /**
- *  Simple implementation of {@link org.apache.tapestry.engine.IPageRecorder}
- *  that stores page changes as {@link javax.servlet.http.HttpSession} attributes.
- *
- *
- *  @author Howard Ship
- *  @version $Id$
+ * Simple implementation of {@link org.apache.tapestry.engine.IPageRecorder}that stores page
+ * changes as {@link javax.servlet.http.HttpSession}attributes.
  * 
- **/
+ * @author Howard Ship
+ * @version $Id$
+ */
 
 public class SessionPageRecorder extends PageRecorder
 {
     private static final Log LOG = LogFactory.getLog(SessionPageRecorder.class);
 
     /**
-     *  Dictionary of changes, keyed on an instance of 
-     *  {@link ChangeKey}
-     *  (which enapsulates component path and property name).  The
-     *  value is the new value for the object.
-     *  The same information is stored into the
-     *  {@link HttpSession}, which is  used as a kind of
-     *  write-behind cache.
-     *
-     **/
+     * Dictionary of changes, keyed on an instance of {@link ChangeKey}(which enapsulates component
+     * path and property name). The value is the new value for the object. The same information is
+     * stored into the {@link HttpSession}, which is used as a kind of write-behind cache.
+     */
 
     private Map _changes;
 
     /**
-     *  The session into which changes are recorded.
+     * The session into which changes are recorded.
      * 
-     *  @since 3.0
-     * 
-     **/
+     * @since 3.0
+     */
 
     private HttpSession _session;
 
     /**
-     *  The fully qualified name of the page being recorded.
+     * The fully qualified name of the page being recorded.
      * 
-     *  @since 3.0
-     * 
-     **/
+     * @since 3.0
+     */
 
     private String _pageName;
 
     /**
-     *  The prefix (for {@link HttpSession} attributes) used by this
-     *  page recorder.
-     * 
-     **/
+     * The prefix (for {@link HttpSession}attributes) used by this page recorder.
+     */
 
     private String _attributePrefix;
 
@@ -110,8 +99,8 @@
         {
             ChangeKey key = (ChangeKey) i.next();
 
-            String attributeKey =
-                constructAttributeKey(key.getComponentPath(), key.getPropertyName());
+            String attributeKey = constructAttributeKey(key.getComponentPath(), key
+                    .getPropertyName());
 
             if (LOG.isDebugEnabled())
                 LOG.debug("Removing session attribute " + attributeKey);
@@ -121,11 +110,9 @@
     }
 
     /**
-     *  Simply clears the dirty flag, because there is no external place
-     *  to store changed page properties.  Sets the locked flag to prevent
-     *  subsequent changes from occuring now.
-     *
-     **/
+     * Simply clears the dirty flag, because there is no external place to store changed page
+     * properties. Sets the locked flag to prevent subsequent changes from occuring now.
+     */
 
     public void commit()
     {
@@ -134,9 +121,8 @@
     }
 
     /**
-     *  Returns true if the recorder has any changes recorded.
-     *
-     **/
+     * Returns true if the recorder has any changes recorded.
+     */
 
     public boolean getHasChanges()
     {
@@ -163,8 +149,7 @@
 
             Object value = entry.getValue();
 
-            PageChange change =
-                new PageChange(key.getComponentPath(), key.getPropertyName(), value);
+            PageChange change = new PageChange(key.getComponentPath(), key.getPropertyName(), value);
 
             result.add(change);
         }
@@ -188,7 +173,10 @@
 
         String attributeKey = constructAttributeKey(componentPath, propertyName);
 
-        _session.setAttribute(attributeKey, newValue);
+        if (newValue == null)
+            _session.removeAttribute(attributeKey);
+        else
+            _session.setAttribute(attributeKey, newValue);
 
         if (LOG.isDebugEnabled())
             LOG.debug("Stored session attribute " + attributeKey + " = " + newValue);
@@ -236,7 +224,7 @@
 
             // The first name is the servlet name, which allows
             // multiple Tapestry apps to share a HttpSession, even
-            // when they use the same page names.  The second name
+            // when they use the same page names. The second name
             // is the page name, which we already know.
 
             int i = 2;
@@ -253,8 +241,8 @@
         }
 
         if (LOG.isDebugEnabled())
-            LOG.debug(
-                count == 0 ? "No recorded changes." : "Restored " + count + " recorded changes.");
+            LOG.debug(count == 0 ? "No recorded changes." : "Restored " + count
+                    + " recorded changes.");
     }
 
 }
\ No newline at end of file
diff --git a/status.xml b/status.xml
index 0a78df3..f1788e2 100644
--- a/status.xml
+++ b/status.xml
@@ -269,6 +269,9 @@
     <action type="fix" dev="HLS" due-to="Morten Holm" fixes-bug="TAPESTRY-248">
        The online Tapestry component reference for 3.0.1 for @Foreach component has an error in the example section. 
     </action>
+    <action type="fix" dev="HLS" due-to="Michael Frericks" fixes-bug="TAPESTRY-218">
+      Persistent properties cant be set to null.
+    </action>
       
   </release>