You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2015/04/23 17:34:21 UTC

svn commit: r1675636 - in /myfaces/tobago/trunk: tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ tobago-core/src/main/java/org/apache/myfaces/tobago/model/ tobag...

Author: lofwyr
Date: Thu Apr 23 15:34:21 2015
New Revision: 1675636

URL: http://svn.apache.org/r1675636
Log:
TOBAGO-1457: Sheet sort may be performed twice and possible NPE when using method binding for sorting

Modified:
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/StringUtils.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
    myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TobagoDemoController.java

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java?rev=1675636&r1=1675635&r2=1675636&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java Thu Apr 23 15:34:21 2015
@@ -54,14 +54,18 @@ import javax.faces.component.UIComponent
 import javax.faces.component.UINamingContainer;
 import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ComponentSystemEvent;
 import javax.faces.event.FacesEvent;
+import javax.faces.event.ListenerFor;
 import javax.faces.event.PhaseId;
+import javax.faces.event.PreRenderComponentEvent;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+@ListenerFor(systemEventClass = PreRenderComponentEvent.class)
 public abstract class AbstractUISheet extends AbstractUIData
     implements SheetStateChangeSource2, SortActionSource2, OnComponentPopulated,
     LayoutContainer, LayoutComponent, SupportsRenderedPartially {
@@ -113,18 +117,6 @@ public abstract class AbstractUISheet ex
       }
     }
 
-    final MethodExpression expression = getSortActionListenerExpression();
-    if (expression != null) {
-      try {
-        FacesEvent facesEvent = new SortActionEvent(this, null);
-        expression.invoke(facesContext.getELContext(), new Object[]{facesEvent});
-      } catch (Exception e) {
-        LOG.warn("Initial sorting not possible!", e);
-      }
-    } else {
-      new Sorter().perform(this);
-    }
-
     super.encodeBegin(facesContext);
   }
 
@@ -456,12 +448,35 @@ public abstract class AbstractUISheet ex
       }
     } else if (facesEvent instanceof SortActionEvent) {
       getSheetState(getFacesContext()).updateSortState((SortActionEvent) facesEvent);
+      sort(getFacesContext(), (SortActionEvent) facesEvent);
+    }
+  }
+
+  public void processEvent(ComponentSystemEvent event) {
+    super.processEvent(event);
+    if (event instanceof PreRenderComponentEvent) {
+      sort(getFacesContext(), null);
+    }
+  }
+
+  protected void sort(FacesContext facesContext, SortActionEvent event) {
+    final SheetState sheetState = getSheetState(getFacesContext());
+    if (sheetState.isToBeSorted()) {
       final MethodExpression expression = getSortActionListenerExpression();
       if (expression != null) {
-        expression.invoke(getFacesContext().getELContext(), new Object[]{facesEvent});
+        try {
+          if (event == null) {
+            event =
+                new SortActionEvent(this, (UIColumn) findComponent(getSheetState(facesContext).getSortedColumnId()));
+          }
+          expression.invoke(facesContext.getELContext(), new Object[]{event});
+        } catch (Exception e) {
+          LOG.warn("Sorting not possible!", e);
+        }
       } else {
-        new Sorter().perform((SortActionEvent) facesEvent);
+        new Sorter().perform(this);
       }
+      sheetState.setToBeSorted(false);
     }
   }
 

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/StringUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/StringUtils.java?rev=1675636&r1=1675635&r2=1675636&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/StringUtils.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/StringUtils.java Thu Apr 23 15:34:21 2015
@@ -458,6 +458,13 @@ public final class StringUtils {
   }
 
   /**
+   * Basically taken from commons-lang
+   */
+  public static boolean notEquals(String a, String b) {
+    return a == null ? b != null : !a.equals(b);
+  }
+
+  /**
    * Checks if the String starts like a url, e.g. http: or xyz:
    */
   public static boolean isUrl(final String link) {

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java?rev=1675636&r1=1675635&r2=1675636&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java Thu Apr 23 15:34:21 2015
@@ -40,6 +40,7 @@ public class SheetState implements Seria
   private int first;
   private String sortedColumnId;
   private boolean ascending;
+  private boolean toBeSorted;
   private String columnWidths;
   private List<Integer> selectedRows;
   private Integer[] scrollPosition;
@@ -54,6 +55,7 @@ public class SheetState implements Seria
     first = -1;
     sortedColumnId = null;
     ascending = true;
+    toBeSorted = false;
     columnWidths = null;
     resetSelected();
     if (expandedState != null) {
@@ -83,7 +85,10 @@ public class SheetState implements Seria
   }
 
   public void setSortedColumnId(final String sortedColumnId) {
-    this.sortedColumnId = sortedColumnId;
+    if (StringUtils.notEquals(this.sortedColumnId, sortedColumnId)) {
+      this.sortedColumnId = sortedColumnId;
+      toBeSorted = true;
+    }
   }
 
   public boolean isAscending() {
@@ -91,7 +96,10 @@ public class SheetState implements Seria
   }
 
   public void setAscending(final boolean ascending) {
-    this.ascending = ascending;
+    if (this.ascending != ascending) {
+      this.ascending = ascending;
+      toBeSorted = true;
+    }
   }
 
   public String getColumnWidths() {
@@ -115,10 +123,10 @@ public class SheetState implements Seria
     final UIColumn actualColumn = sortEvent.getColumn();
 
     if (actualColumn.getId().equals(sortedColumnId)) {
-      ascending = !ascending;
+      setAscending(!isAscending());
     } else {
-      ascending = true;
-      sortedColumnId = actualColumn.getId();
+      setAscending(true);
+      setSortedColumnId(actualColumn.getId());
     }
   }
 
@@ -152,6 +160,14 @@ public class SheetState implements Seria
     this.selectedState = selectedState;
   }
 
+  public boolean isToBeSorted() {
+    return toBeSorted;
+  }
+
+  public void setToBeSorted(boolean toBeSorted) {
+    this.toBeSorted = toBeSorted;
+  }
+
   /**
    * @deprecated since 2.0.0
    */

Modified: myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TobagoDemoController.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TobagoDemoController.java?rev=1675636&r1=1675635&r2=1675636&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TobagoDemoController.java (original)
+++ myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TobagoDemoController.java Thu Apr 23 15:34:21 2015
@@ -511,6 +511,8 @@ public class TobagoDemoController implem
     final SolarObject sun = list.remove(0);
     final String columnId = sheetState.getSortedColumnId();
 
+    LOG.info("Sorting column '{}'", columnId);
+
     Comparator<SolarObject> comparator = null;
 
     if ("name".equals(columnId)) {