You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/03/16 22:38:29 UTC

svn commit: r1082310 - in /myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces: component/html/ext/AbstractHtmlDataTable.java custom/datalist/AbstractHtmlDataList.java

Author: lu4242
Date: Wed Mar 16 21:38:29 2011
New Revision: 1082310

URL: http://svn.apache.org/viewvc?rev=1082310&view=rev
Log:
TOMAHAWK-961 Deleting a row when t:dataList/t:dataTable preserveRowStates=true assigns submitted values to wrong row (see TOMAHAWK-1552 for details)

Modified:
    myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java
    myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/datalist/AbstractHtmlDataList.java

Modified: myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java?rev=1082310&r1=1082309&r2=1082310&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java (original)
+++ myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/component/html/ext/AbstractHtmlDataTable.java Wed Mar 16 21:38:29 2011
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.application.Application;
 import javax.faces.component.ContextCallback;
@@ -35,7 +36,6 @@ import javax.faces.component.EditableVal
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIColumn;
 import javax.faces.component.UIComponent;
-import javax.faces.component.UIComponentBase;
 import javax.faces.component.UINamingContainer;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
@@ -247,7 +247,49 @@ public abstract class AbstractHtmlDataTa
             // Check if the clientId for the component, which we 
             // are looking for, has a rowIndex attached
             char separator = UINamingContainer.SEPARATOR_CHAR;
-            if (clientId.matches(baseClientId + separator+"[0-9]+"+separator+".*"))
+                
+            ValueExpression rowKeyVE = getValueExpression("rowKey");
+            boolean rowKeyFound = false;
+            
+            if (rowKeyVE != null)
+            {
+                int oldRow = this.getRowIndex();
+                try
+                {
+                    // iterate over the rows
+                    int rowsToProcess = getRows();
+                    // if getRows() returns 0, all rows have to be processed
+                    if (rowsToProcess == 0)
+                    {
+                        rowsToProcess = getRowCount();
+                    }
+                    int rowIndex = getFirst();
+                    for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
+                    {
+                        setRowIndex(rowIndex);
+                        if (!isRowAvailable())
+                        {
+                            break;
+                        }
+                        
+                        if (clientId.startsWith(getContainerClientId(context)))
+                        {
+                            rowKeyFound = true;
+                            break;
+                        }
+                    }
+                    
+                    if (rowKeyFound)
+                    {
+                        returnValue = invokeOnComponentTraverseRow(context, clientId, callback);
+                    }
+                }
+                finally
+                {
+                    this.setRowIndex(oldRow);
+                }
+            }
+            if (rowKeyVE == null && clientId.matches(baseClientId + separator+"[0-9]+"+separator+".*"))
             {
                 String subId = clientId.substring(baseClientId.length() + 1);
                 String clientRow = subId.substring(0, subId.indexOf(separator));
@@ -268,21 +310,7 @@ public abstract class AbstractHtmlDataTa
                         return false;
                     }
         
-                    for (Iterator<UIComponent> it1 = getChildren().iterator(); 
-                            !returnValue && it1.hasNext();)
-                    {
-                        //recursive call to find the component
-                        returnValue = it1.next().invokeOnComponent(context, clientId, callback);
-                    }
-                    
-                    if (!returnValue)
-                    {
-                        UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
-                        if (detailStampFacet != null)
-                        {
-                            returnValue = detailStampFacet.invokeOnComponent(context, clientId, callback);
-                        }
-                    }
+                    returnValue = invokeOnComponentTraverseRow(context, clientId, callback);
                 }
                 finally
                 {
@@ -328,6 +356,28 @@ public abstract class AbstractHtmlDataTa
 
         return returnValue;
     }
+    
+    private boolean invokeOnComponentTraverseRow(FacesContext context, String clientId,
+            ContextCallback callback)
+    {
+        boolean returnValue = false;
+        for (Iterator<UIComponent> it1 = getChildren().iterator(); 
+            !returnValue && it1.hasNext();)
+        {
+            //recursive call to find the component
+            returnValue = it1.next().invokeOnComponent(context, clientId, callback);
+        }
+
+        if (!returnValue)
+        {
+            UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
+            if (detailStampFacet != null)
+            {
+                returnValue = detailStampFacet.invokeOnComponent(context, clientId, callback);
+            }
+        }
+        return returnValue;
+    }
 
     public void setRowIndex(int rowIndex)
     {
@@ -1614,7 +1664,7 @@ public abstract class AbstractHtmlDataTa
 
     public boolean isCurrentDetailExpanded()
     {
-        Boolean expanded = (Boolean) _expandedNodes.get(new Integer(getRowIndex()));
+        Boolean expanded = (Boolean) _expandedNodes.get(getClientId(getFacesContext()));
         if (expanded != null)
         {
             return expanded.booleanValue();
@@ -1683,7 +1733,7 @@ public abstract class AbstractHtmlDataTa
      */
     public void toggleDetail()
     {
-        Integer rowIndex = new Integer(getRowIndex());
+        String derivedRowKey = getClientId(getFacesContext());
 
         // get the current expanded state of the row
         boolean expanded = isDetailExpanded();
@@ -1694,12 +1744,12 @@ public abstract class AbstractHtmlDataTa
             if (isDetailStampExpandedDefault())
             {
                 // if default is expanded we have to override with FALSE here
-                _expandedNodes.put(rowIndex, Boolean.FALSE);
+                _expandedNodes.put(derivedRowKey, Boolean.FALSE);
             }
             else
             {
                 // if default is collapsed we can fallback to this default
-                _expandedNodes.remove(rowIndex);
+                _expandedNodes.remove(derivedRowKey);
             }
         }
         else
@@ -1709,12 +1759,12 @@ public abstract class AbstractHtmlDataTa
             if (isDetailStampExpandedDefault())
             {
                 // if default is expanded we can fallback to this default
-                _expandedNodes.remove(rowIndex);
+                _expandedNodes.remove(derivedRowKey);
             }
             else
             {
                 // if default is collapsed we have to override with TRUE
-                _expandedNodes.put(rowIndex, Boolean.TRUE);
+                _expandedNodes.put(derivedRowKey, Boolean.TRUE);
             }
         }
     }
@@ -1726,9 +1776,7 @@ public abstract class AbstractHtmlDataTa
      */
     public boolean isDetailExpanded()
     {
-        Integer rowIndex = new Integer(getRowIndex());
-
-        Boolean expanded = (Boolean) _expandedNodes.get(rowIndex);
+        Boolean expanded = (Boolean) _expandedNodes.get(getClientId(getFacesContext()));
         if (expanded == null)
         {
             return isDetailStampExpandedDefault();
@@ -1793,9 +1841,29 @@ public abstract class AbstractHtmlDataTa
         int rowCount = getRowCount();
 
         _expandedNodes.clear();
-        for (int row = 0; row < rowCount; row++)
+        
+        if (getRowKey() != null)
+        {
+            int oldRow = getRowIndex();
+            try
+            {
+                for (int row = 0; row < rowCount; row++)
+                {
+                    setRowIndex(row);
+                    _expandedNodes.put(getClientId(getFacesContext()), Boolean.TRUE);
+                }
+            }
+            finally
+            {
+                setRowIndex(oldRow);
+            }
+        }
+        else
         {
-            _expandedNodes.put(new Integer(row), Boolean.TRUE);
+            for (int row = 0; row < rowCount; row++)
+            {
+                _expandedNodes.put(new Integer(row).toString(), Boolean.TRUE);
+            }
         }
     }
 

Modified: myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/datalist/AbstractHtmlDataList.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/datalist/AbstractHtmlDataList.java?rev=1082310&r1=1082309&r2=1082310&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/datalist/AbstractHtmlDataList.java (original)
+++ myfaces/tomahawk/trunk/core12/src/main/java/org/apache/myfaces/custom/datalist/AbstractHtmlDataList.java Wed Mar 16 21:38:29 2011
@@ -21,6 +21,7 @@ package org.apache.myfaces.custom.datali
 import java.util.Iterator;
 import java.util.Map;
 
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.component.ContextCallback;
 import javax.faces.component.UIComponent;
@@ -263,12 +264,57 @@ public abstract class AbstractHtmlDataLi
                 // Check if the clientId for the component, which we 
                 // are looking for, has a rowIndex attached
                 char separator = UINamingContainer.SEPARATOR_CHAR;
-                String subId = clientId.substring(baseClientId.length() + 1);
+                ValueExpression rowKeyVE = getValueExpression("rowKey");
+                boolean rowKeyFound = false;
+                
+                if (rowKeyVE != null)
+                {
+                    int oldRow = this.getRowIndex();
+                    try
+                    {
+                        // iterate over the rows
+                        int rowsToProcess = getRows();
+                        // if getRows() returns 0, all rows have to be processed
+                        if (rowsToProcess == 0)
+                        {
+                            rowsToProcess = getRowCount();
+                        }
+                        int rowIndex = getFirst();
+                        for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
+                        {
+                            setRowIndex(rowIndex);
+                            if (!isRowAvailable())
+                            {
+                                break;
+                            }
+                            
+                            if (clientId.startsWith(getContainerClientId(context)))
+                            {
+                                rowKeyFound = true;
+                                break;
+                            }
+                        }
+                        
+                        if (rowKeyFound)
+                        {
+                            for (Iterator<UIComponent> it1 = getChildren().iterator(); 
+                                    !returnValue && it1.hasNext();)
+                            {
+                                //recursive call to find the component
+                                returnValue = it1.next().invokeOnComponent(context, clientId, callback);
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        this.setRowIndex(oldRow);
+                    }
+                }
                 //If the char next to baseClientId is the separator one and
                 //the subId matches the regular expression
-                if (clientId.charAt(baseClientId.length()) == separator && 
-                        subId.matches("[0-9]+"+separator+".*"))
+                if (rowKeyVE == null && clientId.matches(baseClientId + separator+"[0-9]+"+separator+".*"))
                 {
+                    String subId = clientId.substring(baseClientId.length() + 1);
                     String clientRow = subId.substring(0, subId.indexOf(separator));
         
                     //Now we save the current position