You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/03/02 23:29:53 UTC

svn commit: r918228 - /myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java

Author: jakobk
Date: Tue Mar  2 22:29:52 2010
New Revision: 918228

URL: http://svn.apache.org/viewvc?rev=918228&view=rev
Log:
MYFACES-2583 f:ajax cannot retrieve clientId from component (fix for that + major code cleanup on AjaxBehavior)

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java?rev=918228&r1=918227&r2=918228&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/AjaxBehavior.java Tue Mar  2 22:29:52 2010
@@ -18,12 +18,11 @@
  */
 package javax.faces.component.behavior;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -36,7 +35,8 @@
  * @version $Revision: 696523 $ $Date: 2009-03-14 16:04:27 -0400 (mer., 17 sept. 2008) $
  * @since 2.0
  */
-public class AjaxBehavior extends ClientBehaviorBase {
+public class AjaxBehavior extends ClientBehaviorBase 
+{
 
     /**
      * not needed anymore but enforced by the spec
@@ -46,8 +46,6 @@
      */
     public static final String BEHAVIOR_ID = "javax.faces.behavior.Ajax";
 
-    //To enable delta state saving we need this one
-    _AjaxBehaviorDeltaStateHelper<AjaxBehavior> deltaStateHelper = new _AjaxBehaviorDeltaStateHelper<AjaxBehavior>(this);
     private static final String ATTR_EXECUTE = "execute";
     private static final String ATTR_ON_ERROR = "onerror";
     private static final String ATTR_ON_EVENT = "onevent";
@@ -55,7 +53,6 @@
     private static final String ATTR_DISABLED = "disabled";
     private static final String ATTR_IMMEDIATE = "immediate";
 
-
     /**
      * special render and execute targets
      */
@@ -64,188 +61,138 @@
     private static final String VAL_THIS = "@this";
     private static final String VAL_NONE = "@none";
 
-    //we cannot use Collection - singletons here otherwise the delta state restore would fail
-    private static final Collection<String> VAL_FORM_LIST = new ArrayList<String>(1);
-    private static final Collection<String> VAL_ALL_LIST = new ArrayList<String>(1);
-    private static final Collection<String> VAL_THIS_LIST = new ArrayList<String>(1);
-    private static final Collection<String> VAL_NONE_LIST = new ArrayList<String>(1);
-
-    /**
-     * internal errors
-     */
-    private static final String ERR_KEY_IS_NULL = "Given value expression key is null";
-
-
-    Map<String, ValueExpression> _valueExpressions = new HashMap<String, ValueExpression>();
-
-    static {
-        VAL_FORM_LIST.add(VAL_FORM);
-        VAL_ALL_LIST.add(VAL_ALL);
-        VAL_THIS_LIST.add(VAL_THIS);
-        VAL_NONE_LIST.add(VAL_NONE);
-
-    }
+    private static final Collection<String> VAL_FORM_LIST = Collections.singletonList(VAL_FORM);
+    private static final Collection<String> VAL_ALL_LIST = Collections.singletonList(VAL_ALL);
+    private static final Collection<String> VAL_THIS_LIST = Collections.singletonList(VAL_THIS);
+    private static final Collection<String> VAL_NONE_LIST = Collections.singletonList(VAL_NONE);
 
+    //To enable delta state saving we need this one
+    private _AjaxBehaviorDeltaStateHelper<AjaxBehavior> deltaStateHelper 
+            = new _AjaxBehaviorDeltaStateHelper<AjaxBehavior>(this);
+    
+    private Map<String, ValueExpression> _valueExpressions 
+            = new HashMap<String, ValueExpression>();
 
-    public AjaxBehavior() {
+    public AjaxBehavior() 
+    {
         super();
-        getValueExpressionMap();
-    }
-
-
-    private Map<String, ValueExpression> getValueExpressionMap() {
-        return _valueExpressions;
     }
 
-
-    public void addAjaxBehaviorListener(AjaxBehaviorListener listener) {
+    public void addAjaxBehaviorListener(AjaxBehaviorListener listener) 
+    {
         super.addBehaviorListener(listener);
     }
-
-    public Collection<String> getExecute() {
-        Object execute = deltaStateHelper.eval(ATTR_EXECUTE);
-
-        return (Collection<String>) execute;
+    
+    public void removeAjaxBehaviorListener(AjaxBehaviorListener listener) 
+    {
+        removeBehaviorListener(listener);
     }
 
+    public Collection<String> getExecute() 
+    {
+        // we have to evaluate the real value in this method,
+        // because the value of the ValueExpression might
+        // change (almost sure it does!)
+        return evalForCollection(ATTR_EXECUTE);
+    }
 
-    public void setExecute(Collection<String> execute) {
+    public void setExecute(Collection<String> execute) 
+    {
         deltaStateHelper.put(ATTR_EXECUTE, execute);
     }
 
-    public String getOnerror() {
+    public String getOnerror() 
+    {
         return (String) deltaStateHelper.eval(ATTR_ON_ERROR);
     }
 
-    public void setOnerror(String onError) {
+    public void setOnerror(String onError) 
+    {
         deltaStateHelper.put(ATTR_ON_ERROR, onError);
     }
 
-    public String getOnevent() {
+    public String getOnevent() 
+    {
         return (String) deltaStateHelper.eval(ATTR_ON_EVENT);
     }
 
-    public void setOnevent(String onEvent) {
+    public void setOnevent(String onEvent) 
+    {
         deltaStateHelper.put(ATTR_ON_EVENT, onEvent);
     }
 
-    public Collection<String> getRender() {
-        Object render = deltaStateHelper.eval(ATTR_RENDER);
-
-        return (Collection<String>) render;
+    public Collection<String> getRender() 
+    {
+        // we have to evaluate the real value in this method,
+        // because the value of the ValueExpression might
+        // change (almost sure it does!)
+        return evalForCollection(ATTR_RENDER);
     }
 
-    public void setRender(Collection<String> render) {
+    public void setRender(Collection<String> render) 
+    {
         deltaStateHelper.put(ATTR_RENDER, render);
     }
 
-    public ValueExpression getValueExpression(String name) {
+    public ValueExpression getValueExpression(String name) 
+    {
         return getValueExpressionMap().get(name);
     }
 
-    public void setValueExpression(String name, ValueExpression item) {
-        if (item == null) {
+    public void setValueExpression(String name, ValueExpression item) 
+    {
+        if (item == null) 
+        {
             getValueExpressionMap().remove(name);
             deltaStateHelper.remove(name);
-        } else {
-            Object value = item.getValue(FacesContext.getCurrentInstance().getELContext());
-            //the tag handler sets the values over value expressions we do have to do a conversion
-            if (name.equals(ATTR_EXECUTE) && value instanceof String) {
-                //TODO please move this conversion code over to the tag handler
-                //I do not think it belongs in here
-                applyArrayAttributeFromString(ATTR_EXECUTE, value);
-            } else if (name.equals(ATTR_RENDER) && value instanceof String) {
-                applyArrayAttributeFromString(ATTR_RENDER, value);
-            }
+        } 
+        else 
+        {
             getValueExpressionMap().put(name, item);
         }
     }
 
-    /**
-     * facelets applies its values over the value expressions
-     * to have our system working fully we need to reapply
-     * the values to our delta state saver
-     * in converted form so that getters and setters can work on the maps instead
-     * of the string value expression, the delta states have higher priority
-     * than the value expressions
-     * Since Behaviors do not have converters we have to do it here (the getter
-     * or setter is a no go due to the call frequency of this method)
-     *
-     * @param attribute the attribute name
-     * @param value     the value expression to be changed to a collection
-     */
-    private void applyArrayAttributeFromString(String attribute, Object value) {
-
-        String stringValue = (String) value;
-        //@special handling for @all, @none, @form and @this
-        if (stringValue.equals(VAL_FORM)) {
-            deltaStateHelper.put(attribute, VAL_FORM_LIST);
-            return;
-        } else if (stringValue.equals(VAL_ALL)) {
-            deltaStateHelper.put(attribute, VAL_ALL_LIST);
-            return;
-        } else if (stringValue.equals(VAL_NONE)) {
-            deltaStateHelper.put(attribute, VAL_NONE_LIST);
-            return;
-        } else if (stringValue.equals(VAL_THIS)) {
-            deltaStateHelper.put(attribute, VAL_THIS_LIST);
-            return;
-        }
-
-        String[] arrValue = ((String) stringValue).split(" ");
-
-        //we have to manually convert otherwise the delta state saving fails
-        //Arrays.asList returns a list which is not instantiable
-
-        List<String> saveVal = new ArrayList<String>(arrValue.length);
-        saveVal.addAll(Arrays.asList(arrValue));
-
-        deltaStateHelper.put(attribute, saveVal);
-    }
-
-
-    public boolean isDisabled() {
+    public boolean isDisabled() 
+    {
         Boolean retVal = (Boolean) deltaStateHelper.eval(ATTR_DISABLED);
         retVal = (retVal == null) ? false : retVal;
         return retVal;
     }
 
-    public void setDisabled(boolean disabled) {
+    public void setDisabled(boolean disabled) 
+    {
         deltaStateHelper.put(ATTR_DISABLED, disabled);
     }
 
-    public boolean isImmediate() {
+    public boolean isImmediate() 
+    {
         Boolean retVal = (Boolean) deltaStateHelper.eval(ATTR_IMMEDIATE);
         retVal = (retVal == null) ? false : retVal;
         return retVal;
     }
 
-    public void setImmediate(boolean immediate) {
+    public void setImmediate(boolean immediate) 
+    {
         deltaStateHelper.put(ATTR_IMMEDIATE, immediate);
     }
 
-    public boolean isImmediateSet() {
+    public boolean isImmediateSet() 
+    {
         return deltaStateHelper.eval(ATTR_IMMEDIATE) != null;
     }
 
-
-    public void removeAjaxBehaviorListener(AjaxBehaviorListener listener) {
-        removeBehaviorListener(listener);
-    }
-
-
     @Override
-    public Set<ClientBehaviorHint> getHints() {
+    public Set<ClientBehaviorHint> getHints() 
+    {
         return EnumSet.of(ClientBehaviorHint.SUBMITTING);
     }
 
-
     @Override
-    public String getRendererType() {
+    public String getRendererType() 
+    {
         return BEHAVIOR_ID;
     }
 
-
     @Override
     public void restoreState(FacesContext facesContext, Object o)
     {
@@ -254,11 +201,11 @@
             return;
         }
         Object[] values = (Object[]) o;
-
-        if (values[0] != null) {
+        if (values[0] != null) 
+        {
             super.restoreState(facesContext, values[0]);
         }
-       deltaStateHelper.restoreState(facesContext, values[1]);
+        deltaStateHelper.restoreState(facesContext, values[1]);
     }
 
     @Override
@@ -285,11 +232,68 @@
         }
     }
 
-    private void assertNull(Object item) {
-        if (item == null) {
-            throw new NullPointerException(ERR_KEY_IS_NULL);
+    private Map<String, ValueExpression> getValueExpressionMap() 
+    {
+        return _valueExpressions;
+    }
+    
+    /**
+     * Invokes eval on the deltaStateHelper and tries to get a
+     * Collection out of the result.
+     * @param attributeName
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    private Collection<String> evalForCollection(String attributeName)
+    {
+        Object value = deltaStateHelper.eval(attributeName);
+        if (value == null)
+        {
+            return Collections.<String>emptyList();
+        }
+        else if (value instanceof Collection)
+        {
+            return (Collection<String>) value;
+        }
+        else if (value instanceof String)
+        {
+            return getCollectionFromSpaceSplitString((String) value);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Type " + value.getClass()
+                    + " not supported for attribute " + attributeName);
         }
     }
     
+    /**
+     * Splits the String based on spaces and returns the 
+     * resulting Strings as Collection.
+     * @param stringValue
+     * @return
+     */
+    private Collection<String> getCollectionFromSpaceSplitString(String stringValue) {
+        //@special handling for @all, @none, @form and @this
+        if (stringValue.equals(VAL_FORM)) 
+        {
+            return VAL_FORM_LIST;
+        } 
+        else if (stringValue.equals(VAL_ALL)) 
+        {
+            return VAL_ALL_LIST;
+        } 
+        else if (stringValue.equals(VAL_NONE)) 
+        {
+            return VAL_NONE_LIST;
+        } 
+        else if (stringValue.equals(VAL_THIS)) 
+        {
+            return VAL_THIS_LIST; 
+        }
 
+        // not one of the "normal" values - split it and return the Collection
+        String[] arrValue = stringValue.split(" ");
+        return Arrays.asList(arrValue);
+    }
+    
 }