You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jw...@apache.org on 2013/05/30 20:55:34 UTC

svn commit: r1487973 - in /myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component: StampState.java UIXCollection.java

Author: jwaldman
Date: Thu May 30 18:55:33 2013
New Revision: 1487973

URL: http://svn.apache.org/r1487973
Log:
TRINIDAD-2383 issue with table stamp state 
thanks to Jing Wu for the patch

Modified:
    myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/StampState.java
    myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/StampState.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/StampState.java?rev=1487973&r1=1487972&r2=1487973&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/StampState.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/StampState.java Thu May 30 18:55:33 2013
@@ -103,7 +103,8 @@ final class StampState implements Extern
   }
 
   /**
-   * Save the per-row state of a given stamp.
+   * Save the per-row state of a given stamp, the state will be for the component
+   * itself, not including it's child/facet state.
    */
   public static Object saveStampState(FacesContext context, UIComponent stamp)
   {
@@ -135,53 +136,35 @@ final class StampState implements Extern
     UIXCollection table)
   {
     int childCount = stamp.getChildCount();
-    // If we have any children, iterate through the array,
+    // If we have any children, iterate through the map,
     // saving state
     if (childCount == 0)
       return null;
 
-    Object[] childStateArray = null;
+    Map<String, Object> childStateMap = null;
     List<UIComponent> children = stamp.getChildren();
-    boolean childStateIsEmpty = true;
     for(int i=0; i < childCount; i++)
     {
       UIComponent child = children.get(i);
       Object childState = table.saveStampState(context, child);
 
-      // Until we have one non-null entry, don't allocate the array.
-      // Unlike facets, we *do* care about stashing Transient.TRUE,
-      // because we have to keep track of them relative to any
-      // later components, BUT if it's all null and transient, we
-      // can discard the array.  This does mean that putting
-      // transient components into a stamp is a bit inefficient
-
-      // So: allocate the array if we encounter our first
-      // non-null childState (even if it's transient)
-      if (childStateArray == null)
-      {
-        if (childState == null)
-          continue;
+      // Until we have one non-null entry, don't allocate the map.
+      // So: allocate the map if we encounter our first
+      // non-null childState
 
-        childStateArray = new Object[childCount];
-      }
+      if (childState == null)
+        continue;
 
-      // But remember the moment we've encountered a non-null
-      // *and* non-transient component, because that means we'll
-      // really need to keep this array
-      if ((childState != UIXCollection.Transient.TRUE) && (childState != null))
-        childStateIsEmpty = false;
+      if (childStateMap == null)
+      {
+        childStateMap = new HashMap<String, Object>(childCount);
+      }
 
       // Store a value into the array
-      assert(childStateArray != null);
-      childStateArray[i] = childState;
+      childStateMap.put(child.getId(), childState);
     }
 
-    // Even if we bothered to allocate an array, if all we
-    // had were transient + null, don't bother with the array at all
-    if (childStateIsEmpty)
-      return null;
-
-    return childStateArray;
+    return childStateMap;
   }
 
   /**
@@ -195,46 +178,19 @@ final class StampState implements Extern
     UIXCollection table,
     Object stampState)
   {
-    if (stampState == null)
+    if (stampState == null || !(stampState instanceof Map))
       return;
 
     List<UIComponent> kids = stamp.getChildren();
-    Object[] state = (Object[]) stampState;
+    Map<String, Object> state = (Map<String, Object>)stampState;
 
-    int childIndex = 0;
-    for(int i=0; i<state.length; i++)
+    for (UIComponent kid : kids)
     {
-      Object childState = state[i];
-      // Skip over any saved state that corresponds to transient
-      // components
-      if (childState != UIXCollection.Transient.TRUE)
-      {
-        while (childIndex < kids.size())
-        {
-          UIComponent kid = kids.get(childIndex);
-          childIndex++;
-          // Skip over any transient components before restoring state
-          if (!kid.isTransient())
-          {
-            table.restoreStampState(context, kid, childState);
-            break;
-          }
-        }
-      }
-      // The component may or may not still be there;  if it
-      // is, then we'd better skip over it
-      else
-      {
-        if (childIndex < kids.size())
-        {
-          UIComponent child = kids.get(childIndex);
-          // If the child isn't transient, then it must be
-          // something that we want to look at on the next
-          // iteration.
-          if (child.isTransient())
-            childIndex++;
-        }
-      }
+      Object childState = state.get(kid.getId());
+      if (childState == null)
+        continue;
+
+      table.restoreStampState(context, kid, childState);
     }
   }
 

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java?rev=1487973&r1=1487972&r2=1487973&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java Thu May 30 18:55:33 2013
@@ -1002,7 +1002,7 @@ public abstract class UIXCollection exte
   protected Object saveStampState(FacesContext context, UIComponent stamp)
   {
     if (stamp.isTransient())
-      return Transient.TRUE;
+      return null;
 
     boolean needsTearDownContext = false;
 
@@ -1018,8 +1018,8 @@ public abstract class UIXCollection exte
     {
       // The structure we will use is:
       //   0: state of the stamp
-      //   1: state of the children (an array)
-      //   2: state of the facets (an array of name-key pairs)
+      //   1: state of the children (a map from child's id to its state)
+      //   2: state of the facets (a map from facet name to its state)
       // If there is no facet state, we have a two-element array
       // If there is no facet state or child state, we have a one-elment array
       // If there is no state at all, we return null
@@ -1035,45 +1035,30 @@ public abstract class UIXCollection exte
 
       if (facetCount > 0)
       {
-        boolean facetStateIsEmpty = true;
-        Object[] facetState = null;
+        Map<String, Object> facetState = null;
 
         Map<String, UIComponent> facetMap = stamp.getFacets();
 
-        int i = 0;
         for(Map.Entry<String, UIComponent> entry : facetMap.entrySet())
         {
           Object singleFacetState = saveStampState(context, entry.getValue());
-          if ((singleFacetState == null) ||
-              (singleFacetState == Transient.TRUE))
+          if (singleFacetState == null)
             continue;
 
           // Don't bother allocating anything until we have some non-null
-          // and non-transient facet state
-          if (facetStateIsEmpty)
+          // facet state
+          if (facetState == null)
           {
-            facetStateIsEmpty = false;
-            facetState = new Object[facetCount * 2];
+            facetState = new HashMap<String, Object>(facetCount);
           }
 
-          int base = i * 2;
-          assert(facetState != null);
-          facetState[base] = entry.getKey();
-          facetState[base + 1] = singleFacetState;
-          i++;
+          facetState.put(entry.getKey(), singleFacetState);
         }
 
         // OK, we had something:  allocate the state array to three
         // entries, and insert the facet state at position 2
-        if (!facetStateIsEmpty)
+        if (facetState != null)
         {
-          // trim the facetState array if necessary
-          if(i < facetCount)
-          {
-            Object[] trimmed = new Object[i*2];
-            System.arraycopy(facetState, 0, trimmed, 0, i*2);
-            facetState = trimmed;
-          }
           state = new Object[3];
           state[2] = facetState;
         }
@@ -1119,8 +1104,8 @@ public abstract class UIXCollection exte
   protected void restoreStampState(FacesContext context, UIComponent stamp,
                                    Object stampState)
   {
-    // Just a transient component - return
-    if ((stampState == Transient.TRUE) || (stampState == null))
+    // No state for the component - return
+    if (stampState == null)
     {
       return;
     }
@@ -1143,18 +1128,17 @@ public abstract class UIXCollection exte
 
 
     // If there's any facet state, restore it
-    if (stateSize >= 3)
+    if (stateSize >= 3 && (state[2] instanceof Map))
     {
-      Object[] facetStateArray = (Object[]) state[2];
+      Map<String, Object> facetStateMap = (Map<String, Object>) state[2];
       // This had better be non-null, otherwise we never
-      // should have allocated a three-element array!
-      assert(facetStateArray != null);
+      // should have allocated a three-element map!
+      assert(facetStateMap != null);
 
-      for(int i=0; i<facetStateArray.length; i+=2)
+      for (String facetName : facetStateMap.keySet())
       {
-        String facetName = (String) facetStateArray[i];
-        Object facetState = facetStateArray[i + 1];
-        if (facetState != Transient.TRUE)
+        Object facetState = facetStateMap.get(facetName);
+        if (facetState != null)
           restoreStampState(context, stamp.getFacet(facetName), facetState);
       }
     }